From 073ccd276a5977a07eef23ff9145fc2a53506e8e Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sat, 14 Nov 2020 17:06:39 -0500 Subject: [PATCH] New upstream version 1.0.1 --- .gitattributes | 3 + .gitignore | 19 +- .gitmodules | 5 + .travis.yml | 59 +- AUTHORS | 28 - BUGS | 3 - Changelog | 211 +- INSTALLME | 67 - Makefile | 284 +- README.md | 143 +- TODO | 3 - applications/Makefile | 22 +- applications/dashcast/Makefile | 86 - applications/dashcast/audio_data.h | 145 - applications/dashcast/audio_decoder.c | 446 - applications/dashcast/audio_decoder.h | 100 - applications/dashcast/audio_encoder.c | 355 - applications/dashcast/audio_muxer.c | 466 - applications/dashcast/audio_muxer.h | 132 - applications/dashcast/controler.c | 1454 - applications/dashcast/video_data.h | 173 - applications/dashcast/video_decoder.c | 443 - applications/dashcast/video_encoder.c | 292 - applications/dashcast/video_muxer.c | 973 - applications/deprecated/mp42ts/Makefile | 70 + applications/deprecated/mp42ts/main.c | 2932 + applications/deprecated/mp42ts/mp42ts.vcxproj | 265 + .../deprecated/old_arch/GPAX/GPAX.cpp | 76 + .../deprecated/old_arch/GPAX/GPAX.def | 9 + .../deprecated/old_arch/GPAX/GPAX.dsp | 173 + applications/deprecated/old_arch/GPAX/GPAX.h | 570 + .../deprecated/old_arch/GPAX/GPAX.idl | 92 + applications/deprecated/old_arch/GPAX/GPAX.rc | 151 + .../deprecated/old_arch/GPAX/GPAX.rgs | 175 + .../deprecated/old_arch/GPAX/GPAX.vcxproj | 376 + .../deprecated/old_arch/GPAX/GPAXPlugin.cpp | 710 + .../deprecated/old_arch/GPAX/GPAXPlugin.h | 269 + .../deprecated/old_arch/GPAX/GPAX_i.c | 178 + .../deprecated/old_arch/GPAX/GPAX_p.c | 603 + .../deprecated/old_arch/GPAX/GPAXps.def | 11 + .../deprecated/old_arch/GPAX/GPAXps.mk | 16 + .../deprecated/old_arch/GPAX/StdAfx.cpp | 12 + .../deprecated/old_arch/GPAX/StdAfx.h | 34 + .../deprecated/old_arch/GPAX/dlldata.c | 38 + .../deprecated/old_arch/GPAX/gpax.bmp | Bin 0 -> 246 bytes .../deprecated/old_arch/GPAX/resource.h | 24 + .../deprecated/old_arch/dashcast/Makefile | 86 + .../old_arch}/dashcast/audio_data.c | 0 .../deprecated/old_arch/dashcast/audio_data.h | 146 + .../old_arch/dashcast/audio_decoder.c | 446 + .../old_arch/dashcast/audio_decoder.h | 100 + .../old_arch/dashcast/audio_encoder.c | 355 + .../old_arch}/dashcast/audio_encoder.h | 0 .../old_arch/dashcast/audio_muxer.c | 466 + .../old_arch/dashcast/audio_muxer.h | 132 + .../old_arch}/dashcast/circular_buffer.c | 0 .../old_arch}/dashcast/circular_buffer.h | 0 .../old_arch}/dashcast/cmd_data.c | 0 .../old_arch}/dashcast/cmd_data.h | 0 .../deprecated/old_arch/dashcast/controler.c | 1454 + .../old_arch}/dashcast/controler.h | 0 .../old_arch}/dashcast/dashcast.c | 0 .../old_arch}/dashcast/libav_compat.h | 0 .../old_arch}/dashcast/message_queue.c | 0 .../old_arch}/dashcast/message_queue.h | 0 .../old_arch}/dashcast/register.c | 0 .../old_arch}/dashcast/register.h | 0 .../{ => deprecated/old_arch}/dashcast/task.c | 0 .../{ => deprecated/old_arch}/dashcast/task.h | 0 .../old_arch}/dashcast/video_data.c | 0 .../deprecated/old_arch/dashcast/video_data.h | 173 + .../old_arch/dashcast/video_decoder.c | 441 + .../old_arch}/dashcast/video_decoder.h | 0 .../old_arch/dashcast/video_encoder.c | 294 + .../old_arch}/dashcast/video_encoder.h | 0 .../old_arch/dashcast/video_muxer.c | 979 + .../old_arch}/dashcast/video_muxer.h | 0 .../old_arch}/dashcast/video_scaler.c | 0 .../old_arch}/dashcast/video_scaler.h | 0 .../deprecated/old_arch/mp42avi/Makefile | 48 + .../deprecated/old_arch/mp42avi/main.c | 768 + .../old_arch/osmo4_sym/aif/osmo4_icon.bmp | Bin 0 -> 5862 bytes .../osmo4_sym/aif/osmo4_icon_mask.bmp | Bin 0 -> 414 bytes .../old_arch/osmo4_sym/aif/osmo4_menu.bmp | Bin 0 -> 3766 bytes .../osmo4_sym/aif/osmo4_menu_mask.bmp | Bin 0 -> 294 bytes .../old_arch/osmo4_sym/aif/osmo4aif.rss | 14 + .../deprecated/old_arch/osmo4_sym/osmo4.cpp | 82 + .../deprecated/old_arch/osmo4_sym/osmo4.h | 38 + .../old_arch/osmo4_sym/osmo4_ui.cpp | 605 + .../deprecated/old_arch/osmo4_sym/osmo4_ui.h | 181 + .../old_arch/osmo4_sym/osmo4_view.cpp | 587 + .../old_arch/osmo4_sym/osmo4_view.h | 171 + .../old_arch/osmo4_sym/playlist.cpp | 529 + .../deprecated/old_arch/osmo4_sym/playlist.h | 114 + .../old_arch/osmo4_sym/res/osmo4.rss | 19 + .../old_arch/osmo4_sym/res/osmo4.svg | 35 + .../old_arch/osmo4_sym/res/osmo4_caption.rss | 21 + .../old_arch/osmo4_sym/res/osmo4_gen.rss | 59 + .../old_arch/osmo4_sym/res/osmo4_reg.rss | 31 + .../old_arch/osmo4_w32/AddressBar.cpp | 182 + .../old_arch/osmo4_w32/AddressBar.h | 90 + .../old_arch/osmo4_w32/FileProps.cpp | 622 + .../deprecated/old_arch/osmo4_w32/FileProps.h | 70 + .../deprecated/old_arch/osmo4_w32/MainFrm.cpp | 1588 + .../deprecated/old_arch/osmo4_w32/MainFrm.h | 224 + .../deprecated/old_arch/osmo4_w32/OpenUrl.cpp | 98 + .../deprecated/old_arch/osmo4_w32/OpenUrl.h | 49 + .../deprecated/old_arch/osmo4_w32/Options.cpp | 2080 + .../deprecated/old_arch/osmo4_w32/Options.h | 624 + .../deprecated/old_arch/osmo4_w32/Osmo4.cpp | 944 + .../deprecated/old_arch/osmo4_w32/Osmo4.h | 115 + .../deprecated/old_arch/osmo4_w32/Osmo4.rc | 885 + .../old_arch/osmo4_w32/Osmo4.vcxproj | 387 + .../old_arch/osmo4_w32/Playlist.cpp | 969 + .../deprecated/old_arch/osmo4_w32/Playlist.h | 120 + .../deprecated/old_arch/osmo4_w32/Sliders.cpp | 148 + .../deprecated/old_arch/osmo4_w32/Sliders.h | 62 + .../deprecated/old_arch/osmo4_w32/StdAfx.cpp | 8 + .../deprecated/old_arch/osmo4_w32/StdAfx.h | 30 + .../old_arch/osmo4_w32/res/Osmo4.rc2 | 13 + .../old_arch/osmo4_w32/res/error.ico | Bin 0 -> 766 bytes .../old_arch/osmo4_w32/res/maintool.bmp | Bin 0 -> 1438 bytes .../old_arch/osmo4_w32/res/message.ico | Bin 0 -> 766 bytes .../old_arch/osmo4_w32/res/osmo4.ico | Bin 0 -> 15086 bytes .../old_arch/osmo4_w32/res/pause.ico | Bin 0 -> 1078 bytes .../old_arch/osmo4_w32/res/play.ico | Bin 0 -> 1078 bytes .../old_arch/osmo4_w32/res/playlist.bmp | Bin 0 -> 958 bytes .../old_arch/osmo4_w32/res/stop.ico | Bin 0 -> 1078 bytes .../deprecated/old_arch/osmo4_w32/resource.h | 323 + .../deprecated/old_arch/osmo4_wce/MainFrm.cpp | 661 + .../deprecated/old_arch/osmo4_wce/MainFrm.h | 151 + .../deprecated/old_arch/osmo4_wce/OpenDlg.cpp | 92 + .../deprecated/old_arch/osmo4_wce/OpenDlg.h | 47 + .../deprecated/old_arch/osmo4_wce/Options.cpp | 1237 + .../deprecated/old_arch/osmo4_wce/Options.h | 388 + .../deprecated/old_arch/osmo4_wce/Osmo4.cpp | 638 + .../deprecated/old_arch/osmo4_wce/Osmo4.h | 113 + .../deprecated/old_arch/osmo4_wce/Osmo4.rc | 758 + .../old_arch/osmo4_wce/ProgressBar.cpp | 133 + .../old_arch/osmo4_wce/ProgressBar.h | 53 + .../deprecated/old_arch/osmo4_wce/Resource.h | 170 + .../deprecated/old_arch/osmo4_wce/StdAfx.cpp | 6 + .../deprecated/old_arch/osmo4_wce/StdAfx.h | 39 + .../deprecated/old_arch/osmo4_wce/newres.h | 28 + .../old_arch/osmo4_wce/res/Cmdbar.bmp | Bin 0 -> 886 bytes .../old_arch/osmo4_wce/res/Osmo4.ico | Bin 0 -> 1078 bytes .../old_arch/osmo4_wce/res/Osmo4.rc2 | 13 + .../release/install/archive.bat | 16 + .../release/install/build_installer.bat | 42 + .../release/install/gpac.inf | 0 .../release/install/readme.txt | 6 + .../old_arch/osmo4_wx/Darwin.Info.plist | 24 + .../osmo4_wx/Darwin.InfoPlist.strings | Bin 0 -> 504 bytes .../old_arch/osmo4_wx/Darwin.Osmo.icns | Bin 0 -> 38570 bytes .../deprecated/old_arch/osmo4_wx/Makefile | 85 + .../deprecated/old_arch/osmo4_wx/Playlist.cpp | 836 + .../deprecated/old_arch/osmo4_wx/Playlist.h | 135 + .../old_arch/osmo4_wx/fileprops.cpp | 650 + .../deprecated/old_arch/osmo4_wx/fileprops.h | 84 + .../deprecated/old_arch/osmo4_wx/menubtn.cpp | 870 + .../deprecated/old_arch/osmo4_wx/menubtn.h | 356 + .../deprecated/old_arch/osmo4_wx/osmo4.ico | Bin 0 -> 15086 bytes .../deprecated/old_arch/osmo4_wx/osmo4.xpm | 301 + .../deprecated/old_arch/osmo4_wx/playlist.xpm | 158 + .../deprecated/old_arch/osmo4_wx/resource.h | 16 + .../deprecated/old_arch/osmo4_wx/toolbar.xpm | 254 + .../old_arch/osmo4_wx/wxGPACControl.cpp | 1051 + .../old_arch/osmo4_wx/wxGPACControl.h | 138 + .../deprecated/old_arch/osmo4_wx/wxOsmo4.cpp | 2392 + .../deprecated/old_arch/osmo4_wx/wxOsmo4.h | 391 + .../deprecated/old_arch/osmo4_wx/wxOsmo4.rc | 72 + .../deprecated/old_arch/osmophone/Osmo4.ico | Bin 0 -> 1078 bytes .../deprecated/old_arch/osmophone/main.cpp | 1497 + .../deprecated/old_arch/osmophone/newres.h | 41 + .../old_arch/osmophone/openfile.cpp | 405 + .../old_arch/osmophone/osmophone.rc | 425 + .../old_arch/osmophone/osmophone.vcxproj | 343 + .../deprecated/old_arch/osmophone/resource.h | 169 + .../deprecated/old_arch/osmozilla/Makefile | 109 + .../old_arch/osmozilla/nsIOsmozilla.h | 148 + .../old_arch/osmozilla/nsIOsmozilla.idl | 10 + .../old_arch/osmozilla/nsIOsmozilla.xpt_linux | Bin 0 -> 180 bytes .../old_arch/osmozilla/nsIOsmozilla.xpt_w32 | Bin 0 -> 180 bytes .../old_arch/osmozilla/osmo_npapi.cpp | 854 + .../old_arch/osmozilla/osmo_npapi.h | 136 + .../old_arch/osmozilla/osmozilla.cpp | 531 + .../old_arch/osmozilla/osmozilla.def | 6 + .../deprecated/old_arch/osmozilla/osmozilla.h | 75 + .../old_arch/osmozilla/osmozilla.png | Bin 0 -> 121239 bytes .../old_arch/osmozilla/osmozilla.rc | 128 + .../old_arch/osmozilla/osmozilla.vcxproj | 304 + .../deprecated/old_arch/osmozilla/readme.txt | 8 + .../deprecated/old_arch/osmozilla/resource.h | 21 + applications/generators/MPEG4/Makefile | 4 +- applications/generators/MPEG4/main.c | 38 +- applications/generators/Makefile | 4 +- applications/generators/SVG/Makefile | 4 +- applications/generators/SVG/laser.c | 4 +- applications/generators/SVG/main.c | 6 +- applications/generators/SVG/v2.c | 3 - applications/generators/WebGLGen/Makefile | 52 + applications/generators/WebGLGen/WGLGen | Bin 0 -> 27288 bytes applications/generators/WebGLGen/main.c | 652 + applications/generators/WebGLGen/webgl1.idl | 708 + applications/generators/WebGLGen/webgl2.idl | 584 + applications/generators/X3D/Makefile | 4 +- applications/generators/X3D/main.c | 25 +- applications/gpac/Info.plist | 16 + applications/gpac/Makefile | 65 + applications/gpac/main.c | 4039 ++ applications/mp42avi/Makefile | 48 - applications/mp42avi/main.c | 785 - applications/mp42ts/Makefile | 64 - applications/mp42ts/main.c | 2884 - applications/mp4box/Makefile | 22 +- applications/mp4box/filedump.c | 2028 +- applications/mp4box/fileimport.c | 2313 +- applications/mp4box/live.c | 366 +- applications/mp4box/main.c | 4263 +- applications/mp4box/mp4box.h | 145 + applications/mp4box/wrapper.c | 2 - applications/mp4client/Makefile | 25 +- applications/mp4client/carbon_events.c | 2 +- applications/mp4client/extract.c | 984 - applications/mp4client/main.c | 2147 +- applications/mp4client/mp4client.rc | 2 +- applications/testapps/atscdmx/Makefile | 50 + applications/testapps/atscdmx/main.c | 151 + applications/testapps/bmp4demux/Makefile | 4 +- applications/testapps/broadcaster/Makefile | 4 +- .../testapps/broadcaster/RTP_serv_generator.c | 3 +- .../testapps/broadcaster/broadcaster.c | 14 +- .../testapps/broadcaster/sdp_generator.c | 2 +- applications/testapps/fmp4demux/Makefile | 4 +- applications/testapps/fmp4demux/main.c | 2 - applications/testapps/hevcbench/Makefile | 4 +- applications/testapps/hevcbench/main.c | 10 +- applications/testapps/loadcompare/Makefile | 4 +- .../testapps/loadcompare/loadcompare.c | 15 +- applications/testapps/mpedemux/Makefile | 8 +- applications/testapps/player_api/main.c | 2 +- applications/testapps/segmp4demux/Makefile | 4 +- applications/testapps/svg2bifs/main.c | 29 +- applications/testapps/ts2hds/Makefile | 50 + applications/{ => testapps}/ts2hds/f4m.c | 0 applications/testapps/ts2hds/f4v.c | 194 + applications/testapps/ts2hds/main.c | 303 + applications/{ => testapps}/ts2hds/ts2hds.h | 0 applications/testapps/ts2udp/main.c | 4 +- applications/testapps/udptsseg/Makefile | 70 + applications/testapps/udptsseg/main.c | 312 + .../{ => testapps}/udptsseg/udptsseg.dsp | 0 .../{ => testapps}/udptsseg/udptsseg.vcproj | 0 applications/ts2hds/Makefile | 50 - applications/ts2hds/f4v.c | 185 - applications/ts2hds/main.c | 304 - applications/udptsseg/Makefile | 70 - applications/udptsseg/main.c | 314 - .../release/install/archive.bat | 16 - .../release/install/build_installer.bat | 42 - .../release/install/readme.txt | 6 - change_version.sh | 38 +- configure | 925 +- doc/CODING_STYLE | 133 - doc/INSTALL.gcc | 116 - doc/INSTALL.gpe | 100 - doc/INSTALL.symbian | 84 - doc/INSTALL.w32 | 217 - doc/INSTALL.wCE | 134 - doc/configuration.html | 999 - doc/doxyfile | 2433 - doc/doxyfile-full | 2321 - doc/gpac.mp4 | Bin 2688 -> 0 bytes doc/ipmpx_syntax.bt | 237 - doc/man/dashcast.1 | 161 - doc/man/gpac.1 | 447 - doc/man/mp42avi.1 | 69 - doc/man/mp42ts.1 | 172 - doc/man/mp4box.1 | 808 - doc/man/mp4client.1 | 301 - generate_installer.bat | 3 +- gpac.spec | 61 +- gui/extensions/H2B2VS/h2b2vs.js | 462 - gui/extensions/H2B2VS/init.js | 16 - gui/extensions/player/fileopen.js | 255 - gui/extensions/player/init.js | 15 - gui/extensions/player/player.js | 1825 - gui/extensions/player/playlist.js | 383 - gui/extensions/player/stats.js | 608 - gui/extensions/widget_manager/init.js | 927 - gui/gui.js | 253 - gui/gui_old.bt | 42 - gui/gui_old.js | 2104 - gui/gwlib.js | 3629 -- gui/iphone_wm_gui.js | 1651 - gui/iphone_wm_gui.svg | 552 - gui/mpegu-wm.xmt | 69 - gui/tv_wm_gui.js | 485 - gui/webvtt-renderer.js | 285 - include/gpac/00_doxy.h | 116 + include/gpac/Remotery.h | 679 + include/gpac/ait.h | 4 +- include/gpac/atsc.h | 229 + include/gpac/avparse.h | 722 +- include/gpac/base_coding.h | 96 +- include/gpac/bifs.h | 150 +- include/gpac/bitstream.h | 718 +- include/gpac/cache.h | 237 +- include/gpac/color.h | 249 +- include/gpac/compositor.h | 307 +- include/gpac/config_file.h | 239 +- include/gpac/configuration.h | 69 +- include/gpac/constants.h | 1312 +- include/gpac/crypt.h | 246 +- include/gpac/crypt_tools.h | 251 + include/gpac/dash.h | 944 +- include/gpac/download.h | 581 +- include/gpac/dsmcc.h | 6 +- include/gpac/esi.h | 213 - include/gpac/events.h | 184 +- include/gpac/events_constants.h | 50 +- include/gpac/evg.h | 867 + include/gpac/filestreamer.h | 131 - include/gpac/filters.h | 3811 ++ include/gpac/html5_media.h | 102 +- include/gpac/html5_mse.h | 31 +- include/gpac/ietf.h | 1018 +- include/gpac/internal/avilib.h | 44 +- include/gpac/internal/bifs_dev.h | 3 +- include/gpac/internal/camera.h | 6 +- include/gpac/internal/compositor_dev.h | 1435 +- include/gpac/internal/crypt_dev.h | 180 +- include/gpac/internal/dvb_mpe_dev.h | 8 +- include/gpac/internal/ietf_dev.h | 243 +- include/gpac/internal/isomedia_dev.h | 1308 +- include/gpac/internal/laser_dev.h | 8 +- include/gpac/internal/m3u8.h | 20 +- include/gpac/internal/media_dev.h | 373 +- include/gpac/internal/mesh.h | 2 + include/gpac/internal/mpd.h | 478 - include/gpac/internal/odf_dev.h | 5 +- include/gpac/internal/odf_parse_common.h | 11 +- include/gpac/internal/ogg.h | 26 +- include/gpac/internal/scenegraph_dev.h | 201 +- include/gpac/internal/smjs_api.h | 358 - include/gpac/internal/swf_dev.h | 17 +- include/gpac/internal/terminal_dev.h | 1313 - include/gpac/internal/vobsub.h | 18 +- include/gpac/ismacryp.h | 189 - include/gpac/iso639.h | 48 +- include/gpac/isomedia.h | 6982 ++- include/gpac/laser.h | 132 +- include/gpac/list.h | 234 +- include/gpac/main.h | 253 + include/gpac/map.h | 213 - include/gpac/maths.h | 983 +- include/gpac/media_tools.h | 1019 +- include/gpac/mediaobject.h | 364 +- include/gpac/module.h | 312 +- include/gpac/modules/audio_out.h | 73 +- include/gpac/modules/codec.h | 149 +- include/gpac/modules/compositor_ext.h | 111 + include/gpac/modules/font.h | 2 +- include/gpac/modules/hardcoded_proto.h | 2 +- include/gpac/modules/js_usr.h | 70 - include/gpac/modules/raster2d.h | 262 - include/gpac/modules/service.h | 848 - include/gpac/modules/term_ext.h | 112 - include/gpac/modules/video_out.h | 8 +- include/gpac/mpd.h | 1136 + include/gpac/mpeg4_odf.h | 674 +- include/gpac/mpegts.h | 1437 +- include/gpac/network.h | 720 +- include/gpac/nodes_mpeg4.h | 3 +- include/gpac/nodes_svg.h | 196 - include/gpac/nodes_xbl.h | 70 - include/gpac/options.h | 300 +- include/gpac/path2d.h | 544 +- include/gpac/ringbuffer.h | 94 - include/gpac/rtp_streamer.h | 267 +- include/gpac/scene_engine.h | 233 +- include/gpac/scene_manager.h | 336 +- include/gpac/scenegraph.h | 717 +- include/gpac/scenegraph_svg.h | 750 +- include/gpac/scenegraph_vrml.h | 628 +- include/gpac/setup.h | 355 +- include/gpac/svg_types.h | 206 +- include/gpac/sync_layer.h | 66 +- include/gpac/term_info.h | 231 +- include/gpac/terminal.h | 318 +- include/gpac/thread.h | 361 +- include/gpac/token.h | 90 +- include/gpac/tools.h | 2016 +- include/gpac/unicode.h | 63 - include/gpac/user.h | 93 +- include/gpac/utf.h | 110 +- include/gpac/version.h | 50 +- include/gpac/webvtt.h | 73 +- include/gpac/xml.h | 426 +- mkdmg.sh | 85 +- modules/Makefile | 136 +- modules/aac_in/Makefile | 62 - modules/aac_in/aac_in.c | 999 - modules/aac_in/faad_dec.c | 499 - modules/ac3_in/Makefile | 59 - modules/ac3_in/ac3_in.c | 704 - modules/ac3_in/liba52_dec.c | 374 - modules/alsa/Makefile | 6 +- modules/alsa/alsa.c | 43 +- modules/amr_dec/Makefile | 80 - modules/amr_dec/amr_dec.c | 342 - modules/amr_dec/amr_in.c | 620 - modules/amr_dec/amr_nb/typedefs.h | 195 - modules/amr_dec/amr_nb_api.h | 61 - modules/amr_float_dec/Makefile | 62 - modules/amr_float_dec/amr_api.h | 35 - modules/amr_float_dec/amr_float_dec.c | 343 - modules/audio_filter/Makefile | 42 - modules/avcap/Makefile | 46 - modules/avcap/avcap.cpp | 508 - modules/bifs_dec/Makefile | 50 - modules/bifs_dec/bifs_dec.c | 220 - modules/ctx_load/Makefile | 49 - modules/ctx_load/ctx_load.c | 850 - modules/dec_openhevc/Makefile | 59 + modules/dektec_out/Makefile | 10 +- modules/dektec_out/dektec_video.cpp | 1018 +- modules/dektec_out/dektec_video.h | 98 + modules/dektec_out/dektec_video_decl.c | 111 + modules/dektec_out/dektec_video_old.cpp | 367 + modules/dektec_out/out_dektec.vcxproj | 286 + modules/demo_is/Makefile | 6 +- modules/demo_is/demo_is.c | 2 +- .../{ => deprecated}/epoc_hw/epoc_aout.cpp | 0 .../{ => deprecated}/epoc_hw/epoc_codec.cpp | 0 modules/deprecated/epoc_hw/epoc_vout.cpp | 555 + .../deprecated/old_arch/audio_filter/Makefile | 42 + .../old_arch}/audio_filter/audio_filter.c | 0 modules/deprecated/old_arch/avcap/Makefile | 46 + modules/deprecated/old_arch/avcap/avcap.cpp | 508 + .../deprecated/old_arch/ffmpeg_in/Makefile | 88 + .../old_arch/ffmpeg_in/ffmpeg_decode.c | 1811 + .../old_arch/ffmpeg_in/ffmpeg_demux.c | 1060 + .../deprecated/old_arch/ffmpeg_in/ffmpeg_in.h | 326 + .../old_arch}/ffmpeg_in/ffmpeg_load.c | 0 modules/deprecated/old_arch/freenect/Makefile | 54 + .../old_arch}/freenect/freenect.c | 0 modules/deprecated/old_arch/gapi/gapi.cpp | 1675 + modules/{ => deprecated/old_arch}/gapi/gapi.h | 0 .../old_arch/gdip_raster/gdip_font.cpp | 407 + .../old_arch}/gdip_raster/gdip_grad.cpp | 0 .../old_arch}/gdip_raster/gdip_priv.h | 0 .../old_arch/gdip_raster/gdip_rend.cpp | 499 + .../old_arch/gdip_raster/gdip_texture.cpp | 440 + modules/deprecated/old_arch/hyb_in/Makefile | 46 + .../old_arch}/hyb_in/fm_fake_pull.c | 0 .../old_arch}/hyb_in/fm_fake_push.c | 0 .../old_arch}/hyb_in/fm_mmbtools.c | 0 modules/deprecated/old_arch/hyb_in/hyb_in.c | 312 + .../{ => deprecated/old_arch}/hyb_in/hyb_in.h | 0 .../deprecated/old_arch/libplayer/Makefile | 43 + .../old_arch}/libplayer/libplayer.c | 0 modules/deprecated/old_arch/mse_in/Makefile | 59 + modules/deprecated/old_arch/mse_in/mse_in.c | 389 + modules/deprecated/old_arch/netctrl/Makefile | 47 + modules/deprecated/old_arch/netctrl/netctrl.c | 212 + .../deprecated/old_arch/opencv_is/Makefile | 49 + .../old_arch}/opencv_is/demo-sensor.bt | 0 .../haarcascade_frontalface_default.xml | 0 .../old_arch}/opencv_is/opencv_is.c | 0 modules/deprecated/old_arch/osd/Makefile | 47 + modules/deprecated/old_arch/osd/osd.c | 306 + .../platinum/GPACFileMediaServer.cpp | 0 .../old_arch}/platinum/GPACFileMediaServer.h | 0 .../platinum/GPACMediaController.cpp | 0 .../old_arch}/platinum/GPACMediaController.h | 0 .../old_arch/platinum/GPACMediaRenderer.cpp | 600 + .../old_arch}/platinum/GPACMediaRenderer.h | 0 .../old_arch/platinum/GPACPlatinum.cpp | 1740 + .../old_arch}/platinum/GPACPlatinum.h | 0 .../old_arch}/platinum/GenericDevice.cpp | 0 .../old_arch}/platinum/GenericDevice.h | 0 modules/deprecated/old_arch/platinum/Makefile | 65 + modules/deprecated/old_arch/psvr/Makefile | 47 + modules/deprecated/old_arch/psvr/psvr.c | 213 + modules/deprecated/old_arch/rvc_dec/Makefile | 46 + modules/deprecated/old_arch/rvc_dec/rvc_dec.c | 499 + modules/deprecated/old_arch/ui_rec/Makefile | 52 + .../old_arch}/ui_rec/readme.txt | 0 modules/deprecated/old_arch/ui_rec/ui_rec.c | 252 + .../deprecated/old_arch/widgetman/Makefile | 66 + .../old_arch}/widgetman/unzip.c | 0 .../old_arch}/widgetman/unzip.h | 0 .../deprecated/old_arch/widgetman/wgt_load.c | 308 + .../old_arch}/widgetman/wgt_load_base.js | 0 .../deprecated/old_arch/widgetman/widget.c | 452 + .../deprecated/old_arch/widgetman/widgetman.c | 3747 ++ .../old_arch}/widgetman/widgetman.h | 0 modules/deprecated/old_arch/wiiis/Makefile | 49 + .../old_arch}/wiiis/test_wii.bt | 0 modules/deprecated/old_arch/wiiis/wiiis.c | 264 + modules/deprecated/oss_audio/Makefile | 55 + modules/deprecated/oss_audio/oss.c | 294 + modules/directfb_out/Makefile | 7 +- modules/directfb_out/directfb_out.c | 89 +- modules/directfb_out/directfb_wrapper.c | 14 +- modules/droid_audio/droidaudio.c | 16 +- modules/droid_cam/droid_cam.c | 57 +- modules/droid_mpegv/droid_mpegv.c | 13 +- modules/droid_out/droid_vout-bitmap.c | 6 +- modules/droid_out/droid_vout.c | 144 +- modules/dummy_in/Makefile | 49 - modules/dummy_in/dummy_in.c | 527 - modules/dx_hw/Makefile | 10 +- modules/dx_hw/copy_pixels.c | 736 - modules/dx_hw/dx_2d.c | 123 +- modules/dx_hw/dx_audio.c | 53 +- modules/dx_hw/dx_hw.h | 15 +- modules/dx_hw/dx_hw.rc | 2 +- modules/dx_hw/dx_video.c | 180 +- modules/dx_hw/dx_window.c | 555 +- modules/epoc_hw/epoc_vout.cpp | 555 - modules/ffmpeg_in/Makefile | 88 - modules/ffmpeg_in/ffmpeg_decode.c | 1758 - modules/ffmpeg_in/ffmpeg_demux.c | 1057 - modules/ffmpeg_in/ffmpeg_in.h | 315 - modules/filter_export.cpp | 36 + modules/freenect/Makefile | 54 - modules/ft_font/Makefile | 6 +- modules/ft_font/ft_font.c | 79 +- modules/gapi/gapi.cpp | 1675 - modules/gdip_raster/gdip_font.cpp | 407 - modules/gdip_raster/gdip_rend.cpp | 499 - modules/gdip_raster/gdip_texture.cpp | 442 - modules/gpac_js/Makefile | 63 - modules/gpac_js/gpac_js.c | 2517 - modules/hyb_in/Makefile | 46 - modules/hyb_in/hyb_in.c | 312 - modules/img_in/Makefile | 78 - modules/img_in/bmp_dec.c | 210 - modules/img_in/img_dec.c | 159 - modules/img_in/img_in.c | 461 - modules/img_in/img_in.h | 107 - modules/img_in/jp2_dec.c | 469 - modules/img_in/jpeg_dec.c | 156 - modules/img_in/png_dec.c | 181 - modules/ios_cam/ios_cam.c | 12 +- modules/ios_mpegv/ios_mpegv.c | 6 +- modules/ismacryp/Makefile | 48 - modules/ismacryp/isma_ea.c | 658 - modules/isom_in/Makefile | 49 - modules/isom_in/isom_cache.c | 295 - modules/isom_in/isom_in.h | 166 - modules/isom_in/load.c | 331 - modules/isom_in/read.c | 1282 - modules/isom_in/read_ch.c | 946 - modules/jack/Makefile | 8 +- modules/jack/jack.c | 152 +- modules/laser_dec/Makefile | 50 - modules/laser_dec/laser_dec.c | 202 - modules/libplayer/Makefile | 43 - modules/mediacodec_dec/Makefile | 58 - modules/mediacodec_dec/mediacodec_dec.c | 1104 - modules/mediacodec_dec/mediacodec_dec.h | 35 - modules/mediacodec_dec/mediacodec_dec_jni.c | 204 - modules/mp3_in/Makefile | 65 - modules/mp3_in/mad_dec.c | 377 - modules/mp3_in/mp3_in.c | 781 - modules/mpd_in/Makefile | 46 - modules/mpd_in/mpd_in.c | 1668 - modules/mpegts_in/Makefile | 50 - modules/mpegts_in/mpegts_in.c | 1750 - modules/mse_in/Makefile | 59 - modules/mse_in/mse_in.c | 387 - modules/odf_dec/Makefile | 49 - modules/odf_dec/odf_dec.c | 323 - modules/ogg/Makefile | 83 - modules/ogg/ogg_in.c | 1015 - modules/ogg/ogg_in.h | 64 - modules/ogg/ogg_load.c | 165 - modules/ogg/theora_dec.c | 235 - modules/ogg/vorbis_dec.c | 278 - modules/opencv_is/Makefile | 49 - modules/openhevc_dec/Makefile | 58 - modules/openhevc_dec/openhevc_dec.c | 931 - modules/opensvc_dec/Makefile | 45 - modules/opensvc_dec/opensvc_dec.c | 458 - modules/osd/Makefile | 47 - modules/osd/osd.c | 306 - modules/oss_audio/Makefile | 55 - modules/oss_audio/oss.c | 286 - modules/platinum/GPACMediaRenderer.cpp | 600 - modules/platinum/GPACPlatinum.cpp | 1740 - modules/platinum/Makefile | 63 - modules/pulseaudio/Makefile | 6 +- modules/pulseaudio/pulseaudio.c | 93 +- modules/raw_out/Makefile | 58 - modules/raw_out/raw_video.c | 321 - modules/redirect_av/Makefile | 53 - modules/redirect_av/ffmpeg_ts_muxer.c | 417 - modules/redirect_av/gpac_ts_muxer.c | 178 - modules/redirect_av/redirect_av.c | 865 - modules/redirect_av/ts_muxer.h | 161 - modules/rtp_in/Makefile | 51 - modules/rtp_in/rtp_in.c | 1014 - modules/rtp_in/rtp_in.h | 387 - modules/rtp_in/rtp_session.c | 412 - modules/rtp_in/rtp_signaling.c | 922 - modules/rtp_in/rtp_stream.c | 643 - modules/rtp_in/sdp_fetch.c | 186 - modules/rtp_in/sdp_load.c | 585 - modules/rvc_dec/Makefile | 46 - modules/rvc_dec/rvc_dec.c | 499 - modules/saf_in/Makefile | 51 - modules/saf_in/saf_in.c | 645 - modules/sdl_out/Makefile | 8 +- modules/sdl_out/audio.c | 49 +- modules/sdl_out/sdl_out.h | 13 +- modules/sdl_out/video.c | 1235 +- modules/soft_raster/Makefile | 55 - modules/soft_raster/ftgrays.c | 778 - modules/soft_raster/rast_soft.h | 364 - modules/soft_raster/raster_565.c | 495 - modules/soft_raster/raster_argb.c | 730 - modules/soft_raster/raster_load.c | 106 - modules/soft_raster/raster_rgb.c | 402 - modules/soft_raster/stencil.c | 943 - modules/soft_raster/surface.c | 662 - modules/svg_in/Makefile | 57 - modules/svg_in/svg_in.c | 466 - modules/timedtext/Makefile | 50 - modules/timedtext/timedtext_dec.c | 1263 - modules/timedtext/timedtext_in.c | 470 - modules/ui_rec/Makefile | 52 - modules/ui_rec/ui_rec.c | 252 - modules/validator/Makefile | 6 +- modules/validator/validator.c | 263 +- modules/vtb_decode/Makefile | 43 - modules/vtb_decode/vtb_decode.c | 1341 - modules/vtt_in/Makefile | 51 - modules/vtt_in/vtt_dec.c | 490 - modules/vtt_in/vtt_in.c | 374 - modules/wav_out/Makefile | 6 +- modules/wav_out/wav_out.c | 34 +- modules/widgetman/Makefile | 64 - modules/widgetman/wgt_load.c | 308 - modules/widgetman/widget.c | 452 - modules/widgetman/widgetman.c | 3747 -- modules/wiiis/Makefile | 49 - modules/wiiis/wiiis.c | 264 - modules/x11_out/Makefile | 18 +- modules/x11_out/x11_out.c | 784 +- modules/x11_out/x11_out.h | 4 +- modules/xvid_dec/Makefile | 61 - modules/xvid_dec/xvid_dec.c | 515 - modules/xvid_dec/xvid_dec_wce.cpp | 303 - packagers/osx/GPAC.app/Contents/Info.plist | 577 + packagers/osx/GPAC.app/Contents/PkgInfo | 1 + .../osx/GPAC.app/Contents/Resources/osmo.icns | Bin 0 -> 147235 bytes .../Contents/Resources/osmo_audio.icns | Bin 0 -> 209406 bytes .../Contents/Resources/osmo_generic.icns | Bin 0 -> 190916 bytes .../Contents/Resources/osmo_model.icns | Bin 0 -> 236301 bytes .../Contents/Resources/osmo_subs.icns | Bin 0 -> 176846 bytes .../Contents/Resources/osmo_video.icns | Bin 0 -> 221221 bytes .../Contents/Resources/osmo_widget.icns | Bin 0 -> 227171 bytes packagers/osx/SLA.r | 446 + packagers/osx/distribution.xml | 19 + packagers/osx/res/background.png | Bin 0 -> 98776 bytes packagers/osx/res/preamble.txt | 8 + packagers/osx/scripts/postinstall | 14 + packagers/win32_64/nsis/gpac_installer.nsi | 672 +- shaders/fragment.glsl | 386 - share/default.cfg | 16 + share/deprecated/iphone_wm_gui.js | 1651 + share/deprecated/iphone_wm_gui.svg | 552 + share/deprecated/mpegu-core.js | 1794 + {gui => share/deprecated}/mpegu-wm.bt | 0 share/deprecated/mpegu-wm.js | 1723 + share/deprecated/mpegu-wm.xmt | 69 + share/deprecated/tv_wm_gui.js | 485 + {gui => share/deprecated}/tv_wm_gui.svg | 0 share/doc/CODING_STYLE | 137 + {doc => share/doc}/GPAC UPnP.doc | Bin {doc => share/doc}/ISO 639-2 codes.txt | 0 {doc => share/doc}/SceneGenerators | 0 share/doc/configuration.html | 103 + share/doc/doxyfile | 2433 + share/doc/doxyfile-full | 2321 + share/doc/idl/core.idl | 762 + share/doc/idl/evg.idl | 1828 + share/doc/idl/filtersession.idl | 278 + share/doc/idl/jsf.idl | 946 + share/doc/idl/scenejs.idl | 426 + share/doc/idl/storage.idl | 57 + share/doc/idl/webgl.idl | 457 + share/doc/idl/xhr.idl | 56 + share/doc/ipmpx_syntax.bt | 237 + share/doc/man/gpac-filters.1 | 6006 ++ share/doc/man/gpac.1 | 3713 ++ share/doc/man/mp4box.1 | 2317 + share/doc/man/mp4client.1 | 270 + {doc => share/doc}/osmo4.ico | Bin .../gui}/extensions/H2B2VS/H2B2VS.png | Bin share/gui/extensions/H2B2VS/h2b2vs.js | 462 + share/gui/extensions/H2B2VS/init.js | 15 + .../gui}/extensions/H2B2VS/logo_hd.png | Bin .../gui}/extensions/H2B2VS/logo_uhd.png | Bin share/gui/extensions/about/info.js | 15 + share/gui/extensions/about/info.svg | 48 + share/gui/extensions/about/init.js | 15 + .../bifs_tests/applications-other.svg | 0 .../gui}/extensions/bifs_tests/bifs_tests.js | 0 .../gui}/extensions/bifs_tests/init.js | 0 .../player/applications-multimedia.svg | 0 share/gui/extensions/player/fileopen.js | 260 + share/gui/extensions/player/init.js | 24 + share/gui/extensions/player/player.js | 1862 + share/gui/extensions/player/playlist.js | 387 + share/gui/extensions/player/stats.js | 626 + .../gui}/extensions/showroom/init.js | 0 .../gui}/extensions/showroom/osmo.bt | 0 .../gui}/extensions/showroom/showroom.js | 0 .../widget_manager/applications-system.svg | 0 share/gui/extensions/widget_manager/init.js | 927 + {gui => share/gui}/gui.bt | 0 share/gui/gui.js | 311 + share/gui/gwlib.js | 3636 ++ {gui => share/gui}/icons/add.svg | 0 {gui => share/gui}/icons/app.svg | 0 {gui => share/gui}/icons/audio.svg | 0 {gui => share/gui}/icons/audio_full.svg | 0 {gui => share/gui}/icons/audio_mute.svg | 0 {gui => share/gui}/icons/check.svg | 0 {gui => share/gui}/icons/close.svg | 0 {gui => share/gui}/icons/compass.svg | 0 {gui => share/gui}/icons/cross.svg | 0 {gui => share/gui}/icons/down.svg | 0 {gui => share/gui}/icons/expand.svg | 0 {gui => share/gui}/icons/file.svg | 0 {gui => share/gui}/icons/film.svg | 0 {gui => share/gui}/icons/folder.svg | 0 {gui => share/gui}/icons/harddrive.svg | 0 {gui => share/gui}/icons/heart.svg | 0 {gui => share/gui}/icons/home.svg | 0 {gui => share/gui}/icons/image.svg | 0 {gui => share/gui}/icons/info.svg | 0 {gui => share/gui}/icons/laptop.svg | 0 {gui => share/gui}/icons/left.svg | 0 {gui => share/gui}/icons/list.svg | 0 {gui => share/gui}/icons/live.svg | 0 {gui => share/gui}/icons/media_next.svg | 0 {gui => share/gui}/icons/media_prev.svg | 0 {gui => share/gui}/icons/monitor.svg | 0 {gui => share/gui}/icons/more.svg | 0 {gui => share/gui}/icons/musical.svg | 0 {gui => share/gui}/icons/navigation.svg | 0 {gui => share/gui}/icons/network.svg | 0 {gui => share/gui}/icons/next.svg | 0 {gui => share/gui}/icons/osmo.svg | 0 {gui => share/gui}/icons/overflowing.svg | 0 {gui => share/gui}/icons/pause.svg | 0 {gui => share/gui}/icons/pl_next.svg | 0 {gui => share/gui}/icons/pl_prev.svg | 0 {gui => share/gui}/icons/play.svg | 0 {gui => share/gui}/icons/play_loop.svg | 0 {gui => share/gui}/icons/play_shuffle.svg | 0 {gui => share/gui}/icons/play_single.svg | 0 {gui => share/gui}/icons/power.svg | 0 {gui => share/gui}/icons/previous.svg | 0 {gui => share/gui}/icons/remove.svg | 0 {gui => share/gui}/icons/resize.svg | 0 {gui => share/gui}/icons/rewind.svg | 0 {gui => share/gui}/icons/right.svg | 0 {gui => share/gui}/icons/seek_forward.svg | 0 {gui => share/gui}/icons/shrink.svg | 0 {gui => share/gui}/icons/sort.svg | 0 {gui => share/gui}/icons/speed.svg | 0 {gui => share/gui}/icons/star.svg | 0 {gui => share/gui}/icons/stop.svg | 0 {gui => share/gui}/icons/stop2.svg | 0 {gui => share/gui}/icons/trash.svg | 0 {gui => share/gui}/icons/tray.svg | 0 {gui => share/gui}/icons/tv.svg | 0 {gui => share/gui}/icons/up.svg | 0 {gui => share/gui}/icons/world.svg | 0 share/lang/fr.txt | 2440 + share/res/gpac.mp4 | Bin 0 -> 1660 bytes .../logo.png => share/res/gpac.png | Bin share/res/gpac_cfg_test.mp4 | Bin 0 -> 132360 bytes share/scripts/ttml-renderer.js | 277 + share/scripts/webvtt-renderer.js | 289 + share/shaders/fragment.glsl | 335 + {shaders => share/shaders}/vertex.glsl | 0 share/vis/Code/Console.js | 208 + share/vis/Code/DataViewReader.js | 47 + share/vis/Code/PixelTimeRange.js | 61 + share/vis/Code/Remotery.js | 338 + share/vis/Code/SampleWindow.js | 215 + share/vis/Code/ThreadFrame.js | 28 + share/vis/Code/TimelineRow.js | 379 + share/vis/Code/TimelineWindow.js | 284 + share/vis/Code/TitleWindow.js | 71 + share/vis/Code/WebSocketConnection.js | 137 + share/vis/Styles/Remotery.css | 234 + .../extern/BrowserLib/Core/Code/Animation.js | 65 + share/vis/extern/BrowserLib/Core/Code/Bind.js | 92 + .../extern/BrowserLib/Core/Code/Convert.js | 218 + share/vis/extern/BrowserLib/Core/Code/Core.js | 26 + share/vis/extern/BrowserLib/Core/Code/DOM.js | 499 + .../extern/BrowserLib/Core/Code/Keyboard.js | 149 + .../extern/BrowserLib/Core/Code/LocalStore.js | 40 + .../vis/extern/BrowserLib/Core/Code/Mouse.js | 83 + .../BrowserLib/Core/Code/MurmurHash3.js | 68 + .../BrowserLib/WindowManager/Code/Button.js | 131 + .../BrowserLib/WindowManager/Code/ComboBox.js | 237 + .../WindowManager/Code/Container.js | 34 + .../BrowserLib/WindowManager/Code/EditBox.js | 119 + .../BrowserLib/WindowManager/Code/Grid.js | 248 + .../BrowserLib/WindowManager/Code/Label.js | 31 + .../BrowserLib/WindowManager/Code/Treeview.js | 352 + .../WindowManager/Code/TreeviewItem.js | 109 + .../BrowserLib/WindowManager/Code/Window.js | 295 + .../WindowManager/Code/WindowManager.js | 54 + .../WindowManager/Styles/WindowManager.css | 652 + share/vis/index.html | 55 + src/Makefile | 257 +- src/bifs/arith_decoder.c | 5 +- src/bifs/bifs_codec.c | 68 +- src/bifs/com_dec.c | 18 +- src/bifs/com_enc.c | 12 +- src/bifs/conditional.c | 1 + src/bifs/field_decode.c | 22 +- src/bifs/field_encode.c | 25 +- src/bifs/memory_decoder.c | 31 +- src/bifs/predictive_mffield.c | 2 +- src/bifs/quantize.c | 4 +- src/bifs/script.h | 4 +- src/bifs/script_dec.c | 4 +- src/bifs/script_enc.c | 13 +- src/bifs/unquantize.c | 2 +- src/compositor/audio_input.c | 215 +- src/compositor/audio_mixer.c | 622 +- src/compositor/audio_render.c | 860 +- src/compositor/bindable.c | 3 +- src/compositor/camera.c | 43 +- src/compositor/clock.c | 298 + src/compositor/compositor.c | 2122 +- src/compositor/compositor_2d.c | 361 +- src/compositor/compositor_3d.c | 24 +- src/compositor/compositor_node_init.c | 3 +- src/compositor/drawable.c | 41 +- src/compositor/drawable.h | 2 +- src/compositor/events.c | 73 +- src/compositor/font_engine.c | 121 +- src/compositor/gl_inc.h | 302 +- src/compositor/hardcoded_protos.c | 426 +- src/compositor/hc_flash_shape.c | 10 +- src/compositor/media_object.c | 1564 + src/compositor/mesh.c | 40 +- src/compositor/mesh_collide.c | 10 +- src/compositor/mesh_tesselate.c | 26 +- src/compositor/mpeg4_animstream.c | 6 +- src/compositor/mpeg4_audio.c | 67 +- src/compositor/mpeg4_background.c | 9 +- src/compositor/mpeg4_background2d.c | 18 +- src/compositor/mpeg4_bitmap.c | 13 +- src/compositor/mpeg4_composite.c | 780 +- src/compositor/mpeg4_form.c | 7 +- src/compositor/mpeg4_geometry_2d.c | 101 +- src/compositor/mpeg4_geometry_3d.c | 107 +- src/compositor/mpeg4_geometry_ifs2d.c | 54 +- src/compositor/mpeg4_geometry_ils2d.c | 52 +- src/compositor/mpeg4_gradients.c | 161 +- src/compositor/mpeg4_grouping.c | 8 +- src/compositor/mpeg4_grouping_2d.c | 4 + src/compositor/mpeg4_grouping_3d.c | 2 + src/compositor/mpeg4_inline.c | 786 + src/compositor/mpeg4_inputsensor.c | 993 + src/compositor/mpeg4_layer_3d.c | 199 +- src/compositor/mpeg4_layout.c | 28 +- src/compositor/mpeg4_mediacontrol.c | 704 + src/compositor/mpeg4_mediasensor.c | 288 + src/compositor/mpeg4_path_layout.c | 3 +- src/compositor/mpeg4_sensors.c | 68 +- src/compositor/mpeg4_sound.c | 21 +- src/compositor/mpeg4_text.c | 37 +- src/compositor/mpeg4_textures.c | 163 +- src/compositor/mpeg4_timesensor.c | 2 +- src/compositor/mpeg4_viewport.c | 50 +- src/compositor/navigate.c | 304 +- src/compositor/nodes_stacks.h | 29 +- src/compositor/object_manager.c | 1967 + src/compositor/offscreen_cache.c | 45 +- src/compositor/scene.c | 3365 + src/compositor/scene_node_init.c | 361 + src/compositor/scene_ns.c | 612 + src/compositor/svg_base.c | 33 +- src/compositor/svg_external.c | 187 + src/compositor/svg_filters.c | 12 +- src/compositor/svg_font.c | 36 +- src/compositor/svg_geometry.c | 2 +- src/compositor/svg_grouping.c | 125 +- src/compositor/svg_media.c | 55 +- src/compositor/svg_paint_servers.c | 85 +- src/compositor/svg_text.c | 14 +- src/compositor/texturing.c | 114 +- src/compositor/texturing.h | 11 +- src/compositor/texturing_gl.c | 1614 +- src/compositor/visual_manager.c | 18 +- src/compositor/visual_manager.h | 60 +- src/compositor/visual_manager_2d.c | 47 +- src/compositor/visual_manager_2d.h | 8 +- src/compositor/visual_manager_2d_draw.c | 209 +- src/compositor/visual_manager_3d.c | 236 +- src/compositor/visual_manager_3d.h | 9 +- src/compositor/visual_manager_3d_gl.c | 1169 +- src/compositor/x3d_geometry.c | 43 +- src/crypto/g_crypt.c | 105 + src/crypto/g_crypt_openssl.c | 226 + src/crypto/g_crypt_tinyaes.c | 201 + src/crypto/tiny_aes.c | 587 + src/crypto/tiny_aes.h | 93 + src/dir_info | 47 - src/evg/ftgrays.c | 694 + src/evg/rast_soft.h | 524 + src/evg/raster3d.c | 1480 + src/evg/raster_565.c | 662 + src/evg/raster_argb.c | 758 + src/evg/raster_rgb.c | 389 + src/evg/raster_yuv.c | 2228 + src/evg/stencil.c | 2021 + src/evg/surface.c | 1111 + src/export.cpp | 925 +- src/filter_core/filter.c | 3854 ++ src/filter_core/filter_pck.c | 1662 + src/filter_core/filter_pid.c | 6825 ++ src/filter_core/filter_props.c | 1595 + src/filter_core/filter_queue.c | 354 + src/filter_core/filter_register.c | 293 + src/filter_core/filter_session.c | 3254 + src/filter_core/filter_session.h | 1016 + src/filter_core/filter_session_js.c | 1241 + src/filters/base_filter_example.c | 168 + src/filters/bsrw.c | 642 + src/filters/compose.c | 996 + src/filters/dasher.c | 7208 +++ src/filters/dec_ac52.c | 298 + src/filters/dec_bifs.c | 300 + src/filters/dec_faad.c | 430 + src/filters/dec_img.c | 173 + src/filters/dec_j2k.c | 625 + src/filters/dec_laser.c | 273 + src/filters/dec_mad.c | 298 + src/filters/dec_mediacodec.c | 1278 + src/filters/dec_mediacodec.h | 128 + src/filters/dec_mediacodec_jni.c | 408 + src/filters/dec_nvdec.c | 1508 + src/filters/dec_nvdec_sdk.c | 712 + src/filters/dec_nvdec_sdk.h | 2898 + src/filters/dec_odf.c | 482 + src/filters/dec_openhevc.c | 1294 + src/filters/dec_opensvc.c | 597 + src/filters/dec_theora.c | 313 + src/filters/dec_ttml.c | 536 + src/filters/dec_ttxt.c | 1354 + src/filters/dec_vorbis.c | 313 + src/filters/dec_vtb.c | 2017 + .../filters/dec_vtb_glctx.m | 0 src/filters/dec_webvtt.c | 513 + src/filters/dec_xvid.c | 461 + src/filters/decrypt_cenc_isma.c | 1335 + src/filters/dmx_avi.c | 647 + src/filters/dmx_dash.c | 1851 + src/filters/dmx_gsf.c | 1290 + src/filters/dmx_m2ts.c | 1153 + src/filters/dmx_mpegps.c | 493 + src/filters/dmx_nhml.c | 1411 + src/filters/dmx_nhnt.c | 513 + src/filters/dmx_ogg.c | 845 + src/filters/dmx_saf.c | 464 + src/filters/dmx_vobsub.c | 486 + src/filters/enc_jpg.c | 409 + src/filters/enc_png.c | 387 + src/filters/encrypt_cenc_isma.c | 1890 + src/filters/ff_avf.c | 1032 + src/filters/ff_common.c | 1256 + src/filters/ff_common.h | 75 + src/filters/ff_dec.c | 933 + src/filters/ff_dmx.c | 1029 + src/filters/ff_enc.c | 1460 + src/filters/ff_mx.c | 1037 + src/filters/ff_rescale.c | 422 + src/filters/filelist.c | 1049 + src/filters/hevcmerge.c | 1652 + src/filters/hevcsplit.c | 962 + src/filters/in_atsc.c | 507 + src/filters/in_dvb4linux.c | 438 + src/filters/in_file.c | 593 + src/filters/in_http.c | 478 + src/filters/in_pipe.c | 534 + src/filters/in_rtp.c | 809 + src/filters/in_rtp.h | 359 + src/filters/in_rtp_rtsp.c | 383 + src/filters/in_rtp_sdp.c | 378 + src/filters/in_rtp_signaling.c | 867 + src/filters/in_rtp_stream.c | 766 + src/filters/in_sock.c | 543 + src/filters/inspect.c | 2799 + src/filters/isoffin.h | 222 + src/filters/isoffin_load.c | 1260 + src/filters/isoffin_read.c | 1428 + src/filters/isoffin_read_ch.c | 693 + src/filters/jsfilter.c | 4397 ++ src/filters/load_bt_xmt.c | 911 + src/filters/load_svg.c | 481 + src/filters/load_text.c | 3082 + src/filters/mux_avi.c | 627 + src/filters/mux_gsf.c | 1154 + src/filters/mux_isom.c | 5653 ++ src/filters/mux_ts.c | 1725 + src/filters/out_audio.c | 579 + src/filters/out_file.c | 623 + src/filters/out_http.c | 2786 + src/filters/out_pipe.c | 513 + src/filters/out_rtp.c | 1194 + src/filters/out_rtp.h | 107 + src/filters/out_rtsp.c | 1348 + src/filters/out_sock.c | 581 + src/filters/out_video.c | 1554 + src/filters/reframe_ac3.c | 612 + src/filters/reframe_adts.c | 911 + src/filters/reframe_amr.c | 603 + src/filters/reframe_av1.c | 1114 + src/filters/reframe_flac.c | 665 + src/filters/reframe_h263.c | 722 + src/filters/reframe_img.c | 434 + src/filters/reframe_latm.c | 637 + src/filters/reframe_mp3.c | 820 + src/filters/reframe_mpgvid.c | 1188 + src/filters/reframe_nalu.c | 3316 + src/filters/reframe_prores.c | 671 + src/filters/reframe_qcp.c | 729 + src/filters/reframe_rawpcm.c | 324 + src/filters/reframe_rawvid.c | 306 + src/filters/reframer.c | 1859 + src/filters/resample_audio.c | 404 + src/filters/rewind.c | 262 + src/filters/rewrite_adts.c | 396 + src/filters/rewrite_mp4v.c | 169 + src/filters/rewrite_nalu.c | 495 + src/filters/rewrite_obu.c | 420 + src/filters/tileagg.c | 290 + src/filters/tssplit.c | 480 + src/filters/unit_test_filter.c | 1001 + src/filters/vcrop.c | 626 + src/filters/vflip.c | 511 + src/filters/write_generic.c | 1063 + src/filters/write_nhml.c | 954 + src/filters/write_nhnt.c | 390 + src/filters/write_qcp.c | 381 + src/filters/write_vtt.c | 322 + src/ietf/rtcp.c | 141 +- src/ietf/rtp.c | 255 +- src/ietf/rtp_depacketizer.c | 404 +- src/ietf/rtp_packetizer.c | 41 +- src/ietf/rtp_pck_3gpp.c | 65 +- src/ietf/rtp_pck_mpeg12.c | 12 +- src/ietf/rtp_pck_mpeg4.c | 13 +- src/ietf/rtp_streamer.c | 606 +- src/ietf/rtsp_command.c | 68 +- src/ietf/rtsp_common.c | 21 +- src/ietf/rtsp_response.c | 49 +- src/ietf/rtsp_session.c | 195 +- src/ietf/sdp.c | 52 +- src/isomedia/avc_ext.c | 1667 +- src/isomedia/box_code_3gpp.c | 348 +- src/isomedia/box_code_adobe.c | 163 +- src/isomedia/box_code_apple.c | 787 +- src/isomedia/box_code_base.c | 6023 +- src/isomedia/box_code_drm.c | 939 +- src/isomedia/box_code_meta.c | 416 +- src/isomedia/box_dump.c | 3704 +- src/isomedia/box_funcs.c | 903 +- src/isomedia/data_map.c | 189 +- src/isomedia/drm_sample.c | 1033 +- src/isomedia/hint_track.c | 183 +- src/isomedia/hinting.c | 385 +- src/isomedia/iff.c | 786 +- src/isomedia/isom_intern.c | 353 +- src/isomedia/isom_read.c | 1698 +- src/isomedia/isom_store.c | 789 +- src/isomedia/isom_write.c | 3680 +- src/isomedia/media.c | 491 +- src/isomedia/media_odf.c | 32 +- src/isomedia/meta.c | 563 +- src/isomedia/movie_fragments.c | 1753 +- src/isomedia/sample_descs.c | 807 +- src/isomedia/stbl_read.c | 208 +- src/isomedia/stbl_write.c | 961 +- src/isomedia/track.c | 882 +- src/isomedia/ttml.c | 1 + src/isomedia/tx3g.c | 376 +- src/jsmods/WebGLRenderingContextBase.c | 2151 + src/jsmods/core.c | 1919 + src/jsmods/evg.c | 6635 ++ src/jsmods/scene_js.c | 1903 + src/jsmods/storage.c | 231 + src/jsmods/webgl.c | 2026 + src/jsmods/webgl.h | 159 + src/jsmods/xhr.c | 1454 + src/laser/lsr_dec.c | 371 +- src/laser/lsr_enc.c | 189 +- src/mcrypt/cbc.c | 173 - src/mcrypt/cfb.c | 160 - src/mcrypt/ctr.c | 237 - src/mcrypt/des.c | 588 - src/mcrypt/ecb.c | 88 - src/mcrypt/g_crypt.c | 391 - src/mcrypt/ncfb.c | 320 - src/mcrypt/nofb.c | 211 - src/mcrypt/ofb.c | 163 - src/mcrypt/rijndael-128.c | 417 - src/mcrypt/rijndael-192.c | 418 - src/mcrypt/rijndael-256.c | 416 - src/mcrypt/stream.c | 75 - src/mcrypt/tripledes.c | 767 - src/media_tools/ait.c | 45 +- src/media_tools/atsc_dmx.c | 1942 + src/media_tools/av_parsers.c | 6742 +- src/media_tools/avilib.c | 149 +- src/media_tools/crypt_tools.c | 661 + src/media_tools/dash_client.c | 3427 +- src/media_tools/dash_segmenter.c | 7251 +-- src/media_tools/dsmcc.c | 58 +- src/media_tools/dvb_mpe.c | 219 +- src/media_tools/filestreamer.c | 672 - src/media_tools/gpac_ogg.c | 109 +- src/media_tools/html5_media.c | 22 +- src/media_tools/html5_mse.c | 36 +- src/media_tools/img.c | 257 +- src/media_tools/ismacryp.c | 2234 - src/media_tools/isom_hinter.c | 236 +- src/media_tools/isom_tools.c | 1532 +- src/media_tools/m2ts_mux.c | 522 +- src/media_tools/m3u8.c | 100 +- src/media_tools/media_export.c | 3002 +- src/media_tools/media_import.c | 10240 +-- src/media_tools/mpd.c | 2746 +- src/media_tools/mpeg2_ps.c | 373 +- src/media_tools/mpeg2_ps.h | 27 +- src/media_tools/mpegts.c | 2957 +- src/media_tools/reedsolomon.c | 27 +- src/media_tools/saf.c | 13 +- src/media_tools/text_import.c | 2631 - src/media_tools/vobsub.c | 49 +- src/media_tools/webvtt.c | 576 +- src/odf/desc_private.c | 85 +- src/odf/descriptors.c | 864 +- src/odf/ipmpx_code.c | 24 +- src/odf/ipmpx_dump.c | 102 +- src/odf/ipmpx_parse.c | 57 +- src/odf/oci_codec.c | 10 +- src/odf/odf_code.c | 192 +- src/odf/odf_codec.c | 150 +- src/odf/odf_command.c | 8 +- src/odf/odf_dump.c | 259 +- src/odf/odf_parse.c | 529 +- src/odf/qos.c | 22 +- src/odf/slc.c | 31 +- src/quickjs/GPAC_README.md | 9 + src/quickjs/cutils.c | 640 + src/quickjs/cutils.h | 356 + src/quickjs/libbf.c | 8172 +++ src/quickjs/libbf.h | 499 + src/quickjs/libregexp-opcode.h | 58 + src/quickjs/libregexp.c | 2553 + src/quickjs/libregexp.h | 91 + src/quickjs/libunicode-table.h | 4313 ++ src/quickjs/libunicode.c | 1572 + src/quickjs/libunicode.h | 124 + src/quickjs/list.h | 100 + src/quickjs/quickjs-atom.h | 289 + src/quickjs/quickjs-opcode.h | 371 + src/quickjs/quickjs.c | 51836 ++++++++++++++++ src/quickjs/quickjs.h | 1003 + src/scene_manager/encode_isom.c | 148 +- src/scene_manager/loader_bt.c | 180 +- src/scene_manager/loader_isom.c | 92 +- src/scene_manager/loader_qt.c | 48 +- src/scene_manager/loader_svg.c | 318 +- src/scene_manager/loader_xmt.c | 112 +- src/scene_manager/scene_dump.c | 1081 +- src/scene_manager/scene_engine.c | 173 +- src/scene_manager/scene_manager.c | 96 +- src/scene_manager/scene_stats.c | 64 +- src/scene_manager/swf_bifs.c | 72 +- src/scene_manager/swf_parse.c | 114 +- src/scene_manager/swf_svg.c | 14 +- src/scene_manager/text_to_bifs.c | 21 +- src/scenegraph/base_scenegraph.c | 262 +- src/scenegraph/commands.c | 29 +- src/scenegraph/dom_events.c | 68 +- src/scenegraph/dom_js.c | 3104 + src/scenegraph/dom_smjs.c | 4947 -- src/scenegraph/html5_media_js.c | 1711 + src/scenegraph/html5_media_smjs.c | 1718 - src/scenegraph/html5_mse_js.c | 956 + src/scenegraph/html5_mse_smjs.c | 951 - src/scenegraph/mpeg4_animators.c | 21 +- src/scenegraph/mpeg4_nodes.c | 724 +- src/scenegraph/mpeg4_valuator.c | 66 +- src/scenegraph/qjs_common.h | 252 + src/scenegraph/smil_anim.c | 93 +- src/scenegraph/smil_timing.c | 30 +- src/scenegraph/svg_attributes.c | 249 +- src/scenegraph/svg_js.c | 2754 + src/scenegraph/svg_smjs.c | 2986 - src/scenegraph/svg_types.c | 27 +- src/scenegraph/vrml_js.c | 4781 ++ src/scenegraph/vrml_proto.c | 101 +- src/scenegraph/vrml_route.c | 14 +- src/scenegraph/vrml_script.c | 11 +- src/scenegraph/vrml_smjs.c | 5130 -- src/scenegraph/vrml_tools.c | 32 +- src/scenegraph/webvtt_smjs.c | 128 - src/scenegraph/x3d_nodes.c | 2 +- src/scenegraph/xbl_process.c | 242 - src/scenegraph/xml_ns.c | 114 +- src/terminal/channel.c | 1964 - src/terminal/clock.c | 358 - src/terminal/decoder.c | 2152 - src/terminal/input_sensor.c | 990 - src/terminal/input_sensor.h | 111 - src/terminal/media_control.c | 714 - src/terminal/media_control.h | 115 - src/terminal/media_manager.c | 767 - src/terminal/media_memory.c | 757 - src/terminal/media_memory.h | 191 - src/terminal/media_object.c | 1585 - src/terminal/media_sensor.c | 287 - src/terminal/mpeg4_inline.c | 783 - src/terminal/network_service.c | 1479 - src/terminal/object_browser.c | 489 - src/terminal/object_manager.c | 2370 - src/terminal/scene.c | 2861 - src/terminal/svg_external.c | 231 - src/terminal/term_node_init.c | 357 - src/terminal/terminal.c | 2458 +- src/utils/Remotery.c | 7420 +++ src/utils/alloc.c | 155 +- src/utils/base_encoding.c | 207 +- src/utils/bitstream.c | 867 +- src/utils/cache.c | 320 +- src/utils/color.c | 2184 +- src/utils/configfile.c | 183 +- src/utils/constants.c | 1439 + src/utils/dlmalloc.c | 10 +- src/utils/downloader.c | 1998 +- src/utils/error.c | 679 +- src/utils/gltools.c | 1401 + src/utils/gzio.c | 989 + src/utils/gzio.cpp | 1006 - src/utils/list.c | 39 +- src/utils/map.c | 337 - src/utils/math.c | 243 +- src/utils/module.c | 413 +- src/utils/module_wrap.h | 5 + src/utils/os_config_init.c | 1701 +- src/utils/os_divers.c | 813 +- src/utils/os_file.c | 1162 +- src/utils/os_module.c | 46 +- src/utils/os_net.c | 698 +- src/utils/os_thread.c | 217 +- src/utils/path2d.c | 22 +- src/utils/path2d_stroker.c | 27 +- src/utils/ringbuffer.c | 157 - src/utils/sha1.c | 25 +- src/utils/symbian_net.cpp | 4 +- src/utils/symbian_os.cpp | 3 +- src/utils/token.c | 1 + src/utils/unicode.c | 4 +- src/utils/url.c | 58 +- src/utils/utf.c | 158 +- src/utils/xml_parser.c | 261 +- src/utils/zlib_symbian_ext.h | 11 +- src/utils/zutil.c | 2 - src/utils/zutil.h | 6 +- static.mak | 228 +- tests/README.MD | 300 - tests/ghp_deploy.sh | 43 - tests/index.html | 21 - tests/make_tests.sh | 1570 - tests/media/auxiliary_files/count_arabic.mp3 | Bin 59872 -> 0 bytes tests/media/auxiliary_files/count_english.mp3 | Bin 60060 -> 0 bytes tests/media/auxiliary_files/count_french.mp3 | Bin 60060 -> 0 bytes tests/media/auxiliary_files/count_german.mp3 | Bin 57365 -> 0 bytes tests/media/auxiliary_files/count_italian.mp3 | Bin 57678 -> 0 bytes tests/media/auxiliary_files/count_spanish.mp3 | Bin 60186 -> 0 bytes tests/media/auxiliary_files/count_video.cmp | Bin 146688 -> 0 bytes tests/media/auxiliary_files/counter.hvc | Bin 696407 -> 0 bytes tests/media/auxiliary_files/enst_audio.aac | Bin 85058 -> 0 bytes tests/media/auxiliary_files/enst_video.h264 | Bin 47679 -> 0 bytes tests/media/auxiliary_files/index2batch.xslt | 54 - tests/media/auxiliary_files/index2html.xslt | 62 - tests/media/auxiliary_files/index2sh.xslt | 71 - tests/media/auxiliary_files/logo.bt | 126 - tests/media/auxiliary_files/logo.jpg | Bin 13781 -> 0 bytes tests/media/auxiliary_files/nefertiti.wrl | 649 - tests/media/auxiliary_files/sky.jpg | Bin 6496 -> 0 bytes tests/media/auxiliary_files/subs.ismt | Bin 5033 -> 0 bytes tests/media/auxiliary_files/subtitle.srt | 23 - tests/media/auxiliary_files/subtitle_fr.srt | 23 - tests/media/auxiliary_files/svg2html.xslt | 117 - tests/media/auxiliary_files/x3d2html.xslt | 127 - tests/media/auxiliary_files/xmt2html.xslt | 159 - .../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-2D-painting-colortransform-texture.bt | 109 - .../bifs/bifs-2D-painting-lineproperties.bt | 168 - .../media/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 - .../media/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 - tests/media/bifs/bifs-2D-shapes-all.bt | 267 - .../bifs/bifs-2D-shapes-indexfaceset2D.bt | 123 - .../bifs/bifs-2D-shapes-indexlineset2D.bt | 100 - tests/media/bifs/bifs-2D-shapes-pointset2D.bt | 56 - tests/media/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 - tests/media/bifs/bifs-2D-viewport-complete.bt | 715 - tests/media/bifs/bifs-2D-viewport-simple.bt | 88 - tests/media/bifs/bifs-3D-background-images.bt | 87 - tests/media/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 - tests/media/bifs/bifs-3D-lighting-fog.bt | 56 - .../media/bifs/bifs-3D-lighting-pointlight.bt | 71 - .../media/bifs/bifs-3D-lighting-spotlight.bt | 72 - ...-positioning-billboard-viewer-alignment.bt | 62 - .../bifs/bifs-3D-positioning-billboard.bt | 61 - .../media/bifs/bifs-3D-positioning-gravity.bt | 71 - .../bifs/bifs-3D-positioning-layer3D-views.bt | 160 - .../media/bifs/bifs-3D-positioning-layer3D.bt | 193 - tests/media/bifs/bifs-3D-positioning-lod.bt | 63 - .../bifs/bifs-3D-positioning-transform.bt | 64 - .../bifs/bifs-3D-shapes-box-transparent.bt | 117 - tests/media/bifs/bifs-3D-shapes-box.bt | 45 - tests/media/bifs/bifs-3D-shapes-cone.bt | 58 - tests/media/bifs/bifs-3D-shapes-cylinder.bt | 92 - .../bifs/bifs-3D-shapes-elevationgrid.bt | 74 - tests/media/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 - tests/media/bifs/bifs-3D-shapes-pointset.bt | 46 - .../bifs/bifs-3D-texturing-box-transparent.bt | 73 - .../media/bifs/bifs-3D-texturing-box-video.bt | 184 - tests/media/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 - tests/media/bifs/bifs-3D-texturing-cone.bt | 81 - .../bifs-3D-texturing-cylinder-transparent.bt | 93 - .../media/bifs/bifs-3D-texturing-cylinder.bt | 107 - .../bifs/bifs-3D-texturing-transform-box.bt | 85 - .../bifs-3D-texturing-transform-matrix-box.bt | 91 - tests/media/bifs/bifs-3D-viewpoint-anim.bt | 84 - .../media/bifs/bifs-3D-viewpoint-bind-jump.bt | 114 - tests/media/bifs/bifs-3D-viewpoint-bind.bt | 115 - .../bifs/bifs-3D-viewpoint-ortho-bind.bt | 118 - .../bifs/bifs-bitmap-image-meter-metrics.bt | 80 - .../bifs/bifs-bitmap-image-pixel-metrics.bt | 89 - .../media/bifs/bifs-bitmap-image-resizing.bt | 153 - .../bifs/bifs-bitmap-movie-materialkey.bt | 101 - tests/media/bifs/bifs-bitmap-movie.bt | 84 - .../media/bifs/bifs-bitmap-video-resizing.bt | 152 - tests/media/bifs/bifs-cachetexture_cache.bt | 90 - tests/media/bifs/bifs-cachetexture_nocache.bt | 57 - .../bifs/bifs-command-animated-osmo4logo.bt | 315 - tests/media/bifs/bifs-command-delete-index.bt | 58 - tests/media/bifs/bifs-command-delete-node.bt | 58 - tests/media/bifs/bifs-command-delete-route.bt | 67 - tests/media/bifs/bifs-command-global-qp.bt | 66 - tests/media/bifs/bifs-command-insert-index.bt | 58 - tests/media/bifs/bifs-command-insert-node.bt | 74 - .../media/bifs/bifs-command-insert-nodedef.bt | 64 - tests/media/bifs/bifs-command-insert-route.bt | 67 - .../bifs-command-multiple-replace-field.bt | 66 - .../bifs-command-multiple-replace-index.bt | 62 - .../media/bifs/bifs-command-node-delete-ex.bt | 125 - tests/media/bifs/bifs-command-proto-delete.bt | 93 - tests/media/bifs/bifs-command-proto-insert.bt | 83 - .../bifs/bifs-command-protolist-delete.bt | 93 - .../media/bifs/bifs-command-quantification.bt | 186 - .../media/bifs/bifs-command-replace-field.bt | 67 - .../media/bifs/bifs-command-replace-index.bt | 58 - .../bifs/bifs-command-replace-node-null.bt | 65 - tests/media/bifs/bifs-command-replace-node.bt | 67 - .../media/bifs/bifs-command-replace-route.bt | 67 - .../bifs/bifs-command-replace-scene-null.bt | 37 - .../media/bifs/bifs-command-replace-scene.bt | 76 - .../bifs/bifs-command-route-add-children.bt | 79 - .../media/bifs/bifs-command-route-children.bt | 79 - .../bifs-command-route-node-exposedfield.bt | 80 - tests/media/bifs/bifs-command-route-node.bt | 76 - .../bifs-command-route-remove-children.bt | 93 - tests/media/bifs/bifs-environmenttest.bt | 129 - .../bifs/bifs-externproto-forestgump-lib.bt | 463 - .../media/bifs/bifs-externproto-forestgump.bt | 96 - .../media/bifs/bifs-externproto-mfurl-lib.bt | 52 - tests/media/bifs/bifs-externproto-mfurl.bt | 69 - tests/media/bifs/bifs-externproto-nood-lib.bt | 109 - tests/media/bifs/bifs-externproto-nood.bt | 70 - .../media/bifs/bifs-externproto-simple-lib.bt | 90 - tests/media/bifs/bifs-externproto-simple.bt | 81 - tests/media/bifs/bifs-game-arrange.bt | 452 - tests/media/bifs/bifs-game-breakout.bt | 1035 - tests/media/bifs/bifs-game-bubble.bt | 433 - tests/media/bifs/bifs-game-minesweeper.bt | 1538 - tests/media/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 - tests/media/bifs/bifs-keynavigator.bt | 220 - .../bifs/bifs-linking-anchor-mp4-next.bt | 67 - .../bifs/bifs-linking-anchor-mp4-prev.bt | 67 - .../bifs/bifs-linking-anchor-viewpoint.bt | 92 - tests/media/bifs/bifs-linking-anchor-www.bt | 67 - .../bifs/bifs-linking-animationstream.bt | 135 - .../bifs/bifs-linking-inline-direct-inline.bt | 75 - .../media/bifs/bifs-linking-inline-direct.bt | 51 - .../bifs/bifs-linking-inline-http-no-od.bt | 48 - tests/media/bifs/bifs-linking-inline-http.bt | 58 - .../bifs/bifs-linking-inline-od-inline.bt | 76 - tests/media/bifs/bifs-linking-inline-od.bt | 60 - .../bifs-linking-inline-segment-inline.bt | 74 - .../media/bifs/bifs-linking-inline-segment.bt | 41 - tests/media/bifs/bifs-media-audiobuffer.bt | 203 - .../bifs/bifs-media-audioclip-urlchanged.bt | 145 - tests/media/bifs/bifs-media-audioclip.bt | 133 - .../bifs/bifs-media-audiosource-mixing.bt | 194 - .../bifs/bifs-media-audiosource-urlchanged.bt | 146 - tests/media/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 - .../media/bifs/bifs-media-sound-spatialize.bt | 77 - tests/media/bifs/bifs-media-sound.bt | 77 - tests/media/bifs/bifs-misc-UTF16-input.bt | 55 - tests/media/bifs/bifs-misc-cyclic-graph.bt | 55 - tests/media/bifs/bifs-misc-hc-proto-events.bt | 57 - .../bifs/bifs-misc-hc-proto-offscreengroup.bt | 139 - .../bifs/bifs-misc-hc-proto-pathextrusion.bt | 103 - .../bifs-misc-hc-proto-planarextrusion.bt | 87 - .../bifs-misc-hc-proto-planeclipper-box.bt | 77 - .../bifs/bifs-misc-hc-proto-planeclipper.bt | 69 - .../media/bifs/bifs-misc-hc-proto-texture.bt | 63 - ...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 - tests/media/bifs/bifs-misc-srt-import-3gpp.bt | 64 - tests/media/bifs/bifs-misc-srt-import.bt | 76 - tests/media/bifs/bifs-od-language-code.bt | 117 - tests/media/bifs/bifs-od-remove-esd.bt | 78 - tests/media/bifs/bifs-od-remove-od.bt | 78 - tests/media/bifs/bifs-od-update-od.bt | 89 - tests/media/bifs/bifs-proto-conditional.bt | 107 - tests/media/bifs/bifs-proto-delete-def.bt | 91 - tests/media/bifs/bifs-proto-delete-index.bt | 95 - tests/media/bifs/bifs-proto-forestgump.bt | 478 - tests/media/bifs/bifs-proto-mfurl.bt | 78 - tests/media/bifs/bifs-proto-multiple.bt | 180 - tests/media/bifs/bifs-proto-nested.bt | 132 - tests/media/bifs/bifs-proto-route.bt | 110 - .../media/bifs/bifs-proto-sftime-protocode.bt | 99 - .../bifs/bifs-proto-sftime-protointerface.bt | 104 - tests/media/bifs/bifs-proto-simple.bt | 88 - tests/media/bifs/bifs-proto-use.bt | 93 - tests/media/bifs/bifs-script-char-to-int.bt | 87 - tests/media/bifs/bifs-script-child-create.bt | 61 - tests/media/bifs/bifs-script-date.bt | 64 - tests/media/bifs/bifs-script-event-out.bt | 85 - tests/media/bifs/bifs-script-initialize.bt | 86 - tests/media/bifs/bifs-script-load-url.bt | 67 - tests/media/bifs/bifs-script-node-access.bt | 86 - tests/media/bifs/bifs-script-node-create.bt | 80 - tests/media/bifs/bifs-script-proto.bt | 224 - tests/media/bifs/bifs-script-timestamp.bt | 68 - tests/media/bifs/bifs-storage.bt | 65 - tests/media/bifs/bifs-stream-text-switch.bt | 143 - tests/media/bifs/bifs-text-align-horiz1.bt | 304 - tests/media/bifs/bifs-text-align-horiz2.bt | 320 - tests/media/bifs/bifs-text-align-horiz3.bt | 320 - tests/media/bifs/bifs-text-align-horiz4.bt | 336 - tests/media/bifs/bifs-text-align-vert1.bt | 200 - tests/media/bifs/bifs-text-align-vert2.bt | 209 - tests/media/bifs/bifs-text-align-vert3.bt | 209 - tests/media/bifs/bifs-text-align-vert4.bt | 218 - tests/media/bifs/bifs-text-glyph-advance.bt | 436 - tests/media/bifs/bifs-text-length.bt | 230 - tests/media/bifs/bifs-text-maxextend.bt | 176 - tests/media/bifs/bifs-text-style.bt | 184 - tests/media/bifs/bifs-text-unicode.bt | 55 - tests/media/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/bifs-timeline-mediacontrol-http.bt | 340 - ...-timeline-mediacontrol-inline-av-inline.bt | 96 - .../bifs-timeline-mediacontrol-inline-av.bt | 231 - ...ine-mediacontrol-inline-segments-inline.bt | 81 - ...s-timeline-mediacontrol-inline-segments.bt | 66 - .../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 - tests/media/bifs/bifs-timeline-mediasensor.bt | 137 - tests/media/bifs/counter-auto.bt | 177 - .../mozilla_ie_action.html | 35 - .../mozilla_ie_simple.html | 24 - .../media/browser_integration/ppc_action.html | 35 - .../media/browser_integration/ppc_simple.html | 25 - tests/media/build-navigator-sh | 11 - tests/media/build-navigator-w32.bat | 14 - tests/media/chaptering/chapters.txt | 8 - tests/media/dom/gpac-dom-portability.js | 144 - tests/media/dom/gpac-html-portability.js | 96 - tests/media/encryption/drm_adobe.xml | 9 - tests/media/encryption/drm_cbc.xml | 28 - tests/media/encryption/drm_cbcs.xml | 28 - tests/media/encryption/drm_cens.xml | 25 - tests/media/encryption/drm_ctr.xml | 34 - tests/media/encryption/drm_isma.xml | 4 - tests/media/html5_video/basic_arraybuffer.js | 21 - tests/media/html5_video/basic_audio.svg | 12 - tests/media/html5_video/basic_mediasource.js | 25 - tests/media/html5_video/basic_sourcebuffer.js | 53 - tests/media/html5_video/basic_url.js | 26 - tests/media/html5_video/basic_video.js | 81 - tests/media/html5_video/basic_video.svg | 7 - tests/media/html5_video/bind.js | 26 - .../counter-mp4-audio-segments-http.js | 20 - .../counter-mp4-av-segments-http.js | 20 - .../counter-mp4-video-segments-http.js | 36 - ...unter-mp4-video-segments-live-nobs-http.js | 36 - .../counter-mp4-video-segments-local.js | 28 - tests/media/html5_video/file.json | 1 - tests/media/html5_video/file.txt | 1 - tests/media/html5_video/file.xml | 4 - tests/media/html5_video/gpac-mse-spatial.js | 55 - tests/media/html5_video/gpac-mse.js | 358 - .../html5_video/implementation_notes.txt | 36 - tests/media/html5_video/mediaevents.js | 348 - tests/media/html5_video/mediaevents.svg | 29 - tests/media/html5_video/mse-overlap.js | 71 - tests/media/html5_video/mse.svg | 58 - tests/media/html5_video/myanmar-tiles.js | 135 - tests/media/html5_video/nodejs-byte-server.js | 71 - .../redbull-mp4-audio-segments-http.js | 36 - .../redbull-mp4-video-segments-http.js | 140 - tests/media/html5_video/spatial-mse.svg | 28 - tests/media/html5_video/two-videos.svg | 33 - tests/media/html5_video/video.svg | 30 - tests/media/html5_video/xhr.js | 147 - tests/media/html5_video/xhr.svg | 4 - tests/media/index.css | 134 - tests/media/index.xml | 373 - tests/media/laser/enst_2laser3.xml | 90 - tests/media/laser/enst_3laser.xml | 53 - tests/media/laser/enst_afrique.xml | 70 - tests/media/laser/enst_amerique_centrale.xml | 23 - tests/media/laser/enst_amerique_sud.xml | 30 - tests/media/laser/enst_canvas.xml | 193 - tests/media/laser/enst_cee.xml | 103 - tests/media/laser/enst_europe.xml | 114 - tests/media/laser/enst_flow.xml | 1161 - tests/media/laser/enst_gold.xml | 637 - tests/media/laser/enst_hame.xml | 1505 - tests/media/laser/enst_sydn.xml | 292 - tests/media/laser/enst_topk.xml | 1240 - tests/media/laser/enst_tram.xml | 784 - tests/media/laser/stz_Navigation_simple.xml | 27 - tests/media/laser/stz_a_parsing.xml | 41 - tests/media/laser/stz_a_parsing2.xml | 21 - tests/media/laser/stz_animateMotion_mpath.xml | 32 - .../media/laser/stz_animateMotion_parsing.xml | 92 - .../laser/stz_animateMotion_parsing2.xml | 22 - .../laser/stz_animateTransform_rotate.xml | 37 - .../laser/stz_animateTransform_rotate2.xml | 21 - .../laser/stz_animateTransform_scale.xml | 28 - .../laser/stz_animateTransform_scale2.xml | 17 - .../media/laser/stz_animateTransform_skew.xml | 35 - .../laser/stz_animateTransform_skew2.xml | 22 - .../laser/stz_animateTransform_translate.xml | 35 - .../laser/stz_animateTransform_translate2.xml | 19 - tests/media/laser/stz_animate_choice.xml | 28 - tests/media/laser/stz_animate_choice2.xml | 21 - .../laser/stz_animate_colorrendering.xml | 23 - .../laser/stz_animate_colorrendering2.xml | 16 - .../media/laser/stz_animate_display-align.xml | 22 - .../laser/stz_animate_display-align2.xml | 15 - tests/media/laser/stz_animate_display.xml | 23 - tests/media/laser/stz_animate_display2.xml | 16 - tests/media/laser/stz_animate_editable.xml | 22 - tests/media/laser/stz_animate_editable2.xml | 15 - tests/media/laser/stz_animate_fill-rule.xml | 25 - tests/media/laser/stz_animate_fill-rule2.xml | 19 - tests/media/laser/stz_animate_fill.xml | 23 - tests/media/laser/stz_animate_fill2.xml | 16 - .../laser/stz_animate_fillstroke-opacity.xml | 26 - .../laser/stz_animate_fillstroke-opacity2.xml | 17 - tests/media/laser/stz_animate_font-family.xml | 22 - .../media/laser/stz_animate_font-family2.xml | 15 - tests/media/laser/stz_animate_font-style.xml | 22 - tests/media/laser/stz_animate_font-style2.xml | 15 - tests/media/laser/stz_animate_font-weight.xml | 22 - .../media/laser/stz_animate_font-weight2.xml | 15 - .../media/laser/stz_animate_gradientUnits.xml | 29 - .../laser/stz_animate_gradientUnits2.xml | 20 - tests/media/laser/stz_animate_gsize.xml | 28 - tests/media/laser/stz_animate_gsize2.xml | 21 - tests/media/laser/stz_animate_hrefa.xml | 30 - tests/media/laser/stz_animate_hrefa2.xml | 20 - .../media/laser/stz_animate_hrefstreamid.xml | 757 - .../media/laser/stz_animate_hrefstreamid2.xml | 746 - tests/media/laser/stz_animate_hrefuse.xml | 31 - tests/media/laser/stz_animate_hrefuse2.xml | 21 - .../laser/stz_animate_image-rendering.xml | 21 - .../laser/stz_animate_image-rendering2.xml | 14 - tests/media/laser/stz_animate_paintserver.xml | 31 - .../media/laser/stz_animate_paintserver2.xml | 23 - tests/media/laser/stz_animate_parsing.xml | 45 - tests/media/laser/stz_animate_parsing2.xml | 20 - tests/media/laser/stz_animate_path.xml | 25 - tests/media/laser/stz_animate_path2.xml | 18 - .../laser/stz_animate_pointer-events.xml | 23 - .../laser/stz_animate_pointer-events2.xml | 16 - tests/media/laser/stz_animate_points.xml | 24 - tests/media/laser/stz_animate_points2.xml | 16 - .../laser/stz_animate_preserveAspectRatio.xml | 29 - .../stz_animate_preserveAspectRatio2.xml | 319 - .../laser/stz_animate_shaperendering.xml | 23 - .../laser/stz_animate_shaperendering2.xml | 16 - .../laser/stz_animate_stroke-linecap.xml | 23 - .../laser/stz_animate_stroke-linecap2.xml | 16 - .../laser/stz_animate_stroke-linejoin.xml | 23 - .../laser/stz_animate_stroke-linejoin2.xml | 16 - .../media/laser/stz_animate_stroke-width.xml | 23 - .../media/laser/stz_animate_stroke-width2.xml | 16 - tests/media/laser/stz_animate_text-anchor.xml | 22 - .../media/laser/stz_animate_text-anchor2.xml | 15 - .../media/laser/stz_animate_vector-effect.xml | 23 - .../laser/stz_animate_vector-effect2.xml | 16 - tests/media/laser/stz_animate_viewBox.xml | 26 - tests/media/laser/stz_animate_viewBox2.xml | 17 - tests/media/laser/stz_animate_visibility.xml | 25 - tests/media/laser/stz_animate_visibility2.xml | 18 - tests/media/laser/stz_animate_xy.xml | 34 - tests/media/laser/stz_animate_xy2.xml | 17 - tests/media/laser/stz_anyXML_replace.xml | 18 - tests/media/laser/stz_circle_parsing.xml | 21 - tests/media/laser/stz_circle_parsing2.xml | 14 - tests/media/laser/stz_defs_parsing.xml | 28 - tests/media/laser/stz_defs_parsing2.xml | 21 - tests/media/laser/stz_desc_parsing.xml | 21 - tests/media/laser/stz_desc_parsing2.xml | 15 - tests/media/laser/stz_ellipse_parsing.xml | 21 - tests/media/laser/stz_ellipse_parsing2.xml | 14 - .../media/laser/stz_foreignObject_parsing.xml | 27 - tests/media/laser/stz_g_parsing.xml | 45 - tests/media/laser/stz_g_parsing2.xml | 33 - tests/media/laser/stz_image_parsing.xml | 45 - tests/media/laser/stz_image_parsing2.xml | 319 - tests/media/laser/stz_line_parsing.xml | 21 - tests/media/laser/stz_line_parsing2.xml | 14 - tests/media/laser/stz_linearGradient_bbox.xml | 30 - .../media/laser/stz_linearGradient_bbox2.xml | 21 - .../laser/stz_linearGradient_userSpace.xml | 37 - .../laser/stz_linearGradient_userSpace2.xml | 26 - tests/media/laser/stz_metadata_parsing.xml | 44 - tests/media/laser/stz_path_parsing.xml | 41 - tests/media/laser/stz_path_parsing2.xml | 25 - tests/media/laser/stz_polygon_parsing.xml | 34 - tests/media/laser/stz_polygon_parsing2.xml | 17 - tests/media/laser/stz_polyline_parsing.xml | 34 - tests/media/laser/stz_polyline_parsing2.xml | 17 - tests/media/laser/stz_rect_parsing.xml | 50 - tests/media/laser/stz_rect_parsing2.xml | 15 - tests/media/laser/stz_set_color.xml | 24 - tests/media/laser/stz_set_color2.xml | 17 - tests/media/laser/stz_svg_parsing.xml | 42 - tests/media/laser/stz_svg_parsing2.xml | 15 - tests/media/laser/stz_switch_parsing.xml | 31 - tests/media/laser/stz_text_parsing.xml | 38 - tests/media/laser/stz_text_parsing2.xml | 22 - tests/media/laser/stz_title_parsing.xml | 21 - tests/media/laser/stz_use_parsing.xml | 26 - tests/media/laser/stz_use_parsing2.xml | 19 - tests/media/laser/x_austria_relief.png | Bin 56516 -> 0 bytes tests/media/svg/all_syntaxes_1.1F2.svg | 498 - tests/media/svg/createanim-by-script.svg | 73 - tests/media/svg/createimage-by-script.svg | 16 - tests/media/svg/opacity.svg | 67 - tests/media/svg/utfscript.svg | 14 - tests/media/swf/cuisine.swf | Bin 42416 -> 0 bytes tests/media/ttml/ebu-ttd_prefix.ttml | 30 - tests/media/ttml/ebu-ttd_sample.ttml | 39 - ...u-ttd_sample_invalid_mixed_namespaces.ttml | 28 - .../media/ttml/ebu-ttd_sample_invalid_ns.ttml | 28 - .../ttml/ebu-ttd_sample_invalid_root.ttml | 28 - tests/media/ttml/ebu-ttd_sample_span.ttml | 29 - .../media/ttml/ebu-ttd_timing_contiguous.ttml | 30 - .../ttml/ebu-ttd_timing_non-contiguous.ttml | 30 - .../ttml/ebu-ttd_timing_overlapping_fail.ttml | 29 - tests/media/ttml/ttml.nhml | 14 - tests/media/webvtt/comments.vtt | 45 - tests/media/webvtt/concatenation.vtt | 51 - tests/media/webvtt/counter.srt | 2400 - tests/media/webvtt/counter.vtt | 4502 -- .../webvtt/elephants-dream-chapters-en.vtt | 29 - .../webvtt/elephants-dream-subtitles-de.vtt | 309 - .../webvtt/elephants-dream-subtitles-en.vtt | 357 - tests/media/webvtt/empty.vtt | 1 - tests/media/webvtt/empty2.vtt | 1 - tests/media/webvtt/empty3.vtt | 2 - tests/media/webvtt/empty4.vtt | 3 - tests/media/webvtt/header.vtt | 42 - tests/media/webvtt/invalid1.vtt | 3 - tests/media/webvtt/invalid2.vtt | 3 - tests/media/webvtt/invalid3.vtt | 5 - tests/media/webvtt/invalid4.vtt | 8 - tests/media/webvtt/invalid5.vtt | 12 - tests/media/webvtt/long-duration.vtt | 43814 ------------- .../webvtt/multiline-header-additional.vtt | 23 - .../webvtt/multiline-header-id-invalid.vtt | 23 - tests/media/webvtt/multiline-header-id.vtt | 22 - tests/media/webvtt/multiline-header.vtt | 25 - tests/media/webvtt/overlapping-end.vtt | 17 - tests/media/webvtt/overlapping-middle.vtt | 17 - tests/media/webvtt/overlapping-rewritten.vtt | 81 - tests/media/webvtt/overlapping-start.vtt | 17 - tests/media/webvtt/overlapping.vtt | 26 - tests/media/webvtt/simple.vtt | 32 - tests/media/webvtt/spaces.vtt | 36 - tests/media/webvtt/spec-example-basic.vtt | 40 - tests/media/webvtt/spec-example-comment.vtt | 10 - tests/media/webvtt/spec-example-comment2.vtt | 21 - .../media/webvtt/spec-example-identifier.vtt | 8 - .../webvtt/spec-example-multiple-lines.vtt | 11 - tests/media/webvtt/spec-example-nested.vtt | 19 - tests/media/webvtt/spec-example-voice.vtt | 13 - tests/media/webvtt/svg.vtt | 4502 -- tests/media/webvtt/timestamps-invalid.vtt | 10 - tests/media/webvtt/timestamps.vtt | 19 - tests/media/x3d/x3d-2D-Arc2d.x3dv | 23 - tests/media/x3d/x3d-2D-ArcClose2d.x3dv | 24 - tests/media/x3d/x3d-2D-Disk2d.x3dv | 24 - tests/media/x3d/x3d-2D-Polyline2d.x3dv | 23 - tests/media/x3d/x3d-2D-Polypoint2d.x3dv | 23 - tests/media/x3d/x3d-2D-TriangleSet2d.x3dv | 24 - .../x3d/x3d-3D-IndexedTriangleFanSet.x3dv | 28 - .../media/x3d/x3d-3D-IndexedTriangleSet.x3dv | 27 - .../x3d/x3d-3D-IndexedTriangleStripSet.x3dv | 28 - tests/media/x3d/x3d-3D-LineSet.x3dv | 27 - tests/media/x3d/x3d-3D-TriangleFanSet.x3dv | 28 - tests/media/x3d/x3d-3D-TriangleSet.x3dv | 26 - tests/media/x3d/x3d-3D-TriangleStripSet.x3dv | 28 - tests/media/x3d/x3d-misc-ColorRGBA.x3dv | 42 - tests/media/x3d/x3d-misc-HatchStyle.x3dv | 31 - tests/media/x3d/x3d-misc-KeySensor.x3dv | 73 - tests/media/x3d/x3d-misc-StringSensor.x3dv | 83 - tests/media/xmlin4/ebu-ttd_sample.ttml | 39 - tests/media/xmlin4/first.xml | 1 - tests/media/xmlin4/input.txt | 13 - tests/media/xmlin4/input.xml | 5 - tests/media/xmlin4/last.xml | 1 - tests/media/xmlin4/meta-mett-no-mime.nhml | 8 - tests/media/xmlin4/meta-mett-xml-header.nhml | 6 - tests/media/xmlin4/meta-mett-xml.nhml | 6 - tests/media/xmlin4/meta-mett.nhml | 8 - .../media/xmlin4/meta-metx-no-namespace.nhml | 6 - tests/media/xmlin4/meta-metx.nhml | 6 - tests/media/xmlin4/second.xml | 1 - tests/media/xmlin4/subt-sbtt-no-mime.nhml | 6 - tests/media/xmlin4/subt-sbtt.nhml | 6 - .../media/xmlin4/subt-stpp-no-namespace.nhml | 6 - tests/media/xmlin4/subt-stpp.nhml | 6 - tests/media/xmlin4/text-stxt-header.nhml | 7 - tests/media/xmlin4/text-stxt-no-mime.nhml | 8 - tests/media/xmlin4/text-stxt.nhml | 8 - ...D-background-background2D-bind-play-ui.xml | 73 - ...-background-background2D-image-play-ui.xml | 62 - ...-background-background2D-movie-play-ui.xml | 43 - ...ground-background2D-url-change-play-ui.xml | 53 - ...fs-2D-interactivity-discsensor-play-ui.xml | 120 - ...D-interactivity-htk-sensor-play-stderr.txt | 1 - ...ifs-2D-interactivity-keysensor-play-ui.xml | 97 - ...s-2D-interactivity-mousesensor-play-ui.xml | 93 - ...D-interactivity-nested-sensors-play-ui.xml | 81 - ...2D-interactivity-planesensor2D-play-ui.xml | 80 - ...nteractivity-proximitysensor2D-play-ui.xml | 75 - ...-2D-interactivity-stringsensor-play-ui.xml | 62 - ...eractivity-touchsensor-4states-play-ui.xml | 66 - ...ractivity-touchsensor-hitpoint-play-ui.xml | 115 - ...chsensor-isactive-exposedfield-play-ui.xml | 36 - ...ractivity-touchsensor-isactive-play-ui.xml | 26 - ...teractivity-touchsensor-isover-play-ui.xml | 40 - ...activity-touchsensor-move_over-play-ui.xml | 54 - ...D-painting-xlineproperties-cap-play-ui.xml | 75 - ...-painting-xlineproperties-join-play-ui.xml | 52 - ...xlineproperties-lineargradient-play-ui.xml | 23 - ...xlineproperties-radialgradient-play-ui.xml | 26 - .../bifs-2D-positioning-clipper2D-play-ui.xml | 20 - .../bifs-2D-positioning-layer2D-play-ui.xml | 34 - ...ning-layout-scroll-modes-horiz-play-ui.xml | 81 - ...oning-layout-scroll-modes-vert-play-ui.xml | 99 - ...sitioning-layout-scroll-on-off-play-ui.xml | 62 - ...fs-2D-positioning-orderedgroup-play-ui.xml | 34 - ...ositioning-pathlayout-graphics-play-ui.xml | 46 - ...bifs-2D-positioning-pathlayout-play-ui.xml | 40 - ...-positioning-transformmatrix2D-play-ui.xml | 63 - ...-compositetexture2D-background-play-ui.xml | 46 - ...compositetexture2D-transparent-play-ui.xml | 53 - ...fs-2D-texturing-gradients-text-play-ui.xml | 89 - ...exturing-gradients-transparent-play-ui.xml | 112 - ...exturing-lineargradient-simple-play-ui.xml | 123 - ...exturing-lineargradient-spread-play-ui.xml | 42 - ...exturing-radialgradient-simple-play-ui.xml | 92 - ...exturing-radialgradient-spread-play-ui.xml | 33 - ...ring-texturetransform-interact-play-ui.xml | 125 - .../rules/bifs-2D-viewport-simple-play-ui.xml | 36 - ...D-interactivity-cylindersensor-play-ui.xml | 101 - ...s-3D-interactivity-planesensor-play-ui.xml | 105 - ...-interactivity-proximitysensor-play-ui.xml | 56 - ...-3D-interactivity-spheresensor-play-ui.xml | 134 - ...interactivity-visibilitysensor-play-ui.xml | 44 - tests/rules/bifs-3D-lighting-fog-play-ui.xml | 53 - .../bifs-3D-positioning-layer3D-play-ui.xml | 149 - ...bifs-3D-shapes-box-transparent-play-ui.xml | 78 - .../bifs-3D-shapes-elevationgrid-play-ui.xml | 70 - .../bifs-3D-shapes-extrusion-play-ui.xml | 65 - ...fs-3D-shapes-nonlineardeformer-play-ui.xml | 5 - ...ring-compositetexture3D-bitmap-play-ui.xml | 43 - .../bifs-3D-viewpoint-bind-jump-play-ui.xml | 65 - .../rules/bifs-3D-viewpoint-bind-play-ui.xml | 55 - .../bifs-3D-viewpoint-ortho-bind-play-ui.xml | 56 - ...ifs-bitmap-image-meter-metrics-play-ui.xml | 96 - ...ifs-bitmap-image-pixel-metrics-play-ui.xml | 109 - .../bifs-cachetexture_nocache-play-ui.xml | 64 - .../bifs-command-proto-delete-play-stderr.txt | 4 - ...s-command-protolist-delete-play-stderr.txt | 3 - tests/rules/bifs-game-arrange-play-ui.xml | 118 - tests/rules/bifs-game-arrange.sh | 4 - tests/rules/bifs-game-breakout-play-ui.xml | 79 - tests/rules/bifs-game-breakout.sh | 4 - tests/rules/bifs-game-bubble-play-ui.xml | 109 - tests/rules/bifs-game-bubble.sh | 4 - tests/rules/bifs-game-minesweeper-play-ui.xml | 57 - tests/rules/bifs-game-minesweeper.sh | 5 - tests/rules/bifs-game-othello-play-ui.xml | 153 - tests/rules/bifs-game-othello.sh | 4 - ...terpolation-timesensor-enabled-play-ui.xml | 63 - ...timesensor-starttime_norestart-play-ui.xml | 47 - ...n-timesensor-starttime_restart-play-ui.xml | 44 - tests/rules/bifs-keynavigator-play-ui.xml | 70 - ...s-linking-inline-direct-inline-play-ui.xml | 83 - .../bifs-linking-inline-od-inline-play-ui.xml | 114 - ...-linking-inline-segment-inline-play-ui.xml | 61 - .../rules/bifs-media-audiobuffer-play-ui.xml | 84 - tests/rules/bifs-media-audioclip-play-ui.xml | 73 - ...ifs-media-audioclip-urlchanged-play-ui.xml | 51 - .../bifs-media-audiosource-mixing-play-ui.xml | 152 - .../rules/bifs-media-audiosource-play-ui.xml | 54 - ...s-media-audiosource-urlchanged-play-ui.xml | 54 - ...-media-imagetexture-url-change-play-ui.xml | 86 - ...ifs-media-movietexture-control-play-ui.xml | 68 - ...-media-movietexture-url-change-play-ui.xml | 39 - .../bifs-misc-hc-proto-events-play-ui.xml | 92 - ...non-linear-parsing-conditional-play-ui.xml | 72 - .../rules/bifs-proto-conditional-play-ui.xml | 30 - tests/rules/bifs-proto-multiple-play-ui.xml | 79 - tests/rules/bifs-proto-nested-play-ui.xml | 54 - tests/rules/bifs-proto-route-play-ui.xml | 21 - .../bifs-script-child-create-play-ui.xml | 31 - tests/rules/bifs-script-date.sh | 4 - tests/rules/bifs-script-load-url-play-ui.xml | 4 - .../rules/bifs-script-node-create-play-ui.xml | 50 - tests/rules/bifs-script-proto-play-ui.xml | 100 - tests/rules/bifs-storage-play-ui.xml | 68 - .../rules/bifs-stream-text-switch-play-ui.xml | 37 - ...bifs-timeline-mediacontrol-OCR-play-ui.xml | 139 - tests/rules/bifs-timeline-mediacontrol-OCR.sh | 2 - ...fs-timeline-mediacontrol-audio-play-ui.xml | 82 - ...eline-mediacontrol-audio-speed-play-ui.xml | 64 - ...timeline-mediacontrol-complete-play-ui.xml | 95 - ...line-mediacontrol-deactivation-play-ui.xml | 26 - ...ifs-timeline-mediacontrol-http-play-ui.xml | 112 - ...imeline-mediacontrol-inline-av-play-ui.xml | 105 - ...s-timeline-mediacontrol-inline-segments.sh | 2 - ...timeline-mediacontrol-segments-play-ui.xml | 23 - ...fs-timeline-mediacontrol-video-play-ui.xml | 85 - ...meline-mediacontrol-videospeed-play-ui.xml | 59 - ...r-stz_animate_hrefstreamid-play-stderr.txt | 2 - ...-stz_animate_hrefstreamid2-play-stderr.txt | 1 - ...n-meta-metx-no-namespace-import-stderr.txt | 3 - .../xmlin-subt-stpp-export-track-stderr.txt | 3 - ...n-subt-stpp-no-namespace-import-stderr.txt | 2 - .../xmlin-ttml-stpp-export-track-stderr.txt | 3 - tests/scripts/3D-HEVC.sh | 23 - tests/scripts/bifs_all.sh | 147 - tests/scripts/compositor_modes.sh | 80 - tests/scripts/dash-if-live.sh | 11 - tests/scripts/dash-if-ondemand.sh | 11 - tests/scripts/dash-live-generation.sh | 14 - tests/scripts/dash-live.sh | 11 - tests/scripts/dash-multiperiod.sh | 24 - tests/scripts/dash-ts.sh | 17 - tests/scripts/dash.sh | 11 - tests/scripts/encryption.sh | 61 - tests/scripts/fuzz-base.sh | 114 - tests/scripts/hls.sh | 14 - tests/scripts/iff.sh | 15 - tests/scripts/item.sh | 49 - tests/scripts/laser_all.sh | 81 - tests/scripts/mp42ts.sh | 45 - tests/scripts/mp4box-base.sh | 86 - tests/scripts/mp4box-io.sh | 119 - tests/scripts/mp4box-kind.sh | 157 - tests/scripts/mp4box-lang.sh | 86 - tests/scripts/mp4box-rtp.sh | 48 - tests/scripts/mp4box-subtitle.sh | 41 - tests/scripts/mp4client-base.sh | 65 - tests/scripts/mp4client-dash-config.sh | 31 - tests/scripts/mp4client-dash.sh | 33 - tests/scripts/mp4client-http.sh | 35 - tests/scripts/mp4client-rawout.sh | 36 - tests/scripts/negctts.sh | 16 - tests/scripts/nhml-subs.sh | 9 - tests/scripts/noFragsDefault.sh | 11 - tests/scripts/range_extension.sh | 35 - tests/scripts/scalable.sh | 51 - tests/scripts/smooth.sh | 45 - tests/scripts/swf.sh | 8 - tests/scripts/test_prl.sh | 28 - tests/scripts/vtt-all.sh | 43 - tests/scripts/x3d.sh | 27 - tests/scripts/xmlin.sh | 100 - tests/stylesheet.xsl | 38 - 2049 files changed, 485125 insertions(+), 346471 deletions(-) create mode 100644 .gitmodules delete mode 100644 AUTHORS delete mode 100644 BUGS delete mode 100644 INSTALLME delete mode 100644 TODO delete mode 100644 applications/dashcast/Makefile delete mode 100644 applications/dashcast/audio_data.h delete mode 100644 applications/dashcast/audio_decoder.c delete mode 100644 applications/dashcast/audio_decoder.h delete mode 100644 applications/dashcast/audio_encoder.c delete mode 100644 applications/dashcast/audio_muxer.c delete mode 100644 applications/dashcast/audio_muxer.h delete mode 100644 applications/dashcast/controler.c delete mode 100644 applications/dashcast/video_data.h delete mode 100644 applications/dashcast/video_decoder.c delete mode 100644 applications/dashcast/video_encoder.c delete mode 100644 applications/dashcast/video_muxer.c create mode 100644 applications/deprecated/mp42ts/Makefile create mode 100644 applications/deprecated/mp42ts/main.c create mode 100644 applications/deprecated/mp42ts/mp42ts.vcxproj create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.cpp create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.def create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.dsp create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.h create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.idl create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.rc create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.rgs create mode 100644 applications/deprecated/old_arch/GPAX/GPAX.vcxproj create mode 100644 applications/deprecated/old_arch/GPAX/GPAXPlugin.cpp create mode 100644 applications/deprecated/old_arch/GPAX/GPAXPlugin.h create mode 100644 applications/deprecated/old_arch/GPAX/GPAX_i.c create mode 100644 applications/deprecated/old_arch/GPAX/GPAX_p.c create mode 100644 applications/deprecated/old_arch/GPAX/GPAXps.def create mode 100644 applications/deprecated/old_arch/GPAX/GPAXps.mk create mode 100644 applications/deprecated/old_arch/GPAX/StdAfx.cpp create mode 100644 applications/deprecated/old_arch/GPAX/StdAfx.h create mode 100644 applications/deprecated/old_arch/GPAX/dlldata.c create mode 100644 applications/deprecated/old_arch/GPAX/gpax.bmp create mode 100644 applications/deprecated/old_arch/GPAX/resource.h create mode 100644 applications/deprecated/old_arch/dashcast/Makefile rename applications/{ => deprecated/old_arch}/dashcast/audio_data.c (100%) create mode 100644 applications/deprecated/old_arch/dashcast/audio_data.h create mode 100644 applications/deprecated/old_arch/dashcast/audio_decoder.c create mode 100644 applications/deprecated/old_arch/dashcast/audio_decoder.h create mode 100644 applications/deprecated/old_arch/dashcast/audio_encoder.c rename applications/{ => deprecated/old_arch}/dashcast/audio_encoder.h (100%) create mode 100644 applications/deprecated/old_arch/dashcast/audio_muxer.c create mode 100644 applications/deprecated/old_arch/dashcast/audio_muxer.h rename applications/{ => deprecated/old_arch}/dashcast/circular_buffer.c (100%) rename applications/{ => deprecated/old_arch}/dashcast/circular_buffer.h (100%) rename applications/{ => deprecated/old_arch}/dashcast/cmd_data.c (100%) rename applications/{ => deprecated/old_arch}/dashcast/cmd_data.h (100%) create mode 100644 applications/deprecated/old_arch/dashcast/controler.c rename applications/{ => deprecated/old_arch}/dashcast/controler.h (100%) rename applications/{ => deprecated/old_arch}/dashcast/dashcast.c (100%) rename applications/{ => deprecated/old_arch}/dashcast/libav_compat.h (100%) rename applications/{ => deprecated/old_arch}/dashcast/message_queue.c (100%) rename applications/{ => deprecated/old_arch}/dashcast/message_queue.h (100%) rename applications/{ => deprecated/old_arch}/dashcast/register.c (100%) rename applications/{ => deprecated/old_arch}/dashcast/register.h (100%) rename applications/{ => deprecated/old_arch}/dashcast/task.c (100%) rename applications/{ => deprecated/old_arch}/dashcast/task.h (100%) rename applications/{ => deprecated/old_arch}/dashcast/video_data.c (100%) create mode 100644 applications/deprecated/old_arch/dashcast/video_data.h create mode 100644 applications/deprecated/old_arch/dashcast/video_decoder.c rename applications/{ => deprecated/old_arch}/dashcast/video_decoder.h (100%) create mode 100644 applications/deprecated/old_arch/dashcast/video_encoder.c rename applications/{ => deprecated/old_arch}/dashcast/video_encoder.h (100%) create mode 100644 applications/deprecated/old_arch/dashcast/video_muxer.c rename applications/{ => deprecated/old_arch}/dashcast/video_muxer.h (100%) rename applications/{ => deprecated/old_arch}/dashcast/video_scaler.c (100%) rename applications/{ => deprecated/old_arch}/dashcast/video_scaler.h (100%) create mode 100644 applications/deprecated/old_arch/mp42avi/Makefile create mode 100644 applications/deprecated/old_arch/mp42avi/main.c create mode 100644 applications/deprecated/old_arch/osmo4_sym/aif/osmo4_icon.bmp create mode 100644 applications/deprecated/old_arch/osmo4_sym/aif/osmo4_icon_mask.bmp create mode 100644 applications/deprecated/old_arch/osmo4_sym/aif/osmo4_menu.bmp create mode 100644 applications/deprecated/old_arch/osmo4_sym/aif/osmo4_menu_mask.bmp create mode 100644 applications/deprecated/old_arch/osmo4_sym/aif/osmo4aif.rss create mode 100644 applications/deprecated/old_arch/osmo4_sym/osmo4.cpp create mode 100644 applications/deprecated/old_arch/osmo4_sym/osmo4.h create mode 100644 applications/deprecated/old_arch/osmo4_sym/osmo4_ui.cpp create mode 100644 applications/deprecated/old_arch/osmo4_sym/osmo4_ui.h create mode 100644 applications/deprecated/old_arch/osmo4_sym/osmo4_view.cpp create mode 100644 applications/deprecated/old_arch/osmo4_sym/osmo4_view.h create mode 100644 applications/deprecated/old_arch/osmo4_sym/playlist.cpp create mode 100644 applications/deprecated/old_arch/osmo4_sym/playlist.h create mode 100644 applications/deprecated/old_arch/osmo4_sym/res/osmo4.rss create mode 100644 applications/deprecated/old_arch/osmo4_sym/res/osmo4.svg create mode 100644 applications/deprecated/old_arch/osmo4_sym/res/osmo4_caption.rss create mode 100644 applications/deprecated/old_arch/osmo4_sym/res/osmo4_gen.rss create mode 100644 applications/deprecated/old_arch/osmo4_sym/res/osmo4_reg.rss create mode 100644 applications/deprecated/old_arch/osmo4_w32/AddressBar.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/AddressBar.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/FileProps.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/FileProps.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/MainFrm.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/MainFrm.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/OpenUrl.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/OpenUrl.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/Options.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/Options.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/Osmo4.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/Osmo4.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/Osmo4.rc create mode 100644 applications/deprecated/old_arch/osmo4_w32/Osmo4.vcxproj create mode 100644 applications/deprecated/old_arch/osmo4_w32/Playlist.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/Playlist.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/Sliders.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/Sliders.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/StdAfx.cpp create mode 100644 applications/deprecated/old_arch/osmo4_w32/StdAfx.h create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/Osmo4.rc2 create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/error.ico create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/maintool.bmp create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/message.ico create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/osmo4.ico create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/pause.ico create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/play.ico create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/playlist.bmp create mode 100644 applications/deprecated/old_arch/osmo4_w32/res/stop.ico create mode 100644 applications/deprecated/old_arch/osmo4_w32/resource.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/MainFrm.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wce/MainFrm.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/OpenDlg.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wce/OpenDlg.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/Options.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wce/Options.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/Osmo4.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wce/Osmo4.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/Osmo4.rc create mode 100644 applications/deprecated/old_arch/osmo4_wce/ProgressBar.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wce/ProgressBar.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/Resource.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/StdAfx.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wce/StdAfx.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/newres.h create mode 100644 applications/deprecated/old_arch/osmo4_wce/res/Cmdbar.bmp create mode 100644 applications/deprecated/old_arch/osmo4_wce/res/Osmo4.ico create mode 100644 applications/deprecated/old_arch/osmo4_wce/res/Osmo4.rc2 create mode 100644 applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/archive.bat create mode 100644 applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/build_installer.bat rename {bin => applications/deprecated/old_arch/osmo4_wce}/smartphone 2003 (armv4)/release/install/gpac.inf (100%) create mode 100644 applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/readme.txt create mode 100644 applications/deprecated/old_arch/osmo4_wx/Darwin.Info.plist create mode 100644 applications/deprecated/old_arch/osmo4_wx/Darwin.InfoPlist.strings create mode 100644 applications/deprecated/old_arch/osmo4_wx/Darwin.Osmo.icns create mode 100644 applications/deprecated/old_arch/osmo4_wx/Makefile create mode 100644 applications/deprecated/old_arch/osmo4_wx/Playlist.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wx/Playlist.h create mode 100644 applications/deprecated/old_arch/osmo4_wx/fileprops.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wx/fileprops.h create mode 100644 applications/deprecated/old_arch/osmo4_wx/menubtn.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wx/menubtn.h create mode 100644 applications/deprecated/old_arch/osmo4_wx/osmo4.ico create mode 100644 applications/deprecated/old_arch/osmo4_wx/osmo4.xpm create mode 100644 applications/deprecated/old_arch/osmo4_wx/playlist.xpm create mode 100644 applications/deprecated/old_arch/osmo4_wx/resource.h create mode 100644 applications/deprecated/old_arch/osmo4_wx/toolbar.xpm create mode 100644 applications/deprecated/old_arch/osmo4_wx/wxGPACControl.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wx/wxGPACControl.h create mode 100644 applications/deprecated/old_arch/osmo4_wx/wxOsmo4.cpp create mode 100644 applications/deprecated/old_arch/osmo4_wx/wxOsmo4.h create mode 100644 applications/deprecated/old_arch/osmo4_wx/wxOsmo4.rc create mode 100644 applications/deprecated/old_arch/osmophone/Osmo4.ico create mode 100644 applications/deprecated/old_arch/osmophone/main.cpp create mode 100644 applications/deprecated/old_arch/osmophone/newres.h create mode 100644 applications/deprecated/old_arch/osmophone/openfile.cpp create mode 100644 applications/deprecated/old_arch/osmophone/osmophone.rc create mode 100644 applications/deprecated/old_arch/osmophone/osmophone.vcxproj create mode 100644 applications/deprecated/old_arch/osmophone/resource.h create mode 100644 applications/deprecated/old_arch/osmozilla/Makefile create mode 100644 applications/deprecated/old_arch/osmozilla/nsIOsmozilla.h create mode 100644 applications/deprecated/old_arch/osmozilla/nsIOsmozilla.idl create mode 100644 applications/deprecated/old_arch/osmozilla/nsIOsmozilla.xpt_linux create mode 100644 applications/deprecated/old_arch/osmozilla/nsIOsmozilla.xpt_w32 create mode 100644 applications/deprecated/old_arch/osmozilla/osmo_npapi.cpp create mode 100644 applications/deprecated/old_arch/osmozilla/osmo_npapi.h create mode 100644 applications/deprecated/old_arch/osmozilla/osmozilla.cpp create mode 100644 applications/deprecated/old_arch/osmozilla/osmozilla.def create mode 100644 applications/deprecated/old_arch/osmozilla/osmozilla.h create mode 100644 applications/deprecated/old_arch/osmozilla/osmozilla.png create mode 100644 applications/deprecated/old_arch/osmozilla/osmozilla.rc create mode 100644 applications/deprecated/old_arch/osmozilla/osmozilla.vcxproj create mode 100644 applications/deprecated/old_arch/osmozilla/readme.txt create mode 100644 applications/deprecated/old_arch/osmozilla/resource.h create mode 100644 applications/generators/WebGLGen/Makefile create mode 100755 applications/generators/WebGLGen/WGLGen create mode 100644 applications/generators/WebGLGen/main.c create mode 100644 applications/generators/WebGLGen/webgl1.idl create mode 100644 applications/generators/WebGLGen/webgl2.idl create mode 100644 applications/gpac/Info.plist create mode 100644 applications/gpac/Makefile create mode 100644 applications/gpac/main.c delete mode 100644 applications/mp42avi/Makefile delete mode 100644 applications/mp42avi/main.c delete mode 100644 applications/mp42ts/Makefile delete mode 100644 applications/mp42ts/main.c create mode 100644 applications/mp4box/mp4box.h delete mode 100644 applications/mp4client/extract.c create mode 100644 applications/testapps/atscdmx/Makefile create mode 100644 applications/testapps/atscdmx/main.c create mode 100644 applications/testapps/ts2hds/Makefile rename applications/{ => testapps}/ts2hds/f4m.c (100%) create mode 100644 applications/testapps/ts2hds/f4v.c create mode 100644 applications/testapps/ts2hds/main.c rename applications/{ => testapps}/ts2hds/ts2hds.h (100%) create mode 100644 applications/testapps/udptsseg/Makefile create mode 100644 applications/testapps/udptsseg/main.c rename applications/{ => testapps}/udptsseg/udptsseg.dsp (100%) rename applications/{ => testapps}/udptsseg/udptsseg.vcproj (100%) delete mode 100644 applications/ts2hds/Makefile delete mode 100644 applications/ts2hds/f4v.c delete mode 100644 applications/ts2hds/main.c delete mode 100644 applications/udptsseg/Makefile delete mode 100644 applications/udptsseg/main.c delete mode 100644 bin/smartphone 2003 (armv4)/release/install/archive.bat delete mode 100644 bin/smartphone 2003 (armv4)/release/install/build_installer.bat delete mode 100644 bin/smartphone 2003 (armv4)/release/install/readme.txt delete mode 100644 doc/CODING_STYLE delete mode 100644 doc/INSTALL.gcc delete mode 100644 doc/INSTALL.gpe delete mode 100644 doc/INSTALL.symbian delete mode 100644 doc/INSTALL.w32 delete mode 100644 doc/INSTALL.wCE delete mode 100644 doc/configuration.html delete mode 100644 doc/doxyfile delete mode 100644 doc/doxyfile-full delete mode 100644 doc/gpac.mp4 delete mode 100644 doc/ipmpx_syntax.bt delete mode 100644 doc/man/dashcast.1 delete mode 100644 doc/man/gpac.1 delete mode 100644 doc/man/mp42avi.1 delete mode 100644 doc/man/mp42ts.1 delete mode 100644 doc/man/mp4box.1 delete mode 100644 doc/man/mp4client.1 delete mode 100644 gui/extensions/H2B2VS/h2b2vs.js delete mode 100644 gui/extensions/H2B2VS/init.js delete mode 100644 gui/extensions/player/fileopen.js delete mode 100644 gui/extensions/player/init.js delete mode 100644 gui/extensions/player/player.js delete mode 100644 gui/extensions/player/playlist.js delete mode 100644 gui/extensions/player/stats.js delete mode 100644 gui/extensions/widget_manager/init.js delete mode 100644 gui/gui.js delete mode 100644 gui/gui_old.bt delete mode 100644 gui/gui_old.js delete mode 100644 gui/gwlib.js delete mode 100644 gui/iphone_wm_gui.js delete mode 100644 gui/iphone_wm_gui.svg delete mode 100644 gui/mpegu-wm.xmt delete mode 100644 gui/tv_wm_gui.js delete mode 100644 gui/webvtt-renderer.js create mode 100644 include/gpac/00_doxy.h create mode 100644 include/gpac/Remotery.h create mode 100644 include/gpac/atsc.h create mode 100644 include/gpac/crypt_tools.h delete mode 100644 include/gpac/esi.h create mode 100644 include/gpac/evg.h delete mode 100644 include/gpac/filestreamer.h create mode 100644 include/gpac/filters.h delete mode 100644 include/gpac/internal/mpd.h delete mode 100644 include/gpac/internal/smjs_api.h delete mode 100644 include/gpac/internal/terminal_dev.h delete mode 100644 include/gpac/ismacryp.h create mode 100644 include/gpac/main.h delete mode 100644 include/gpac/map.h create mode 100644 include/gpac/modules/compositor_ext.h delete mode 100644 include/gpac/modules/js_usr.h delete mode 100644 include/gpac/modules/raster2d.h delete mode 100644 include/gpac/modules/service.h delete mode 100644 include/gpac/modules/term_ext.h create mode 100644 include/gpac/mpd.h delete mode 100644 include/gpac/nodes_xbl.h delete mode 100644 include/gpac/ringbuffer.h delete mode 100644 include/gpac/unicode.h delete mode 100644 modules/aac_in/Makefile delete mode 100644 modules/aac_in/aac_in.c delete mode 100644 modules/aac_in/faad_dec.c delete mode 100644 modules/ac3_in/Makefile delete mode 100644 modules/ac3_in/ac3_in.c delete mode 100644 modules/ac3_in/liba52_dec.c delete mode 100644 modules/amr_dec/Makefile delete mode 100644 modules/amr_dec/amr_dec.c delete mode 100644 modules/amr_dec/amr_in.c delete mode 100644 modules/amr_dec/amr_nb/typedefs.h delete mode 100644 modules/amr_dec/amr_nb_api.h delete mode 100644 modules/amr_float_dec/Makefile delete mode 100644 modules/amr_float_dec/amr_api.h delete mode 100644 modules/amr_float_dec/amr_float_dec.c delete mode 100644 modules/audio_filter/Makefile delete mode 100644 modules/avcap/Makefile delete mode 100644 modules/avcap/avcap.cpp delete mode 100644 modules/bifs_dec/Makefile delete mode 100644 modules/bifs_dec/bifs_dec.c delete mode 100644 modules/ctx_load/Makefile delete mode 100644 modules/ctx_load/ctx_load.c create mode 100644 modules/dec_openhevc/Makefile create mode 100644 modules/dektec_out/dektec_video.h create mode 100644 modules/dektec_out/dektec_video_decl.c create mode 100644 modules/dektec_out/dektec_video_old.cpp create mode 100644 modules/dektec_out/out_dektec.vcxproj rename modules/{ => deprecated}/epoc_hw/epoc_aout.cpp (100%) rename modules/{ => deprecated}/epoc_hw/epoc_codec.cpp (100%) create mode 100644 modules/deprecated/epoc_hw/epoc_vout.cpp create mode 100644 modules/deprecated/old_arch/audio_filter/Makefile rename modules/{ => deprecated/old_arch}/audio_filter/audio_filter.c (100%) create mode 100644 modules/deprecated/old_arch/avcap/Makefile create mode 100644 modules/deprecated/old_arch/avcap/avcap.cpp create mode 100644 modules/deprecated/old_arch/ffmpeg_in/Makefile create mode 100644 modules/deprecated/old_arch/ffmpeg_in/ffmpeg_decode.c create mode 100644 modules/deprecated/old_arch/ffmpeg_in/ffmpeg_demux.c create mode 100644 modules/deprecated/old_arch/ffmpeg_in/ffmpeg_in.h rename modules/{ => deprecated/old_arch}/ffmpeg_in/ffmpeg_load.c (100%) create mode 100644 modules/deprecated/old_arch/freenect/Makefile rename modules/{ => deprecated/old_arch}/freenect/freenect.c (100%) create mode 100644 modules/deprecated/old_arch/gapi/gapi.cpp rename modules/{ => deprecated/old_arch}/gapi/gapi.h (100%) create mode 100644 modules/deprecated/old_arch/gdip_raster/gdip_font.cpp rename modules/{ => deprecated/old_arch}/gdip_raster/gdip_grad.cpp (100%) rename modules/{ => deprecated/old_arch}/gdip_raster/gdip_priv.h (100%) create mode 100644 modules/deprecated/old_arch/gdip_raster/gdip_rend.cpp create mode 100644 modules/deprecated/old_arch/gdip_raster/gdip_texture.cpp create mode 100644 modules/deprecated/old_arch/hyb_in/Makefile rename modules/{ => deprecated/old_arch}/hyb_in/fm_fake_pull.c (100%) rename modules/{ => deprecated/old_arch}/hyb_in/fm_fake_push.c (100%) rename modules/{ => deprecated/old_arch}/hyb_in/fm_mmbtools.c (100%) create mode 100644 modules/deprecated/old_arch/hyb_in/hyb_in.c rename modules/{ => deprecated/old_arch}/hyb_in/hyb_in.h (100%) create mode 100644 modules/deprecated/old_arch/libplayer/Makefile rename modules/{ => deprecated/old_arch}/libplayer/libplayer.c (100%) create mode 100644 modules/deprecated/old_arch/mse_in/Makefile create mode 100644 modules/deprecated/old_arch/mse_in/mse_in.c create mode 100644 modules/deprecated/old_arch/netctrl/Makefile create mode 100644 modules/deprecated/old_arch/netctrl/netctrl.c create mode 100644 modules/deprecated/old_arch/opencv_is/Makefile rename modules/{ => deprecated/old_arch}/opencv_is/demo-sensor.bt (100%) rename modules/{ => deprecated/old_arch}/opencv_is/haarcascade_frontalface_default.xml (100%) rename modules/{ => deprecated/old_arch}/opencv_is/opencv_is.c (100%) create mode 100644 modules/deprecated/old_arch/osd/Makefile create mode 100644 modules/deprecated/old_arch/osd/osd.c rename modules/{ => deprecated/old_arch}/platinum/GPACFileMediaServer.cpp (100%) rename modules/{ => deprecated/old_arch}/platinum/GPACFileMediaServer.h (100%) rename modules/{ => deprecated/old_arch}/platinum/GPACMediaController.cpp (100%) rename modules/{ => deprecated/old_arch}/platinum/GPACMediaController.h (100%) create mode 100644 modules/deprecated/old_arch/platinum/GPACMediaRenderer.cpp rename modules/{ => deprecated/old_arch}/platinum/GPACMediaRenderer.h (100%) create mode 100644 modules/deprecated/old_arch/platinum/GPACPlatinum.cpp rename modules/{ => deprecated/old_arch}/platinum/GPACPlatinum.h (100%) rename modules/{ => deprecated/old_arch}/platinum/GenericDevice.cpp (100%) rename modules/{ => deprecated/old_arch}/platinum/GenericDevice.h (100%) create mode 100644 modules/deprecated/old_arch/platinum/Makefile create mode 100644 modules/deprecated/old_arch/psvr/Makefile create mode 100644 modules/deprecated/old_arch/psvr/psvr.c create mode 100644 modules/deprecated/old_arch/rvc_dec/Makefile create mode 100644 modules/deprecated/old_arch/rvc_dec/rvc_dec.c create mode 100644 modules/deprecated/old_arch/ui_rec/Makefile rename modules/{ => deprecated/old_arch}/ui_rec/readme.txt (100%) create mode 100644 modules/deprecated/old_arch/ui_rec/ui_rec.c create mode 100644 modules/deprecated/old_arch/widgetman/Makefile rename modules/{ => deprecated/old_arch}/widgetman/unzip.c (100%) rename modules/{ => deprecated/old_arch}/widgetman/unzip.h (100%) create mode 100644 modules/deprecated/old_arch/widgetman/wgt_load.c rename modules/{ => deprecated/old_arch}/widgetman/wgt_load_base.js (100%) create mode 100644 modules/deprecated/old_arch/widgetman/widget.c create mode 100644 modules/deprecated/old_arch/widgetman/widgetman.c rename modules/{ => deprecated/old_arch}/widgetman/widgetman.h (100%) create mode 100644 modules/deprecated/old_arch/wiiis/Makefile rename modules/{ => deprecated/old_arch}/wiiis/test_wii.bt (100%) create mode 100644 modules/deprecated/old_arch/wiiis/wiiis.c create mode 100644 modules/deprecated/oss_audio/Makefile create mode 100644 modules/deprecated/oss_audio/oss.c delete mode 100644 modules/dummy_in/Makefile delete mode 100644 modules/dummy_in/dummy_in.c delete mode 100644 modules/dx_hw/copy_pixels.c delete mode 100644 modules/epoc_hw/epoc_vout.cpp delete mode 100644 modules/ffmpeg_in/Makefile delete mode 100644 modules/ffmpeg_in/ffmpeg_decode.c delete mode 100644 modules/ffmpeg_in/ffmpeg_demux.c delete mode 100644 modules/ffmpeg_in/ffmpeg_in.h create mode 100644 modules/filter_export.cpp delete mode 100644 modules/freenect/Makefile delete mode 100644 modules/gapi/gapi.cpp delete mode 100644 modules/gdip_raster/gdip_font.cpp delete mode 100644 modules/gdip_raster/gdip_rend.cpp delete mode 100644 modules/gdip_raster/gdip_texture.cpp delete mode 100644 modules/gpac_js/Makefile delete mode 100644 modules/gpac_js/gpac_js.c delete mode 100644 modules/hyb_in/Makefile delete mode 100644 modules/hyb_in/hyb_in.c delete mode 100644 modules/img_in/Makefile delete mode 100644 modules/img_in/bmp_dec.c delete mode 100644 modules/img_in/img_dec.c delete mode 100644 modules/img_in/img_in.c delete mode 100644 modules/img_in/img_in.h delete mode 100644 modules/img_in/jp2_dec.c delete mode 100644 modules/img_in/jpeg_dec.c delete mode 100644 modules/img_in/png_dec.c delete mode 100644 modules/ismacryp/Makefile delete mode 100644 modules/ismacryp/isma_ea.c delete mode 100644 modules/isom_in/Makefile delete mode 100644 modules/isom_in/isom_cache.c delete mode 100644 modules/isom_in/isom_in.h delete mode 100644 modules/isom_in/load.c delete mode 100644 modules/isom_in/read.c delete mode 100644 modules/isom_in/read_ch.c delete mode 100644 modules/laser_dec/Makefile delete mode 100644 modules/laser_dec/laser_dec.c delete mode 100644 modules/libplayer/Makefile delete mode 100755 modules/mediacodec_dec/Makefile delete mode 100644 modules/mediacodec_dec/mediacodec_dec.c delete mode 100644 modules/mediacodec_dec/mediacodec_dec.h delete mode 100644 modules/mediacodec_dec/mediacodec_dec_jni.c delete mode 100644 modules/mp3_in/Makefile delete mode 100644 modules/mp3_in/mad_dec.c delete mode 100644 modules/mp3_in/mp3_in.c delete mode 100644 modules/mpd_in/Makefile delete mode 100644 modules/mpd_in/mpd_in.c delete mode 100644 modules/mpegts_in/Makefile delete mode 100644 modules/mpegts_in/mpegts_in.c delete mode 100644 modules/mse_in/Makefile delete mode 100644 modules/mse_in/mse_in.c delete mode 100644 modules/odf_dec/Makefile delete mode 100644 modules/odf_dec/odf_dec.c delete mode 100644 modules/ogg/Makefile delete mode 100644 modules/ogg/ogg_in.c delete mode 100644 modules/ogg/ogg_in.h delete mode 100644 modules/ogg/ogg_load.c delete mode 100644 modules/ogg/theora_dec.c delete mode 100644 modules/ogg/vorbis_dec.c delete mode 100644 modules/opencv_is/Makefile delete mode 100644 modules/openhevc_dec/Makefile delete mode 100644 modules/openhevc_dec/openhevc_dec.c delete mode 100644 modules/opensvc_dec/Makefile delete mode 100644 modules/opensvc_dec/opensvc_dec.c delete mode 100644 modules/osd/Makefile delete mode 100644 modules/osd/osd.c delete mode 100644 modules/oss_audio/Makefile delete mode 100644 modules/oss_audio/oss.c delete mode 100644 modules/platinum/GPACMediaRenderer.cpp delete mode 100644 modules/platinum/GPACPlatinum.cpp delete mode 100644 modules/platinum/Makefile delete mode 100644 modules/raw_out/Makefile delete mode 100644 modules/raw_out/raw_video.c delete mode 100644 modules/redirect_av/Makefile delete mode 100644 modules/redirect_av/ffmpeg_ts_muxer.c delete mode 100644 modules/redirect_av/gpac_ts_muxer.c delete mode 100644 modules/redirect_av/redirect_av.c delete mode 100644 modules/redirect_av/ts_muxer.h delete mode 100644 modules/rtp_in/Makefile delete mode 100644 modules/rtp_in/rtp_in.c delete mode 100644 modules/rtp_in/rtp_in.h delete mode 100644 modules/rtp_in/rtp_session.c delete mode 100644 modules/rtp_in/rtp_signaling.c delete mode 100644 modules/rtp_in/rtp_stream.c delete mode 100644 modules/rtp_in/sdp_fetch.c delete mode 100644 modules/rtp_in/sdp_load.c delete mode 100644 modules/rvc_dec/Makefile delete mode 100644 modules/rvc_dec/rvc_dec.c delete mode 100644 modules/saf_in/Makefile delete mode 100644 modules/saf_in/saf_in.c delete mode 100644 modules/soft_raster/Makefile delete mode 100644 modules/soft_raster/ftgrays.c delete mode 100644 modules/soft_raster/rast_soft.h delete mode 100644 modules/soft_raster/raster_565.c delete mode 100644 modules/soft_raster/raster_argb.c delete mode 100644 modules/soft_raster/raster_load.c delete mode 100644 modules/soft_raster/raster_rgb.c delete mode 100644 modules/soft_raster/stencil.c delete mode 100644 modules/soft_raster/surface.c delete mode 100644 modules/svg_in/Makefile delete mode 100644 modules/svg_in/svg_in.c delete mode 100644 modules/timedtext/Makefile delete mode 100644 modules/timedtext/timedtext_dec.c delete mode 100644 modules/timedtext/timedtext_in.c delete mode 100644 modules/ui_rec/Makefile delete mode 100644 modules/ui_rec/ui_rec.c delete mode 100644 modules/vtb_decode/Makefile delete mode 100644 modules/vtb_decode/vtb_decode.c delete mode 100644 modules/vtt_in/Makefile delete mode 100644 modules/vtt_in/vtt_dec.c delete mode 100644 modules/vtt_in/vtt_in.c delete mode 100644 modules/widgetman/Makefile delete mode 100644 modules/widgetman/wgt_load.c delete mode 100644 modules/widgetman/widget.c delete mode 100644 modules/widgetman/widgetman.c delete mode 100644 modules/wiiis/Makefile delete mode 100644 modules/wiiis/wiiis.c delete mode 100644 modules/xvid_dec/Makefile delete mode 100644 modules/xvid_dec/xvid_dec.c delete mode 100644 modules/xvid_dec/xvid_dec_wce.cpp create mode 100644 packagers/osx/GPAC.app/Contents/Info.plist create mode 100644 packagers/osx/GPAC.app/Contents/PkgInfo create mode 100644 packagers/osx/GPAC.app/Contents/Resources/osmo.icns create mode 100644 packagers/osx/GPAC.app/Contents/Resources/osmo_audio.icns create mode 100644 packagers/osx/GPAC.app/Contents/Resources/osmo_generic.icns create mode 100644 packagers/osx/GPAC.app/Contents/Resources/osmo_model.icns create mode 100644 packagers/osx/GPAC.app/Contents/Resources/osmo_subs.icns create mode 100644 packagers/osx/GPAC.app/Contents/Resources/osmo_video.icns create mode 100644 packagers/osx/GPAC.app/Contents/Resources/osmo_widget.icns create mode 100644 packagers/osx/SLA.r create mode 100644 packagers/osx/distribution.xml create mode 100755 packagers/osx/res/background.png create mode 100644 packagers/osx/res/preamble.txt create mode 100755 packagers/osx/scripts/postinstall delete mode 100644 shaders/fragment.glsl create mode 100644 share/default.cfg create mode 100644 share/deprecated/iphone_wm_gui.js create mode 100644 share/deprecated/iphone_wm_gui.svg create mode 100644 share/deprecated/mpegu-core.js rename {gui => share/deprecated}/mpegu-wm.bt (100%) create mode 100644 share/deprecated/mpegu-wm.js create mode 100644 share/deprecated/mpegu-wm.xmt create mode 100644 share/deprecated/tv_wm_gui.js rename {gui => share/deprecated}/tv_wm_gui.svg (100%) create mode 100644 share/doc/CODING_STYLE rename {doc => share/doc}/GPAC UPnP.doc (100%) rename {doc => share/doc}/ISO 639-2 codes.txt (100%) rename {doc => share/doc}/SceneGenerators (100%) create mode 100644 share/doc/configuration.html create mode 100644 share/doc/doxyfile create mode 100644 share/doc/doxyfile-full create mode 100644 share/doc/idl/core.idl create mode 100644 share/doc/idl/evg.idl create mode 100644 share/doc/idl/filtersession.idl create mode 100644 share/doc/idl/jsf.idl create mode 100644 share/doc/idl/scenejs.idl create mode 100644 share/doc/idl/storage.idl create mode 100644 share/doc/idl/webgl.idl create mode 100644 share/doc/idl/xhr.idl create mode 100644 share/doc/ipmpx_syntax.bt create mode 100644 share/doc/man/gpac-filters.1 create mode 100644 share/doc/man/gpac.1 create mode 100644 share/doc/man/mp4box.1 create mode 100644 share/doc/man/mp4client.1 rename {doc => share/doc}/osmo4.ico (100%) rename {gui => share/gui}/extensions/H2B2VS/H2B2VS.png (100%) create mode 100644 share/gui/extensions/H2B2VS/h2b2vs.js create mode 100644 share/gui/extensions/H2B2VS/init.js rename {gui => share/gui}/extensions/H2B2VS/logo_hd.png (100%) rename {gui => share/gui}/extensions/H2B2VS/logo_uhd.png (100%) create mode 100644 share/gui/extensions/about/info.js create mode 100644 share/gui/extensions/about/info.svg create mode 100644 share/gui/extensions/about/init.js rename {gui => share/gui}/extensions/bifs_tests/applications-other.svg (100%) rename {gui => share/gui}/extensions/bifs_tests/bifs_tests.js (100%) rename {gui => share/gui}/extensions/bifs_tests/init.js (100%) rename {gui => share/gui}/extensions/player/applications-multimedia.svg (100%) create mode 100644 share/gui/extensions/player/fileopen.js create mode 100644 share/gui/extensions/player/init.js create mode 100644 share/gui/extensions/player/player.js create mode 100644 share/gui/extensions/player/playlist.js create mode 100644 share/gui/extensions/player/stats.js rename {gui => share/gui}/extensions/showroom/init.js (100%) rename {gui => share/gui}/extensions/showroom/osmo.bt (100%) rename {gui => share/gui}/extensions/showroom/showroom.js (100%) rename {gui => share/gui}/extensions/widget_manager/applications-system.svg (100%) create mode 100644 share/gui/extensions/widget_manager/init.js rename {gui => share/gui}/gui.bt (100%) create mode 100644 share/gui/gui.js create mode 100644 share/gui/gwlib.js rename {gui => share/gui}/icons/add.svg (100%) rename {gui => share/gui}/icons/app.svg (100%) rename {gui => share/gui}/icons/audio.svg (100%) rename {gui => share/gui}/icons/audio_full.svg (100%) rename {gui => share/gui}/icons/audio_mute.svg (100%) rename {gui => share/gui}/icons/check.svg (100%) rename {gui => share/gui}/icons/close.svg (100%) rename {gui => share/gui}/icons/compass.svg (100%) rename {gui => share/gui}/icons/cross.svg (100%) rename {gui => share/gui}/icons/down.svg (100%) rename {gui => share/gui}/icons/expand.svg (100%) rename {gui => share/gui}/icons/file.svg (100%) rename {gui => share/gui}/icons/film.svg (100%) rename {gui => share/gui}/icons/folder.svg (100%) rename {gui => share/gui}/icons/harddrive.svg (100%) rename {gui => share/gui}/icons/heart.svg (100%) rename {gui => share/gui}/icons/home.svg (100%) rename {gui => share/gui}/icons/image.svg (100%) rename {gui => share/gui}/icons/info.svg (100%) rename {gui => share/gui}/icons/laptop.svg (100%) rename {gui => share/gui}/icons/left.svg (100%) rename {gui => share/gui}/icons/list.svg (100%) rename {gui => share/gui}/icons/live.svg (100%) rename {gui => share/gui}/icons/media_next.svg (100%) rename {gui => share/gui}/icons/media_prev.svg (100%) rename {gui => share/gui}/icons/monitor.svg (100%) rename {gui => share/gui}/icons/more.svg (100%) rename {gui => share/gui}/icons/musical.svg (100%) rename {gui => share/gui}/icons/navigation.svg (100%) rename {gui => share/gui}/icons/network.svg (100%) rename {gui => share/gui}/icons/next.svg (100%) rename {gui => share/gui}/icons/osmo.svg (100%) rename {gui => share/gui}/icons/overflowing.svg (100%) rename {gui => share/gui}/icons/pause.svg (100%) rename {gui => share/gui}/icons/pl_next.svg (100%) rename {gui => share/gui}/icons/pl_prev.svg (100%) rename {gui => share/gui}/icons/play.svg (100%) rename {gui => share/gui}/icons/play_loop.svg (100%) rename {gui => share/gui}/icons/play_shuffle.svg (100%) rename {gui => share/gui}/icons/play_single.svg (100%) rename {gui => share/gui}/icons/power.svg (100%) rename {gui => share/gui}/icons/previous.svg (100%) rename {gui => share/gui}/icons/remove.svg (100%) rename {gui => share/gui}/icons/resize.svg (100%) rename {gui => share/gui}/icons/rewind.svg (100%) rename {gui => share/gui}/icons/right.svg (100%) rename {gui => share/gui}/icons/seek_forward.svg (100%) rename {gui => share/gui}/icons/shrink.svg (100%) rename {gui => share/gui}/icons/sort.svg (100%) rename {gui => share/gui}/icons/speed.svg (100%) rename {gui => share/gui}/icons/star.svg (100%) rename {gui => share/gui}/icons/stop.svg (100%) rename {gui => share/gui}/icons/stop2.svg (100%) rename {gui => share/gui}/icons/trash.svg (100%) rename {gui => share/gui}/icons/tray.svg (100%) rename {gui => share/gui}/icons/tv.svg (100%) rename {gui => share/gui}/icons/up.svg (100%) rename {gui => share/gui}/icons/world.svg (100%) create mode 100644 share/lang/fr.txt create mode 100644 share/res/gpac.mp4 rename tests/media/auxiliary_files/logo.png => share/res/gpac.png (100%) create mode 100644 share/res/gpac_cfg_test.mp4 create mode 100644 share/scripts/ttml-renderer.js create mode 100644 share/scripts/webvtt-renderer.js create mode 100644 share/shaders/fragment.glsl rename {shaders => share/shaders}/vertex.glsl (100%) create mode 100644 share/vis/Code/Console.js create mode 100644 share/vis/Code/DataViewReader.js create mode 100644 share/vis/Code/PixelTimeRange.js create mode 100644 share/vis/Code/Remotery.js create mode 100644 share/vis/Code/SampleWindow.js create mode 100644 share/vis/Code/ThreadFrame.js create mode 100644 share/vis/Code/TimelineRow.js create mode 100644 share/vis/Code/TimelineWindow.js create mode 100644 share/vis/Code/TitleWindow.js create mode 100644 share/vis/Code/WebSocketConnection.js create mode 100644 share/vis/Styles/Remotery.css create mode 100644 share/vis/extern/BrowserLib/Core/Code/Animation.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/Bind.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/Convert.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/Core.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/DOM.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/Keyboard.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/LocalStore.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/Mouse.js create mode 100644 share/vis/extern/BrowserLib/Core/Code/MurmurHash3.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/Button.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/ComboBox.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/Container.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/EditBox.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/Grid.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/Label.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/Treeview.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/TreeviewItem.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/Window.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Code/WindowManager.js create mode 100644 share/vis/extern/BrowserLib/WindowManager/Styles/WindowManager.css create mode 100644 share/vis/index.html create mode 100644 src/compositor/clock.c create mode 100644 src/compositor/media_object.c create mode 100644 src/compositor/mpeg4_inline.c create mode 100644 src/compositor/mpeg4_inputsensor.c create mode 100644 src/compositor/mpeg4_mediacontrol.c create mode 100644 src/compositor/mpeg4_mediasensor.c create mode 100644 src/compositor/object_manager.c create mode 100644 src/compositor/scene.c create mode 100644 src/compositor/scene_node_init.c create mode 100644 src/compositor/scene_ns.c create mode 100644 src/compositor/svg_external.c create mode 100644 src/crypto/g_crypt.c create mode 100644 src/crypto/g_crypt_openssl.c create mode 100644 src/crypto/g_crypt_tinyaes.c create mode 100644 src/crypto/tiny_aes.c create mode 100644 src/crypto/tiny_aes.h delete mode 100644 src/dir_info create mode 100644 src/evg/ftgrays.c create mode 100644 src/evg/rast_soft.h create mode 100644 src/evg/raster3d.c create mode 100644 src/evg/raster_565.c create mode 100644 src/evg/raster_argb.c create mode 100644 src/evg/raster_rgb.c create mode 100644 src/evg/raster_yuv.c create mode 100644 src/evg/stencil.c create mode 100644 src/evg/surface.c create mode 100644 src/filter_core/filter.c create mode 100644 src/filter_core/filter_pck.c create mode 100644 src/filter_core/filter_pid.c create mode 100644 src/filter_core/filter_props.c create mode 100644 src/filter_core/filter_queue.c create mode 100644 src/filter_core/filter_register.c create mode 100644 src/filter_core/filter_session.c create mode 100644 src/filter_core/filter_session.h create mode 100644 src/filter_core/filter_session_js.c create mode 100644 src/filters/base_filter_example.c create mode 100644 src/filters/bsrw.c create mode 100644 src/filters/compose.c create mode 100644 src/filters/dasher.c create mode 100644 src/filters/dec_ac52.c create mode 100644 src/filters/dec_bifs.c create mode 100644 src/filters/dec_faad.c create mode 100644 src/filters/dec_img.c create mode 100644 src/filters/dec_j2k.c create mode 100644 src/filters/dec_laser.c create mode 100644 src/filters/dec_mad.c create mode 100644 src/filters/dec_mediacodec.c create mode 100644 src/filters/dec_mediacodec.h create mode 100644 src/filters/dec_mediacodec_jni.c create mode 100644 src/filters/dec_nvdec.c create mode 100644 src/filters/dec_nvdec_sdk.c create mode 100644 src/filters/dec_nvdec_sdk.h create mode 100644 src/filters/dec_odf.c create mode 100644 src/filters/dec_openhevc.c create mode 100644 src/filters/dec_opensvc.c create mode 100644 src/filters/dec_theora.c create mode 100644 src/filters/dec_ttml.c create mode 100644 src/filters/dec_ttxt.c create mode 100644 src/filters/dec_vorbis.c create mode 100644 src/filters/dec_vtb.c rename modules/vtb_decode/glcontext.m => src/filters/dec_vtb_glctx.m (100%) create mode 100644 src/filters/dec_webvtt.c create mode 100644 src/filters/dec_xvid.c create mode 100644 src/filters/decrypt_cenc_isma.c create mode 100644 src/filters/dmx_avi.c create mode 100644 src/filters/dmx_dash.c create mode 100644 src/filters/dmx_gsf.c create mode 100644 src/filters/dmx_m2ts.c create mode 100644 src/filters/dmx_mpegps.c create mode 100644 src/filters/dmx_nhml.c create mode 100644 src/filters/dmx_nhnt.c create mode 100644 src/filters/dmx_ogg.c create mode 100644 src/filters/dmx_saf.c create mode 100644 src/filters/dmx_vobsub.c create mode 100644 src/filters/enc_jpg.c create mode 100644 src/filters/enc_png.c create mode 100644 src/filters/encrypt_cenc_isma.c create mode 100644 src/filters/ff_avf.c create mode 100644 src/filters/ff_common.c create mode 100644 src/filters/ff_common.h create mode 100644 src/filters/ff_dec.c create mode 100644 src/filters/ff_dmx.c create mode 100644 src/filters/ff_enc.c create mode 100644 src/filters/ff_mx.c create mode 100644 src/filters/ff_rescale.c create mode 100644 src/filters/filelist.c create mode 100644 src/filters/hevcmerge.c create mode 100644 src/filters/hevcsplit.c create mode 100644 src/filters/in_atsc.c create mode 100644 src/filters/in_dvb4linux.c create mode 100644 src/filters/in_file.c create mode 100644 src/filters/in_http.c create mode 100644 src/filters/in_pipe.c create mode 100644 src/filters/in_rtp.c create mode 100644 src/filters/in_rtp.h create mode 100644 src/filters/in_rtp_rtsp.c create mode 100644 src/filters/in_rtp_sdp.c create mode 100644 src/filters/in_rtp_signaling.c create mode 100644 src/filters/in_rtp_stream.c create mode 100644 src/filters/in_sock.c create mode 100644 src/filters/inspect.c create mode 100644 src/filters/isoffin.h create mode 100644 src/filters/isoffin_load.c create mode 100644 src/filters/isoffin_read.c create mode 100644 src/filters/isoffin_read_ch.c create mode 100644 src/filters/jsfilter.c create mode 100644 src/filters/load_bt_xmt.c create mode 100644 src/filters/load_svg.c create mode 100644 src/filters/load_text.c create mode 100644 src/filters/mux_avi.c create mode 100644 src/filters/mux_gsf.c create mode 100644 src/filters/mux_isom.c create mode 100644 src/filters/mux_ts.c create mode 100644 src/filters/out_audio.c create mode 100644 src/filters/out_file.c create mode 100644 src/filters/out_http.c create mode 100644 src/filters/out_pipe.c create mode 100644 src/filters/out_rtp.c create mode 100644 src/filters/out_rtp.h create mode 100644 src/filters/out_rtsp.c create mode 100644 src/filters/out_sock.c create mode 100644 src/filters/out_video.c create mode 100644 src/filters/reframe_ac3.c create mode 100644 src/filters/reframe_adts.c create mode 100644 src/filters/reframe_amr.c create mode 100644 src/filters/reframe_av1.c create mode 100644 src/filters/reframe_flac.c create mode 100644 src/filters/reframe_h263.c create mode 100644 src/filters/reframe_img.c create mode 100644 src/filters/reframe_latm.c create mode 100644 src/filters/reframe_mp3.c create mode 100644 src/filters/reframe_mpgvid.c create mode 100644 src/filters/reframe_nalu.c create mode 100644 src/filters/reframe_prores.c create mode 100644 src/filters/reframe_qcp.c create mode 100644 src/filters/reframe_rawpcm.c create mode 100644 src/filters/reframe_rawvid.c create mode 100644 src/filters/reframer.c create mode 100644 src/filters/resample_audio.c create mode 100644 src/filters/rewind.c create mode 100644 src/filters/rewrite_adts.c create mode 100644 src/filters/rewrite_mp4v.c create mode 100644 src/filters/rewrite_nalu.c create mode 100644 src/filters/rewrite_obu.c create mode 100644 src/filters/tileagg.c create mode 100644 src/filters/tssplit.c create mode 100644 src/filters/unit_test_filter.c create mode 100644 src/filters/vcrop.c create mode 100644 src/filters/vflip.c create mode 100644 src/filters/write_generic.c create mode 100644 src/filters/write_nhml.c create mode 100644 src/filters/write_nhnt.c create mode 100644 src/filters/write_qcp.c create mode 100644 src/filters/write_vtt.c create mode 100644 src/jsmods/WebGLRenderingContextBase.c create mode 100644 src/jsmods/core.c create mode 100644 src/jsmods/evg.c create mode 100644 src/jsmods/scene_js.c create mode 100644 src/jsmods/storage.c create mode 100644 src/jsmods/webgl.c create mode 100644 src/jsmods/webgl.h create mode 100644 src/jsmods/xhr.c delete mode 100644 src/mcrypt/cbc.c delete mode 100644 src/mcrypt/cfb.c delete mode 100644 src/mcrypt/ctr.c delete mode 100644 src/mcrypt/des.c delete mode 100644 src/mcrypt/ecb.c delete mode 100644 src/mcrypt/g_crypt.c delete mode 100644 src/mcrypt/ncfb.c delete mode 100644 src/mcrypt/nofb.c delete mode 100644 src/mcrypt/ofb.c delete mode 100644 src/mcrypt/rijndael-128.c delete mode 100644 src/mcrypt/rijndael-192.c delete mode 100644 src/mcrypt/rijndael-256.c delete mode 100644 src/mcrypt/stream.c delete mode 100644 src/mcrypt/tripledes.c create mode 100644 src/media_tools/atsc_dmx.c create mode 100644 src/media_tools/crypt_tools.c delete mode 100644 src/media_tools/filestreamer.c delete mode 100644 src/media_tools/ismacryp.c delete mode 100644 src/media_tools/text_import.c create mode 100644 src/quickjs/GPAC_README.md create mode 100644 src/quickjs/cutils.c create mode 100644 src/quickjs/cutils.h create mode 100644 src/quickjs/libbf.c create mode 100644 src/quickjs/libbf.h create mode 100644 src/quickjs/libregexp-opcode.h create mode 100644 src/quickjs/libregexp.c create mode 100644 src/quickjs/libregexp.h create mode 100644 src/quickjs/libunicode-table.h create mode 100644 src/quickjs/libunicode.c create mode 100644 src/quickjs/libunicode.h create mode 100644 src/quickjs/list.h create mode 100644 src/quickjs/quickjs-atom.h create mode 100644 src/quickjs/quickjs-opcode.h create mode 100644 src/quickjs/quickjs.c create mode 100644 src/quickjs/quickjs.h create mode 100644 src/scenegraph/dom_js.c delete mode 100644 src/scenegraph/dom_smjs.c create mode 100644 src/scenegraph/html5_media_js.c delete mode 100644 src/scenegraph/html5_media_smjs.c create mode 100644 src/scenegraph/html5_mse_js.c delete mode 100644 src/scenegraph/html5_mse_smjs.c create mode 100644 src/scenegraph/qjs_common.h create mode 100644 src/scenegraph/svg_js.c delete mode 100644 src/scenegraph/svg_smjs.c create mode 100644 src/scenegraph/vrml_js.c delete mode 100644 src/scenegraph/vrml_smjs.c delete mode 100644 src/scenegraph/webvtt_smjs.c delete mode 100644 src/scenegraph/xbl_process.c delete mode 100644 src/terminal/channel.c delete mode 100644 src/terminal/clock.c delete mode 100644 src/terminal/decoder.c delete mode 100644 src/terminal/input_sensor.c delete mode 100644 src/terminal/input_sensor.h delete mode 100644 src/terminal/media_control.c delete mode 100644 src/terminal/media_control.h delete mode 100644 src/terminal/media_manager.c delete mode 100644 src/terminal/media_memory.c delete mode 100644 src/terminal/media_memory.h delete mode 100644 src/terminal/media_object.c delete mode 100644 src/terminal/media_sensor.c delete mode 100644 src/terminal/mpeg4_inline.c delete mode 100644 src/terminal/network_service.c delete mode 100644 src/terminal/object_browser.c delete mode 100644 src/terminal/object_manager.c delete mode 100644 src/terminal/scene.c delete mode 100644 src/terminal/svg_external.c delete mode 100644 src/terminal/term_node_init.c create mode 100644 src/utils/Remotery.c create mode 100644 src/utils/constants.c create mode 100644 src/utils/gltools.c create mode 100644 src/utils/gzio.c delete mode 100644 src/utils/gzio.cpp delete mode 100644 src/utils/map.c delete mode 100644 src/utils/ringbuffer.c delete mode 100644 tests/README.MD delete mode 100755 tests/ghp_deploy.sh delete mode 100644 tests/index.html delete mode 100755 tests/make_tests.sh delete mode 100644 tests/media/auxiliary_files/count_arabic.mp3 delete mode 100644 tests/media/auxiliary_files/count_english.mp3 delete mode 100644 tests/media/auxiliary_files/count_french.mp3 delete mode 100644 tests/media/auxiliary_files/count_german.mp3 delete mode 100644 tests/media/auxiliary_files/count_italian.mp3 delete mode 100644 tests/media/auxiliary_files/count_spanish.mp3 delete mode 100644 tests/media/auxiliary_files/count_video.cmp delete mode 100644 tests/media/auxiliary_files/counter.hvc delete mode 100644 tests/media/auxiliary_files/enst_audio.aac delete mode 100644 tests/media/auxiliary_files/enst_video.h264 delete mode 100644 tests/media/auxiliary_files/index2batch.xslt delete mode 100644 tests/media/auxiliary_files/index2html.xslt delete mode 100644 tests/media/auxiliary_files/index2sh.xslt delete mode 100644 tests/media/auxiliary_files/logo.bt delete mode 100644 tests/media/auxiliary_files/logo.jpg delete mode 100644 tests/media/auxiliary_files/nefertiti.wrl delete mode 100644 tests/media/auxiliary_files/sky.jpg delete mode 100644 tests/media/auxiliary_files/subs.ismt delete mode 100644 tests/media/auxiliary_files/subtitle.srt delete mode 100644 tests/media/auxiliary_files/subtitle_fr.srt delete mode 100644 tests/media/auxiliary_files/svg2html.xslt delete mode 100644 tests/media/auxiliary_files/x3d2html.xslt delete mode 100644 tests/media/auxiliary_files/xmt2html.xslt delete mode 100644 tests/media/bifs/bifs-2D-background-background2D-bind.bt delete mode 100644 tests/media/bifs/bifs-2D-background-background2D-image.bt delete mode 100644 tests/media/bifs/bifs-2D-background-background2D-layer2D.bt delete mode 100644 tests/media/bifs/bifs-2D-background-background2D-movie.bt delete mode 100644 tests/media/bifs/bifs-2D-background-background2D-url-change.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-discsensor.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-htk-sensor.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-keysensor.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-mousesensor.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-nested-sensors.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-planesensor2D.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-proximitysensor2D.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-stringsensor.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-touchsensor-4states.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-touchsensor-hitpoint.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-touchsensor-isactive.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-touchsensor-isover.bt delete mode 100644 tests/media/bifs/bifs-2D-interactivity-touchsensor-move_over.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-colortransform-alpha.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-colortransform-bitmap.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-colortransform-color.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-colortransform-texture.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-lineproperties.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-material2D.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-cap.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-compositetexture2D.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-dash.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-imagetexture.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-join.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-lineargradient.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-radialgradient.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-scalable.bt delete mode 100644 tests/media/bifs/bifs-2D-painting-xlineproperties-transparent.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-clipper2D.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-form-align-center.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-form-align-horiz.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-form-align-vert.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-form-spread-horiz.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-form-spread-vert.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layer2D.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layer2d-in-layer2d.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-horiz-text.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-scroll-child.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-scroll-full.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-scroll-modes-horiz.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-scroll-modes-vert.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-scroll-on-off.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-vert-btt-nowrap.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-vert-ttb-nowrap.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-orderedgroup.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-pathlayout-graphics.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-pathlayout.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-transform2D.bt delete mode 100644 tests/media/bifs/bifs-2D-positioning-transformmatrix2D.bt delete mode 100644 tests/media/bifs/bifs-2D-shapes-all.bt delete mode 100644 tests/media/bifs/bifs-2D-shapes-indexfaceset2D.bt delete mode 100644 tests/media/bifs/bifs-2D-shapes-indexlineset2D.bt delete mode 100644 tests/media/bifs/bifs-2D-shapes-pointset2D.bt delete mode 100644 tests/media/bifs/bifs-2D-shapes-xcurve2D.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-compositetexture2D-background.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-compositetexture2D-bitmap.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-compositetexture2D-transparent.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-gradients-text.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-gradients-transparent.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-imagetexture-shapes.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-lineargradient-simple.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-lineargradient-spread.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-movietexture-shapes.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-pixeltexture.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-radialgradient-simple.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-radialgradient-spread.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-texturetransform-base.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-texturetransform-interact.bt delete mode 100644 tests/media/bifs/bifs-2D-texturing-texturetransform-transformmatrix2D.bt delete mode 100644 tests/media/bifs/bifs-2D-viewport-complete.bt delete mode 100644 tests/media/bifs/bifs-2D-viewport-simple.bt delete mode 100644 tests/media/bifs/bifs-3D-background-images.bt delete mode 100644 tests/media/bifs/bifs-3D-background.bt delete mode 100644 tests/media/bifs/bifs-3D-interactivity-collision-proxy.bt delete mode 100644 tests/media/bifs/bifs-3D-interactivity-collision.bt delete mode 100644 tests/media/bifs/bifs-3D-interactivity-cylindersensor.bt delete mode 100644 tests/media/bifs/bifs-3D-interactivity-planesensor.bt delete mode 100644 tests/media/bifs/bifs-3D-interactivity-proximitysensor.bt delete mode 100644 tests/media/bifs/bifs-3D-interactivity-spheresensor.bt delete mode 100644 tests/media/bifs/bifs-3D-interactivity-visibilitysensor.bt delete mode 100644 tests/media/bifs/bifs-3D-lighting-directionalLight.bt delete mode 100644 tests/media/bifs/bifs-3D-lighting-fog.bt delete mode 100644 tests/media/bifs/bifs-3D-lighting-pointlight.bt delete mode 100644 tests/media/bifs/bifs-3D-lighting-spotlight.bt delete mode 100644 tests/media/bifs/bifs-3D-positioning-billboard-viewer-alignment.bt delete mode 100644 tests/media/bifs/bifs-3D-positioning-billboard.bt delete mode 100644 tests/media/bifs/bifs-3D-positioning-gravity.bt delete mode 100644 tests/media/bifs/bifs-3D-positioning-layer3D-views.bt delete mode 100644 tests/media/bifs/bifs-3D-positioning-layer3D.bt delete mode 100644 tests/media/bifs/bifs-3D-positioning-lod.bt delete mode 100644 tests/media/bifs/bifs-3D-positioning-transform.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-box-transparent.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-box.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-cone.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-cylinder.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-elevationgrid.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-extrusion.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-indexedfaceset.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-indexedlineset.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-nonlineardeformer.bt delete mode 100644 tests/media/bifs/bifs-3D-shapes-pointset.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-box-transparent.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-box-video.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-box.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-compositetexture3D-bitmap.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-compositetexture3D-box.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-cone-transparent.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-cone.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-cylinder-transparent.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-cylinder.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-transform-box.bt delete mode 100644 tests/media/bifs/bifs-3D-texturing-transform-matrix-box.bt delete mode 100644 tests/media/bifs/bifs-3D-viewpoint-anim.bt delete mode 100644 tests/media/bifs/bifs-3D-viewpoint-bind-jump.bt delete mode 100644 tests/media/bifs/bifs-3D-viewpoint-bind.bt delete mode 100644 tests/media/bifs/bifs-3D-viewpoint-ortho-bind.bt delete mode 100644 tests/media/bifs/bifs-bitmap-image-meter-metrics.bt delete mode 100644 tests/media/bifs/bifs-bitmap-image-pixel-metrics.bt delete mode 100644 tests/media/bifs/bifs-bitmap-image-resizing.bt delete mode 100644 tests/media/bifs/bifs-bitmap-movie-materialkey.bt delete mode 100644 tests/media/bifs/bifs-bitmap-movie.bt delete mode 100644 tests/media/bifs/bifs-bitmap-video-resizing.bt delete mode 100644 tests/media/bifs/bifs-cachetexture_cache.bt delete mode 100644 tests/media/bifs/bifs-cachetexture_nocache.bt delete mode 100644 tests/media/bifs/bifs-command-animated-osmo4logo.bt delete mode 100644 tests/media/bifs/bifs-command-delete-index.bt delete mode 100644 tests/media/bifs/bifs-command-delete-node.bt delete mode 100644 tests/media/bifs/bifs-command-delete-route.bt delete mode 100644 tests/media/bifs/bifs-command-global-qp.bt delete mode 100644 tests/media/bifs/bifs-command-insert-index.bt delete mode 100644 tests/media/bifs/bifs-command-insert-node.bt delete mode 100644 tests/media/bifs/bifs-command-insert-nodedef.bt delete mode 100644 tests/media/bifs/bifs-command-insert-route.bt delete mode 100644 tests/media/bifs/bifs-command-multiple-replace-field.bt delete mode 100644 tests/media/bifs/bifs-command-multiple-replace-index.bt delete mode 100644 tests/media/bifs/bifs-command-node-delete-ex.bt delete mode 100644 tests/media/bifs/bifs-command-proto-delete.bt delete mode 100644 tests/media/bifs/bifs-command-proto-insert.bt delete mode 100644 tests/media/bifs/bifs-command-protolist-delete.bt delete mode 100644 tests/media/bifs/bifs-command-quantification.bt delete mode 100644 tests/media/bifs/bifs-command-replace-field.bt delete mode 100644 tests/media/bifs/bifs-command-replace-index.bt delete mode 100644 tests/media/bifs/bifs-command-replace-node-null.bt delete mode 100644 tests/media/bifs/bifs-command-replace-node.bt delete mode 100644 tests/media/bifs/bifs-command-replace-route.bt delete mode 100644 tests/media/bifs/bifs-command-replace-scene-null.bt delete mode 100644 tests/media/bifs/bifs-command-replace-scene.bt delete mode 100644 tests/media/bifs/bifs-command-route-add-children.bt delete mode 100644 tests/media/bifs/bifs-command-route-children.bt delete mode 100644 tests/media/bifs/bifs-command-route-node-exposedfield.bt delete mode 100644 tests/media/bifs/bifs-command-route-node.bt delete mode 100644 tests/media/bifs/bifs-command-route-remove-children.bt delete mode 100644 tests/media/bifs/bifs-environmenttest.bt delete mode 100644 tests/media/bifs/bifs-externproto-forestgump-lib.bt delete mode 100644 tests/media/bifs/bifs-externproto-forestgump.bt delete mode 100644 tests/media/bifs/bifs-externproto-mfurl-lib.bt delete mode 100644 tests/media/bifs/bifs-externproto-mfurl.bt delete mode 100644 tests/media/bifs/bifs-externproto-nood-lib.bt delete mode 100644 tests/media/bifs/bifs-externproto-nood.bt delete mode 100644 tests/media/bifs/bifs-externproto-simple-lib.bt delete mode 100644 tests/media/bifs/bifs-externproto-simple.bt delete mode 100644 tests/media/bifs/bifs-game-arrange.bt delete mode 100644 tests/media/bifs/bifs-game-breakout.bt delete mode 100644 tests/media/bifs/bifs-game-bubble.bt delete mode 100644 tests/media/bifs/bifs-game-minesweeper.bt delete mode 100644 tests/media/bifs/bifs-game-othello.bt delete mode 100644 tests/media/bifs/bifs-interpolation-colorinterpolator.bt delete mode 100644 tests/media/bifs/bifs-interpolation-coordinateinterpolator2D.bt delete mode 100644 tests/media/bifs/bifs-interpolation-positionanimator.bt delete mode 100644 tests/media/bifs/bifs-interpolation-positionanimator2D.bt delete mode 100644 tests/media/bifs/bifs-interpolation-positioninterpolator-position.bt delete mode 100644 tests/media/bifs/bifs-interpolation-positioninterpolator-size.bt delete mode 100644 tests/media/bifs/bifs-interpolation-positioninterpolator2D-position.bt delete mode 100644 tests/media/bifs/bifs-interpolation-positioninterpolator2D-size.bt delete mode 100644 tests/media/bifs/bifs-interpolation-scalaranimator.bt delete mode 100644 tests/media/bifs/bifs-interpolation-scalarinterpolator.bt delete mode 100644 tests/media/bifs/bifs-interpolation-timesensor-enabled.bt delete mode 100644 tests/media/bifs/bifs-interpolation-timesensor-starttime_norestart.bt delete mode 100644 tests/media/bifs/bifs-interpolation-timesensor-starttime_restart.bt delete mode 100644 tests/media/bifs/bifs-interpolation-valuator-sftime.bt delete mode 100644 tests/media/bifs/bifs-keynavigator.bt delete mode 100644 tests/media/bifs/bifs-linking-anchor-mp4-next.bt delete mode 100644 tests/media/bifs/bifs-linking-anchor-mp4-prev.bt delete mode 100644 tests/media/bifs/bifs-linking-anchor-viewpoint.bt delete mode 100644 tests/media/bifs/bifs-linking-anchor-www.bt delete mode 100644 tests/media/bifs/bifs-linking-animationstream.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-direct-inline.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-direct.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-http-no-od.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-http.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-od-inline.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-od.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-segment-inline.bt delete mode 100644 tests/media/bifs/bifs-linking-inline-segment.bt delete mode 100644 tests/media/bifs/bifs-media-audiobuffer.bt delete mode 100644 tests/media/bifs/bifs-media-audioclip-urlchanged.bt delete mode 100644 tests/media/bifs/bifs-media-audioclip.bt delete mode 100644 tests/media/bifs/bifs-media-audiosource-mixing.bt delete mode 100644 tests/media/bifs/bifs-media-audiosource-urlchanged.bt delete mode 100644 tests/media/bifs/bifs-media-audiosource.bt delete mode 100644 tests/media/bifs/bifs-media-imagetexture-OD-reuse.bt delete mode 100644 tests/media/bifs/bifs-media-imagetexture-no-od.bt delete mode 100644 tests/media/bifs/bifs-media-imagetexture-object-scale.bt delete mode 100644 tests/media/bifs/bifs-media-imagetexture-transparent.bt delete mode 100644 tests/media/bifs/bifs-media-imagetexture-url-change.bt delete mode 100644 tests/media/bifs/bifs-media-movietexture-control.bt delete mode 100644 tests/media/bifs/bifs-media-movietexture-no-od.bt delete mode 100644 tests/media/bifs/bifs-media-movietexture-od-joinsession.bt delete mode 100644 tests/media/bifs/bifs-media-movietexture-od-leave-session.bt delete mode 100644 tests/media/bifs/bifs-media-movietexture-owns-OCR.bt delete mode 100644 tests/media/bifs/bifs-media-movietexture-shares-OCR.bt delete mode 100644 tests/media/bifs/bifs-media-movietexture-url-change.bt delete mode 100644 tests/media/bifs/bifs-media-sound-spatialize.bt delete mode 100644 tests/media/bifs/bifs-media-sound.bt delete mode 100644 tests/media/bifs/bifs-misc-UTF16-input.bt delete mode 100644 tests/media/bifs/bifs-misc-cyclic-graph.bt delete mode 100644 tests/media/bifs/bifs-misc-hc-proto-events.bt delete mode 100644 tests/media/bifs/bifs-misc-hc-proto-offscreengroup.bt delete mode 100644 tests/media/bifs/bifs-misc-hc-proto-pathextrusion.bt delete mode 100644 tests/media/bifs/bifs-misc-hc-proto-planarextrusion.bt delete mode 100644 tests/media/bifs/bifs-misc-hc-proto-planeclipper-box.bt delete mode 100644 tests/media/bifs/bifs-misc-hc-proto-planeclipper.bt delete mode 100644 tests/media/bifs/bifs-misc-hc-proto-texture.bt delete mode 100644 tests/media/bifs/bifs-misc-non-linear-parsing-conditional.bt delete mode 100644 tests/media/bifs/bifs-misc-non-linear-parsing-use.bt delete mode 100644 tests/media/bifs/bifs-misc-srt-import-3gpp-control-share-ocr.bt delete mode 100644 tests/media/bifs/bifs-misc-srt-import-3gpp-control.bt delete mode 100644 tests/media/bifs/bifs-misc-srt-import-3gpp.bt delete mode 100644 tests/media/bifs/bifs-misc-srt-import.bt delete mode 100755 tests/media/bifs/bifs-od-language-code.bt delete mode 100644 tests/media/bifs/bifs-od-remove-esd.bt delete mode 100644 tests/media/bifs/bifs-od-remove-od.bt delete mode 100644 tests/media/bifs/bifs-od-update-od.bt delete mode 100644 tests/media/bifs/bifs-proto-conditional.bt delete mode 100644 tests/media/bifs/bifs-proto-delete-def.bt delete mode 100644 tests/media/bifs/bifs-proto-delete-index.bt delete mode 100644 tests/media/bifs/bifs-proto-forestgump.bt delete mode 100644 tests/media/bifs/bifs-proto-mfurl.bt delete mode 100644 tests/media/bifs/bifs-proto-multiple.bt delete mode 100644 tests/media/bifs/bifs-proto-nested.bt delete mode 100644 tests/media/bifs/bifs-proto-route.bt delete mode 100644 tests/media/bifs/bifs-proto-sftime-protocode.bt delete mode 100644 tests/media/bifs/bifs-proto-sftime-protointerface.bt delete mode 100644 tests/media/bifs/bifs-proto-simple.bt delete mode 100644 tests/media/bifs/bifs-proto-use.bt delete mode 100644 tests/media/bifs/bifs-script-char-to-int.bt delete mode 100644 tests/media/bifs/bifs-script-child-create.bt delete mode 100644 tests/media/bifs/bifs-script-date.bt delete mode 100644 tests/media/bifs/bifs-script-event-out.bt delete mode 100644 tests/media/bifs/bifs-script-initialize.bt delete mode 100644 tests/media/bifs/bifs-script-load-url.bt delete mode 100644 tests/media/bifs/bifs-script-node-access.bt delete mode 100644 tests/media/bifs/bifs-script-node-create.bt delete mode 100644 tests/media/bifs/bifs-script-proto.bt delete mode 100644 tests/media/bifs/bifs-script-timestamp.bt delete mode 100644 tests/media/bifs/bifs-storage.bt delete mode 100644 tests/media/bifs/bifs-stream-text-switch.bt delete mode 100644 tests/media/bifs/bifs-text-align-horiz1.bt delete mode 100644 tests/media/bifs/bifs-text-align-horiz2.bt delete mode 100644 tests/media/bifs/bifs-text-align-horiz3.bt delete mode 100644 tests/media/bifs/bifs-text-align-horiz4.bt delete mode 100644 tests/media/bifs/bifs-text-align-vert1.bt delete mode 100644 tests/media/bifs/bifs-text-align-vert2.bt delete mode 100644 tests/media/bifs/bifs-text-align-vert3.bt delete mode 100644 tests/media/bifs/bifs-text-align-vert4.bt delete mode 100644 tests/media/bifs/bifs-text-glyph-advance.bt delete mode 100644 tests/media/bifs/bifs-text-length.bt delete mode 100644 tests/media/bifs/bifs-text-maxextend.bt delete mode 100644 tests/media/bifs/bifs-text-style.bt delete mode 100644 tests/media/bifs/bifs-text-unicode.bt delete mode 100644 tests/media/bifs/bifs-text-vrml-alignment.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-OCR.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-audio-speed.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-audio.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-complete.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-deactivation.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-http.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-inline-av-inline.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-inline-av.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-inline-segments-inline.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-inline-segments.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-segments.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-video.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediacontrol-videospeed.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediasensor-segment-switch.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediasensor-segment.bt delete mode 100644 tests/media/bifs/bifs-timeline-mediasensor.bt delete mode 100644 tests/media/bifs/counter-auto.bt delete mode 100644 tests/media/browser_integration/mozilla_ie_action.html delete mode 100644 tests/media/browser_integration/mozilla_ie_simple.html delete mode 100644 tests/media/browser_integration/ppc_action.html delete mode 100644 tests/media/browser_integration/ppc_simple.html delete mode 100755 tests/media/build-navigator-sh delete mode 100644 tests/media/build-navigator-w32.bat delete mode 100755 tests/media/chaptering/chapters.txt delete mode 100644 tests/media/dom/gpac-dom-portability.js delete mode 100644 tests/media/dom/gpac-html-portability.js delete mode 100644 tests/media/encryption/drm_adobe.xml delete mode 100644 tests/media/encryption/drm_cbc.xml delete mode 100644 tests/media/encryption/drm_cbcs.xml delete mode 100644 tests/media/encryption/drm_cens.xml delete mode 100644 tests/media/encryption/drm_ctr.xml delete mode 100644 tests/media/encryption/drm_isma.xml delete mode 100644 tests/media/html5_video/basic_arraybuffer.js delete mode 100644 tests/media/html5_video/basic_audio.svg delete mode 100644 tests/media/html5_video/basic_mediasource.js delete mode 100644 tests/media/html5_video/basic_sourcebuffer.js delete mode 100644 tests/media/html5_video/basic_url.js delete mode 100644 tests/media/html5_video/basic_video.js delete mode 100644 tests/media/html5_video/basic_video.svg delete mode 100644 tests/media/html5_video/bind.js delete mode 100644 tests/media/html5_video/counter-mp4-audio-segments-http.js delete mode 100644 tests/media/html5_video/counter-mp4-av-segments-http.js delete mode 100644 tests/media/html5_video/counter-mp4-video-segments-http.js delete mode 100644 tests/media/html5_video/counter-mp4-video-segments-live-nobs-http.js delete mode 100644 tests/media/html5_video/counter-mp4-video-segments-local.js delete mode 100644 tests/media/html5_video/file.json delete mode 100644 tests/media/html5_video/file.txt delete mode 100644 tests/media/html5_video/file.xml delete mode 100644 tests/media/html5_video/gpac-mse-spatial.js delete mode 100644 tests/media/html5_video/gpac-mse.js delete mode 100644 tests/media/html5_video/implementation_notes.txt delete mode 100644 tests/media/html5_video/mediaevents.js delete mode 100644 tests/media/html5_video/mediaevents.svg delete mode 100644 tests/media/html5_video/mse-overlap.js delete mode 100644 tests/media/html5_video/mse.svg delete mode 100644 tests/media/html5_video/myanmar-tiles.js delete mode 100644 tests/media/html5_video/nodejs-byte-server.js delete mode 100644 tests/media/html5_video/redbull-mp4-audio-segments-http.js delete mode 100644 tests/media/html5_video/redbull-mp4-video-segments-http.js delete mode 100644 tests/media/html5_video/spatial-mse.svg delete mode 100644 tests/media/html5_video/two-videos.svg delete mode 100644 tests/media/html5_video/video.svg delete mode 100644 tests/media/html5_video/xhr.js delete mode 100644 tests/media/html5_video/xhr.svg delete mode 100644 tests/media/index.css delete mode 100644 tests/media/index.xml delete mode 100755 tests/media/laser/enst_2laser3.xml delete mode 100755 tests/media/laser/enst_3laser.xml delete mode 100755 tests/media/laser/enst_afrique.xml delete mode 100755 tests/media/laser/enst_amerique_centrale.xml delete mode 100755 tests/media/laser/enst_amerique_sud.xml delete mode 100755 tests/media/laser/enst_canvas.xml delete mode 100755 tests/media/laser/enst_cee.xml delete mode 100755 tests/media/laser/enst_europe.xml delete mode 100755 tests/media/laser/enst_flow.xml delete mode 100755 tests/media/laser/enst_gold.xml delete mode 100755 tests/media/laser/enst_hame.xml delete mode 100755 tests/media/laser/enst_sydn.xml delete mode 100755 tests/media/laser/enst_topk.xml delete mode 100755 tests/media/laser/enst_tram.xml delete mode 100755 tests/media/laser/stz_Navigation_simple.xml delete mode 100755 tests/media/laser/stz_a_parsing.xml delete mode 100755 tests/media/laser/stz_a_parsing2.xml delete mode 100755 tests/media/laser/stz_animateMotion_mpath.xml delete mode 100755 tests/media/laser/stz_animateMotion_parsing.xml delete mode 100755 tests/media/laser/stz_animateMotion_parsing2.xml delete mode 100755 tests/media/laser/stz_animateTransform_rotate.xml delete mode 100755 tests/media/laser/stz_animateTransform_rotate2.xml delete mode 100755 tests/media/laser/stz_animateTransform_scale.xml delete mode 100755 tests/media/laser/stz_animateTransform_scale2.xml delete mode 100755 tests/media/laser/stz_animateTransform_skew.xml delete mode 100755 tests/media/laser/stz_animateTransform_skew2.xml delete mode 100755 tests/media/laser/stz_animateTransform_translate.xml delete mode 100755 tests/media/laser/stz_animateTransform_translate2.xml delete mode 100755 tests/media/laser/stz_animate_choice.xml delete mode 100755 tests/media/laser/stz_animate_choice2.xml delete mode 100755 tests/media/laser/stz_animate_colorrendering.xml delete mode 100755 tests/media/laser/stz_animate_colorrendering2.xml delete mode 100755 tests/media/laser/stz_animate_display-align.xml delete mode 100755 tests/media/laser/stz_animate_display-align2.xml delete mode 100755 tests/media/laser/stz_animate_display.xml delete mode 100755 tests/media/laser/stz_animate_display2.xml delete mode 100755 tests/media/laser/stz_animate_editable.xml delete mode 100755 tests/media/laser/stz_animate_editable2.xml delete mode 100755 tests/media/laser/stz_animate_fill-rule.xml delete mode 100755 tests/media/laser/stz_animate_fill-rule2.xml delete mode 100755 tests/media/laser/stz_animate_fill.xml delete mode 100755 tests/media/laser/stz_animate_fill2.xml delete mode 100755 tests/media/laser/stz_animate_fillstroke-opacity.xml delete mode 100755 tests/media/laser/stz_animate_fillstroke-opacity2.xml delete mode 100755 tests/media/laser/stz_animate_font-family.xml delete mode 100755 tests/media/laser/stz_animate_font-family2.xml delete mode 100755 tests/media/laser/stz_animate_font-style.xml delete mode 100755 tests/media/laser/stz_animate_font-style2.xml delete mode 100755 tests/media/laser/stz_animate_font-weight.xml delete mode 100755 tests/media/laser/stz_animate_font-weight2.xml delete mode 100755 tests/media/laser/stz_animate_gradientUnits.xml delete mode 100755 tests/media/laser/stz_animate_gradientUnits2.xml delete mode 100755 tests/media/laser/stz_animate_gsize.xml delete mode 100755 tests/media/laser/stz_animate_gsize2.xml delete mode 100755 tests/media/laser/stz_animate_hrefa.xml delete mode 100755 tests/media/laser/stz_animate_hrefa2.xml delete mode 100755 tests/media/laser/stz_animate_hrefstreamid.xml delete mode 100755 tests/media/laser/stz_animate_hrefstreamid2.xml delete mode 100755 tests/media/laser/stz_animate_hrefuse.xml delete mode 100755 tests/media/laser/stz_animate_hrefuse2.xml delete mode 100755 tests/media/laser/stz_animate_image-rendering.xml delete mode 100755 tests/media/laser/stz_animate_image-rendering2.xml delete mode 100755 tests/media/laser/stz_animate_paintserver.xml delete mode 100755 tests/media/laser/stz_animate_paintserver2.xml delete mode 100755 tests/media/laser/stz_animate_parsing.xml delete mode 100755 tests/media/laser/stz_animate_parsing2.xml delete mode 100755 tests/media/laser/stz_animate_path.xml delete mode 100755 tests/media/laser/stz_animate_path2.xml delete mode 100755 tests/media/laser/stz_animate_pointer-events.xml delete mode 100755 tests/media/laser/stz_animate_pointer-events2.xml delete mode 100755 tests/media/laser/stz_animate_points.xml delete mode 100755 tests/media/laser/stz_animate_points2.xml delete mode 100755 tests/media/laser/stz_animate_preserveAspectRatio.xml delete mode 100755 tests/media/laser/stz_animate_preserveAspectRatio2.xml delete mode 100755 tests/media/laser/stz_animate_shaperendering.xml delete mode 100755 tests/media/laser/stz_animate_shaperendering2.xml delete mode 100755 tests/media/laser/stz_animate_stroke-linecap.xml delete mode 100755 tests/media/laser/stz_animate_stroke-linecap2.xml delete mode 100755 tests/media/laser/stz_animate_stroke-linejoin.xml delete mode 100755 tests/media/laser/stz_animate_stroke-linejoin2.xml delete mode 100755 tests/media/laser/stz_animate_stroke-width.xml delete mode 100755 tests/media/laser/stz_animate_stroke-width2.xml delete mode 100755 tests/media/laser/stz_animate_text-anchor.xml delete mode 100755 tests/media/laser/stz_animate_text-anchor2.xml delete mode 100755 tests/media/laser/stz_animate_vector-effect.xml delete mode 100755 tests/media/laser/stz_animate_vector-effect2.xml delete mode 100755 tests/media/laser/stz_animate_viewBox.xml delete mode 100755 tests/media/laser/stz_animate_viewBox2.xml delete mode 100755 tests/media/laser/stz_animate_visibility.xml delete mode 100755 tests/media/laser/stz_animate_visibility2.xml delete mode 100755 tests/media/laser/stz_animate_xy.xml delete mode 100755 tests/media/laser/stz_animate_xy2.xml delete mode 100755 tests/media/laser/stz_anyXML_replace.xml delete mode 100755 tests/media/laser/stz_circle_parsing.xml delete mode 100755 tests/media/laser/stz_circle_parsing2.xml delete mode 100755 tests/media/laser/stz_defs_parsing.xml delete mode 100755 tests/media/laser/stz_defs_parsing2.xml delete mode 100755 tests/media/laser/stz_desc_parsing.xml delete mode 100755 tests/media/laser/stz_desc_parsing2.xml delete mode 100755 tests/media/laser/stz_ellipse_parsing.xml delete mode 100755 tests/media/laser/stz_ellipse_parsing2.xml delete mode 100755 tests/media/laser/stz_foreignObject_parsing.xml delete mode 100755 tests/media/laser/stz_g_parsing.xml delete mode 100755 tests/media/laser/stz_g_parsing2.xml delete mode 100755 tests/media/laser/stz_image_parsing.xml delete mode 100755 tests/media/laser/stz_image_parsing2.xml delete mode 100755 tests/media/laser/stz_line_parsing.xml delete mode 100755 tests/media/laser/stz_line_parsing2.xml delete mode 100755 tests/media/laser/stz_linearGradient_bbox.xml delete mode 100755 tests/media/laser/stz_linearGradient_bbox2.xml delete mode 100755 tests/media/laser/stz_linearGradient_userSpace.xml delete mode 100755 tests/media/laser/stz_linearGradient_userSpace2.xml delete mode 100755 tests/media/laser/stz_metadata_parsing.xml delete mode 100755 tests/media/laser/stz_path_parsing.xml delete mode 100755 tests/media/laser/stz_path_parsing2.xml delete mode 100755 tests/media/laser/stz_polygon_parsing.xml delete mode 100755 tests/media/laser/stz_polygon_parsing2.xml delete mode 100755 tests/media/laser/stz_polyline_parsing.xml delete mode 100755 tests/media/laser/stz_polyline_parsing2.xml delete mode 100755 tests/media/laser/stz_rect_parsing.xml delete mode 100755 tests/media/laser/stz_rect_parsing2.xml delete mode 100755 tests/media/laser/stz_set_color.xml delete mode 100755 tests/media/laser/stz_set_color2.xml delete mode 100755 tests/media/laser/stz_svg_parsing.xml delete mode 100755 tests/media/laser/stz_svg_parsing2.xml delete mode 100755 tests/media/laser/stz_switch_parsing.xml delete mode 100755 tests/media/laser/stz_text_parsing.xml delete mode 100755 tests/media/laser/stz_text_parsing2.xml delete mode 100755 tests/media/laser/stz_title_parsing.xml delete mode 100755 tests/media/laser/stz_use_parsing.xml delete mode 100755 tests/media/laser/stz_use_parsing2.xml delete mode 100644 tests/media/laser/x_austria_relief.png delete mode 100644 tests/media/svg/all_syntaxes_1.1F2.svg delete mode 100644 tests/media/svg/createanim-by-script.svg delete mode 100644 tests/media/svg/createimage-by-script.svg delete mode 100644 tests/media/svg/opacity.svg delete mode 100644 tests/media/svg/utfscript.svg delete mode 100644 tests/media/swf/cuisine.swf delete mode 100644 tests/media/ttml/ebu-ttd_prefix.ttml delete mode 100644 tests/media/ttml/ebu-ttd_sample.ttml delete mode 100644 tests/media/ttml/ebu-ttd_sample_invalid_mixed_namespaces.ttml delete mode 100644 tests/media/ttml/ebu-ttd_sample_invalid_ns.ttml delete mode 100644 tests/media/ttml/ebu-ttd_sample_invalid_root.ttml delete mode 100644 tests/media/ttml/ebu-ttd_sample_span.ttml delete mode 100644 tests/media/ttml/ebu-ttd_timing_contiguous.ttml delete mode 100644 tests/media/ttml/ebu-ttd_timing_non-contiguous.ttml delete mode 100644 tests/media/ttml/ebu-ttd_timing_overlapping_fail.ttml delete mode 100644 tests/media/ttml/ttml.nhml delete mode 100644 tests/media/webvtt/comments.vtt delete mode 100644 tests/media/webvtt/concatenation.vtt delete mode 100644 tests/media/webvtt/counter.srt delete mode 100644 tests/media/webvtt/counter.vtt delete mode 100644 tests/media/webvtt/elephants-dream-chapters-en.vtt delete mode 100644 tests/media/webvtt/elephants-dream-subtitles-de.vtt delete mode 100644 tests/media/webvtt/elephants-dream-subtitles-en.vtt delete mode 100644 tests/media/webvtt/empty.vtt delete mode 100644 tests/media/webvtt/empty2.vtt delete mode 100644 tests/media/webvtt/empty3.vtt delete mode 100644 tests/media/webvtt/empty4.vtt delete mode 100644 tests/media/webvtt/header.vtt delete mode 100644 tests/media/webvtt/invalid1.vtt delete mode 100644 tests/media/webvtt/invalid2.vtt delete mode 100644 tests/media/webvtt/invalid3.vtt delete mode 100644 tests/media/webvtt/invalid4.vtt delete mode 100644 tests/media/webvtt/invalid5.vtt delete mode 100644 tests/media/webvtt/long-duration.vtt delete mode 100644 tests/media/webvtt/multiline-header-additional.vtt delete mode 100644 tests/media/webvtt/multiline-header-id-invalid.vtt delete mode 100644 tests/media/webvtt/multiline-header-id.vtt delete mode 100644 tests/media/webvtt/multiline-header.vtt delete mode 100644 tests/media/webvtt/overlapping-end.vtt delete mode 100644 tests/media/webvtt/overlapping-middle.vtt delete mode 100644 tests/media/webvtt/overlapping-rewritten.vtt delete mode 100644 tests/media/webvtt/overlapping-start.vtt delete mode 100644 tests/media/webvtt/overlapping.vtt delete mode 100644 tests/media/webvtt/simple.vtt delete mode 100644 tests/media/webvtt/spaces.vtt delete mode 100644 tests/media/webvtt/spec-example-basic.vtt delete mode 100644 tests/media/webvtt/spec-example-comment.vtt delete mode 100644 tests/media/webvtt/spec-example-comment2.vtt delete mode 100644 tests/media/webvtt/spec-example-identifier.vtt delete mode 100644 tests/media/webvtt/spec-example-multiple-lines.vtt delete mode 100644 tests/media/webvtt/spec-example-nested.vtt delete mode 100644 tests/media/webvtt/spec-example-voice.vtt delete mode 100644 tests/media/webvtt/svg.vtt delete mode 100644 tests/media/webvtt/timestamps-invalid.vtt delete mode 100644 tests/media/webvtt/timestamps.vtt delete mode 100644 tests/media/x3d/x3d-2D-Arc2d.x3dv delete mode 100644 tests/media/x3d/x3d-2D-ArcClose2d.x3dv delete mode 100644 tests/media/x3d/x3d-2D-Disk2d.x3dv delete mode 100644 tests/media/x3d/x3d-2D-Polyline2d.x3dv delete mode 100644 tests/media/x3d/x3d-2D-Polypoint2d.x3dv delete mode 100644 tests/media/x3d/x3d-2D-TriangleSet2d.x3dv delete mode 100644 tests/media/x3d/x3d-3D-IndexedTriangleFanSet.x3dv delete mode 100644 tests/media/x3d/x3d-3D-IndexedTriangleSet.x3dv delete mode 100644 tests/media/x3d/x3d-3D-IndexedTriangleStripSet.x3dv delete mode 100644 tests/media/x3d/x3d-3D-LineSet.x3dv delete mode 100644 tests/media/x3d/x3d-3D-TriangleFanSet.x3dv delete mode 100644 tests/media/x3d/x3d-3D-TriangleSet.x3dv delete mode 100644 tests/media/x3d/x3d-3D-TriangleStripSet.x3dv delete mode 100644 tests/media/x3d/x3d-misc-ColorRGBA.x3dv delete mode 100644 tests/media/x3d/x3d-misc-HatchStyle.x3dv delete mode 100644 tests/media/x3d/x3d-misc-KeySensor.x3dv delete mode 100644 tests/media/x3d/x3d-misc-StringSensor.x3dv delete mode 100644 tests/media/xmlin4/ebu-ttd_sample.ttml delete mode 100644 tests/media/xmlin4/first.xml delete mode 100644 tests/media/xmlin4/input.txt delete mode 100644 tests/media/xmlin4/input.xml delete mode 100644 tests/media/xmlin4/last.xml delete mode 100644 tests/media/xmlin4/meta-mett-no-mime.nhml delete mode 100644 tests/media/xmlin4/meta-mett-xml-header.nhml delete mode 100644 tests/media/xmlin4/meta-mett-xml.nhml delete mode 100644 tests/media/xmlin4/meta-mett.nhml delete mode 100644 tests/media/xmlin4/meta-metx-no-namespace.nhml delete mode 100644 tests/media/xmlin4/meta-metx.nhml delete mode 100644 tests/media/xmlin4/second.xml delete mode 100644 tests/media/xmlin4/subt-sbtt-no-mime.nhml delete mode 100644 tests/media/xmlin4/subt-sbtt.nhml delete mode 100644 tests/media/xmlin4/subt-stpp-no-namespace.nhml delete mode 100644 tests/media/xmlin4/subt-stpp.nhml delete mode 100644 tests/media/xmlin4/text-stxt-header.nhml delete mode 100644 tests/media/xmlin4/text-stxt-no-mime.nhml delete mode 100644 tests/media/xmlin4/text-stxt.nhml delete mode 100644 tests/rules/bifs-2D-background-background2D-bind-play-ui.xml delete mode 100644 tests/rules/bifs-2D-background-background2D-image-play-ui.xml delete mode 100644 tests/rules/bifs-2D-background-background2D-movie-play-ui.xml delete mode 100644 tests/rules/bifs-2D-background-background2D-url-change-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-discsensor-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-htk-sensor-play-stderr.txt delete mode 100644 tests/rules/bifs-2D-interactivity-keysensor-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-mousesensor-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-nested-sensors-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-planesensor2D-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-proximitysensor2D-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-stringsensor-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-touchsensor-4states-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-touchsensor-hitpoint-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-touchsensor-isactive-exposedfield-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-touchsensor-isactive-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-touchsensor-isover-play-ui.xml delete mode 100644 tests/rules/bifs-2D-interactivity-touchsensor-move_over-play-ui.xml delete mode 100644 tests/rules/bifs-2D-painting-xlineproperties-cap-play-ui.xml delete mode 100644 tests/rules/bifs-2D-painting-xlineproperties-join-play-ui.xml delete mode 100644 tests/rules/bifs-2D-painting-xlineproperties-lineargradient-play-ui.xml delete mode 100644 tests/rules/bifs-2D-painting-xlineproperties-radialgradient-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-clipper2D-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-layer2D-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-layout-scroll-modes-horiz-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-layout-scroll-modes-vert-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-layout-scroll-on-off-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-orderedgroup-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-pathlayout-graphics-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-pathlayout-play-ui.xml delete mode 100644 tests/rules/bifs-2D-positioning-transformmatrix2D-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-compositetexture2D-background-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-compositetexture2D-transparent-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-gradients-text-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-gradients-transparent-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-lineargradient-simple-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-lineargradient-spread-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-radialgradient-simple-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-radialgradient-spread-play-ui.xml delete mode 100644 tests/rules/bifs-2D-texturing-texturetransform-interact-play-ui.xml delete mode 100644 tests/rules/bifs-2D-viewport-simple-play-ui.xml delete mode 100644 tests/rules/bifs-3D-interactivity-cylindersensor-play-ui.xml delete mode 100644 tests/rules/bifs-3D-interactivity-planesensor-play-ui.xml delete mode 100644 tests/rules/bifs-3D-interactivity-proximitysensor-play-ui.xml delete mode 100644 tests/rules/bifs-3D-interactivity-spheresensor-play-ui.xml delete mode 100644 tests/rules/bifs-3D-interactivity-visibilitysensor-play-ui.xml delete mode 100644 tests/rules/bifs-3D-lighting-fog-play-ui.xml delete mode 100644 tests/rules/bifs-3D-positioning-layer3D-play-ui.xml delete mode 100644 tests/rules/bifs-3D-shapes-box-transparent-play-ui.xml delete mode 100644 tests/rules/bifs-3D-shapes-elevationgrid-play-ui.xml delete mode 100644 tests/rules/bifs-3D-shapes-extrusion-play-ui.xml delete mode 100644 tests/rules/bifs-3D-shapes-nonlineardeformer-play-ui.xml delete mode 100644 tests/rules/bifs-3D-texturing-compositetexture3D-bitmap-play-ui.xml delete mode 100644 tests/rules/bifs-3D-viewpoint-bind-jump-play-ui.xml delete mode 100644 tests/rules/bifs-3D-viewpoint-bind-play-ui.xml delete mode 100644 tests/rules/bifs-3D-viewpoint-ortho-bind-play-ui.xml delete mode 100644 tests/rules/bifs-bitmap-image-meter-metrics-play-ui.xml delete mode 100644 tests/rules/bifs-bitmap-image-pixel-metrics-play-ui.xml delete mode 100644 tests/rules/bifs-cachetexture_nocache-play-ui.xml delete mode 100644 tests/rules/bifs-command-proto-delete-play-stderr.txt delete mode 100644 tests/rules/bifs-command-protolist-delete-play-stderr.txt delete mode 100644 tests/rules/bifs-game-arrange-play-ui.xml delete mode 100644 tests/rules/bifs-game-arrange.sh delete mode 100644 tests/rules/bifs-game-breakout-play-ui.xml delete mode 100644 tests/rules/bifs-game-breakout.sh delete mode 100644 tests/rules/bifs-game-bubble-play-ui.xml delete mode 100644 tests/rules/bifs-game-bubble.sh delete mode 100644 tests/rules/bifs-game-minesweeper-play-ui.xml delete mode 100644 tests/rules/bifs-game-minesweeper.sh delete mode 100644 tests/rules/bifs-game-othello-play-ui.xml delete mode 100644 tests/rules/bifs-game-othello.sh delete mode 100644 tests/rules/bifs-interpolation-timesensor-enabled-play-ui.xml delete mode 100644 tests/rules/bifs-interpolation-timesensor-starttime_norestart-play-ui.xml delete mode 100644 tests/rules/bifs-interpolation-timesensor-starttime_restart-play-ui.xml delete mode 100644 tests/rules/bifs-keynavigator-play-ui.xml delete mode 100644 tests/rules/bifs-linking-inline-direct-inline-play-ui.xml delete mode 100644 tests/rules/bifs-linking-inline-od-inline-play-ui.xml delete mode 100644 tests/rules/bifs-linking-inline-segment-inline-play-ui.xml delete mode 100644 tests/rules/bifs-media-audiobuffer-play-ui.xml delete mode 100644 tests/rules/bifs-media-audioclip-play-ui.xml delete mode 100644 tests/rules/bifs-media-audioclip-urlchanged-play-ui.xml delete mode 100644 tests/rules/bifs-media-audiosource-mixing-play-ui.xml delete mode 100644 tests/rules/bifs-media-audiosource-play-ui.xml delete mode 100644 tests/rules/bifs-media-audiosource-urlchanged-play-ui.xml delete mode 100644 tests/rules/bifs-media-imagetexture-url-change-play-ui.xml delete mode 100644 tests/rules/bifs-media-movietexture-control-play-ui.xml delete mode 100644 tests/rules/bifs-media-movietexture-url-change-play-ui.xml delete mode 100644 tests/rules/bifs-misc-hc-proto-events-play-ui.xml delete mode 100644 tests/rules/bifs-misc-non-linear-parsing-conditional-play-ui.xml delete mode 100644 tests/rules/bifs-proto-conditional-play-ui.xml delete mode 100644 tests/rules/bifs-proto-multiple-play-ui.xml delete mode 100644 tests/rules/bifs-proto-nested-play-ui.xml delete mode 100644 tests/rules/bifs-proto-route-play-ui.xml delete mode 100644 tests/rules/bifs-script-child-create-play-ui.xml delete mode 100644 tests/rules/bifs-script-date.sh delete mode 100644 tests/rules/bifs-script-load-url-play-ui.xml delete mode 100644 tests/rules/bifs-script-node-create-play-ui.xml delete mode 100644 tests/rules/bifs-script-proto-play-ui.xml delete mode 100644 tests/rules/bifs-storage-play-ui.xml delete mode 100644 tests/rules/bifs-stream-text-switch-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-OCR-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-OCR.sh delete mode 100644 tests/rules/bifs-timeline-mediacontrol-audio-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-audio-speed-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-complete-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-deactivation-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-http-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-inline-av-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-inline-segments.sh delete mode 100644 tests/rules/bifs-timeline-mediacontrol-segments-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-video-play-ui.xml delete mode 100644 tests/rules/bifs-timeline-mediacontrol-videospeed-play-ui.xml delete mode 100644 tests/rules/laser-stz_animate_hrefstreamid-play-stderr.txt delete mode 100644 tests/rules/laser-stz_animate_hrefstreamid2-play-stderr.txt delete mode 100644 tests/rules/xmlin-meta-metx-no-namespace-import-stderr.txt delete mode 100644 tests/rules/xmlin-subt-stpp-export-track-stderr.txt delete mode 100644 tests/rules/xmlin-subt-stpp-no-namespace-import-stderr.txt delete mode 100644 tests/rules/xmlin-ttml-stpp-export-track-stderr.txt delete mode 100644 tests/scripts/3D-HEVC.sh delete mode 100755 tests/scripts/bifs_all.sh delete mode 100755 tests/scripts/compositor_modes.sh delete mode 100644 tests/scripts/dash-if-live.sh delete mode 100644 tests/scripts/dash-if-ondemand.sh delete mode 100644 tests/scripts/dash-live-generation.sh delete mode 100644 tests/scripts/dash-live.sh delete mode 100644 tests/scripts/dash-multiperiod.sh delete mode 100644 tests/scripts/dash-ts.sh delete mode 100644 tests/scripts/dash.sh delete mode 100755 tests/scripts/encryption.sh delete mode 100755 tests/scripts/fuzz-base.sh delete mode 100644 tests/scripts/hls.sh delete mode 100644 tests/scripts/iff.sh delete mode 100644 tests/scripts/item.sh delete mode 100755 tests/scripts/laser_all.sh delete mode 100755 tests/scripts/mp42ts.sh delete mode 100755 tests/scripts/mp4box-base.sh delete mode 100755 tests/scripts/mp4box-io.sh delete mode 100644 tests/scripts/mp4box-kind.sh delete mode 100644 tests/scripts/mp4box-lang.sh delete mode 100755 tests/scripts/mp4box-rtp.sh delete mode 100755 tests/scripts/mp4box-subtitle.sh delete mode 100755 tests/scripts/mp4client-base.sh delete mode 100644 tests/scripts/mp4client-dash-config.sh delete mode 100755 tests/scripts/mp4client-dash.sh delete mode 100755 tests/scripts/mp4client-http.sh delete mode 100755 tests/scripts/mp4client-rawout.sh delete mode 100644 tests/scripts/negctts.sh delete mode 100644 tests/scripts/nhml-subs.sh delete mode 100644 tests/scripts/noFragsDefault.sh delete mode 100644 tests/scripts/range_extension.sh delete mode 100755 tests/scripts/scalable.sh delete mode 100755 tests/scripts/smooth.sh delete mode 100644 tests/scripts/swf.sh delete mode 100755 tests/scripts/test_prl.sh delete mode 100755 tests/scripts/vtt-all.sh delete mode 100755 tests/scripts/x3d.sh delete mode 100755 tests/scripts/xmlin.sh delete mode 100644 tests/stylesheet.xsl diff --git a/.gitattributes b/.gitattributes index fe272ac..f32d776 100644 --- a/.gitattributes +++ b/.gitattributes @@ -20,3 +20,6 @@ configure text eol=lf #tests tests/media/xmlin4/input.txt text eol=crlf +tests/media/xmlin4/input.xml text eol=lf +tests/media/laser/*.xml text eol=lf +tests/media/ttml/ebu-ttd_sample.ttml text eol=lf diff --git a/.gitignore b/.gitignore index 803dfb7..ba9dd27 100644 --- a/.gitignore +++ b/.gitignore @@ -60,12 +60,12 @@ bld/ *.so *.dylib *.dll -*.lai -*.la -*.a +*.lai +*.la +*.a *.lib -*.exe -*.out +*.exe +*.out *.app *.apk *.dmg @@ -74,17 +74,18 @@ bld/ .depend .deps/ +.dep -#GPAC specific +#GPAC specific config.h include/gpac/revision.h include/gpac/revision.h.new extra_lib/lib/ -extra_lib/include/SDL/ -extra_lib/include/ios/ +extra_lib/include/ config.mak configure-stamp gpac.pc +share/gpac.desktop tests/external_media/ tests/results/ - +tests/hash_refs/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..670f16f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,5 @@ +[submodule "testsuite"] + path = testsuite + url = https://github.com/gpac/testsuite.git + branch = filters + ignore = dirty diff --git a/.travis.yml b/.travis.yml index 5047ab9..7ec1e92 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,30 @@ +#changes for GPAC filters (0.9+) for travis CI: GPAC hosts its own buildbot for building on various platforms, running tests, coverage and safety checks +#TravisCI is only used for checking sanity of PRs. Consequently: +#- OSX and mingw no longer compiled +#- linux only compiled for +# - mp4box static +# - release mode with mem tracking and gcov + language: c compiler: gcc os: - linux - - osx +# - osx +dist: bionic +services: + - xvfb + before_install: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -y update -qq ; fi install: - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -y install build-essential fakeroot dpkg-dev devscripts ccache debhelper pkg-config g++ mesa-utils ; fi - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -y install -y zlib1g-dev libfreetype6-dev libjpeg62-dev libpng12-dev libopenjpeg-dev libmad0-dev libfaad-dev libogg-dev libvorbis-dev libtheora-dev liba52-0.7.4-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavdevice-dev libxv-dev x11proto-video-dev libgl1-mesa-dev x11proto-gl-dev linux-sound-base libxvidcore-dev libssl-dev libjack-dev libasound2-dev libpulse-dev libsdl1.2-dev dvb-apps libavcodec-extra-53 libmozjs185-dev ; fi - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -y install -y gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev ; fi - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -qq -y install lcov time; fi - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then sudo chown -R "$USER":admin /usr/local; fi - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install gnu-time gnu-sed gnu-tar xz lcov ; fi - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install faad2 sdl freetype libvorbis theora openjpeg libmad xvid libogg spidermonkey ffmpeg ; fi + - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -y install build-essential fakeroot dpkg-dev devscripts ccache debhelper pkg-config g++ mesa-utils lcov ; fi + - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -y install -y zlib1g-dev libfreetype6-dev libjpeg62-dev libpng-dev libmad0-dev libfaad-dev libogg-dev libvorbis-dev libtheora-dev liba52-0.7.4-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavdevice-dev libxv-dev x11proto-video-dev libgl1-mesa-dev x11proto-gl-dev libxvidcore-dev libssl-dev libjack-dev libasound2-dev libpulse-dev libsdl2-dev dvb-apps ; fi + - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -qq -y install time; fi +# - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get -y install -y gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-x86-64-dev ; fi +# - if [ "$TRAVIS_OS_NAME" == "osx" ]; then sudo chown -R "$USER":admin /usr/local; fi +# - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi +# - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install gnu-time gnu-sed gnu-tar xz lcov ; fi +# - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install faad2 sdl freetype libvorbis theora openjpeg libmad xvid libogg spidermonkey ffmpeg ; fi env: - GPAC_CONFIGURE_OPTIONS="--prefix=build/mp4box --enable-debug --static-mp4box" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="make install" DOTRAVIS="" - GPAC_CONFIGURE_OPTIONS="--enable-debug --static-modules" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="" DOTRAVIS="" @@ -22,23 +33,23 @@ matrix: include: - os: linux before_script: - - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" - - sleep 3 # give xvfb some time to start - - glxinfo # check glx status + #git submodule update is called by travis, just checkout filter branch + - "git -C ./testsuite checkout filters" + - xvfb-run -e /dev/stdout --auto-servernum --server-num=1 glxinfo # check glx status env: GPAC_CONFIGURE_OPTIONS="--enable-mem-track --enable-gcov" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="sudo make install" DOTRAVIS="make travis" AUDIODEV=null - - os: linux - env: GPAC_CONFIGURE_OPTIONS="--prefix=build/x86_64-w64-mingw32 --enable-debug --static-mp4box --use-zlib=no --target-os=mingw32 --cross-prefix=i686-w64-mingw32- --extra-ldflags=-Lbuild/x86_64-w64-mingw32/lib" GPAC_CONFIGURE_ECFLAGS="-Ibuild/x86_64-w64-mingw32/include -w -fPIC" DOINSTALL="" DOTRAVIS="" - - os: linux - env: GPAC_CONFIGURE_OPTIONS="--prefix=build/x86_64-w64-mingw32 --enable-debug --static-mp4box --use-zlib=no --target-os=mingw32 --cross-prefix=x86_64-w64-mingw32- --extra-ldflags=-Lbuild/x86_64-w64-mingw32/lib" GPAC_CONFIGURE_ECFLAGS="-Ibuild/x86_64-w64-mingw32/include -w -fPIC" DOINSTALL="" DOTRAVIS="" - - os: linux - env: GPAC_CONFIGURE_OPTIONS="--prefix=build/all --enable-debug --disable-all" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="make install" DOTRAVIS="" - - os: linux - env: GPAC_CONFIGURE_OPTIONS="--enable-debug --use-js=no --use-mad=no --use-xvid=no --use-ogg=no --use-vorbis=no --use-theora=no --use-openjpeg=no --disable-streaming --disable-isoff-frag --disable-isoff-hint --disable-isoff-write --disable-loader-xmt --disable-loader-bt --disable-loader-isoff --disable-scene-encode --disable-mcrypt --disable-od-dump --disable-scene-dump --disable-scene-stats --disable-swf --disable-export --disable-import --disable-m2ps --disable-ogg -disable-avi --disable-qtvr --disable-seng --disable-smgr --disable-x3d --disable-3d --disable-ssl --disable-jack --disable-pulse --use-a52=no --disable-odf --disable-isoff --disable-m2ts-mux --disable-dvbx --disable-saf --disable-vobsub --disable-ttxt --disable-od-parse" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="" DOTRAVIS="" - - os: osx - env: GPAC_CONFIGURE_OPTIONS="--enable-mem-track" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="sudo make install" DOTRAVIS="" AUDIODEV=null + +# - os: linux +# env: GPAC_CONFIGURE_OPTIONS="--prefix=build/x86_64-w64-mingw32 --enable-debug --static-mp4box --use-zlib=no --target-os=mingw32 --cross-prefix=i686-w64-mingw32- --extra-ldflags=-Lbuild/x86_64-w64-mingw32/lib" GPAC_CONFIGURE_ECFLAGS="-Ibuild/x86_64-w64-mingw32/include -w -fPIC" DOINSTALL="" DOTRAVIS="" +# - os: linux +# env: GPAC_CONFIGURE_OPTIONS="--prefix=build/x86_64-w64-mingw32 --enable-debug --static-mp4box --use-zlib=no --target-os=mingw32 --cross-prefix=x86_64-w64-mingw32- --extra-ldflags=-Lbuild/x86_64-w64-mingw32/lib" GPAC_CONFIGURE_ECFLAGS="-Ibuild/x86_64-w64-mingw32/include -w -fPIC" DOINSTALL="" DOTRAVIS="" +# - os: linux +# env: GPAC_CONFIGURE_OPTIONS="--prefix=build/all --enable-debug --disable-all" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="make install" DOTRAVIS="" +# - os: linux +# env: GPAC_CONFIGURE_OPTIONS="--enable-debug --use-js=no --use-mad=no --use-xvid=no --use-ogg=no --use-vorbis=no --use-theora=no --use-openjpeg=no --disable-streaming --disable-isoff-frag --disable-isoff-hint --disable-isoff-write --disable-loader-xmt --disable-loader-bt --disable-loader-isoff --disable-scene-encode --disable-mcrypt --disable-od-dump --disable-scene-dump --disable-scene-stats --disable-swf --disable-export --disable-import --disable-m2ps --disable-ogg -disable-avi --disable-qtvr --disable-seng --disable-smgr --disable-x3d --disable-3d --disable-ssl --disable-jack --disable-pulse --use-a52=no --disable-odf --disable-isoff --disable-m2ts-mux --disable-dvbx --disable-saf --disable-vobsub --disable-ttxt --disable-od-parse --disable-atsc" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="" DOTRAVIS="" +# - os: osx +# env: GPAC_CONFIGURE_OPTIONS="--enable-mem-track" GPAC_CONFIGURE_ECFLAGS="" DOINSTALL="sudo make install" DOTRAVIS="" AUDIODEV=null script: - - ./configure --extra-cflags=''"$GPAC_CONFIGURE_ECFLAGS"'' $GPAC_CONFIGURE_OPTIONS && make && $DOINSTALL && $DOTRAVIS + - ./configure --extra-cflags=''"$GPAC_CONFIGURE_ECFLAGS"'' $GPAC_CONFIGURE_OPTIONS && make && $DOINSTALL && ( if [ -n "$DOTRAVIS" ]; then xvfb-run -e /dev/stdout --auto-servernum --server-num=1 --server-args="-screen 0 1024x768x24" $DOTRAVIS ; fi ) after_success: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then bash <(curl -s https://codecov.io/bash) ; fi diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 1dd25b9..0000000 --- a/AUTHORS +++ /dev/null @@ -1,28 +0,0 @@ -Author: -======= -Jean Le Feuvre - -Contributors: -============= -Cyril Concolato -Romain Bouqueau -Pierre Souchay -Viet Tran Trung Nguyen -Emmanouil Potetsianakis -Rodolphe Fouquet -Jérôme Gorin -Arash Shafiei -Ivan Vecera -Jean-Claude Moissinac -Jean-Claude Dufourd -Benoit Pellan -Philippe de Cuetos -Jonathan Sillan -Harlina Daud -Daniel Comalrena -Stanislas Selle -Stéphane Thomas -Ayodeji Aribuki -Yi-Zhen Zhang -Berthele Rodriguez -Yen Chi Hsuan diff --git a/BUGS b/BUGS deleted file mode 100644 index 2785752..0000000 --- a/BUGS +++ /dev/null @@ -1,3 +0,0 @@ -BUGS - -A bug tracker is available at https://github.com/gpac/gpac/issues diff --git a/Changelog b/Changelog index 6c682c2..a3f1d79 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,212 @@ +10/09/2020: GPAC 1.0.1 +This release fixes build and installation issues in 1.0.0, as well as various bugs introduced during the migration to the filters architecture. + +It also adds several small features: +- better ttml import +- better support for MPEGH audio +- support fur DASH UTCTiming +- manifest generation from pre-fragmented DASH/HLS mp4 +- speed optimization in isobmf reading (normal and fragmented) +- improved JS API for the filter session +- core tools exposed as JS module (file io, bitstream, etc ...) +- android fixes + +16/06/2020: GPAC 1.0 + - Complete rewrite of GPAC streaming core: + * addition of a filter-based architecture, used by MP4Client and MP4Box. + * moving all decoders and demuxer plugins of MP4Client and most of MP4Box import/export code as filters for this new architecture, + * moving DASH/HLS segmenter to a filter + * moving MP4Client compositor and most of the GF_Terminal internals to a filter + * addition of a new application gpac, whose only purpose is to create and run filter chains + * removal of MP42TS and DashCast applications since these functionalities are provided by gpac + * deprecation of some features (widget management, MSE draft implementation for SVG media, UPnP, TEMI player support). +- Profile system allowing to override through a static file default options of all filters and libgpac core +- Alias system for gpac app to simplify your command lines +- Enhanced DASHer: + * Support for HLS and dual HLS / DASH generation + * Support for any input + * True low-latency mode for DASH + * Support for multiple periods + * Support for other segment formats (raw, mkv, webm currently tested) +- Input and outputs + * Generic pipe, TCP, UDP, and Unix Domain socket input and output + * RTSP server output + * HTTP output (client and server), supporting low latency DASH access + * Ad-hoc stream format called GSF to allow serialization to file, pipe or socket of a session (for distributed filter chains), supporting AES-128 CBC encryption. +- Raw audio (PCM) and video (RGB, YUV) reframers and exporters +- HEVC tile spliting and merging filters +- Compositor is a standalone filter (SVG/BIFS/VRML graphics in a filter chain) +- Image encoding support through libjpg and libpng +- Full FFMPEG support: + * Encoding/decoding through FFMPEG libavcodec + * Multiplexing/demultiplexing through FFMPEG libavformat + * Device grabbers through FFMPEG libavdevice + * Raw audio and video filters through FFMPEG libavfilter +- Support for QuickJS (ES2002) and bindings for: + * Complete filter API + * GPAC software rasterizer (EVG) + * WebGL 1.0 Core + * XmlHttpRequest and uDOM APIs + * Storage +- Inspect and analyze filter +- MPEG-2 TS splitter +- Video cropper filter with zero-copy mode +- Video flip filter +- Source concatenator filter +- Simple audio and video output filters +- Experimental audio and video rewinder filter +- Encryption + * On-the-fly encryption and decryption, now available as filters + * Segment-based encryption and decryption +- ISOBMFF + * box customization + * Better QT support, prores parsing and dumping + * Support for raw media (QT style or ISOBMFF for audio) + * Simplify HEIF batch conversion through item to track mapping + * Reading from pipes (fragmented or progressive files) + * Writing to packets rather than files + * Fast interleaved file creation mode with less storage requirements +- FileIO wrapper for cases where files are not stored in a file system known by GPAC +- Testing and Documentation + * Live doc generation (man and wiki) + * Improved coverage + * Split test suite as dedicated repo + * Moved all resource to https://wiki.gpac.io + * Started howto pages on wiki + * Many bug fixes + +27/06/2019: GPAC 0.8.0 + - General + * Many security fixes (static compile and fuzzing through AFL, always ongoing). + * Many bugs fixes + * Added :ncl option in log levels to disable color logs + * More tests and coverage + - File Formats + * Better support of QTFF / ProRes files + * Support for AV1 + - import and export + - source formats: OBUs (Section 5), IVF and AnnexB + - AV1 in HEIF + * Support for color (nclc, nclx and ICC profiles) in HEIF and ISOBMFF + * Support for HDR (mdcv, clli) info in HEIF and ISOBMFF + * Support for alpha in HEIF + * Support for enforcing pasp presence even for 1:1 ratios + * HEVC temporal sublayer split in MP4Box + * Allow meta storage before mdat for meta-only files (heif and co) + * Added option to keep AU delimiter in isobmff samples + * Support for opus import + * Support for pixi and ccst in HEIF + * DolbyVision 'dvcC' and partial 'dvhe' boxes for HDR + * Support for VP9 import and playback + * Sample dependency in avc and hevc importers, and track thinner for non-refs images + * Support for audio_roll signaling + * New audio import mode to control AudioSampleEntry creation (v0, v1 ISOBMFF, v1 QTFF) + * xHE-AAC import with detection of sync samples + * Added support for MPEG-H 3D audio boxes (no import yet) + * Handle Vobsub empty SPU packets + * Added auxv and pict support + - Common Encryption + * Fully compliant CENC supporting cenc, cens, cbc1 and cbcs + * CENC for AV1 + * Improved DASH+CENC support, pssh in MPD + * ForceClear mode for CENC to skip encryption without sample groups + * Made senc in movie fragments always stored before truns + * Added default values handling for cbcs and possibility to set protection system per track + * Compatibility with OpenSSL 1.1.x + - Streaming and Adaptive Streaming + * Support for ATSC3.0 both US and Korean versions ! + * Support for for live splices (xlink period insertions) in DASH client + * Automatic period continuity in DASH when no codec change between periods + * Added DASH cue-base segmentation (XML based) and -dsap option to generate cue files from source + * Support for BBA-0 and BOLA implementations + * Write fragment defaults in trex even when not using them + * Support for simple ssix for keyframe data byterange at the start of a segment + * Moved segment template at AdaptationSet level if only one representation + * Changed default bsmode in dasher if single input file + * Added init-seg-ext option + * Added -mvex-after-traks option to MP4Box when dashing for CMAF + * Added segmentation option to insert a tfdt per traf + * Added -closest mode for DASH segmentation + * Added -bound option to use audio segmenting method for video + * Renamed -dash-run-for to -run-for + * Added '=' in dash templates + * Improved bandwith estimation when using HTTP 1.1 chunk transfer + * Add option to force moof base offsets + - MP4Box + * Added -catpl to concatenate from playlist in MP4Box + * Added options to set movie timescale at import and dash time + * Added mpd rip option and top-level box compressor in MP4Box + * Made -dts skip timing check and added -dtsc for that + * Made force-cat option more agressive + * Support for MovieFragmentRandomAccess using -mfra option + * Added -dtsx to dump timing without offset + * Added -dnalc opt for nal CRC dump + * Added chunk extraction up to time until end + * ISOBMFF single track import now removes references by default + - Decoders + * Updated ffmpeg to 4.0.2 + * Moved to openHEVC 3.0 API + * Added nvdec support (windows, linux) with reuse of decoder context for tiled VR + * Added HEVC support to mediacodec on android + * AV1 playback through ffmpeg + * Opus playback through ffmpeg + - 3D, VR and 360 + * Added vrhud for multiviewpoint 360 + * Added forced visibility mode of tiles in VR + * Added tile visibility debug mode + * Added forced stereo output for openhevc + * Disable face nav if mouse grabbed + * Added simple face tracking vr navigation based on udp commands + * Added PSVR support + * Added mouse move emulation at window border to force sphere rotation when inactive + * Changed tile visibility algo to sample points in mesh + - Players (Mobile and Desktop) + * Added about extension + * Added multiple audio objects in dynamic scene + * Added addon splicing of main content + * Added mosaic://v1:.:vN url support + * Added gaze simulation through mouse and gaze-sphere visibility test + - Subtitles + * Allow * as argument of -srt|ttxt to dump all possible tracks (#925) + * Improved support for WebVTT import + * Improved support for WebVTT DASHing/fragmentation + - Misc + * OSX install now done through PKG and modify PATH env in/etc/paths + * Added initial PMT version and disc marker to TS muxer + * Moved dektec output to matrix API, added SDI clipping + * Added temi periodic toggle and manual toggle in MP42TS + +26/04/2017: GPAC 0.7.1 + - Full changelog at https://github.com/gpac/gpac/wiki/GPAC-0.7.0 + - Many security fixes (static compile and fuzzing through [AFL](http://lcamtuf.coredump.cx/afl/), always ongoing) + - Colorized log. + - Fix pkg-config Private.libs. + - Changed default audio volume to 100% instead of 75%. + - Expose more experimental options through the [documentation](http://htmlpreview.github.io/?https://github.com/gpac/gpac/blob/master/doc/configuration.html). + - Improved GLES renderer on mobile platforms + - YUV422 and YUV444 8 and 10 bit support in GLES renderer + - Improvements on AVI dump. + - SAT>IP modified RTSP client. + - Added L-HEVC File Format support (SHVC/MV-HEVC tracks and HEVC Tile Tracks). + - Added MPEG IFF (image File Format) support. + - Range extension support for AVC and HEVC. + - SHVC and MV-HEVC importers and playback: moved to final spec version (SHM6+). + - Support of HLS with fragmented MP4 playback. + - APIs: gf_mpd_() functions and new segmenter API. + - Improved alternate groups. + - More support for PIFF PSEC and Smooth Streaming ( file format & playback). + - DASH client: pluggable algorithms + improvements with scalable contents. + - The counter source from the DASH sequences added to the public content. + - HLS and DASH playback minor fixes. + - Cleanup of DASH client logs. + - Added support for DASH SRD in 360 for independent videos videos (NxM partial spheres) [more](https://gpac.wp.imt.fr/2016/05/25/srd/) + - Added support for DASH SRD in 360 for HEV Ctiled videos (NxM tiles on one sphere) - [checkout tuto](https://gpac.wp.imt.fr/2017/02/01/hevc-tile-based-adaptation-guide/) + - Apple VideoToolBox hardware decoding support for OSX and iOS for AVC|H264. + - Android hardware decoding hardware acceleration for AVC|H264 (HEVC on its way). + - Android build is based on Android Studio. + - Android: new File Manager. + - Import of TTML via NHML according to MPEG-4 part 30 improved. + 19/02/2016: GPAC 0.6.0 Many things added, improved and fixed - see https://github.com/gpac/gpac/releases/tag/v0.6.0 @@ -343,7 +552,7 @@ - added support for nero chapters in MP4 ('chpl' box), in MP4Box (-chap file.chp) and selection in players (chapters mapped to MPEG-4 SegmentDescriptors). note regarding chp files: not sure about file syntax, currently support for (one chapter entry per line): ZoomPlayer syntax: AddChapter (-fps for import framerate selection), AddChapterBySecond and AddChapterByTime - Regular time code … la SRT: HH:MM:SS[:ms or .ms] [Chapter Name] + Regular time code … la SRT: HH:MM:SS[:ms or .ms] [Chapter Name] SMPTE time code: HH:MM:SS;fr/fps [Chapter Name] - if fps is omitted, use '-fps' if specified or 25 fps default. - fixed avi packed bitstream flag removal bug with beta versions of DivX. diff --git a/INSTALLME b/INSTALLME deleted file mode 100644 index 9f7eb51..0000000 --- a/INSTALLME +++ /dev/null @@ -1,67 +0,0 @@ -Installation instructions for latest GPAC GIT version - March 2015: - -For Windows, Linux and Mac OS X versions, follow the instructions on http://gpac.io/downloads/ - -For Android, follow the instructions in gpac/build/android/README - -(WindowsMobile platform is no longer maintained) -For WindowsMobile platform, get the latest package of gpac extra libs available here: - -https://sourceforge.net/p/gpac/code/HEAD/tree/trunk/gpac_extra_libs/ - -and follow the instructions in gpac/doc/INSTALL.wCE - - - -Other Installation instructions for GPAC - - -* Foreword - - GPAC may be compiled without any third party libraries, but in this case its functionalities are very -limited (no still image, no audio, no video, no text, no scripting). It is therefore recommended to download the -extra lib package available at http://sourceforge.net/projects/gpac. Compilation instructions for these libraries -are provided per library in the package. - - The current extra_lib package to use with gpac is gpac_extra_libs available here: -http://download.tsi.telecom-paristech.fr/gpac/gpac_extra_libs.zip - - 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). - * libjpg version 6b - * Libpng version 1.2.33 (older versions should work) - * MAD version 0.15.1b (older versions should work) - * xvid version 1.0 (0.9.0 / .1 / .2 should also work) - * ffmpeg (latest stable API version checked was 17 February 2016 snapshot, you may need to change a few things with current versions) - * libogg 1.1, libvorbis 1.1 and libtheora 1.0 from Xiph.org (newer versions work) - * faad2, version 2.0 or above (2.6.1 working) - * liba52, version 0.7.4 - * OpenJPEG, version 1.3 - * OpenSVCDecoder, version 1.3 - -* Installing GPAC - -/!\ GPAC won't compile if the 'git' command is not in your path /!\ - -!! WARNING !! -The following instructions may not be completely up to data -You should use online instructions which may be more up-to-date: -http://gpac.io/2011/04/18/command-line-gpac-compiling-on-windows-x86-using-free-microsoft-visual-c/ - -Detailed instruction for Win32 MSVC Compilation are available in gpac/doc/INSTALL.w32 - -Detailed instruction for WinCE eVC Compilation are available in gpac/doc/INSTALL.wCE - -Detailed instruction for GCC Compilation are available in gpac/doc/INSTALL.gcc - -Detailed instruction for GCC cross-compilation for familiar+GPE systems are available in gpac/doc/INSTALL.gpe - -Detailed instruction for GCCE/Symbian cross-compilation for Symbian v9.1 systems are available in gpac/doc/INSTALL.symbian - -Detailed instruction for iOS Compilation are available in gpac/build/xcode/README_IOS.txt - -* Configuring GPAC - -GPAC's client configuration is documented in gpac/doc/configuration.html -MP4Box documentation is available online at http://gpac.sourceforge.net diff --git a/Makefile b/Makefile index 9849173..303a413 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,10 @@ # include config.mak +ifndef SRC_PATH +override SRC_PATH = . +endif + vpath %.c $(SRC_PATH) all: version @@ -12,6 +16,11 @@ ifneq ($(MP4BOX_STATIC),yes) $(MAKE) -C modules all endif + +config.mak: + ./configure + + GITREV_PATH:=$(SRC_PATH)/include/gpac/revision.h TAG:=$(shell git --git-dir=$(SRC_PATH)/.git describe --tags --abbrev=0 2> /dev/null) VERSION:=$(shell echo `git --git-dir=$(SRC_PATH)/.git describe --tags --long || echo "UNKNOWN"` | sed "s/^$(TAG)-//") @@ -41,7 +50,7 @@ mods: instmoz: $(MAKE) -C applications/osmozilla install - + depend: $(MAKE) -C src dep $(MAKE) -C applications dep @@ -56,16 +65,21 @@ distclean: $(MAKE) -C src distclean $(MAKE) -C applications distclean $(MAKE) -C modules distclean - rm -f config.mak config.h + rm -f config.mak config.h config.log @find . -type f -name '*.gcno*' -delete @find . -type f -name '*.gcda*' -delete @rm -f coverage.info 2> /dev/null + @rm -f bin/gcc/gm_*$(DYN_LIB_SUFFIX) 2> /dev/null + @rm -f bin/gcc/gf_*$(DYN_LIB_SUFFIX) 2> /dev/null -docs: - @cd $(SRC_PATH)/doc && doxygen +doc: + @cd $(SRC_PATH)/share/doc && doxygen + +man: + @cd $(SRC_PATH)/share/doc/man && MP4Box -genman && MP4Client -genman && gpac -genman test_suite: - @cd $(SRC_PATH)/tests && ./make_tests.sh + @cd $(SRC_PATH)/testsuite && ./make_tests.sh -precommit -p=0 lcov_clean: lcov --directory . --zerocounters @@ -73,8 +87,8 @@ lcov_clean: lcov_only: @echo "Generating lcov info in coverage.info" @rm -f ./gpac-conf-* > /dev/null - @lcov -q -capture --directory . --output-file all.info - @lcov --remove all.info /usr/* /usr/include/* /usr/local/include/* /usr/include/libkern/i386/* /usr/include/sys/_types/* /opt/* /opt/local/include/* /opt/local/include/mozjs185/* --output coverage.info + @lcov -q -capture --directory . --output-file all.info + @lcov --remove all.info '*/usr/*' '*/opt/*' '*/include/*' '*/validator/*' '*/quickjs/*' '*/jsmods/WebGLRenderingContextBase*' '*/utils/Remotery*' '*/utils/gzio*' --output coverage.info @rm all.info @echo "Purging lcov info" @cd src ; for dir in * ; do cd .. ; sed -i -- "s/$$dir\/$$dir\//$$dir\//g" coverage.info; cd src; done ; cd .. @@ -85,12 +99,12 @@ lcov: lcov_only @genhtml -q -o coverage coverage.info travis_tests: - @echo "Running tests" - @cd $(SRC_PATH)/tests && ./make_tests.sh -warn -sync-before + @echo "Running tests in $(SRC_PATH)/testsuite" + @cd $(SRC_PATH)/testsuite && ./make_tests.sh -precommit -p=0 travis_deploy: @echo "Deploying results" - @cd $(SRC_PATH)/tests && ./ghp_deploy.sh + @cd $(SRC_PATH)/testsuite && ./ghp_deploy.sh travis: travis_tests lcov travis_deploy @@ -98,176 +112,202 @@ dep: depend install: $(INSTALL) -d "$(DESTDIR)$(prefix)" - $(INSTALL) -d "$(DESTDIR)$(prefix)/$(libdir)" + + $(MAKE) install-lib + $(INSTALL) -d "$(DESTDIR)$(prefix)/bin" -ifeq ($(DISABLE_ISOFF), no) + $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/gpac$(EXE_SUFFIX) "$(DESTDIR)$(prefix)/bin" +ifeq ($(DISABLE_ISOFF),no) if [ -f bin/gcc/MP4Box$(EXE_SUFFIX) ] ; then \ $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Box$(EXE_SUFFIX) "$(DESTDIR)$(prefix)/bin" ; \ fi -ifneq ($(MP4BOX_STATIC), yes) - if [ -f bin/gcc/MP42TS$(EXE_SUFFIX) ] ; then \ - $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP42TS$(EXE_SUFFIX) "$(DESTDIR)$(prefix)/bin" ; \ - fi -ifneq ($(CONFIG_WIN32), yes) -ifneq ($(CONFIG_FFMPEG), no) -ifneq ($(DISABLE_CORE_TOOLS), yes) -ifneq ($(DISABLE_AV_PARSERS), yes) - if [ -f bin/gcc/DashCast$(EXE_SUFFIX)g ] ; then \ - $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/DashCast$(EXE_SUFFIX) "$(DESTDIR)$(prefix)/bin" ; \ - fi -endif -endif -endif -endif -endif endif -ifneq ($(MP4BOX_STATIC), yes) -ifeq ($(DISABLE_PLAYER), no) +ifneq ($(MP4BOX_STATIC),yes) +ifeq ($(DISABLE_PLAYER),no) if [ -f bin/gcc/MP4Client$(EXE_SUFFIX) ] ; then \ $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Client$(EXE_SUFFIX) "$(DESTDIR)$(prefix)/bin" ; \ fi endif endif - if [ -d $(DESTDIR)$(prefix)/$(libdir)/pkgconfig ] ; then \ - $(INSTALL) $(INSTFLAGS) -m 644 gpac.pc "$(DESTDIR)$(prefix)/$(libdir)/pkgconfig" ; \ - fi - $(INSTALL) -d "$(DESTDIR)$(moddir)" + $(INSTALL) -d "$(DESTDIR)$(prefix)/$(lib_dir)/$(moddir)" ifneq ($(MP4BOX_STATIC),yes) - $(INSTALL) bin/gcc/*$(DYN_LIB_SUFFIX) "$(DESTDIR)$(moddir)" - rm -f $(DESTDIR)$(moddir)/libgpac$(DYN_LIB_SUFFIX) - rm -f $(DESTDIR)$(moddir)/nposmozilla$(DYN_LIB_SUFFIX) - $(MAKE) installdylib + $(INSTALL) bin/gcc/gm_*$(DYN_LIB_SUFFIX) "$(DESTDIR)$(prefix)/$(lib_dir)/$(moddir)" || true + $(INSTALL) bin/gcc/gf_*$(DYN_LIB_SUFFIX) "$(DESTDIR)$(prefix)/$(lib_dir)/$(moddir)" || true +ifeq ($(CONFIG_OPENHEVC),yes) + cp -a bin/gcc/libopenhevc* $(DESTDIR)$(prefix)/$(lib_dir)/ || true +endif + endif - $(INSTALL) -d "$(DESTDIR)$(mandir)" - $(INSTALL) -d "$(DESTDIR)$(mandir)/man1" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/doc/man/mp4box.1 $(DESTDIR)$(mandir)/man1/ - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/doc/man/mp4client.1 $(DESTDIR)$(mandir)/man1/ - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/doc/man/gpac.1 $(DESTDIR)$(mandir)/man1/ + $(INSTALL) -d "$(DESTDIR)$(prefix)/$(man_dir)" + $(INSTALL) -d "$(DESTDIR)$(prefix)/$(man_dir)/man1" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/doc/man/mp4box.1 $(DESTDIR)$(prefix)/$(man_dir)/man1/ + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/doc/man/mp4client.1 $(DESTDIR)$(prefix)/$(man_dir)/man1/ + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/doc/man/gpac.1 $(DESTDIR)$(prefix)/$(man_dir)/man1/ + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/doc/man/gpac-filters.1 $(DESTDIR)$(prefix)/$(man_dir)/man1/ $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/doc/gpac.mp4 $(DESTDIR)$(prefix)/share/gpac/ + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/res" $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/gui" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/gui/gui.bt "$(DESTDIR)$(prefix)/share/gpac/gui/" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/gui/gui.js "$(DESTDIR)$(prefix)/share/gpac/gui/" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/gui/gwlib.js "$(DESTDIR)$(prefix)/share/gpac/gui/" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/gui/mpegu-core.js "$(DESTDIR)$(prefix)/share/gpac/gui/" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/gui/webvtt-renderer.js "$(DESTDIR)$(prefix)/share/gpac/gui/" $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/gui/icons" $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/gui/extensions" - $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/shaders/" + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/shaders" + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/scripts" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/res/gpac.mp4 $(DESTDIR)$(prefix)/share/gpac/res/ + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/res/gpac_cfg_test.mp4 $(DESTDIR)$(prefix)/share/gpac/res/ + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/res/gpac.png $(DESTDIR)$(prefix)/share/gpac/res/ + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/default.cfg $(DESTDIR)$(prefix)/share/gpac/ + +ifneq ($(CONFIG_DARWIN),yes) + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/pixmaps" + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/applications" + + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/res/gpac.png "$(DESTDIR)$(prefix)/share/pixmaps/" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/gpac.desktop "$(DESTDIR)$(prefix)/share/applications/" +endif + + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/gui/gui.bt "$(DESTDIR)$(prefix)/share/gpac/gui/" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/gui/gui.js "$(DESTDIR)$(prefix)/share/gpac/gui/" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/gui/gwlib.js "$(DESTDIR)$(prefix)/share/gpac/gui/" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/scripts/webvtt-renderer.js "$(DESTDIR)$(prefix)/share/gpac/scripts/" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/share/scripts/ttml-renderer.js "$(DESTDIR)$(prefix)/share/gpac/scripts/" + + ifeq ($(CONFIG_DARWIN),yes) - cp $(SRC_PATH)/gui/icons/* "$(DESTDIR)$(prefix)/share/gpac/gui/icons/" - cp -R $(SRC_PATH)/gui/extensions/* "$(DESTDIR)$(prefix)/share/gpac/gui/extensions/" - cp $(SRC_PATH)/shaders/* "$(DESTDIR)$(prefix)/share/gpac/shaders/" + cp $(SRC_PATH)/share/gui/icons/* "$(DESTDIR)$(prefix)/share/gpac/gui/icons/" + cp -R $(SRC_PATH)/share/gui/extensions/* "$(DESTDIR)$(prefix)/share/gpac/gui/extensions/" + cp $(SRC_PATH)/share/shaders/* "$(DESTDIR)$(prefix)/share/gpac/shaders/" else - cp --no-preserve=mode,ownership,timestamp $(SRC_PATH)/gui/icons/* $(DESTDIR)$(prefix)/share/gpac/gui/icons/ - cp -R --no-preserve=mode,ownership,timestamp $(SRC_PATH)/gui/extensions/* $(DESTDIR)$(prefix)/share/gpac/gui/extensions/ - cp --no-preserve=mode,ownership,timestamp $(SRC_PATH)/shaders/* $(DESTDIR)$(prefix)/share/gpac/shaders/ + cp --no-preserve=mode,ownership,timestamp $(SRC_PATH)/share/gui/icons/* $(DESTDIR)$(prefix)/share/gpac/gui/icons/ + cp -R --no-preserve=mode,ownership,timestamp $(SRC_PATH)/share/gui/extensions/* $(DESTDIR)$(prefix)/share/gpac/gui/extensions/ + cp --no-preserve=mode,ownership,timestamp $(SRC_PATH)/share/shaders/* $(DESTDIR)$(prefix)/share/gpac/shaders/ endif lninstall: $(INSTALL) -d "$(DESTDIR)$(prefix)" - $(INSTALL) -d "$(DESTDIR)$(prefix)/$(libdir)" + $(INSTALL) -d "$(DESTDIR)$(prefix)/$(lib_dir)" $(INSTALL) -d "$(DESTDIR)$(prefix)/bin" -ifeq ($(DISABLE_ISOFF), no) + ln -sf $(BUILD_PATH)/bin/gcc/gpac$(EXE_SUFFIX) $(DESTDIR)$(prefix)/bin/gpac$(EXE_SUFFIX) +ifeq ($(DISABLE_ISOFF),no) ln -sf $(BUILD_PATH)/bin/gcc/MP4Box$(EXE_SUFFIX) $(DESTDIR)$(prefix)/bin/MP4Box$(EXE_SUFFIX) - ln -sf $(BUILD_PATH)/bin/gcc/MP42TS$(EXE_SUFFIX) $(DESTDIR)$(prefix)/bin/MP42TS$(EXE_SUFFIX) endif ifneq ($(MP4BOX_STATIC),yes) -ifeq ($(DISABLE_PLAYER), no) +ifeq ($(DISABLE_PLAYER),no) ln -sf $(BUILD_PATH)/bin/gcc/MP4Client$(EXE_SUFFIX) $(DESTDIR)$(prefix)/bin/MP4Client$(EXE_SUFFIX) endif -ifneq ($(CONFIG_WIN32), yes) -ifneq ($(CONFIG_FFMPEG), no) -ifneq ($(DISABLE_CORE_TOOLS), yes) -ifneq ($(DISABLE_AV_PARSERS), yes) - ln -sf $(BUILD_PATH)/bin/gcc/DashCast$(EXE_SUFFIX) $(DESTDIR)$(prefix)/bin/DashCast$(EXE_SUFFIX) -endif -endif -endif -endif endif ifeq ($(CONFIG_DARWIN),yes) - ln -s $(BUILD_PATH)/bin/gcc/libgpac$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_MAJOR) - ln -sf $(DESTDIR)$(prefix)/$(libdir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_MAJOR) $(DESTDIR)$(prefix)/$(libdir)/libgpac$(DYN_LIB_SUFFIX) + ln -s $(BUILD_PATH)/bin/gcc/libgpac$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.$(VERSION_SONAME)$(DYN_LIB_SUFFIX) + ln -sf $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.$(VERSION_SONAME)$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.$(VERSION_MAJOR)$(DYN_LIB_SUFFIX) + ln -sf $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.$(VERSION_SONAME)$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac$(DYN_LIB_SUFFIX) else - ln -s $(BUILD_PATH)/bin/gcc/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) - ln -sf $(DESTDIR)$(prefix)/$(libdir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac.so.$(VERSION_MAJOR) - ln -sf $(DESTDIR)$(prefix)/$(libdir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac.so + ln -s $(BUILD_PATH)/bin/gcc/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) + ln -sf $(DESTDIR)$(prefix)/$(lib_dir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.so.$(VERSION_MAJOR) + ln -sf $(DESTDIR)$(prefix)/$(lib_dir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.so + + ln -s $(SRC_PATH)/share/ $(DESTDIR)$(prefix)/share/gpac + ln -sf $(DESTDIR)$(prefix)/share/gpac/res/gpac.png $(DESTDIR)/usr/share/pixmaps/gpac.png + ln -sf $(SRC_PATH)/share/gpac.desktop $(DESTDIR)/usr/share/applications/ + ifeq ($(DESTDIR)$(prefix),$(prefix)) ldconfig || true endif + endif uninstall: $(MAKE) -C applications uninstall - rm -rf $(DESTDIR)$(moddir) - rm -rf $(DESTDIR)$(prefix)/$(libdir)/libgpac* -ifeq ($(CONFIG_WIN32),yes) - rm -rf "$(DESTDIR)$(prefix)/bin/libgpac*" -endif - rm -rf $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/gpac.pc + $(MAKE) uninstall-lib + rm -rf $(DESTDIR)$(prefix)/$(lib_dir)/$(moddir) rm -rf $(DESTDIR)$(prefix)/bin/MP4Box rm -rf $(DESTDIR)$(prefix)/bin/MP4Client - rm -rf $(DESTDIR)$(prefix)/bin/MP42TS - rm -rf $(DESTDIR)$(prefix)/bin/DashCast - rm -rf $(DESTDIR)$(mandir)/man1/mp4box.1 - rm -rf $(DESTDIR)$(mandir)/man1/mp4client.1 - rm -rf $(DESTDIR)$(mandir)/man1/gpac.1 + rm -rf $(DESTDIR)$(prefix)/bin/gpac + rm -rf $(DESTDIR)$(prefix)/$(man_dir)/man1/mp4box.1 + rm -rf $(DESTDIR)$(prefix)/$(man_dir)/man1/mp4client.1 + rm -rf $(DESTDIR)$(prefix)/$(man_dir)/man1/gpac.1 + rm -rf $(DESTDIR)$(prefix)/$(man_dir)/man1/gpac-filters.1 rm -rf $(DESTDIR)$(prefix)/share/gpac - rm -rf $(DESTDIR)$(prefix)/include/gpac + rm -rf $(DESTDIR)$(prefix)/share/pixmaps/gpac.png + rm -rf $(DESTDIR)$(prefix)/share/applications/gpac.desktop + installdylib: ifneq ($(MP4BOX_STATIC),yes) + + $(INSTALL) -d "$(DESTDIR)$(prefix)/$(lib_dir)" + ifeq ($(CONFIG_WIN32),yes) - $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac.dll.a $(DESTDIR)$(prefix)/$(libdir) + $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac.dll.a $(DESTDIR)$(prefix)/$(lib_dir) $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac.dll $(DESTDIR)$(prefix)/bin else + ifeq ($(DEBUGBUILD),no) - $(STRIP) bin/gcc/libgpac$(DYN_LIB_SUFFIX) + $(STRIP) -S 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) + $(INSTALL) -m 755 bin/gcc/libgpac$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.$(VERSION_SONAME)$(DYN_LIB_SUFFIX) + ln -sf libgpac.$(VERSION_SONAME)$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.$(VERSION_MAJOR)$(DYN_LIB_SUFFIX) + ln -sf libgpac.$(VERSION_SONAME)$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac$(DYN_LIB_SUFFIX) else - $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) - ln -sf libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac.so.$(VERSION_MAJOR) - ln -sf libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(libdir)/libgpac.so + $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) + ln -sf libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.so.$(VERSION_MAJOR) + ln -sf libgpac$(DYN_LIB_SUFFIX).$(VERSION_SONAME) $(DESTDIR)$(prefix)/$(lib_dir)/libgpac.so ifeq ($(DESTDIR)$(prefix),$(prefix)) ldconfig || true endif endif + +endif + endif + + +uninstalldylib: + rm -rf $(DESTDIR)$(prefix)/$(lib_dir)/libgpac* +ifeq ($(CONFIG_WIN32),yes) + rm -rf "$(DESTDIR)$(prefix)/bin/libgpac*" endif install-lib: - mkdir -p "$(DESTDIR)$(prefix)/include/gpac" + $(INSTALL) -d "$(DESTDIR)$(prefix)/include/gpac" + $(INSTALL) -d "$(DESTDIR)$(prefix)/include/gpac/internal" + $(INSTALL) -d "$(DESTDIR)$(prefix)/include/gpac/modules" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/*.h "$(DESTDIR)$(prefix)/include/gpac" - mkdir -p "$(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) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/modules/*.h "$(DESTDIR)$(prefix)/include/gpac/modules" - $(INSTALL) $(INSTFLAGS) -m 644 config.h "$(DESTDIR)$(prefix)/include/gpac/configuration.h" -ifeq ($(GPAC_ENST), yes) - mkdir -p "$(DESTDIR)$(prefix)/include/gpac/enst" + + $(INSTALL) $(INSTFLAGS) -m 644 config.h "$(DESTDIR)$(prefix)/include/gpac/configuration.h" || true + +ifeq ($(GPAC_ENST),yes) + $(INSTALL) -d "$(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)/$(libdir)" - $(INSTALL) $(INSTFLAGS) -m 644 "./bin/gcc/libgpac_static.a" "$(DESTDIR)$(prefix)/$(libdir)" + + $(INSTALL) -d "$(DESTDIR)$(prefix)/$(lib_dir)" + $(INSTALL) $(INSTFLAGS) -m 644 "./bin/gcc/libgpac_static.a" "$(DESTDIR)$(prefix)/$(lib_dir)" || true + + $(INSTALL) -d $(DESTDIR)$(prefix)/$(lib_dir)/pkgconfig + $(INSTALL) $(INSTFLAGS) -m 644 gpac.pc "$(DESTDIR)$(prefix)/$(lib_dir)/pkgconfig" + $(MAKE) installdylib + uninstall-lib: - rm -rf "$(prefix)/include/gpac/internal" - rm -rf "$(prefix)/include/gpac/modules" - rm -rf "$(prefix)/include/gpac/enst" - rm -rf "$(prefix)/include/gpac" + rm -rf "$(DESTDIR)$(prefix)/include/gpac/internal" + rm -rf "$(DESTDIR)$(prefix)/include/gpac/modules" + rm -rf "$(DESTDIR)$(prefix)/include/gpac/enst" + rm -rf "$(DESTDIR)$(prefix)/include/gpac" + rm -f "$(DESTDIR)$(prefix)/$(lib_dir)/libgpac_static.a" + rm -f "$(DESTDIR)$(prefix)/$(lib_dir)/pkgconfig/gpac.pc" + $(MAKE) uninstalldylib ifeq ($(CONFIG_DARWIN),yes) dmg: - @if [ ! -z "$(shell git diff FETCH_HEAD)" ]; then \ - echo "Local revision and remote revision are not congruent; you may have local commit."; \ - echo "Please consider pushing your commit before generating an installer"; \ - exit 1; \ - fi +# @if [ ! -z "$(shell git diff FETCH_HEAD)" ]; then \ +# echo "Local revision and remote revision are not congruent; you may have local commit."; \ +# echo "Please consider pushing your commit before generating an installer"; \ +# exit 1; \ +# fi rm "bin/gcc/MP4Client" $(MAKE) -C applications/mp4client ./mkdmg.sh $(arch) @@ -275,14 +315,10 @@ endif ifeq ($(CONFIG_LINUX),yes) deb: - @if [ ! -z "$(shell git diff FETCH_HEAD)" ]; then \ - echo "Local revision and remote revision are not congruent; you may have local commit."; \ - echo "Please consider pushing your commit before generating an installer"; \ - exit 1; \ - fi git checkout -- debian/changelog fakeroot debian/rules clean - sed -i "s/-DEV/-DEV-rev$(VERSION)-$(BRANCH)/" debian/changelog + # add version to changelog for final filename + sed -i -r "s/^(\w+) \(([0-9\.]+)(-[A-Z]+)?\)/\1 (\2\3-rev$(VERSION)-$(BRANCH))/" debian/changelog fakeroot debian/rules configure fakeroot debian/rules binary rm -rf debian/ @@ -298,27 +334,29 @@ help: @echo "modules: builds modules only" @echo "instmoz: build and local install of osmozilla" @echo "sggen: builds scene graph generators" - @echo + @echo @echo "clean: clean src repository" @echo "distclean: clean src repository and host config file" - @echo + @echo @echo "install: install applications and modules on system" @echo "uninstall: uninstall applications and modules" ifeq ($(CONFIG_DARWIN),yes) @echo "dmg: creates DMG package file for OSX" endif ifeq ($(CONFIG_LINUX),yes) - @echo "deb: creates DEB package file for debian based systems" + @echo "deb: creates DEB package file for debian based systems" endif - @echo + @echo @echo "install-lib: install gpac library (dyn and static) and headers , and " @echo "uninstall-lib: uninstall gpac library (dyn and static) and headers" @echo - @echo "tests: run all tests. For more info, check gpac/regression_tests/test_suite_make.sh -h" + @echo "test_suite: run all tests. For more info, check https://github.com/gpac/testsuite" + @echo + @echo "doc: build libgpac documentation in gpac/doc" + @echo "man: build gpac man files in gpac/doc/man (must have latest build binaries installed)" @echo @echo "lcov: generate lcov files" @echo "lcov_clean: clean all lcov/gcov files" - @echo - @echo "docs: build libgpac documentation in gpac/doc" + -include .depend diff --git a/README.md b/README.md index 3ced437..b9c4a4a 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,134 @@ -[![Build Status](https://travis-ci.org/gpac/gpac.svg?branch=master)](https://travis-ci.org/gpac/gpac) -[![codecov.io](https://codecov.io/github/gpac/gpac/coverage.svg?branch=master)](https://codecov.io/github/gpac/gpac?branch=master) +[![Build Status](https://tests.gpac.io/testres/badge/build/ubuntu64)](https://buildbot.gpac.io/#/grid?branch=master) +[![Tests](https://tests.gpac.io/testres/badge/tests/linux64)](https://tests.gpac.io/) -README for GPAC version 0.7.1 +[![Build Status](https://tests.gpac.io/testres/badge/build/ubuntu32)](https://buildbot.gpac.io/#/grid?branch=master) +[![Tests](https://tests.gpac.io/testres/badge/tests/linux32)](https://tests.gpac.io/) -GPAC is a multimedia framework oriented towards rich media and distributed under the LGPL license (see COPYING). -GPAC supports many multimedia formats, from simple audiovisual containers (avi, mov, mpg) to complex -presentation formats (MPEG-4 Systems, SVG Tiny 1.2, VRML/X3D). GPAC supports scripting of presentation for MPEG4/VRML/X3D through -mozilla SpiderMonkey javascript engine. -GPAC currently supports local playback, http progressive download, Adaptive HTTP Streaming (MPEG-DASH, HLS), RTP/RTSP streaming over UDP (unicast or multicast) or TCP and TS demuxing (from file, IP or DVB4Linux). -GPAC also features MP4Box, a multimedia swiss-army knife for the prompt. +[![Build Status](https://tests.gpac.io/testres/badge/build/windows64)](https://buildbot.gpac.io/#/grid?branch=master) +[![Tests](https://tests.gpac.io/testres/badge/tests/win64)](https://tests.gpac.io/) -For compilation and installation instruction, check INSTALLME file +[![Build Status](https://tests.gpac.io/testres/badge/build/windows32)](https://buildbot.gpac.io/#/grid?branch=master) +[![Tests](https://tests.gpac.io/testres/badge/tests/win32)](https://tests.gpac.io/) -For GPAC configuration instruction, check gpac/doc/configuration.html or gpac/doc/man/gpac.1 (man gpac when installed) +[![Build Status](https://tests.gpac.io/testres/badge/build/macos)](https://buildbot.gpac.io/#/grid?branch=master) +[![Tests](https://tests.gpac.io/testres/badge/tests/macos)](https://tests.gpac.io/) -For more information, visit the GPAC website: - http://gpac.io +[![Build Status](https://tests.gpac.io/testres/badge/build/ios)](https://buildbot.gpac.io/#/grid?branch=master) +[![Build Status](https://tests.gpac.io/testres/badge/build/android)](https://buildbot.gpac.io/#/grid?branch=master) - - +[![Coverage](https://tests.gpac.io/testres/badge/cov/linux64?branch=master)](https://tests.gpac.io/testres/) +[![Coverage](https://tests.gpac.io/testres/badge/covfn/linux64?branch=master)](https://tests.gpac.io/testres/) + +![License](https://img.shields.io/badge/license-LGPL-blue.svg) +[![OpenHub](https://www.openhub.net/p/gpac/widgets/project_thin_badge.gif)](https://www.openhub.net/p/gpac) + + +# GPAC Introduction +Current version: 1.0.1 + +GPAC is an open-source multimedia framework focused on modularity and standards compliance. +GPAC provides tools to process, inspect, package, stream playback and interact with media content. Such content can be any combination of audio, video, subtitles, metadata, scalable graphics, encrypted media, 2D/3D graphics and ECMAScript. +GPAC is best-known for its wide MP4 capabilities and is popular among video enthusiasts, academic researchers, standardization bodies, and professional broadcasters. + +For more information, visit [GPAC website](http://gpac.io) + +GPAC is distributed under the LGPL v2.1 or later, and is also available, for most of it, under a [commercial license](https://www.gpac-licensing.com). + +Please cite our work in your research: +- GPAC Filters: https://doi.org/10.1145/3339825.3394929 +- GPAC: https://doi.org/10.1145/1291233.1291452 + +# Features + +GPAC can process, analyse, package, stream, encode, decode and playback a wide variety of contents. Selected feature list: +- Audio: MPEG audio (mp1/2/3, aac), AC3, E-AC3, Opus, FLAC, … +- Video: MPEG 1 / 2 / 4 (H264/AVC) / H (HEVC), AV1, VP9, Theora, ... +- Subtitles: WebVTT, TTML (full, EBU-TTD, …), 3GPP/Apple Timed Text, … +- Encryption: CENC, PIFF, ISMA, OMA, ... +- Containers: MP4/fMP4/CMAF/Quicktime MOV/ProRes MOV, AVI, MPG, OGG, MKV, ... +- Streaming: MPEG-2 Transport Stream, RTP, RTSP, HTTP, Apple HLS, MPEG-DASH, ATSC 3.0 ROUTE, ... +- Supported IOs: local files, pipes, UDP/TCP, HTTP(S), custom IO +- Presentation formats: MPEG-4 BIFS, SVG Tiny 1.2, VRML/X3D +- JS scripting through QuickJS for both SVG/BIFS/VRML and extending GPAC framework tools +- 3D support (360 videos, WebGL JS filters…) +- Inputs: microphone, camera, desktop grabbing +- Highly configurable media processing pipeline + +Features are encapsulated in processing modules called filters: +- to get the full list of available features, you can run the command line `gpac -h filters` or check [filters' wiki](https://github.com/gpac/gpac/wiki/Filters). +- to get the full list of playback features, check [our wiki](https://github.com/gpac/gpac/wiki/Player-Features). + + +# Tools + +## MP4Box +MP4Box is a multi-purpose MP4 file manipulation for the prompt, featuring media importing and extracting, file inspection, DASH segmentation, RTP hinting, ... See `MP4Box -h`, `man MP4Box` or [our wiki](https://wiki.gpac.io/MP4Box-Introduction). + + +## gpac +As of version 0.9.0, GPAC includes a filter engine in charge of stream management and used by most applications in GPAC - [read this post](https://wiki.gpac.io/Rearchitecture) for more dicussion on how this impacts MP4Box and MP4Client. +The gpac application is a direct interface to the filter engine of GPAC, allowing any combinaison of filters not enabled by other applications. See `gpac -h`, `man gpac`, `man gpac-filters` or [our wiki](https://wiki.gpac.io/Filters) for more details. + +## MP4Client +MP4Client is a media player built upon libgpac, featuring a rich media interactive composition engine with MPEG-4 BIFS, SVG, VRML/X3D support. +For GPAC configuration instruction, check `MP4Client -h` , `man MP4Client` or [our wiki](https://wiki.gpac.io/mp4client). + + + +# Getting started +## Download +Stable and nightly builds installers for Windows, Linux, OSX, Android, iOS are available on [gpac.io](https://gpac.wp.imt.fr/downloads/). + +If you want to compile GPAC yourself, please follow the instructions in the [build section](https://wiki.gpac.io/Build-Introduction) of our wiki. + +## Documentation +The general GPAC framework documentation is available on [wiki.gpac.io](https://wiki.gpac.io), including [HowTos](https://github.com/gpac/gpac/wiki/Howtos). + +GPAC tools are mostly wrappers around an underlying library called libgpac which can easily be embedded in your projects. The libgpac developer documentation is available at [doxygen.gpac.io](https://doxygen.gpac.io), including documentation of [JS APIs](https://doxygen.gpac.io/group__jsapi__grp.html). + + +## Testing +GPAC has a test suite exercicing most features of the framework. The test suite is in a separate repository [https://github.com/gpac/testsuite/](https://github.com/gpac/testsuite/), but is available as a submodule of the GPAC main repository. To initialize the testsuite submodule, do `git submodule update --init`. + +For more details on the test suite, read [this page](https://github.com/gpac/gpac/wiki/GPAC_tests) and check the [testsuite readme](https://github.com/gpac/testsuite). + +Per-commit [build](https://buildbot.gpac.io/) and [tests results](https://tests.gpac.io) are available. + + +## Support +Please use [github](https://github.com/gpac/gpac/issues) for feature requests and bug reports. When filing a request there, please tag it as _feature-request_. + +## Contributing +A complex project like GPAC wouldn’t exist and persist without the support of its community. Please contribute: a nice message, supporting us in our communication, reporting issues when you see them… any gesture, even the smallest ones, counts. + +If you use GPAC in your published research, ! _please cite_ ! using +- [this paper](https://dl.acm.org/doi/abs/10.1145/3339825.3394929) for recent versions (0.9 or above) +- [this paper](https://dl.acm.org/doi/abs/10.1145/1291233.1291452) for legacy versions (0.8 or below). + +If you want to contribute to GPAC, you can find ideas at [GSoC page](https://gpac.wp.imt.fr/jobs/google-summer-of-code-ideas/) or look for ‘good first issue’ on [github](https://github.com/gpac/gpac/issues). In any doubt please feel free to [contact us](mailto:contact@gpac.io). + +# Team +GPAC is brought to you by an experienced team of developers with a wide track-record on media processing. + +The project is mainly developed at [Telecom Paris](https://www.telecom-paris.fr/), in the [MultiMedia group](http://www.tsi.telecom-paristech.fr/mm/), with the help of many [great contributors](https://github.com/gpac/gpac/graphs/contributors) + +GPAC has a peculiar story: started as a startup in NYC, GPAC gained traction from research and a nascent multimedia community as it was open-sourced in 2003. Since then we have never stopped transforming GPAC into a useful and up-to-date project, with many industrial R&D collaborations and a community of tens of thousands of users. This makes GPAC one of the few open-source multimedia projects that gathers so much diversity. + + +# Roadmap +Users are encouraged to use the latest tag or the master branch. + +The previous v0.8.X release (the last one using the legacy architecture) is LTS until 30/06/2021. Important bug fixes will be backported but new features won’t. API compatibility between both versions should make the migration easy. If not please [file a bug](https://github.com/gpac/gpac/issues). + +## Ongoing tasks and bugs +Please use [github](https://github.com/gpac/gpac/issues) for feature requests and bug reports. When filing a request there, please tag it as feature-request. + +## V1.1.0 +Targets: +- [ ] add kvazaar/other encoders support? +- [ ] improve remotery support +- [ ] more JS filters +- [ ] filters scriptable through other languages (python) ? +- [ ] move input sensors to filter ? +- [ ] fixed features disabled during rearchitecture or drop them (FILTER_FIXME macro) +- [ ] move Android client to filters diff --git a/TODO b/TODO deleted file mode 100644 index c68a2f9..0000000 --- a/TODO +++ /dev/null @@ -1,3 +0,0 @@ -cf https://github.com/gpac/gpac/issues for ongoing tasks and bugs. - -When filing a request there, please tag it as feature-request. diff --git a/applications/Makefile b/applications/Makefile index e60a811..935e231 100644 --- a/applications/Makefile +++ b/applications/Makefile @@ -1,31 +1,17 @@ include ../config.mak -APPDIRS= +APPDIRS=gpac ifeq ($(MP4BOX_STATIC),yes) APPDIRS+=mp4box else -ifeq ($(DISABLE_PLAYER), no) +ifeq ($(DISABLE_PLAYER),no) APPDIRS+=mp4client endif -ifeq ($(DISABLE_ISOFF), no) +ifeq ($(DISABLE_ISOFF),no) APPDIRS+=mp4box -ifeq ($(DISABLE_M2TS_MUX), no) -APPDIRS+=mp42ts -endif - -ifneq ($(CONFIG_WIN32), yes) -ifneq ($(CONFIG_FFMPEG), no) -ifneq ($(DISABLE_CORE_TOOLS), yes) -ifneq ($(DISABLE_AV_PARSERS), yes) -APPDIRS+=dashcast -endif -endif -endif -endif - endif @@ -38,7 +24,7 @@ else endif #disable due to version incompatibilities -ifeq ($(USE_WXWIDGETS), yes) +ifeq ($(USE_WXWIDGETS),yes) #APPDIRS+=osmo4_wx #V4STUDIODIR=V4Studio #INSTDIRS+=osmo4_wx diff --git a/applications/dashcast/Makefile b/applications/dashcast/Makefile deleted file mode 100644 index dc963d9..0000000 --- a/applications/dashcast/Makefile +++ /dev/null @@ -1,86 +0,0 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/applications/dashcast - -CFLAGS= $(OPTFLAGS) -D_GNU_SOURCE -I"$(SRC_PATH)/include" -I../../ $(ffmpeg_cflags) - -LINKFLAGS=$(GPAC_SH_FLAGS) - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -ifeq ($(GPACREADONLY), yes) -CFLAGS+=-DGPAC_READ_ONLY -endif - -ifneq ($(CONFIG_LIBAV),no) -CFLAGS+=-DGPAC_USE_LIBAV -endif - -ifeq ($(CONFIG_WIN32),yes) -EXE=.exe -PROG=DashCast$(EXE) -else -EXT= -PROG=DashCast -endif - - -ifeq ($(STATICBUILD),yes) -##include static modules and other deps for libgpac -include ../../static.mak -LINKFLAGS+=-lgpac_static -LINKFLAGS+= $(GPAC_SH_FLAGS) -LINKFLAGS+=$(EXTRALIBS) -else -LINKFLAGS+=-lgpac -endif - -#common obj -OBJS= dashcast.o audio_data.o audio_decoder.o audio_encoder.o audio_muxer.o circular_buffer.o cmd_data.o controler.o message_queue.o register.o video_data.o video_decoder.o video_encoder.o video_muxer.o video_scaler.o task.o - -LINKFLAGS+= $(ffmpeg_lflags_dashcast) - -ifneq ($(CONFIG_LIBAVRESAMPLE),no) -CFLAGS+=-DDC_AUDIO_RESAMPLER -LINKFLAGS+=-lavresample -endif - -ifeq ($(CONFIG_DARWIN), yes) -#fixme - use proper detection of libavdevice dependencies -#LINKFLAGS+=-lavfilter -lswresample -lbz2 -endif - -SRCS := $(OBJS:.o=.c) - -all: $(PROG) - -DashCast$(EXE): $(OBJS) - $(CC) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc $(LDFLAGS) $(LINKFLAGS) - -clean: - rm -f $(OBJS) ../../bin/gcc/$(PROG) - -install: clean - install -m 755 $(INSTFLAGS) ../../bin/gcc/DashCast "$(DESTDIR)$(prefix)/bin" - -uninstall: - rm -rf $(DESTDIR)$(prefix)/bin/DashCast - -dep: depend - -depend: - rm -f .depend - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -distclean: clean - rm -f Makefile.bak .depend - --include .depend diff --git a/applications/dashcast/audio_data.h b/applications/dashcast/audio_data.h deleted file mode 100644 index 3f60bbb..0000000 --- a/applications/dashcast/audio_data.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 AUDIO_DATA_H_ -#define AUDIO_DATA_H_ - -#define AUDIO_CB_SIZE 3 - -#define LIVE_FRAME_SIZE 1024 -#define MAX_AUDIO_PACKET_SIZE (128 * 1024) - - -#include "../../modules/ffmpeg_in/ffmpeg_in.h" -#include "libavcodec/avcodec.h" -#include "libavutil/mem.h" -#include "libav_compat.h" -#include "circular_buffer.h" - -#include - -//we force the number of channels between the decoder and the encoder: interleaved 16 bits stereo 44100Hz -#define DC_AUDIO_SAMPLE_RATE 44100 -#define DC_AUDIO_NUM_CHANNELS 2 -#define DC_AUDIO_CHANNEL_LAYOUT AV_CH_LAYOUT_STEREO -#define DC_AUDIO_SAMPLE_FORMAT AV_SAMPLE_FMT_S16 - -#define DC_AUDIO_MAX_CHUNCK_SIZE 192000 - - -/* - * AudioInputData is designed to keep the data of input audio in a circular buffer. - * The circular buffer has its own mechanism for synchronization. - */ -typedef struct { - /* The circular buffer of input audio. Input audio is the audio frames after decoding. */ - CircularBuffer circular_buf; - - /* The user of circular buffer has an index to it, which is in this variable. */ - Producer producer; - - AVFrame *aframe; - - int64_t next_pts; - - int channels; - int samplerate; -} AudioInputData; - -/* - * This structure corresponds to an entry of audio configuration in the configuration file - */ -typedef struct { - /* audio file name */ - char filename[GF_MAX_PATH]; - /* audio format */ - char format[GF_MAX_PATH]; - /* audio bitrate */ - int bitrate; - /* audio samplerate */ - int samplerate; - /* audio channel number */ - int channels; - /* audio codec */ - char codec[GF_MAX_PATH]; - /* custom parameter to be passed directly to the encoder - free it once you're done */ - char custom[GF_MAX_PATH]; - - /* used for source switching */ - char source_id[GF_MAX_PATH]; - time_t start_time; - time_t end_time; - - /* RFC6381 codec name, only valid when VIDEO_MUXER == GPAC_INIT_VIDEO_MUXER_AVC1 */ - char codec6381[GF_MAX_PATH]; -} AudioDataConf; - -/* - * Each node in a circular buffer is a pointer. - * To use the circular buffer for audio frame we must - * define the node. AudioDataNode simply contains - * an AVFrame. - */ -typedef struct { - uint8_t *abuf; - int abuf_size; - uint64_t channel_layout; - int sample_rate; - int format; - int channels; -} AudioDataNode; - -void dc_audio_data_set_default(AudioDataConf *audio_data_conf); - -/* - * Initialize an AudioInputData. - * - * @param audio_input_data [out] is the structure to be initialize. - * @param num_consumers [in] contains information on the number of users of circular buffer; - * which means the number of audio encoders. - * @param live [in] indicates the system is live - * - * @return 0 on success, -1 on failure. - * - * @note Must use dc_audio_data_destroy to free memory. - */ -int dc_audio_input_data_init(AudioInputData *audio_input_data, int channels, int samplerate, int num_consumers, int mode); - -/* - * Destroy an AudioInputData - * - * @param audio_input_data [in] the structure to be destroyed. - */ -void dc_audio_input_data_destroy(AudioInputData *audio_input_data); - -/* - * Signal to all the users of the circular buffer in the AudioInputData - * which the current node is the last node to consume. - * - * @param audio_input_data [in] the structure to be signaled on. - */ -void dc_audio_inout_data_end_signal(AudioInputData *audio_input_data); - -#endif /* AUDIO_DATA_H_ */ diff --git a/applications/dashcast/audio_decoder.c b/applications/dashcast/audio_decoder.c deleted file mode 100644 index e2d7045..0000000 --- a/applications/dashcast/audio_decoder.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 "audio_decoder.h" - -int dc_audio_decoder_open(AudioInputFile *audio_input_file, AudioDataConf *audio_data_conf, int mode, int no_loop, int video_framerate) -{ - u32 i; - AVCodecContext *codec_ctx; - AVCodec *codec; - AVInputFormat *in_fmt = NULL; - - if (!audio_data_conf) return -1; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio Decoder enter setup at UTC "LLU"\n", gf_net_get_utc() )); - - if (strcmp(audio_data_conf->format,"") != 0) { - in_fmt = av_find_input_format(audio_data_conf->format); - if (in_fmt == NULL) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find the format %s.\n", audio_data_conf->format)); - return -1; - } - } - - /* - * Open audio (may already be opened when shared with the video input). - */ - if (!audio_input_file->av_fmt_ctx) { - s32 ret; - AVDictionary *options = NULL; - //we may need to set the framerate when the default one used by ffmpeg is not supported - if (video_framerate > 0) { - char vfr[16]; - snprintf(vfr, sizeof(vfr), "%d", video_framerate); - ret = av_dict_set(&options, "framerate", vfr, 0); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set video framerate %s.\n", vfr)); - return -1; - } - } - - ret = avformat_open_input(&audio_input_file->av_fmt_ctx, audio_data_conf->filename, in_fmt, options ? &options : NULL); - - if (ret != 0) { - if (options) { - av_dict_free(&options); - options = NULL; - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error %d opening input - retrying without options\n", ret)); - ret = avformat_open_input(&audio_input_file->av_fmt_ctx, audio_data_conf->filename, in_fmt, NULL); - } - - if (ret != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open file: %s\n", audio_data_conf->filename)); - return -1; - } - } - - if (options) av_dict_free(&options); - - /* - * Retrieve stream information - */ - if (avformat_find_stream_info(audio_input_file->av_fmt_ctx, NULL) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find stream information\n")); - return -1; - } - - av_dump_format(audio_input_file->av_fmt_ctx, 0, audio_data_conf->filename, 0); - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio capture open at UTC "LLU"\n", gf_net_get_utc() )); - - /* - * Find the first audio stream - */ - audio_input_file->astream_idx = -1; - for (i=0; iav_fmt_ctx->nb_streams; i++) { - if (audio_input_file->av_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - audio_input_file->astream_idx = i; - break; - } - } - if (audio_input_file->astream_idx == -1) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find a audio stream\n")); - return -1; - } - - /* - * Get a pointer to the codec context for the audio stream - */ - codec_ctx = audio_input_file->av_fmt_ctx->streams[audio_input_file->astream_idx]->codec; - - /* - * Find the decoder for the audio stream - */ - codec = avcodec_find_decoder(codec_ctx->codec_id); - if (codec == NULL) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Input audio codec is not supported.\n")); - avformat_close_input(&audio_input_file->av_fmt_ctx); - return -1; - } - - /* - * Open codec - */ - if (avcodec_open2(codec_ctx, codec, NULL) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input audio codec.\n")); - avformat_close_input(&audio_input_file->av_fmt_ctx); - return -1; - } - -#ifdef DC_AUDIO_RESAMPLER - audio_input_file->aresampler = NULL; -#endif - audio_input_file->fifo = av_fifo_alloc(2 * MAX_AUDIO_PACKET_SIZE); - - audio_data_conf->channels = codec_ctx->channels; - audio_data_conf->samplerate = codec_ctx->sample_rate; - - audio_input_file->mode = mode; - audio_input_file->no_loop = no_loop; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio Decoder open at UTC "LLU"\n", gf_net_get_utc() )); - - return 0; -} - -#ifdef DC_AUDIO_RESAMPLER -static int ensure_resampler(AudioInputFile *audio_input_file, int sample_rate, int num_channels, u64 channel_layout, enum AVSampleFormat sample_format) -{ - if (!audio_input_file->aresampler) { - audio_input_file->aresampler = avresample_alloc_context(); - if (!audio_input_file->aresampler) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate the audio resampler. Aborting.\n")); - return -1; - } - av_opt_set_int(audio_input_file->aresampler, "in_channel_layout", channel_layout, 0); - av_opt_set_int(audio_input_file->aresampler, "out_channel_layout", DC_AUDIO_CHANNEL_LAYOUT, 0); - av_opt_set_int(audio_input_file->aresampler, "in_sample_fmt", sample_format, 0); - av_opt_set_int(audio_input_file->aresampler, "out_sample_fmt", DC_AUDIO_SAMPLE_FORMAT, 0); - av_opt_set_int(audio_input_file->aresampler, "in_sample_rate", sample_rate, 0); - av_opt_set_int(audio_input_file->aresampler, "out_sample_rate", DC_AUDIO_SAMPLE_RATE, 0); - av_opt_set_int(audio_input_file->aresampler, "in_channels", num_channels, 0); - av_opt_set_int(audio_input_file->aresampler, "out_channels", DC_AUDIO_NUM_CHANNELS, 0); - - if (avresample_open(audio_input_file->aresampler)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not open the audio resampler. Aborting.\n")); - return -1; - } - } - - return 0; -} - -//resample - see http://ffmpeg.org/pipermail/libav-user/2012-June/002164.html -static int resample_audio(AudioInputFile *audio_input_file, AudioInputData *audio_input_data, AVCodecContext *audio_codec_ctx, uint8_t ***output, int *num_planes_out, int num_channels, enum AVSampleFormat sample_format) -{ - int i; - *num_planes_out = av_sample_fmt_is_planar(DC_AUDIO_SAMPLE_FORMAT) ? DC_AUDIO_NUM_CHANNELS : 1; - *output = (uint8_t**)av_malloc(*num_planes_out*sizeof(uint8_t*)); - for (i=0; i<*num_planes_out; i++) { - (*output) [i] = (uint8_t*)av_malloc(DC_AUDIO_MAX_CHUNCK_SIZE); //FIXME: fix using size below av_samples_get_buffer_size() - } - - i = avresample_convert(audio_input_file->aresampler, *output, DC_AUDIO_MAX_CHUNCK_SIZE, audio_input_data->aframe->nb_samples, audio_input_data->aframe->extended_data, audio_input_data->aframe->linesize[0], audio_input_data->aframe->nb_samples); - if (i < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not resample audio frame. Aborting.\n")); - return -1; - } - - return i; -} -#endif - -int dc_audio_decoder_read(AudioInputFile *audio_input_file, AudioInputData *audio_input_data) -{ - int ret; - AVPacket packet; - int got_frame = 0; - AVCodecContext *codec_ctx; - AudioDataNode *audio_data_node; - - /* Get a pointer to the codec context for the audio stream */ - codec_ctx = audio_input_file->av_fmt_ctx->streams[audio_input_file->astream_idx]->codec; - - /* Read frames */ - while (1) { - if (audio_input_file->av_pkt_list) { - if (gf_list_count(audio_input_file->av_pkt_list)) { - AVPacket *packet_copy; - assert(audio_input_file->av_pkt_list); - gf_mx_p(audio_input_file->av_pkt_list_mutex); - packet_copy = (AVPacket*)gf_list_pop_front(audio_input_file->av_pkt_list); - gf_mx_v(audio_input_file->av_pkt_list_mutex); - - if (packet_copy == NULL) { - ret = AVERROR_EOF; - } else { - memcpy(&packet, packet_copy, sizeof(AVPacket)); - gf_free(packet_copy); - ret = 0; - } - } else { - gf_sleep(1); - continue; - } - } else { - ret = av_read_frame(audio_input_file->av_fmt_ctx, &packet); - } - if (ret == AVERROR_EOF) { - if (audio_input_file->mode == LIVE_MEDIA && audio_input_file->no_loop == 0) { - av_seek_frame(audio_input_file->av_fmt_ctx, audio_input_file->astream_idx, 0, 0); - continue; - } - - /* Flush decoder */ - packet.data = NULL; - packet.size = 0; - -#ifndef FF_API_AVFRAME_LAVC - avcodec_get_frame_defaults(audio_input_data->aframe); -#else - av_frame_unref(audio_input_data->aframe); -#endif - - avcodec_decode_audio4(codec_ctx, audio_input_data->aframe, &got_frame, &packet); - - if (got_frame) { - dc_producer_lock(&audio_input_data->producer, &audio_input_data->circular_buf); - dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); - audio_data_node = (AudioDataNode*)dc_producer_produce(&audio_input_data->producer, &audio_input_data->circular_buf); - - audio_data_node->abuf_size = audio_input_data->aframe->linesize[0]; - memcpy(audio_data_node->abuf, audio_input_data->aframe->data[0], audio_data_node->abuf_size); - - dc_producer_advance(&audio_input_data->producer, &audio_input_data->circular_buf); - return 0; - } - - dc_producer_end_signal(&audio_input_data->producer, &audio_input_data->circular_buf); - dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); - - return -2; - } - else if (ret < 0) - { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot read audio frame.\n")); - continue; - } - - /* Is this a packet from the audio stream? */ - if (packet.stream_index == audio_input_file->astream_idx) { - /* Set audio frame to default */ - -#ifndef FF_API_AVFRAME_LAVC - avcodec_get_frame_defaults(audio_input_data->aframe); -#else - av_frame_unref(audio_input_data->aframe); -#endif - - /* Decode audio frame */ - if (avcodec_decode_audio4(codec_ctx, audio_input_data->aframe, &got_frame, &packet) < 0) { - av_free_packet(&packet); - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while decoding audio.\n")); - dc_producer_end_signal(&audio_input_data->producer, &audio_input_data->circular_buf); - dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); - return -1; - } - - if (audio_input_data->aframe->pts != AV_NOPTS_VALUE) - audio_input_data->next_pts = audio_input_data->aframe->pts; - - audio_input_data->next_pts += ((int64_t)AV_TIME_BASE * audio_input_data->aframe->nb_samples) / codec_ctx->sample_rate; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Decode audio frame pts %d at UTC "LLU"\n", audio_input_data->next_pts, gf_net_get_utc() )); - - /* Did we get an audio frame? */ - if (got_frame) { - uint8_t **data; - int data_size; - enum AVSampleFormat sample_format; - Bool resample; -#ifdef DC_AUDIO_RESAMPLER - int num_planes_out=0; -#endif -#ifdef GPAC_USE_LIBAV - int sample_rate = codec_ctx->sample_rate; - int num_channels = codec_ctx->channels; - u64 channel_layout = codec_ctx->channel_layout; -#else - int sample_rate = audio_input_data->aframe->sample_rate; - int num_channels = audio_input_data->aframe->channels; - u64 channel_layout; - if (!audio_input_data->aframe->channel_layout) { - if (audio_input_data->aframe->channels == 2) { - audio_input_data->aframe->channel_layout = AV_CH_LAYOUT_STEREO; - } else if (audio_input_data->aframe->channels == 1) { - audio_input_data->aframe->channel_layout = AV_CH_LAYOUT_MONO; - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Unknown input channel layout for %d channels. Aborting.\n", audio_input_data->aframe->channels)); - exit(1); - } - } - channel_layout = audio_input_data->aframe->channel_layout; -#endif - sample_format = (enum AVSampleFormat)audio_input_data->aframe->format; - resample = (sample_rate != DC_AUDIO_SAMPLE_RATE - || num_channels != DC_AUDIO_NUM_CHANNELS - || channel_layout != DC_AUDIO_CHANNEL_LAYOUT - || sample_format != DC_AUDIO_SAMPLE_FORMAT); - - /* Resample if needed */ - if (resample) { -#ifndef DC_AUDIO_RESAMPLER - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Audio resampling is needed at the decoding stage, but not supported by your version of DashCast. Aborting.\n")); - exit(1); -#else - uint8_t **output; - int nb_samp; - if (ensure_resampler(audio_input_file, sample_rate, num_channels, channel_layout, sample_format)) { - return -1; - } - - nb_samp = resample_audio(audio_input_file, audio_input_data, codec_ctx, &output, &num_planes_out, num_channels, sample_format); - if (nb_samp<0) { - return -1; - } - - av_samples_get_buffer_size(&data_size, DC_AUDIO_NUM_CHANNELS, nb_samp, DC_AUDIO_SAMPLE_FORMAT, 0); - data = output; -#endif - } else { - /*no resampling needed: read data from the AVFrame*/ - data = audio_input_data->aframe->extended_data; - data_size = audio_input_data->aframe->linesize[0]; - } - - assert(!av_sample_fmt_is_planar(DC_AUDIO_SAMPLE_FORMAT)); - av_fifo_generic_write(audio_input_file->fifo, data[0], data_size, NULL); - - if (/*audio_input_file->circular_buf.mode == OFFLINE*/audio_input_file->mode == ON_DEMAND || audio_input_file->mode == LIVE_MEDIA) { - dc_producer_lock(&audio_input_data->producer, &audio_input_data->circular_buf); - - /* Unlock the previous node in the circular buffer. */ - dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); - - /* Get the pointer of the current node in circular buffer. */ - audio_data_node = (AudioDataNode *) dc_producer_produce(&audio_input_data->producer, &audio_input_data->circular_buf); - audio_data_node->channels = DC_AUDIO_NUM_CHANNELS; - audio_data_node->channel_layout = DC_AUDIO_CHANNEL_LAYOUT; - audio_data_node->sample_rate = DC_AUDIO_SAMPLE_RATE; - audio_data_node->format = DC_AUDIO_SAMPLE_FORMAT; - audio_data_node->abuf_size = data_size; - av_fifo_generic_read(audio_input_file->fifo, audio_data_node->abuf, audio_data_node->abuf_size, NULL); - - dc_producer_advance(&audio_input_data->producer, &audio_input_data->circular_buf); - } else { - while (av_fifo_size(audio_input_file->fifo) >= LIVE_FRAME_SIZE) { - /* Lock the current node in the circular buffer. */ - if (dc_producer_lock(&audio_input_data->producer, &audio_input_data->circular_buf) < 0) { - continue; - } - - /* Unlock the previous node in the circular buffer. */ - dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); - - /* Get the pointer of the current node in circular buffer. */ - audio_data_node = (AudioDataNode *) dc_producer_produce(&audio_input_data->producer, &audio_input_data->circular_buf); - - audio_data_node->abuf_size = LIVE_FRAME_SIZE; - av_fifo_generic_read(audio_input_file->fifo, audio_data_node->abuf, audio_data_node->abuf_size, NULL); - - dc_producer_advance(&audio_input_data->producer, &audio_input_data->circular_buf); - } - } - -#ifdef DC_AUDIO_RESAMPLER - if (resample) { - int i; - for (i=0; iav_fmt_ctx); - - if (audio_input_file->av_pkt_list_mutex) { - gf_mx_p(audio_input_file->av_pkt_list_mutex); - while (gf_list_count(audio_input_file->av_pkt_list)) { - AVPacket *pkt = (AVPacket*)gf_list_last(audio_input_file->av_pkt_list); - av_free_packet(pkt); - gf_list_rem_last(audio_input_file->av_pkt_list); - } - gf_list_del(audio_input_file->av_pkt_list); - gf_mx_v(audio_input_file->av_pkt_list_mutex); - gf_mx_del(audio_input_file->av_pkt_list_mutex); - } - - av_fifo_free(audio_input_file->fifo); - -#ifdef DC_AUDIO_RESAMPLER - avresample_free(&audio_input_file->aresampler); -#endif -} diff --git a/applications/dashcast/audio_decoder.h b/applications/dashcast/audio_decoder.h deleted file mode 100644 index 9f155f0..0000000 --- a/applications/dashcast/audio_decoder.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 AUDIO_DECODER_H_ -#define AUDIO_DECODER_H_ - -#include "audio_data.h" - -#include "libavformat/avformat.h" -#include "libavutil/fifo.h" -#ifdef DC_AUDIO_RESAMPLER -#include "libavutil/opt.h" -#include "libavresample/avresample.h" -#endif - - -/* - * The structure which keeps the data of - * input audio file. - */ -typedef struct { - /* Format context structure provided by avlib to open and read from a media file. */ - AVFormatContext *av_fmt_ctx; - - /* A list of AVPackets and return value to be processed: when this parameter is non-null, - * the video thread makes the demux and pushes the packets. */ - GF_List *av_pkt_list; - GF_Mutex *av_pkt_list_mutex; - - /* The index of the audio stream in the file. */ - int astream_idx; - - /* This is the output FIFO linking the decoder to the other encoder: only conveys - * stereo 44100 (and resample if needed) */ - AVFifoBuffer *fifo; -#ifdef DC_AUDIO_RESAMPLER - /* Optional audio resampling between the decoder and the encoder */ - AVAudioResampleContext *aresampler; -#endif - - LockMode mode; - int no_loop; -} AudioInputFile; - -/* - * Open the input audio - * - * @param cmd_data [in] contains information about the file name - * and the audio format. - * - * @param audio_input_file [out] pointer to the structure which we want to - * open the file - * - * @return 0 on success -1 on failure. - */ -int dc_audio_decoder_open(AudioInputFile *audio_input_file, AudioDataConf *audio_data_conf, int mode, int no_loop, int video_framerate); - -/* - * Read and decode audio and put samples on circular buffer - * - * @param audio_input_file [in] contains info on input audio. This parameter - * must have been opened with open_audio_input - * - * @param audio_input_data [out] the samples will be saved on the circular buffer - * of this parameter. - * - * @return 0 on success, -1 on failure, -2 on EOF (end of the file) - */ -int dc_audio_decoder_read(AudioInputFile *audio_input_file, AudioInputData *audio_input_data); - -/* - * Close the input audio - * - * @param audio_input_file [in] the audio file to be closed - */ -void dc_audio_decoder_close(AudioInputFile *audio_input_file); - -#endif /* AUDIO_DECODER_H_ */ diff --git a/applications/dashcast/audio_encoder.c b/applications/dashcast/audio_encoder.c deleted file mode 100644 index 8d69c40..0000000 --- a/applications/dashcast/audio_encoder.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 "audio_encoder.h" - - -extern void build_dict(void *priv_data, const char *options); - - -int dc_audio_encoder_open(AudioOutputFile *audio_output_file, AudioDataConf *audio_data_conf) -{ - AVDictionary *opts = NULL; - - audio_output_file->audio_data_conf = audio_data_conf; - audio_output_file->fifo = av_fifo_alloc(2 * MAX_AUDIO_PACKET_SIZE); - audio_output_file->aframe = FF_ALLOC_FRAME(); - audio_output_file->adata_buf = (uint8_t*) av_malloc(2 * MAX_AUDIO_PACKET_SIZE); -#ifndef GPAC_USE_LIBAV - audio_output_file->aframe->channels = -1; -#endif -#ifndef LIBAV_FRAME_OLD - audio_output_file->aframe->channel_layout = 0; - audio_output_file->aframe->sample_rate = -1; -#endif - audio_output_file->aframe->format = -1; - audio_output_file->codec = avcodec_find_encoder_by_name(audio_data_conf->codec); - if (audio_output_file->codec == NULL) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Output audio codec %s not found\n", audio_data_conf->codec)); - return -1; - } - - audio_output_file->codec_ctx = avcodec_alloc_context3(audio_output_file->codec); - audio_output_file->codec_ctx->codec_id = audio_output_file->codec->id; - audio_output_file->codec_ctx->codec_type = AVMEDIA_TYPE_AUDIO; - audio_output_file->codec_ctx->bit_rate = audio_data_conf->bitrate; - audio_output_file->codec_ctx->sample_rate = DC_AUDIO_SAMPLE_RATE /*audio_data_conf->samplerate*/; - - { - AVRational time_base; - time_base.num = 1; - time_base.den = audio_output_file->codec_ctx->sample_rate; - audio_output_file->codec_ctx->time_base = time_base; - } - audio_output_file->codec_ctx->channels = audio_data_conf->channels; - - /*FIXME: depends on channels -> http://ffmpeg.org/doxygen/trunk/channel__layout_8c_source.html#l00074*/ - if (audio_data_conf->channels == 1) { - audio_output_file->codec_ctx->channel_layout = AV_CH_LAYOUT_MONO; - } else { - audio_output_file->codec_ctx->channel_layout = AV_CH_LAYOUT_STEREO; - } - - audio_output_file->codec_ctx->sample_fmt = audio_output_file->codec->sample_fmts[0]; -#ifdef DC_AUDIO_RESAMPLER - audio_output_file->aresampler = NULL; -#endif - if (strcmp(audio_data_conf->custom, "")) { - build_dict(audio_output_file->codec_ctx->priv_data, audio_data_conf->custom); - } - audio_output_file->astream_idx = 0; - - /* open the audio codec */ - av_dict_set(&opts, "strict", "experimental", 0); - if (avcodec_open2(audio_output_file->codec_ctx, audio_output_file->codec, &opts) < 0) { - /*FIXME: if we enter here (set "mp2" as a codec and "200000" as a bitrate -> deadlock*/ - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output audio codec\n")); - av_dict_free(&opts); - return -1; - } - av_dict_free(&opts); - - audio_output_file->frame_bytes = audio_output_file->codec_ctx->frame_size * av_get_bytes_per_sample(DC_AUDIO_SAMPLE_FORMAT) * DC_AUDIO_NUM_CHANNELS; - -#ifndef FF_API_AVFRAME_LAVC - avcodec_get_frame_defaults(audio_output_file->aframe); -#else - av_frame_unref(audio_output_file->aframe); -#endif - - - audio_output_file->aframe->nb_samples = audio_output_file->codec_ctx->frame_size; - - if (avcodec_fill_audio_frame(audio_output_file->aframe, audio_output_file->codec_ctx->channels, audio_output_file->codec_ctx->sample_fmt, - audio_output_file->adata_buf, audio_output_file->codec_ctx->frame_size * av_get_bytes_per_sample(audio_output_file->codec_ctx->sample_fmt) * audio_output_file->codec_ctx->channels, 1) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Fill audio frame failed\n")); - return -1; - } - - //audio_output_file->acc_samples = 0; - - return 0; -} - -int dc_audio_encoder_read(AudioOutputFile *audio_output_file, AudioInputData *audio_input_data) -{ - int ret; - AudioDataNode *audio_data_node; - - ret = dc_consumer_lock(&audio_output_file->consumer, &audio_input_data->circular_buf); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Audio encoder got an end of buffer!\n")); - return -2; - } - - dc_consumer_unlock_previous(&audio_output_file->consumer, &audio_input_data->circular_buf); - - audio_data_node = (AudioDataNode *) dc_consumer_consume(&audio_output_file->consumer, &audio_input_data->circular_buf); -#ifndef GPAC_USE_LIBAV - audio_output_file->aframe->channels = audio_output_file->codec_ctx->channels; -#endif -#ifndef LIBAV_FRAME_OLD - audio_output_file->aframe->channel_layout = audio_output_file->codec_ctx->channel_layout; - audio_output_file->aframe->sample_rate = audio_output_file->codec_ctx->sample_rate; -#endif - audio_output_file->aframe->format = audio_output_file->codec_ctx->sample_fmt; - - /* Write audio sample on fifo */ - av_fifo_generic_write(audio_output_file->fifo, audio_data_node->abuf, audio_data_node->abuf_size, NULL); - - dc_consumer_advance(&audio_output_file->consumer); - - return 0; -} - -#if 0 -int dc_audio_encoder_flush(AudioOutputFile *audio_output_file, AudioInputData *audio_input_data) -{ - int got_pkt; - //AVStream *audio_stream = audio_output_file->av_fmt_ctx->streams[audio_output_file->astream_idx]; - //AVCodecContext *audio_codec_ctx = audio_stream->codec; - AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; - - av_init_packet(&audio_output_file->packet); - audio_output_file->packet.data = NULL; - audio_output_file->packet.size = 0; - - /* Set PTS (method 1) */ - audio_output_file->aframe->pts = audio_input_data->next_pts; - /* Encode audio */ -#ifdef DC_AUDIO_RESAMPLER -#error resampling is not done here -#endif - if (avcodec_encode_audio2(audio_codec_ctx, &audio_output_file->packet, NULL, &got_pkt) != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while encoding audio.\n")); - return -1; - } - if (got_pkt) { - //audio_output_file->acc_samples += audio_output_file->aframe->nb_samples; - return 0; - } - av_free_packet(&audio_output_file->packet); - return 1; -} -#endif - -#ifdef DC_AUDIO_RESAMPLER -static int ensure_resampler(AudioOutputFile *audio_output_file, AVCodecContext *audio_codec_ctx) -{ - if (!audio_output_file->aresampler) { - audio_output_file->aresampler = avresample_alloc_context(); - if (!audio_output_file->aresampler) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate the audio resampler. Aborting.\n")); - return -1; - } - av_opt_set_int(audio_output_file->aresampler, "in_channel_layout", DC_AUDIO_CHANNEL_LAYOUT, 0); - av_opt_set_int(audio_output_file->aresampler, "out_channel_layout", audio_codec_ctx->channel_layout, 0); - av_opt_set_int(audio_output_file->aresampler, "in_sample_fmt", DC_AUDIO_SAMPLE_FORMAT, 0); - av_opt_set_int(audio_output_file->aresampler, "out_sample_fmt", audio_codec_ctx->sample_fmt, 0); - av_opt_set_int(audio_output_file->aresampler, "in_sample_rate", DC_AUDIO_SAMPLE_RATE, 0); - av_opt_set_int(audio_output_file->aresampler, "out_sample_rate", audio_codec_ctx->sample_rate, 0); - av_opt_set_int(audio_output_file->aresampler, "in_channels", DC_AUDIO_NUM_CHANNELS, 0); - av_opt_set_int(audio_output_file->aresampler, "out_channels", audio_codec_ctx->channels, 0); - - if (avresample_open(audio_output_file->aresampler)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not open the audio resampler. Aborting.\n")); - return -1; - } - } - - return 0; -} - -//resample - see http://ffmpeg.org/pipermail/libav-user/2012-June/002164.html -static int resample_audio(AudioOutputFile *audio_output_file, AVCodecContext *audio_codec_ctx, int *num_planes_out) -{ - int i, linesize; - uint8_t **output; - *num_planes_out = av_sample_fmt_is_planar(audio_output_file->codec->sample_fmts[0]) ? audio_output_file->codec_ctx->channels : 1; - linesize = audio_output_file->codec_ctx->frame_size * av_get_bytes_per_sample(audio_output_file->codec->sample_fmts[0]) * audio_output_file->codec_ctx->channels / *num_planes_out; - output = (uint8_t**)av_malloc(*num_planes_out*sizeof(uint8_t*)); - for (i=0; i<*num_planes_out; i++) { - output[i] = (uint8_t*)av_malloc(linesize); - } - - if (avresample_convert(audio_output_file->aresampler, output, linesize, audio_output_file->aframe->nb_samples, audio_output_file->aframe->extended_data, audio_output_file->aframe->linesize[0], audio_output_file->aframe->nb_samples) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not resample audio frame. Aborting.\n")); - return -1; - } - - audio_output_file->aframe->extended_data = output; - for (i=0; i<*num_planes_out; i++) { - audio_output_file->aframe->linesize[i] = linesize; - } - audio_codec_ctx->channel_layout = audio_output_file->aframe->channel_layout; - audio_codec_ctx->sample_fmt = audio_output_file->aframe->format; - audio_codec_ctx->sample_rate = audio_output_file->aframe->sample_rate; -#ifndef GPAC_USE_LIBAV - audio_codec_ctx->channels = audio_output_file->aframe->channels; -#endif - - return 0; -} -#endif - -int dc_audio_encoder_encode(AudioOutputFile *audio_output_file, AudioInputData *audio_input_data) -{ - int got_pkt; - AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; - - while (av_fifo_size(audio_output_file->fifo) >= audio_output_file->frame_bytes) { -#ifdef DC_AUDIO_RESAMPLER - uint8_t **data = NULL; //mirror AVFrame::data - int num_planes_out = 0; -#endif - Bool resample; - - av_fifo_generic_read(audio_output_file->fifo, audio_output_file->adata_buf, audio_output_file->frame_bytes, NULL); - - audio_output_file->aframe->data[0] = audio_output_file->adata_buf; - audio_output_file->aframe->linesize[0] = audio_output_file->frame_bytes; - audio_output_file->aframe->linesize[1] = 0; - - av_init_packet(&audio_output_file->packet); - audio_output_file->packet.data = NULL; - audio_output_file->packet.size = 0; - - /* - * Set PTS (method 1) - */ - //audio_output_file->aframe->pts = audio_input_data->next_pts; - - /* - * Set PTS (method 2) - */ - //{ - // int64_t now = av_gettime(); - // AVRational avr; - // avr.num = 1; - // avr.den = AV_TIME_BASE; - // audio_output_file->aframe->pts = av_rescale_q(now, avr, audio_codec_ctx->time_base); - //} - - resample = (DC_AUDIO_SAMPLE_FORMAT != audio_codec_ctx->sample_fmt - || DC_AUDIO_SAMPLE_RATE != audio_codec_ctx->sample_rate - || DC_AUDIO_NUM_CHANNELS != audio_codec_ctx->channels - || DC_AUDIO_CHANNEL_LAYOUT != audio_codec_ctx->channel_layout); - /* Resample if needed */ - if (resample) { -#ifndef DC_AUDIO_RESAMPLER - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Audio resampling is needed at the encoding stage, but not supported by your version of DashCast. Aborting.\n")); - exit(1); -#else - if (ensure_resampler(audio_output_file, audio_codec_ctx)) { - return -1; - } - - data = audio_output_file->aframe->extended_data; - if (resample_audio(audio_output_file, audio_codec_ctx, &num_planes_out)) { - return -1; - } -#endif - } - - /* Encode audio */ - if (avcodec_encode_audio2(audio_codec_ctx, &audio_output_file->packet, audio_output_file->aframe, &got_pkt) != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while encoding audio.\n")); -#ifdef DC_AUDIO_RESAMPLER - if (resample) { - int i; - for (i=0; iaframe->extended_data[i]); - } - av_free(audio_output_file->aframe->extended_data); - audio_output_file->aframe->extended_data = data; - } -#endif - return -1; - } - -#ifdef DC_AUDIO_RESAMPLER - if (resample) { - int i; - for (i=0; iaframe->extended_data[i]); - } - av_free(audio_output_file->aframe->extended_data); - audio_output_file->aframe->extended_data = data; - } -#endif - - if (got_pkt) { - //audio_output_file->acc_samples += audio_output_file->aframe->nb_samples; - return 0; - } - - av_free_packet(&audio_output_file->packet); - } - - return 1; -} - -void dc_audio_encoder_close(AudioOutputFile *audio_output_file) -{ -// int i; -// -// /* free the streams */ -// for (i = 0; i < audio_output_file->av_fmt_ctx->nb_streams; i++) { -// avcodec_close(audio_output_file->av_fmt_ctx->streams[i]->codec); -// av_freep(&audio_output_file->av_fmt_ctx->streams[i]->info); -// } - - av_fifo_free(audio_output_file->fifo); - - av_free(audio_output_file->adata_buf); - av_free(audio_output_file->aframe); - - avcodec_close(audio_output_file->codec_ctx); - av_free(audio_output_file->codec_ctx); - -#ifdef DC_AUDIO_RESAMPLER - avresample_free(&audio_output_file->aresampler); -#endif -} diff --git a/applications/dashcast/audio_muxer.c b/applications/dashcast/audio_muxer.c deleted file mode 100644 index 2374c9d..0000000 --- a/applications/dashcast/audio_muxer.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 "audio_muxer.h" -#include "libavformat/avio.h" - -#ifndef GPAC_DISABLE_ISOM - -int dc_gpac_audio_moov_create(AudioOutputFile *audio_output_file, char *filename) -{ - GF_Err ret; - u32 di, track; - u8 bpsample; - GF_ESD *esd; -#ifndef GPAC_DISABLE_AV_PARSERS - GF_M4ADecSpecInfo acfg; -#endif - AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; - - audio_output_file->isof = gf_isom_open(filename, GF_ISOM_OPEN_WRITE, NULL); - if (!audio_output_file->isof) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open iso file %s\n", filename)); - return -1; - } - - esd = gf_odf_desc_esd_new(2); - if (!esd) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create GF_ESD\n")); - return -1; - } - - esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); - esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); - esd->decoderConfig->streamType = GF_STREAM_AUDIO; - if (!strcmp(audio_output_file->codec_ctx->codec->name, "aac")) { //TODO: find an automatic table - esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; - esd->decoderConfig->bufferSizeDB = 20; - esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; - esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - esd->ESID = 1; - -#ifndef GPAC_DISABLE_AV_PARSERS - memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); - acfg.base_object_type = GF_M4A_AAC_LC; - acfg.base_sr = audio_codec_ctx->sample_rate; - acfg.nb_chan = audio_codec_ctx->channels; - acfg.sbr_object_type = 0; - acfg.audioPL = gf_m4a_get_profile(&acfg); - - ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); - assert(ret == GF_OK); -#endif - } else { - if (strcmp(audio_output_file->codec_ctx->codec->name, "mp2")) { - GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Unlisted codec, setting GPAC_OTI_AUDIO_MPEG1 descriptor.\n")); - } - esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; - esd->decoderConfig->bufferSizeDB = 20; - esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; - esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - esd->ESID = 1; - -#ifndef GPAC_DISABLE_AV_PARSERS - memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); - acfg.base_object_type = GF_M4A_LAYER2; - acfg.base_sr = audio_codec_ctx->sample_rate; - acfg.nb_chan = audio_codec_ctx->channels; - acfg.sbr_object_type = 0; - acfg.audioPL = gf_m4a_get_profile(&acfg); - - ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); - assert(ret == GF_OK); -#endif - } - - //gf_isom_store_movie_config(video_output_file->isof, 0); - track = gf_isom_new_track(audio_output_file->isof, esd->ESID, GF_ISOM_MEDIA_AUDIO, audio_codec_ctx->sample_rate); - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("TimeScale: %d \n", audio_codec_ctx->time_base.den)); - if (!track) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create new track\n")); - return -1; - } - - ret = gf_isom_set_track_enabled(audio_output_file->isof, track, 1); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret))); - return -1; - } - -// if (!esd->ESID) esd->ESID = gf_isom_get_track_id(audio_output_file->isof, track); - - ret = gf_isom_new_mpeg4_description(audio_output_file->isof, track, esd, NULL, NULL, &di); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_new_mpeg4_description\n", gf_error_to_string(ret))); - return -1; - } - - gf_odf_desc_del((GF_Descriptor *) esd); - esd = NULL; - - bpsample = av_get_bytes_per_sample(audio_output_file->codec_ctx->sample_fmt) * 8; - - ret = gf_isom_set_audio_info(audio_output_file->isof, track, di, audio_codec_ctx->sample_rate, audio_output_file->codec_ctx->channels, bpsample); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_audio_info\n", gf_error_to_string(ret))); - return -1; - } - -#ifndef GPAC_DISABLE_AV_PARSERS - ret = gf_isom_set_pl_indication(audio_output_file->isof, GF_ISOM_PL_AUDIO, acfg.audioPL); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_pl_indication\n", gf_error_to_string(ret))); - return -1; - } -#endif - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("time scale: %d sample dur: %d \n", audio_codec_ctx->time_base.den, audio_output_file->codec_ctx->frame_size)); - - ret = gf_isom_setup_track_fragment(audio_output_file->isof, track, 1, audio_output_file->codec_ctx->frame_size, 0, 0, 0, 0); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret))); - return -1; - } - - //gf_isom_add_track_to_root_od(video_output_file->isof,1); - - ret = gf_isom_finalize_for_fragment(audio_output_file->isof, 1); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); - return -1; - } - - ret = gf_media_get_rfc_6381_codec_name(audio_output_file->isof, track, audio_output_file->audio_data_conf->codec6381, GF_FALSE, GF_FALSE); - if (ret != GF_OK) return -1; - return 0; -} - -int dc_gpac_audio_isom_open_seg(AudioOutputFile *audio_output_file, char *filename) -{ - GF_Err ret; - ret = gf_isom_start_segment(audio_output_file->isof, filename, GF_TRUE); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_start_segment\n", gf_error_to_string(ret))); - return -1; - } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio segment %s started at "LLU"\n", filename, gf_net_get_utc() )); - - audio_output_file->dts = 0; - - return 0; -} - -int dc_gpac_audio_isom_write(AudioOutputFile *audio_output_file) -{ - GF_Err ret; - audio_output_file->sample->data = (char *) audio_output_file->packet.data; - audio_output_file->sample->dataLength = audio_output_file->packet.size; - - audio_output_file->sample->DTS = audio_output_file->dts; //audio_output_file->aframe->pts; - audio_output_file->sample->IsRAP = RAP; //audio_output_file->aframe->key_frame;//audio_codec_ctx->coded_frame->key_frame; - - ret = gf_isom_fragment_add_sample(audio_output_file->isof, 1, audio_output_file->sample, 1, audio_output_file->codec_ctx->frame_size, 0, 0, 0); - audio_output_file->dts += audio_output_file->codec_ctx->frame_size; - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_fragment_add_sample\n", gf_error_to_string(ret))); - return -1; - } - return 0; -} - -int dc_gpac_audio_isom_close_seg(AudioOutputFile *audio_output_file) -{ - GF_Err ret; - ret = gf_isom_close_segment(audio_output_file->isof, 0, 0,0, 0, 0, 0, 1, audio_output_file->seg_marker, NULL, NULL); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close_segment\n", gf_error_to_string(ret))); - return -1; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio segment closed at "LLU"\n", gf_net_get_utc() )); - - //audio_output_file->acc_samples = 0; - - return 0; -} - -int dc_gpac_audio_isom_close(AudioOutputFile *audio_output_file) -{ - GF_Err ret; - ret = gf_isom_close(audio_output_file->isof); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close\n", gf_error_to_string(ret))); - return -1; - } - - //audio_output_file->acc_samples = 0; - - return 0; -} - -#endif - - - -int dc_ffmpeg_audio_muxer_open(AudioOutputFile *audio_output_file, char *filename) -{ - AVStream *audio_stream; - AVOutputFormat *output_fmt; - AVDictionary *opts = NULL; - - AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; - audio_output_file->av_fmt_ctx = NULL; - -// strcpy(audio_output_file->filename, audio_data_conf->filename); -// audio_output_file->abr = audio_data_conf->bitrate; -// audio_output_file->asr = audio_data_conf->samplerate; -// audio_output_file->ach = audio_data_conf->channels; -// strcpy(audio_output_file->codec, audio_data_conf->codec); - - /* Find output format */ - output_fmt = av_guess_format(NULL, filename, NULL); - if (!output_fmt) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find suitable output format\n")); - return -1; - } - - audio_output_file->av_fmt_ctx = avformat_alloc_context(); - if (!audio_output_file->av_fmt_ctx) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate memory for pOutVideoFormatCtx\n")); - return -1; - } - - audio_output_file->av_fmt_ctx->oformat = output_fmt; - strcpy(audio_output_file->av_fmt_ctx->filename, filename); - - /* Open the output file */ - if (!(output_fmt->flags & AVFMT_NOFILE)) { - if (avio_open(&audio_output_file->av_fmt_ctx->pb, filename, URL_WRONLY) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot not open '%s'\n", filename)); - return -1; - } - } - - audio_stream = avformat_new_stream(audio_output_file->av_fmt_ctx, audio_output_file->codec); - if (!audio_stream) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create output video stream\n")); - return -1; - } - - audio_stream->codec->codec_id = audio_output_file->codec->id; - audio_stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; - audio_stream->codec->bit_rate = audio_codec_ctx->bit_rate;//audio_output_file->audio_data_conf->bitrate; - audio_stream->codec->sample_rate = audio_codec_ctx->sample_rate;//audio_output_file->audio_data_conf->samplerate; - audio_stream->codec->channels = audio_codec_ctx->channels;//audio_output_file->audio_data_conf->channels; - assert(audio_codec_ctx->codec->sample_fmts); - audio_stream->codec->sample_fmt = audio_codec_ctx->codec->sample_fmts[0]; - -// if (audio_output_file->av_fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) -// audio_output_file->codec_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; - - //video_stream->codec = video_output_file->codec_ctx; - - /* open the video codec */ - av_dict_set(&opts, "strict", "experimental", 0); - if (avcodec_open2(audio_stream->codec, audio_output_file->codec, &opts) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video codec\n")); - av_dict_free(&opts); - return -1; - } - av_dict_free(&opts); - - avformat_write_header(audio_output_file->av_fmt_ctx, NULL); - - return 0; -} - -int dc_ffmpeg_audio_muxer_write(AudioOutputFile *audio_output_file) -{ - AVStream *audio_stream = audio_output_file->av_fmt_ctx->streams[audio_output_file->astream_idx]; - AVCodecContext *audio_codec_ctx = audio_stream->codec; - - audio_output_file->packet.stream_index = audio_stream->index; - - if (audio_output_file->packet.pts != AV_NOPTS_VALUE) - audio_output_file->packet.pts = av_rescale_q(audio_output_file->packet.pts, audio_codec_ctx->time_base, audio_stream->time_base); - - if (audio_output_file->packet.duration > 0) - audio_output_file->packet.duration = (int)av_rescale_q(audio_output_file->packet.duration, audio_codec_ctx->time_base, audio_stream->time_base); - /* - * if (pkt.pts != AV_NOPTS_VALUE) - * pkt.pts = av_rescale_q(pkt.pts, audioEncCtx->time_base, audioStream->time_base); - */ - - audio_output_file->packet.flags |= AV_PKT_FLAG_KEY; - - if (av_interleaved_write_frame(audio_output_file->av_fmt_ctx, &audio_output_file->packet) != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Writing frame is not successful\n")); - av_free_packet(&audio_output_file->packet); - return -1; - } - - av_free_packet(&audio_output_file->packet); - - return 0; -} - -int dc_ffmpeg_audio_muxer_close(AudioOutputFile *audio_output_file) -{ - u32 i; - - av_write_trailer(audio_output_file->av_fmt_ctx); - avio_close(audio_output_file->av_fmt_ctx->pb); - - // free the streams - for (i = 0; i < audio_output_file->av_fmt_ctx->nb_streams; i++) { - avcodec_close(audio_output_file->av_fmt_ctx->streams[i]->codec); - av_freep(&audio_output_file->av_fmt_ctx->streams[i]->info); - } - - //video_output_file->av_fmt_ctx->streams[video_output_file->vstream_idx]->codec = NULL; - avformat_free_context(audio_output_file->av_fmt_ctx); - - //audio_output_file->acc_samples = 0; - - return 0; - -} - -int dc_audio_muxer_init(AudioOutputFile *audio_output_file, AudioDataConf *audio_data_conf, AudioMuxerType muxer_type, int frame_per_seg, int frame_per_frag, u32 seg_marker) -{ - char name[GF_MAX_PATH]; - snprintf(name, sizeof(name), "audio encoder %s", audio_data_conf->filename); - dc_consumer_init(&audio_output_file->consumer, AUDIO_CB_SIZE, name); - -#ifndef GPAC_DISABLE_ISOM - audio_output_file->sample = gf_isom_sample_new(); - audio_output_file->isof = NULL; -#endif - - audio_output_file->muxer_type = muxer_type; - audio_output_file->frame_per_seg = frame_per_seg; - audio_output_file->frame_per_frag = frame_per_frag; - audio_output_file->seg_marker = seg_marker; - return 0; -} - -void dc_audio_muxer_free(AudioOutputFile *audio_output_file) -{ -#ifndef GPAC_DISABLE_ISOM - if (audio_output_file->isof != NULL) { - gf_isom_close(audio_output_file->isof); - } - //gf_isom_sample_del(&audio_output_file->sample); -#endif -} - -GF_Err dc_audio_muxer_open(AudioOutputFile *audio_output_file, char *directory, char *id_name, int seg) -{ - GF_Err ret = GF_NOT_SUPPORTED; - char name[GF_MAX_PATH]; - - switch (audio_output_file->muxer_type) { - case FFMPEG_AUDIO_MUXER: - snprintf(name, sizeof(name), "%s/%s_%d_ffmpeg.mp4", directory, id_name, seg); - return dc_ffmpeg_audio_muxer_open(audio_output_file, name); -#ifndef GPAC_DISABLE_ISOM - case GPAC_AUDIO_MUXER: - snprintf(name, sizeof(name), "%s/%s_%d_gpac.mp4", directory, id_name, seg); - dc_gpac_audio_moov_create(audio_output_file, name); - return dc_gpac_audio_isom_open_seg(audio_output_file, NULL); - case GPAC_INIT_AUDIO_MUXER: - if (seg == 1) { - snprintf(name, sizeof(name), "%s/%s_init_gpac.mp4", directory, id_name); - dc_gpac_audio_moov_create(audio_output_file, name); - audio_output_file->first_dts = 0; - } - snprintf(name, sizeof(name), "%s/%s_%d_gpac.m4s", directory, id_name, seg); - ret = dc_gpac_audio_isom_open_seg(audio_output_file, name); - return ret; -#endif - default: - ret = GF_BAD_PARAM; - break; - } - - return ret; -} - -int dc_audio_muxer_write(AudioOutputFile *audio_output_file, int frame_nb, Bool insert_ntp) -{ - switch (audio_output_file->muxer_type) { - case FFMPEG_AUDIO_MUXER: - return dc_ffmpeg_audio_muxer_write(audio_output_file); -#ifndef GPAC_DISABLE_ISOM - case GPAC_AUDIO_MUXER: - case GPAC_INIT_AUDIO_MUXER: - if (frame_nb % audio_output_file->frame_per_frag == 0) { - gf_isom_start_fragment(audio_output_file->isof, 1); - - if (insert_ntp) { - gf_isom_set_fragment_reference_time(audio_output_file->isof, 1, audio_output_file->frame_ntp, audio_output_file->first_dts * audio_output_file->codec_ctx->frame_size); - } - - gf_isom_set_traf_base_media_decode_time(audio_output_file->isof, 1, audio_output_file->first_dts * audio_output_file->codec_ctx->frame_size); - audio_output_file->first_dts += audio_output_file->frame_per_frag; - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio start fragment first DTS %u at "LLU"\n", audio_output_file->first_dts, gf_net_get_utc() )); - } - dc_gpac_audio_isom_write(audio_output_file); - if (frame_nb % audio_output_file->frame_per_frag == audio_output_file->frame_per_frag - 1) { - gf_isom_flush_fragments(audio_output_file->isof, 1); - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio flush fragment first DTS %u at "LLU"\n", audio_output_file->first_dts, gf_net_get_utc() )); - } - //TODO - do same as video, flush based on time in case of losses - if (frame_nb + 1 == audio_output_file->frame_per_seg) { - return 1; - } - - return 0; -#endif - - default: - return GF_BAD_PARAM; - } - return GF_BAD_PARAM; -} - -int dc_audio_muxer_close(AudioOutputFile *audio_output_file) -{ - switch (audio_output_file->muxer_type) { - case FFMPEG_AUDIO_MUXER: - return dc_ffmpeg_audio_muxer_close(audio_output_file); -#ifndef GPAC_DISABLE_ISOM - case GPAC_AUDIO_MUXER: - dc_gpac_audio_isom_close_seg(audio_output_file); - return dc_gpac_audio_isom_close(audio_output_file); - case GPAC_INIT_AUDIO_MUXER: - return dc_gpac_audio_isom_close_seg(audio_output_file); -#endif - default: - return GF_BAD_PARAM; - } - - return GF_BAD_PARAM; -} diff --git a/applications/dashcast/audio_muxer.h b/applications/dashcast/audio_muxer.h deleted file mode 100644 index 94151d8..0000000 --- a/applications/dashcast/audio_muxer.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 AUDIO_MUXER_H_ -#define AUDIO_MUXER_H_ - -#include -#include "../../modules/ffmpeg_in/ffmpeg_in.h" -#include "libavutil/fifo.h" -#include "libavformat/avformat.h" -#include "libavdevice/avdevice.h" -#ifdef DC_AUDIO_RESAMPLER -#include "libavresample/avresample.h" -#endif -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include -#include -#include -#include "audio_data.h" - - -typedef enum { - FFMPEG_AUDIO_MUXER, - GPAC_AUDIO_MUXER, - GPAC_INIT_AUDIO_MUXER -} AudioMuxerType; - -/* - * AudioOutputFile structure has the data needed - * to encode audio samples and write them on the file. - * It reads the data from a circular buffer so it needs - * to keep the index to that circular buffer. This index is - * available in Consumer data structure. - * - */ -typedef struct { - AudioDataConf *audio_data_conf; - - /* File format context structure */ - AVFormatContext *av_fmt_ctx; - AVCodec *codec; - AVCodecContext *codec_ctx; - -#ifndef GPAC_DISABLE_ISOM - GF_ISOFile *isof; - GF_ISOSample *sample; -#endif - - int dts; - - /* The index to the audio stream in the file */ - int astream_idx; - - /* It keeps the index with which encoder access to the circular buffer (as a consumer) */ - Consumer consumer; - -#ifdef DC_AUDIO_RESAMPLER - /* Optional audio resampling between the decoder and the encoder */ - AVAudioResampleContext *aresampler; -#endif - - /* Variables that encoder needs to encode data */ - AVFrame *aframe; - uint8_t *adata_buf; - int frame_bytes; - AVPacket packet; - - /* - * Audio samples stored in the AVFrame are not always - * complete. Which means more than 1 AVFrame is needed - * to complete an access unit. This fifo is provided - * to store audio samples in the fifo and once an access unit - * is complete we can encode it. - */ - AVFifoBuffer *fifo; - - AudioMuxerType muxer_type; - - /* Accumulated sample */ - //int acc_samples; - - int frame_per_seg; - int frame_per_frag; - int first_dts; - - u32 seg_marker; - u64 frame_ntp; -} AudioOutputFile; - -int dc_audio_muxer_init(AudioOutputFile *audio_output_file, AudioDataConf *audio_data_conf, AudioMuxerType muxer_type, int frame_per_seg, int frame_per_frag, u32 seg_marker); -void dc_audio_muxer_free(AudioOutputFile *audio_output_file); - -/* - * Open the output audio - * - * @param audio_output_file [out] open the audio output on this file - * - * @param audio_data_conf [in] the structure containing the - * configuration of the output file (bitrate, samplerate, name, channels) - * - * @return 0 on success, -1 on failure - */ -GF_Err dc_audio_muxer_open(AudioOutputFile *audio_output_file, char *directory, char *id_name, int seg); - -GF_Err dc_audio_muxer_write(AudioOutputFile *audio_output_file, int frame_nb, Bool insert_ntp); - -GF_Err dc_audio_muxer_close(AudioOutputFile *audio_output_file); - -#endif /* AUDIO_MUXER_H_ */ diff --git a/applications/dashcast/controler.c b/applications/dashcast/controler.c deleted file mode 100644 index 1cab9d7..0000000 --- a/applications/dashcast/controler.c +++ /dev/null @@ -1,1454 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 "controler.h" - - -#if (!defined(__DARWIN__) && !defined(__APPLE__)) -# include -#endif - -#include - -#if defined(__GNUC__) -# include -# include -#elif defined(WIN32) -# include -# include -# define suseconds_t long -#else -# error -#endif - -#include - -typedef struct { - int segnum; - u64 utc_time, ntpts; -} segtime; - - -//#define MAX_SOURCE_NUMBER 20 -#define FRAGMENTER 0 -//#define DEBUG 1 - -//#define VIDEO_MUXER FFMPEG_VIDEO_MUXER -//#define VIDEO_MUXER RAW_VIDEO_H264 -//#define VIDEO_MUXER GPAC_VIDEO_MUXER -#define VIDEO_MUXER GPAC_INIT_VIDEO_MUXER_AVC1 -//#define VIDEO_MUXER GPAC_INIT_VIDEO_MUXER_AVC3 - -//#define AUDIO_MUXER FFMPEG_AUDIO_MUXER -//#define AUDIO_MUXER GPAC_AUDIO_MUXER -#define AUDIO_MUXER GPAC_INIT_AUDIO_MUXER - -#define AUDIO_FRAME_SIZE 1024 - - -void optimize_seg_frag_dur(int *seg, int *frag) -{ - int min_rem; - int seg_nb = *seg; - int frag_nb = *frag; - if (!frag_nb) frag_nb = 1; - - min_rem = seg_nb % frag_nb; - - if (seg_nb % (frag_nb + 1) < min_rem) { - min_rem = seg_nb % (frag_nb + 1); - *seg = seg_nb; - *frag = frag_nb + 1; - } - - if ((seg_nb + 1) % frag_nb < min_rem) { - min_rem = (seg_nb + 1) % frag_nb; - *seg = seg_nb + 1; - *frag = frag_nb; - } - - if ((seg_nb + 1) % (frag_nb + 1) < min_rem) { - min_rem = (seg_nb + 1) % (frag_nb + 1); - *seg = seg_nb + 1; - *frag = frag_nb + 1; - } - - *seg -= min_rem; -} - -Bool change_source_thread(void *params) -{ - Bool ret = GF_FALSE; - return ret; -} - -u32 send_frag_event(void *params) -{ - int ret; - //int status; - char buff[GF_MAX_PATH]; - ThreadParam *th_param = (ThreadParam*)params; - CmdData *cmd_data = th_param->in_data; - MessageQueue *mq = th_param->mq; - - while (1) { - if (cmd_data->exit_signal) { - break; - } - - ret = dc_message_queue_get(mq, (void*) buff); - if (ret > 0) { - fprintf(stdout, "Message received: %s\n", buff); - } - } - - return 0; -} - -static void dc_write_mpd(CmdData *cmddata, const AudioDataConf *audio_data_conf, const VideoDataConf *video_data_conf, const char *presentation_duration, const char *availability_start_time, const char *time_shift, const int segnum, const int ast_offset) -{ - u32 i = 0, sec; - int audio_seg_dur = 0, video_seg_dur = 0, audio_frag_dur = 0, video_frag_dur = 0; - int audio_frame_size = AUDIO_FRAME_SIZE; - time_t gtime; - struct tm *t; - FILE *f; - - char name[GF_MAX_PATH]; - - snprintf(name, sizeof(name), "%s/%s", cmddata->out_dir, cmddata->mpd_filename); - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Write MPD at UTC "LLU" ms - %s : %s\n", gf_net_get_utc(), (cmddata->mode == ON_DEMAND) ? "mediaPresentationDuration" : "availabilityStartTime", (cmddata->mode == ON_DEMAND) ? presentation_duration : availability_start_time)); - - if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { - audio_data_conf = (const AudioDataConf*)gf_list_get(cmddata->audio_lst, 0); - if (audio_data_conf) { - audio_seg_dur = (int)((audio_data_conf->samplerate / (double) audio_frame_size) * (cmddata->seg_dur / 1000.0)); - audio_frag_dur = (int)((audio_data_conf->samplerate / (double) audio_frame_size) * (cmddata->frag_dur / 1000.0)); - optimize_seg_frag_dur(&audio_seg_dur, &audio_frag_dur); - } - } - - if (strcmp(cmddata->video_data_conf.filename, "") != 0) { - video_data_conf = (VideoDataConf*)gf_list_get(cmddata->video_lst, 0); - if (video_data_conf) { - video_seg_dur = (int)(video_data_conf->framerate * (cmddata->seg_dur / 1000.0)); - video_frag_dur = (int)(video_data_conf->framerate * (cmddata->frag_dur / 1000.0)); - optimize_seg_frag_dur(&video_seg_dur, &video_frag_dur); - } - } - - f = gf_fopen(name, "w"); - //TODO: if (!f) ... - - // time_t t = time(NULL); - // time_t t2 = t + 2; - // t += (2 * (cmddata->seg_dur / 1000.0)); - // tm = *gmtime(&t2); - // snprintf(availability_start_time, "%d-%d-%dT%d:%d:%dZ", tm.tm_year + 1900, - // tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - // fprintf(stdout, "%s \n", availability_start_time); - - fprintf(f, "\n"); - fprintf(f, "min_buffer_time); - - if (cmddata->mode == ON_DEMAND) { - fprintf(f, " type=\"static\" mediaPresentationDuration=\"%s\"", presentation_duration); - } else { - fprintf(f, " type=\"dynamic\" availabilityStartTime=\"%s\"", availability_start_time); - if (time_shift) fprintf(f, " timeShiftBufferDepth=\"%s\"", time_shift); - - if (cmddata->minimum_update_period > 0) - fprintf(f, " minimumUpdatePeriod=\"PT%dS\"", cmddata->minimum_update_period); - - gf_net_get_ntp(&sec, NULL); - gtime = sec - GF_NTP_SEC_1900_TO_1970; - t = gmtime(>ime); - fprintf(f, " publishTime=\"%d-%02d-%02dT%02d:%02d:%02dZ\"", 1900+t->tm_year, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); - - } - - fprintf(f, ">\n"); - - fprintf(f, - " \n" - " %s\n" - " \n", cmddata->mpd_filename); - - if (strcmp(cmddata->base_url, "") != 0) { - fprintf(f, " %s\n", cmddata->base_url); - } - - fprintf(f, " \n"); - - if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { - fprintf(f, " \n"); - - fprintf(f, - " \n"); - - fprintf(f, - " samplerate, audio_seg_dur * audio_frame_size, segnum); - - if (ast_offset<0) { - fprintf(f, " availabilityTimeOffset=\"%g\"", -ast_offset/1000.0); - } - fprintf(f, "/>\n"); - - - - for (i = 0; i < gf_list_count(cmddata->audio_lst); i++) { - audio_data_conf = (const AudioDataConf*)gf_list_get(cmddata->audio_lst, i); - fprintf(f, - " \n" - " \n", audio_data_conf->filename, audio_data_conf->codec6381, audio_data_conf->samplerate, audio_data_conf->bitrate); - } - - fprintf(f, " \n"); - } - - if (strcmp(cmddata->video_data_conf.filename, "") != 0) { - fprintf(f, " \n"); - - fprintf(f, - " framerate, video_seg_dur, segnum); - - - if (ast_offset<0) { - fprintf(f, " availabilityTimeOffset=\"%g\"", -ast_offset/1000.0); - } - fprintf(f, "/>\n"); - - for (i = 0; i < gf_list_count(cmddata->video_lst); i++) { - video_data_conf = (VideoDataConf*)gf_list_get(cmddata->video_lst, i); - fprintf(f, " \n" - " \n", video_data_conf->filename, - VIDEO_MUXER == GPAC_INIT_VIDEO_MUXER_AVC1 ? video_data_conf->codec6381 : "avc3", - video_data_conf->width, video_data_conf->height, video_data_conf->framerate, - video_data_conf->bitrate); - } - - fprintf(f, " \n"); - } - - fprintf(f, " \n"); - - fprintf(f, "\n"); - - gf_fclose(f); -} - -static u32 mpd_thread(void *params) -{ - ThreadParam *th_param = (ThreadParam*)params; - CmdData *cmddata = th_param->in_data; - MessageQueue *mq = th_param->mq; - char availability_start_time[GF_MAX_PATH]; - char presentation_duration[GF_MAX_PATH]; - char time_shift[GF_MAX_PATH] = ""; - AudioDataConf *audio_data_conf = NULL; - VideoDataConf *video_data_conf = NULL; - struct tm ast_time; - int dur = 0; - int h, m, s, ms; - segtime last_seg_time; - segtime main_seg_time; - Bool first = GF_TRUE; - main_seg_time.segnum = 0; - main_seg_time.utc_time = 0; - main_seg_time.ntpts = 0; - last_seg_time = main_seg_time; - - if (cmddata->mode == LIVE_CAMERA || cmddata->mode == LIVE_MEDIA) { - while (1) { - u32 msecs; - time_t t; - segtime seg_time; - seg_time.segnum = 0; - seg_time.utc_time = 0; - seg_time.ntpts = 0; - - if (cmddata->exit_signal) { - break; - } - - if (strcmp(cmddata->video_data_conf.filename, "") != 0) { - if (dc_message_queue_get(mq, &seg_time) < 0) { - continue; - } - } - - if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { - if (dc_message_queue_get(mq, &seg_time) < 0) { - continue; - } - } - assert(seg_time.ntpts); - - if (cmddata->use_dynamic_ast) { - main_seg_time = seg_time; - } else { - //get the last notification of AST - if (first) { - main_seg_time = seg_time; - first = GF_FALSE; - } - assert(main_seg_time.ntpts); - } - - last_seg_time = seg_time; - assert(main_seg_time.ntpts <= seg_time.ntpts); - - t = (seg_time.ntpts >> 32) - GF_NTP_SEC_1900_TO_1970; - msecs = (u32) ( (seg_time.ntpts & 0xFFFFFFFF) * (1000.0/0xFFFFFFFF) ); - ast_time = *gmtime(&t); - fprintf(stdout, "Generating MPD at %d-%02d-%02dT%02d:%02d:%02d.%03dZ\n", 1900 + ast_time.tm_year, ast_time.tm_mon+1, ast_time.tm_mday, ast_time.tm_hour, ast_time.tm_min, ast_time.tm_sec, msecs); - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Generating MPD at %d-%02d-%02dT%02d:%02d:%02d.%03dZ - UTC "LLU" ms - AST UTC "LLU" ms\n", 1900 + ast_time.tm_year, ast_time.tm_mon+1, ast_time.tm_mday, ast_time.tm_hour, ast_time.tm_min, ast_time.tm_sec, msecs, seg_time.utc_time, main_seg_time.utc_time)); - - t = (main_seg_time.ntpts >> 32) - GF_NTP_SEC_1900_TO_1970; - if (cmddata->ast_offset>0) { - t += cmddata->ast_offset/1000; - } - msecs = (u32) ( (main_seg_time.ntpts & 0xFFFFFFFF) * (1000.0/0xFFFFFFFF) ); - ast_time = *gmtime(&t); - assert(ast_time.tm_year); - - sprintf(availability_start_time, "%d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + ast_time.tm_year, ast_time.tm_mon+1, ast_time.tm_mday, ast_time.tm_hour, ast_time.tm_min, ast_time.tm_sec, msecs); - fprintf(stdout, "StartTime: %s - startNumber %d - last number %d\n", availability_start_time, main_seg_time.segnum+1, seg_time.segnum+1); - - if (cmddata->time_shift != -1) { - int ts, h, m, s; - ts = cmddata->time_shift; - h = ts / 3600; - ts = ts % 3600; - m = ts / 60; - s = ts % 60; - snprintf(time_shift, sizeof(time_shift), "PT%02dH%02dM%02dS", h, m, s); - } - - dc_write_mpd(cmddata, audio_data_conf, video_data_conf, presentation_duration, availability_start_time, time_shift, main_seg_time.segnum+1, cmddata->ast_offset); - } - - if (cmddata->no_mpd_rewrite) return 0; - - //finally rewrite the MPD to static - dur = cmddata->seg_dur * (last_seg_time.segnum - main_seg_time.segnum); - if (cmddata->time_shift) { - if (dur > cmddata->time_shift * 1000) { - u32 nb_seg = cmddata->time_shift*1000 / cmddata->seg_dur; - main_seg_time.segnum = last_seg_time.segnum - nb_seg; - //dur = cmddata->time_shift; - } - dur = cmddata->seg_dur * (last_seg_time.segnum - main_seg_time.segnum); - } - cmddata->mode = ON_DEMAND; - - } else { - int a_dur = 0; - int v_dur = 0; - - if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { - dc_message_queue_get(mq, &a_dur); - } - - if (strcmp(cmddata->video_data_conf.filename, "") != 0) { - dc_message_queue_get(mq, &v_dur); - } - - dur = v_dur > a_dur ? v_dur : a_dur; - } - - - h = dur / 3600000; - dur = dur % 3600000; - m = dur / 60000; - dur = dur % 60000; - s = dur / 1000; - ms = dur % 1000; - snprintf(presentation_duration, sizeof(presentation_duration), "PT%02dH%02dM%02d.%03dS", h, m, s, ms); - fprintf(stdout, "Duration: %s\n", presentation_duration); - - - dc_write_mpd(cmddata, audio_data_conf, video_data_conf, presentation_duration, availability_start_time, 0, main_seg_time.segnum+1, 0); - - return 0; -} - -u32 delete_seg_thread(void *params) -{ - int ret; - ThreadParam *th_param = (ThreadParam*)params; - CmdData *cmd_data = th_param->in_data; - MessageQueue *mq = th_param->mq; - - char buff[GF_MAX_PATH]; - - while (1) { - ret = dc_message_queue_get(mq, (void*) buff); - if (ret > 0) { - int status; - status = unlink(buff); - if (status != 0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Unable to delete the file %s\n", buff)); - } - } - - if (cmd_data->exit_signal) { - break; - } - } - - return 0; -} - -Bool fragmenter_thread(void *params) -{ -// int ret; - ThreadParam *th_param = (ThreadParam*)params; - CmdData *cmd_data = th_param->in_data; - MessageQueue *mq = th_param->mq; - - char buff[GF_MAX_PATH]; - - while (1) { - /*ret = */dc_message_queue_get(mq, (void*) buff); - if (cmd_data->exit_signal) { - break; - } - } - - return GF_FALSE; -} - -static u32 keyboard_thread(void *params) -{ - - ThreadParam *th_param = (ThreadParam*)params; - CmdData *in_data = th_param->in_data; - char c; - - while (1) { - if (gf_prompt_has_input()) { - c = gf_prompt_get_char(); - if (c == 'q' || c == 'Q') { - in_data->exit_signal = 1; - break; - } - } - - if (in_data->exit_signal) { - break; - } - - gf_sleep(100); - } - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Keyboard thread exit\n")); - return 0; -} - -u32 video_decoder_thread(void *params) -{ -#ifdef DASHCAST_PRINT - int i = 0; -#endif - int ret; - int source_number = 0; - - //int first_time = 1; - struct timeval time_start, time_end, time_wait; - VideoThreadParam *thread_params = (VideoThreadParam *) params; - - CmdData *in_data = thread_params->in_data; - VideoInputData *video_input_data = thread_params->video_input_data; - VideoInputFile **video_input_file = thread_params->video_input_file; - - suseconds_t total_wait_time = (int) (1000000.0 / (double) in_data->video_data_conf.framerate); - suseconds_t pick_packet_delay, select_delay = 0, real_wait, other_delays = 2; - - Task t; - //fprintf(stdout, "wait time : %f\n", total_wait_time); - - if (!gf_list_count(in_data->video_lst)) - return 0; - - while (1) { - dc_task_get_current(&in_data->task_list, &t); - source_number = t.source_number; - - //fprintf(stdout, "sourcenumber: %d\n", source_number); - -// if (video_input_file[source_number]->mode == LIVE_MEDIA) { - gf_gettimeofday(&time_start, NULL); -// } - - ret = dc_video_decoder_read(video_input_file[source_number], video_input_data, source_number, in_data->use_source_timing, (in_data->mode == LIVE_CAMERA) ? 1 : 0, (const int *) &in_data->exit_signal); -#ifdef DASHCAST_PRINT - fprintf(stdout, "Read video frame %d\r", i++); - fflush(stdout); -#endif - if (ret == -2) { - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video reader has no more frame to read.\n")); - break; - } - if (ret == -1) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occurred while reading video frame.\n")); - break; - } - - if (in_data->exit_signal) { - dc_video_input_data_end_signal(video_input_data); - break; - } - - if (video_input_file[source_number]->mode == LIVE_MEDIA) { - gf_gettimeofday(&time_end, NULL); - pick_packet_delay = ((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec; - time_wait.tv_sec = 0; - real_wait = total_wait_time - pick_packet_delay - select_delay - other_delays; - time_wait.tv_usec = real_wait; - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("delay: %ld = %ld - %ld\n", time_wait.tv_usec, total_wait_time, pick_packet_delay)); - - gf_gettimeofday(&time_start, NULL); - select(0, NULL, NULL, NULL, &time_wait); - gf_gettimeofday(&time_end, NULL); - - select_delay = (((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec) - real_wait; - } - } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Video decoder is exiting...\n")); - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("video decoder thread exit\n")); - return 0; -} - -u32 audio_decoder_thread(void *params) -{ - int ret; - struct timeval time_start, time_end, time_wait; - AudioThreadParam *thread_params = (AudioThreadParam*)params; - - CmdData *in_data = thread_params->in_data; - AudioInputData *audio_input_data = thread_params->audio_input_data; - AudioInputFile *audio_input_file = thread_params->audio_input_file; - - suseconds_t pick_packet_delay, select_delay = 0, real_wait, other_delays = 1; - suseconds_t total_wait_time; - if (in_data->audio_data_conf.samplerate < 1024) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error: invalid audio sample rate: %d\n", in_data->audio_data_conf.samplerate)); - dc_audio_inout_data_end_signal(audio_input_data); - //FIXME: deadlock on the mpd thread. Reproduce with big_buck_bunny.mp4. - return 1; - } - total_wait_time = (int) (1000000.0 / (in_data->audio_data_conf.samplerate / (double) AUDIO_FRAME_SIZE)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("wait time : %ld\n", total_wait_time)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("sample-rate : %ld\n", in_data->audio_data_conf.samplerate)); - - if (!gf_list_count(in_data->audio_lst)) - return 0; - - while (1) { -// if (audio_input_file->mode == LIVE_MEDIA) { - gf_gettimeofday(&time_start, NULL); -// } - - ret = dc_audio_decoder_read(audio_input_file, audio_input_data); - if (ret == -2) { - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio decoder has no more frame to read.\n")); - break; - } - if (ret == -1) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occurred while reading audio frame.\n")); - break; - } - - if (in_data->exit_signal) { - dc_audio_inout_data_end_signal(audio_input_data); - break; - } - - if (audio_input_file->mode == LIVE_MEDIA) { - gf_gettimeofday(&time_end, NULL); - pick_packet_delay = ((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec; - time_wait.tv_sec = 0; - real_wait = total_wait_time - pick_packet_delay - select_delay - other_delays; - time_wait.tv_usec = real_wait; - - gf_gettimeofday(&time_start, NULL); - select(0, NULL, NULL, NULL, &time_wait); - gf_gettimeofday(&time_end, NULL); - - select_delay = (((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec) - real_wait; - } - } - - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio decoder is exiting...\n")); - return 0; -} - -u32 video_scaler_thread(void *params) -{ - int ret; - VideoThreadParam *thread_params = (VideoThreadParam *) params; - CmdData *in_data = thread_params->in_data; - VideoInputData *video_input_data = thread_params->video_input_data; - VideoScaledData *video_scaled_data = thread_params->video_scaled_data; - - if (!gf_list_count(in_data->video_lst)) - return 0; - - while (1) { - ret = dc_video_scaler_scale(video_input_data, video_scaled_data); - if (ret == -2) { - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video scaler has no more frame to read.\n")); - break; - } - } - - dc_video_scaler_end_signal(video_scaled_data); - - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("video scaler thread exit\n")); - return 0; -} - -u32 video_encoder_thread(void *params) -{ - int ret, shift, frame_nb, seg_frame_max, frag_frame_max, seg_nb = 0, loss_state = 0, quit = 0, real_video_seg_dur; - char name_to_delete[GF_MAX_PATH], name_to_send[GF_MAX_PATH]; - u64 start_utc, seg_utc; - segtime time_at_segment_start; - VideoMuxerType muxer_type = VIDEO_MUXER; - VideoThreadParam *thread_params = (VideoThreadParam*)params; - u32 sec, frac; - Bool init_mpd = GF_FALSE; - CmdData *in_data = thread_params->in_data; - int video_conf_idx = thread_params->video_conf_idx; - VideoDataConf *video_data_conf = (VideoDataConf*)gf_list_get(in_data->video_lst, video_conf_idx); - - VideoScaledData *video_scaled_data = thread_params->video_scaled_data; - int video_cb_size = (in_data->mode == LIVE_MEDIA || in_data->mode == LIVE_CAMERA) ? 1 : VIDEO_CB_DEFAULT_SIZE; - VideoOutputFile out_file; - - MessageQueue *mq = thread_params->mq; - MessageQueue *delete_seg_mq = thread_params->delete_seg_mq; - MessageQueue *send_seg_mq = thread_params->send_seg_mq; - - if (!gf_list_count(in_data->video_lst)) - return 0; - - seg_frame_max = (int)(video_data_conf->framerate * (float) (in_data->seg_dur / 1000.0)); - frag_frame_max = (int)(video_data_conf->framerate * (float) (in_data->frag_dur / 1000.0)); - optimize_seg_frag_dur(&seg_frame_max, &frag_frame_max); - - real_video_seg_dur = (int) (seg_frame_max * 1000.0 / (float) video_data_conf->framerate); - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[video_encoder] seg_frame_max=%d, frag_frame_max=%d, real_video_seg_dur=%d ms\n", seg_frame_max, frag_frame_max, real_video_seg_dur)); - - - if (seg_frame_max <= 0) - seg_frame_max = -1; - - if (dc_video_muxer_init(&out_file, video_data_conf, muxer_type, seg_frame_max, frag_frame_max, in_data->seg_marker, in_data->gdr, in_data->seg_dur, in_data->frag_dur, (u32) video_scaled_data->vsprop->video_input_data->frame_duration, in_data->gop_size, video_cb_size) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot init output video file.\n")); - in_data->exit_signal = 1; - return -1; - } - - if (dc_video_encoder_open(&out_file, video_data_conf, in_data->use_source_timing, video_scaled_data->sar) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video stream.\n")); - in_data->exit_signal = 1; - return -1; - } - - if (in_data->mode == LIVE_MEDIA || in_data->mode == LIVE_CAMERA) { - init_mpd = GF_TRUE; - } - - - time_at_segment_start.ntpts = 0; - start_utc = gf_net_get_utc(); - - while (1) { - frame_nb = 0; - //log time at segment start, because segment availabilityStartTime is computed from AST anchor + segment duration - //logging at the end of the segment production will induce one segment delay - time_at_segment_start.segnum = seg_nb; - time_at_segment_start.utc_time = gf_net_get_utc(); - gf_net_get_ntp(&sec, &frac); - -#ifndef GPAC_DISABLE_LOG - if (gf_log_tool_level_on(GF_LOG_DASH, GF_LOG_INFO)) { - if (time_at_segment_start.ntpts) { - u32 ref_sec, ref_frac; - Double tr, t; - ref_sec = (time_at_segment_start.ntpts>>32) & 0xFFFFFFFFULL; - ref_frac = (u32) (time_at_segment_start.ntpts & 0xFFFFFFFFULL); - tr = ref_sec * 1000.0; - tr += ref_frac*1000.0 /0xFFFFFFFF; - t = sec * 1000.0; - t += frac*1000.0 /0xFFFFFFFF; - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] NTP diff since last segment start in msec is %f\n", t - tr)); - - } - } -#endif - - time_at_segment_start.ntpts = sec; - time_at_segment_start.ntpts <<= 32; - time_at_segment_start.ntpts |= frac; - - //force writing MPD before any encoding happens (eg don't wait for the end of the first segment) - if (init_mpd) { - init_mpd = GF_FALSE; - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Initial MPD publish at UTC "LLU" ms\n", time_at_segment_start.utc_time)); - dc_message_queue_put(mq, &time_at_segment_start, sizeof(time_at_segment_start)); - } - - assert(! out_file.segment_started); - - if (dc_video_muxer_open(&out_file, in_data->out_dir, video_data_conf->filename, seg_nb+1) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video file.\n")); - in_data->exit_signal = 1; - return -1; - } -// fprintf(stdout, "Header size: %d\n", ret); - while (1) { - //we have the RAP already encoded, skip coder - if (loss_state == 2) { - ret = 1; - loss_state = 0; - } else { - ret = dc_video_encoder_encode(&out_file, video_scaled_data); - } - - if (ret == -2) { - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video encoder has no more data to encode.\n")); - quit = 1; - break; - } - if (ret == -1) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occured while writing video frame.\n")); - quit = 1; - break; - } - - if (ret > 0) { - int r; - - /*resync at first RAP: flush current broken segment and restart next one on rap*/ - if ((loss_state==1) && out_file.codec_ctx->coded_frame->key_frame) { - loss_state = 2; - break; - } - - r = dc_video_muxer_write(&out_file, frame_nb, in_data->insert_utc ? GF_TRUE : GF_FALSE); - if (r < 0) { - quit = 1; - in_data->exit_signal = 1; - break; - } else if (r == 1) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("fragment is written!\n")); - if (in_data->send_message == 1) { - snprintf(name_to_send, sizeof(name_to_send), "%s/%s_%d_gpac.m4s", in_data->out_dir, video_data_conf->filename, seg_nb); - dc_message_queue_put(send_seg_mq, name_to_send, sizeof(name_to_send)); - } - - break; - } - - frame_nb++; - } - } - - dc_video_muxer_close(&out_file); - - // If system is live, - // Send the time that a segment is available to MPD generator thread. - if (in_data->mode == LIVE_MEDIA || in_data->mode == LIVE_CAMERA) { - //check we don't loose sync - int diff; - int seg_diff; - seg_utc = gf_net_get_utc(); - diff = (int) (seg_utc - start_utc); - - //if seg UTC is after next segment UTC (current ends at seg_nb+1, next at seg_nb+2), adjust numbers - if (diff > (seg_nb+2) * real_video_seg_dur) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff %d bigger than segment duration %d - some frame where probably lost. Adjusting\n", out_file.rep_id, diff, seg_nb)); - - while (diff > (seg_nb+2) * real_video_seg_dur) { - seg_nb++; - - //do a rough estimate of losses to adjust timing... - if (! in_data->use_source_timing) { - out_file.first_dts_in_fragment += out_file.codec_ctx->time_base.den; - } - } - //wait for RAP to cut next segment - loss_state = 1; - } else { -#define SYNC_SAFE 800 - - seg_diff = diff; - seg_diff -= (seg_nb+1) * real_video_seg_dur; - if (seg_diff > SYNC_SAFE) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff at segment close: %d is higher than cumulated segment duration %d (diff %d) - frame rate is probably not correct!\n", out_file.rep_id, diff, (seg_nb+1) * in_data->seg_dur, seg_diff)); - } - else if (seg_diff < -SYNC_SAFE) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff at segment close: %d is lower than cumulated segment duration %d (diff %d) - frame rate is probably not correct or frames were lost!\n", out_file.rep_id, diff, (seg_nb+1) * in_data->seg_dur, seg_diff)); - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff at segment close: %d - cumulated segment duration %d (diff %d)\n", out_file.rep_id, diff, (seg_nb+1) * in_data->seg_dur, seg_diff)); - } - } - - //time_t t = time(NULL); - dc_message_queue_put(mq, &time_at_segment_start, sizeof(time_at_segment_start)); - } - - if ((in_data->time_shift != -1)) { - shift = 1000 * in_data->time_shift / in_data->seg_dur; - if (seg_nb > shift) { - snprintf(name_to_delete, sizeof(name_to_delete), "%s/%s_%d_gpac.m4s", in_data->out_dir, video_data_conf->filename, (seg_nb - shift)); - dc_message_queue_put(delete_seg_mq, name_to_delete, sizeof(name_to_delete)); - } - } - - seg_nb++; - - if (quit) - break; - } - - // If system is not live, - // Send the duration of the video - if (in_data->mode == ON_DEMAND) { - if (thread_params->video_conf_idx == 0) { - int dur = (seg_nb * seg_frame_max * 1000) / video_data_conf->framerate; - int dur_tot = (out_file.codec_ctx->frame_number * 1000) - / video_data_conf->framerate; - if (dur > dur_tot) - dur = dur_tot; - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Duration: %d \n", dur)); - dc_message_queue_put(mq, &dur, sizeof(dur)); - } - } - - /* Close output video file */ - dc_video_encoder_close(&out_file); - - dc_video_muxer_free(&out_file); - - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("video encoder thread exit\n")); - return 0; -} - -u32 audio_encoder_thread(void *params) -{ - int ret, exit_loop = 0, quit = 0, seg_nb = 0, frame_per_seg, frame_per_frag, frame_nb, shift, real_audio_seg_dur; - //int seg_frame_max; - //int frag_frame_max; - //int audio_frame_size = AUDIO_FRAME_SIZE; - char name_to_delete[GF_MAX_PATH]; - u64 start_utc, seg_utc; - segtime time_at_segment_start; - Bool check_first_seg_utc = GF_TRUE; - - AudioMuxerType muxer_type = AUDIO_MUXER; - AudioThreadParam *thread_params = (AudioThreadParam *) params; - - CmdData *in_data = thread_params->in_data; - int audio_conf_idx = thread_params->audio_conf_idx; - AudioDataConf *audio_data_conf = (AudioDataConf*)gf_list_get(in_data->audio_lst, audio_conf_idx); - - AudioInputData *audio_input_data = thread_params->audio_input_data; - AudioOutputFile audio_output_file; - - MessageQueue *mq = thread_params->mq; - MessageQueue *delete_seg_mq = thread_params->delete_seg_mq; - - if (!gf_list_count(in_data->audio_lst)) - return 0; - - //seg_frame_max = audio_data_conf->samplerate - // * (float) (in_data->seg_dur / 1000.0); - - //frag_frame_max = audio_data_conf->samplerate * (float) (in_data->frag_dur / 1000.0); - //if (seg_frame_max <= 0) - // seg_frame_max = -1; - - if (dc_audio_encoder_open(&audio_output_file, audio_data_conf) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output audio stream.\n")); - in_data->exit_signal = 1; - return -1; - } - - frame_per_seg = (int)((audio_data_conf->samplerate / (double) audio_output_file.codec_ctx->frame_size) * (in_data->seg_dur / 1000.0)); - frame_per_frag = (int)((audio_data_conf->samplerate / (double) audio_output_file.codec_ctx->frame_size) * (in_data->frag_dur / 1000.0)); - optimize_seg_frag_dur(&frame_per_seg, &frame_per_frag); - - real_audio_seg_dur = (int) (frame_per_seg * (double) audio_output_file.codec_ctx->frame_size * 1000.0 / (double) audio_data_conf->samplerate); - GF_LOG(GF_LOG_INFO, GF_LOG_DASH,("[audio_encoder] frame_per_seg=%d, frame_per_frag=%d, real_audio_seg_dur=%d ms\n", frame_per_seg, frame_per_frag, real_audio_seg_dur) ); - - if (dc_audio_muxer_init(&audio_output_file, audio_data_conf, muxer_type, frame_per_seg, frame_per_frag, in_data->seg_marker) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot init output audio.\n")); - in_data->exit_signal = 1; - return -1; - } - - start_utc = gf_net_get_utc(); - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[audio_encoder] start_utc="LLU"\n", start_utc)); - - while (1) { - //logging at the end of the segment production will induce one segment delay - time_at_segment_start.utc_time = gf_net_get_utc(); - time_at_segment_start.ntpts = gf_net_get_ntp_ts(); - - frame_nb = 0; - quit = 0; - - if (dc_audio_muxer_open(&audio_output_file, in_data->out_dir, audio_data_conf->filename, seg_nb+1) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output audio.\n")); - in_data->exit_signal = 1; - return -1; - } - - while (1) { - exit_loop = 0; -// if (frame_per_seg > 0) { -// if (frame_nb == frame_per_seg) { -// -// //if (dc_audio_encoder_flush(&audio_output_file, audio_input_data) == 0) { -// // dc_audio_muxer_write(&audio_output_file); -// // frame_nb++;//= audio_output_file.codec_ctx->frame_size; //audio_output_file.acc_samples; -// //} -// -// exit_loop = 1; -// break; -// } -// } - - audio_output_file.frame_ntp = gf_net_get_ntp_ts(); - ret = dc_audio_encoder_read(&audio_output_file, audio_input_data); - if (ret == -2) { - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio encoder has no more data to encode.\n")); - //if (dc_audio_encoder_flush(&audio_output_file, audio_input_data) == 0) { - // dc_audio_muxer_write(&audio_output_file); - // frame_nb++;//= audio_output_file.codec_ctx->frame_size; //audio_output_file.acc_samples; - //} - quit = 1; - break; - } - - while (1) { - ret = dc_audio_encoder_encode(&audio_output_file, audio_input_data); - if (ret == 1) { - break; - } - if (ret == -1) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occured while encoding audio frame.\n")); - quit = 1; - break; - } - - ret = dc_audio_muxer_write(&audio_output_file, frame_nb, in_data->insert_utc); - if (ret == -1) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occured while writing audio frame.\n")); - quit = 1; - break; - } - - if (ret == 1) { - exit_loop = 1; - break; - } - - frame_nb++; //= audio_output_file.codec_ctx->frame_size; //audio_output_file.acc_samples; - } - - if (exit_loop || quit) - break; - } - - dc_audio_muxer_close(&audio_output_file); - - // Send the time that a segment is available to MPD generator thread. - if (in_data->mode == LIVE_CAMERA || in_data->mode == LIVE_MEDIA) { - int diff; - if (check_first_seg_utc) { - u64 now = gf_net_get_utc(); - check_first_seg_utc = GF_FALSE; - - diff = (int) (now - time_at_segment_start.utc_time); - if (diff < real_audio_seg_dur / 2) { - u32 sec, frac, ms; - s32 left, nb_s; - gf_net_get_ntp(&sec, &frac); - nb_s = real_audio_seg_dur/1000; - sec -= nb_s; - ms = (u32) ((u64) 1000 * frac / 0xFFFFFFFF); - left = ms; - left -= (s32) (real_audio_seg_dur - 1000*nb_s); - while (left<0) { - left += 1000; - sec-=1; - } - time_at_segment_start.ntpts = sec; - time_at_segment_start.ntpts <<= 32; - time_at_segment_start.ntpts |= (u32) ((0xFFFFFFFF*left)/1000); - - start_utc = time_at_segment_start.utc_time = now - real_audio_seg_dur; - GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[audio_encoder] First segment produced faster (%d ms) than duration (%d ms) probably due to HW buffers - adjusting ast\n", diff, real_audio_seg_dur)); - } - } - if (thread_params->audio_conf_idx == 0) { - - //check we don't loose sync - seg_utc = gf_net_get_utc(); - diff = (int) (seg_utc - start_utc); - //if seg UTC is after next segment UTC (current ends at seg_nb+1, next at seg_nb+2), adjust numbers - if (diff > (seg_nb+2) * real_audio_seg_dur) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[audio_encoder] UTC dur %d bigger than segment duration %d - some frame where probably lost. Adjusting\n", diff, seg_nb)); - while (diff > (seg_nb+2) * real_audio_seg_dur) { - seg_nb++; - } - } - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[audio_encoder] UTC dur %d - cumulated segment duration %d (diff %d ms)\n", diff, (seg_nb+1) * real_audio_seg_dur, diff - (seg_nb+1) * real_audio_seg_dur)); - - - time_at_segment_start.segnum = seg_nb; - dc_message_queue_put(mq, &time_at_segment_start, sizeof(time_at_segment_start)); - } - } - - if (in_data->time_shift != -1) { - shift = 1000 * in_data->time_shift / in_data->seg_dur; - if (seg_nb > shift) { - snprintf(name_to_delete, sizeof(name_to_delete), "%s/%s_%d_gpac.m4s", in_data->out_dir, audio_data_conf->filename, (seg_nb - shift)); - dc_message_queue_put(delete_seg_mq, name_to_delete, sizeof(name_to_delete)); - } - } - - seg_nb++; - - if (quit) - break; - } - - // If system is not live, - // Send the duration of the video - if (in_data->mode == ON_DEMAND) { - if (thread_params->audio_conf_idx == 0) { - int dur = (seg_nb * audio_output_file.codec_ctx->frame_size * frame_per_seg * 1000) / audio_data_conf->samplerate; - int dur_tot = (audio_output_file.codec_ctx->frame_number * audio_output_file.codec_ctx->frame_size * 1000) / audio_data_conf->samplerate; - if (dur > dur_tot) - dur = dur_tot; - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Duration: %d \n", dur)); - dc_message_queue_put(mq, &dur, sizeof(dur)); - } - } - - dc_audio_muxer_free(&audio_output_file); - - /* Close output audio file */ - dc_audio_encoder_close(&audio_output_file); - - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio encoder is exiting...\n")); - return 0; -} - -int dc_run_controler(CmdData *in_data) -{ - int ret = 0; - u32 video_cb_size = VIDEO_CB_DEFAULT_SIZE; - u32 i, j; - - ThreadParam keyboard_th_params; - ThreadParam mpd_th_params; - ThreadParam delete_seg_th_params; - ThreadParam send_frag_th_params; - - //Video parameters - VideoThreadParam vdecoder_th_params; - VideoThreadParam *vencoder_th_params = (VideoThreadParam*)alloca(gf_list_count(in_data->video_lst) * sizeof(VideoThreadParam)); - VideoInputData video_input_data; - VideoInputFile *video_input_file[MAX_SOURCE_NUMBER]; - VideoScaledDataList video_scaled_data_list; - VideoThreadParam *vscaler_th_params = NULL; - - //Audio parameters - AudioThreadParam adecoder_th_params; - AudioThreadParam *aencoder_th_params = (AudioThreadParam*)alloca(gf_list_count(in_data->audio_lst) * sizeof(AudioThreadParam)); - AudioInputData audio_input_data; - AudioInputFile audio_input_file; - - MessageQueue mq; - MessageQueue delete_seg_mq; - MessageQueue send_frag_mq; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Controler init at UTC "LLU"\n", gf_net_get_utc() )); - dc_register_libav(); - - for (i = 0; i < MAX_SOURCE_NUMBER; i++) - video_input_file[i] = (VideoInputFile*)gf_malloc(sizeof(VideoInputFile)); - - dc_message_queue_init(&mq); - dc_message_queue_init(&delete_seg_mq); - dc_message_queue_init(&send_frag_mq); - - memset(&audio_input_data, 0, sizeof(AudioInputData));; - memset(&audio_input_file, 0, sizeof(AudioInputFile)); - memset(&video_input_data, 0, sizeof(VideoInputData)); - - - if (in_data->mode == LIVE_CAMERA || in_data->mode == LIVE_MEDIA) - video_cb_size = 1; - - if (strcmp(in_data->video_data_conf.filename, "") != 0) { - dc_video_scaler_list_init(&video_scaled_data_list, in_data->video_lst); - vscaler_th_params = (VideoThreadParam*)gf_malloc(video_scaled_data_list.size * sizeof(VideoThreadParam)); - - /* Open input video */ - if (dc_video_decoder_open(video_input_file[0], &in_data->video_data_conf, in_data->mode, in_data->no_loop, video_scaled_data_list.size) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input video.\n")); - ret = -1; - goto exit; - } - - if (dc_video_input_data_init(&video_input_data, /*video_input_file[0]->width, video_input_file[0]->height, - video_input_file[0]->pix_fmt,*/video_scaled_data_list.size, in_data->mode, MAX_SOURCE_NUMBER, video_cb_size) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot initialize audio data.\n")); - ret = -1; - goto exit; - } - - /* open other input videos for source switching */ - for (i = 0; i < gf_list_count(in_data->vsrc); i++) { - VideoDataConf *video_data_conf = (VideoDataConf*)gf_list_get(in_data->vsrc, i); - if (dc_video_decoder_open(video_input_file[i + 1], video_data_conf, LIVE_MEDIA, 1, video_scaled_data_list.size) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input video.\n")); - ret = -1; - goto exit; - } - } - - for (i=0; ivsrc) + 1; i++) { - dc_video_input_data_set_prop(&video_input_data, i, video_input_file[i]->width, video_input_file[i]->height, in_data->video_data_conf.crop_x, in_data->video_data_conf.crop_y, video_input_file[i]->pix_fmt, video_input_file[i]->sar); - } - - for (i=0; ivsrc) + 1; j++) { - dc_video_scaler_data_set_prop(&video_input_data, video_scaled_data_list.video_scaled_data[i], j); - } - } - - /* Initialize video decoder thread */ - vdecoder_th_params.thread = gf_th_new("video_decoder_thread"); - - for (i=0; ivideo_lst); i++) - vencoder_th_params[i].thread = gf_th_new("video_encoder_thread"); - } - - /* When video and audio share the same source, open it once. This allow to read from unicast streams */ - if (!strcmp(in_data->video_data_conf.filename, in_data->audio_data_conf.filename)) { - audio_input_file.av_fmt_ctx = video_input_file[0]->av_fmt_ctx; - video_input_file[0]->av_fmt_ctx_ref_cnt++; - audio_input_file.av_pkt_list = video_input_file[0]->av_pkt_list = gf_list_new(); - audio_input_file.av_pkt_list_mutex = video_input_file[0]->av_pkt_list_mutex = gf_mx_new("Demux AVPackets List"); - } - - if (strcmp(in_data->audio_data_conf.filename, "") != 0) { - /* Open input audio */ - if (dc_audio_decoder_open(&audio_input_file, &in_data->audio_data_conf, in_data->mode, in_data->no_loop, in_data->video_data_conf.framerate) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input audio.\n")); - ret = -1; - goto exit; - } - - if (dc_audio_input_data_init(&audio_input_data, in_data->audio_data_conf.channels, in_data->audio_data_conf.samplerate, gf_list_count(in_data->audio_lst), in_data->mode) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot initialize audio data.\n")); - ret = -1; - goto exit; - } - - /* Initialize audio decoder thread */ - adecoder_th_params.thread = gf_th_new("audio_decoder_thread"); - - /* Initialize audio encoder threads */ - for (i = 0; i < gf_list_count(in_data->audio_lst); i++) - aencoder_th_params[i].thread = gf_th_new("video_encoder_thread"); - } - - /******** Keyboard controler Thread ********/ - - /* Initialize keyboard controller thread */ - keyboard_th_params.thread = gf_th_new("keyboard_thread"); - - /* Create keyboard controller thread */ - keyboard_th_params.in_data = in_data; - if (gf_th_run(keyboard_th_params.thread, keyboard_thread, (void *)&keyboard_th_params) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for keyboard_thread.\n")); - } - - /********************************************/ - - //Communication between decoder and audio encoder - for (i = 0; i < gf_list_count(in_data->audio_lst); i++) { - AudioDataConf *tmadata = (AudioDataConf*)gf_list_get(in_data->audio_lst, i); - tmadata->channels = in_data->audio_data_conf.channels; - tmadata->samplerate = in_data->audio_data_conf.samplerate; - } - - //Communication between decoder and video encoder - for (i = 0; i < gf_list_count(in_data->video_lst); i++) { - VideoDataConf *tmvdata = (VideoDataConf*)gf_list_get(in_data->video_lst, i); - tmvdata->framerate = in_data->video_data_conf.framerate; - if (in_data->use_source_timing) { - tmvdata->time_base = in_data->video_data_conf.time_base; - } - } - - /******** MPD Thread ********/ - - /* Initialize MPD generator thread */ - mpd_th_params.thread = gf_th_new("mpd_thread"); - - /* Create MPD generator thread */ - mpd_th_params.in_data = in_data; - mpd_th_params.mq = &mq; - if (gf_th_run(mpd_th_params.thread, mpd_thread, (void *)&mpd_th_params) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for mpd_thread.\n")); - } - - - if (strcmp(in_data->video_data_conf.filename, "") != 0) { - /* Create video decoder thread */ - vdecoder_th_params.in_data = in_data; - vdecoder_th_params.video_input_data = &video_input_data; - vdecoder_th_params.video_input_file = video_input_file; - if (gf_th_run(vdecoder_th_params.thread, video_decoder_thread, (void *) &vdecoder_th_params) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for video_decoder_thread.\n")); - } - - while ((in_data->mode == LIVE_CAMERA) && !video_input_data.frame_duration) { - gf_sleep(0); - } - } - - if (strcmp(in_data->audio_data_conf.filename, "") != 0) { - /* Create audio decoder thread */ - adecoder_th_params.in_data = in_data; - adecoder_th_params.audio_input_data = &audio_input_data; - adecoder_th_params.audio_input_file = &audio_input_file; - if (gf_th_run(adecoder_th_params.thread, audio_decoder_thread, (void *) &adecoder_th_params) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for audio_decoder_thread.\n")); - } - } - - /****************************/ - - if (strcmp(in_data->video_data_conf.filename, "") != 0) { - /* Create video encoder threads */ - for (i=0; ivideo_lst); i++) { - VideoDataConf * video_data_conf = (VideoDataConf*)gf_list_get(in_data->video_lst, i); - - vencoder_th_params[i].in_data = in_data; - vencoder_th_params[i].video_conf_idx = i; - vencoder_th_params[i].video_scaled_data = dc_video_scaler_get_data(&video_scaled_data_list, video_data_conf->width, video_data_conf->height); - - vencoder_th_params[i].mq = &mq; - vencoder_th_params[i].delete_seg_mq = &delete_seg_mq; - vencoder_th_params[i].send_seg_mq = &send_frag_mq; - - if (gf_th_run(vencoder_th_params[i].thread, video_encoder_thread, (void*)&vencoder_th_params[i]) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for video_encoder_thread.\n")); - } - } - - /* Create video scaler threads */ - for (i=0; iaudio_data_conf.filename, "") != 0) { - /* Create audio encoder threads */ - for (i = 0; i < gf_list_count(in_data->audio_lst); i++) { - aencoder_th_params[i].in_data = in_data; - aencoder_th_params[i].audio_conf_idx = i; - aencoder_th_params[i].audio_input_data = &audio_input_data; - - aencoder_th_params[i].mq = &mq; - aencoder_th_params[i].delete_seg_mq = &delete_seg_mq; - aencoder_th_params[i].send_seg_mq = &send_frag_mq; - - if (gf_th_run(aencoder_th_params[i].thread, audio_encoder_thread, (void *) &aencoder_th_params[i]) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for audio_encoder_thread.\n")); - } - } - } - - if (in_data->time_shift != -1) { - /* Initialize delete segment thread */ - delete_seg_th_params.thread = gf_th_new("delete_seg_thread"); - delete_seg_th_params.in_data = in_data; - delete_seg_th_params.mq = &delete_seg_mq; - if (gf_th_run(delete_seg_th_params.thread, delete_seg_thread, (void *) &delete_seg_th_params) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for delete_seg_thread.\n")); - } - } - - if (in_data->send_message == 1) { - /* Initialize delete segment thread */ - send_frag_th_params.thread = gf_th_new("send_frag_event_thread"); - send_frag_th_params.in_data = in_data; - send_frag_th_params.mq = &send_frag_mq; - if (gf_th_run(send_frag_th_params.thread, send_frag_event, (void *) &send_frag_th_params) != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for send_frag_event_thread.\n")); - } - } - - fprintf(stdout, "Press q or Q to exit...\n"); - - if (strcmp(in_data->audio_data_conf.filename, "") != 0) { - /* Wait for and destroy audio decoder threads */ - gf_th_stop(adecoder_th_params.thread); - gf_th_del(adecoder_th_params.thread); - } - - if (strcmp(in_data->video_data_conf.filename, "") != 0) { - /* Wait for and destroy video decoder threads */ - gf_th_stop(vdecoder_th_params.thread); - gf_th_del(vdecoder_th_params.thread); - } - - if (strcmp(in_data->audio_data_conf.filename, "") != 0) { - /* Wait for and destroy audio encoder threads */ - for (i = 0; i < gf_list_count(in_data->audio_lst); i++) { - gf_th_stop(aencoder_th_params[i].thread); - gf_th_del(aencoder_th_params[i].thread); - } - } - - if (strcmp(in_data->video_data_conf.filename, "") != 0) { - /* Wait for and destroy video encoder threads */ - for (i=0; ivideo_lst); i++) { - gf_th_stop(vencoder_th_params[i].thread); - gf_th_del(vencoder_th_params[i].thread); - } - - /* Wait for and destroy video scaler threads */ - for (i=0; iexit_signal = 1; - - /********** Keyboard thread ***********/ - - /* Wait for and destroy keyboard controler thread */ - gf_th_stop(keyboard_th_params.thread); - gf_th_del(keyboard_th_params.thread); - - /**************************************/ - - /********** MPD generator thread ***********/ - - /* Wait for and destroy MPD generator thread */ - gf_th_stop(mpd_th_params.thread); - gf_th_del(mpd_th_params.thread); - - /**************************************/ - - if (in_data->time_shift != -1) { - // dc_message_queue_flush(&delete_seg_mq); - /* Wait for and destroy delete segment thread */ - gf_th_stop(delete_seg_th_params.thread); - gf_th_del(delete_seg_th_params.thread); - } - - if (in_data->send_message == 1) { - /* Wait for and destroy delete segment thread */ - gf_th_stop(send_frag_th_params.thread); - gf_th_del(send_frag_th_params.thread); - } - -exit: - if (strcmp(in_data->audio_data_conf.filename, "") != 0) { - /* Destroy audio input data */ - dc_audio_input_data_destroy(&audio_input_data); - /* Close input audio */ - dc_audio_decoder_close(&audio_input_file); - } - - if (strcmp(in_data->video_data_conf.filename, "") != 0) { - /* Destroy video input data */ - dc_video_input_data_destroy(&video_input_data); - - for (i = 0; i < gf_list_count(in_data->vsrc); i++) { - /* Close input video */ - dc_video_decoder_close(video_input_file[i]); - } - - for (i=0; i - -//anything different is broken in dash cast (random frame inversions at encoding time ...) -#define VIDEO_CB_DEFAULT_SIZE 1 - - -/* - * This structure corresponds to an - * entry of video configuration in the - * configuration file. - */ -typedef struct { - /* video file name */ - char filename[GF_MAX_PATH]; - /* video format */ - char format[GF_MAX_PATH]; - /* video format */ - char pixel_format[GF_MAX_PATH]; - /* v4l2 format */ - char v4l2f[GF_MAX_PATH]; - /* left crop */ - int crop_x; - /* top crop */ - int crop_y; - /* video final width */ - int width; - /* video final height */ - int height; - /* video bitrate */ - int bitrate; - /* video frame rate */ - int framerate; - /* video codec */ - char codec[GF_MAX_PATH]; - /* RFC6381 codec name, only valid when VIDEO_MUXER == GPAC_INIT_VIDEO_MUXER_AVC1 */ - char codec6381[GF_MAX_PATH]; - /* custom parameter to be passed directly to the encoder - free it once you're done */ - char custom[GF_MAX_PATH]; - /*low delay is used*/ - int low_delay; - /*demuxer buffer size or 0 if default FFmpeg one is used*/ - int demux_buffer_size; - - /* used for source switching */ - char source_id[GF_MAX_PATH]; - time_t start_time; - time_t end_time; - - //copy over from source file - AVRational time_base; - u64 frame_duration; -} VideoDataConf; - -typedef struct { - /* Width, height and pixel format of the input video. */ - int width; - int height; - int crop_x, crop_y; - int pix_fmt; - AVRational sar; -} VideoInputProp; - -/* - * VideoInputData is designed to keep the data - * of input video in a circular buffer. - * The circular buffer has its own mechanism for synchronization. - */ -typedef struct { - /* The circular buffer of the video frames after decoding. */ - CircularBuffer circular_buf; - /* The user of circular buffer has an index to it, which is in this variable. */ - Producer producer; - - VideoInputProp *vprop; - - /* Width, height and pixel format of the input video */ - //int width; - //int height; - //int pix_fmt; - u64 frame_duration; -} VideoInputData; - - -/* - * Each node in a circular buffer is a pointer. - * To use the circular buffer for video frame we must - * define the node. VideoDataNode simply contains - * an AVFrame. - */ -typedef struct { - AVFrame * vframe; - int source_number; - uint8_t nb_raw_frames_ref; - AVPacket raw_packet; - - u64 frame_ntp, frame_utc; -} VideoDataNode; - -void dc_video_data_set_default(VideoDataConf *video_data_conf); - -/* - * Initialize a VideoInputData. - * - * @param video_input_data [out] is the structure to be initialize. - * @param width [in] input video width - * @param height [in] input video height - * @param pixfmt [in] input video pixel format - * @param num_consumers [in] contains information on the number of users of circular buffer; - * which means the number of video encoders. - * @param live [in] indicates the system is live - * - * @return 0 on success, -1 on failure. - * - * @note Must use dc_video_data_destroy to free memory. - */ -int dc_video_input_data_init(VideoInputData *video_input_data,/* int width, int height, int pix_fmt,*/ int num_consumers, int mode, int num_producers, int video_cb_size); - -/* - * Set properties for a VideoInputData. - */ -void dc_video_input_data_set_prop(VideoInputData *video_input_data, int index, int width, int height, int crop_x, int crop_y, int pix_fmt, AVRational sar); - -/* - * Destroy a VideoInputData. - * - * @param video_input_data [in] the structure to be destroyed. - */ -void dc_video_input_data_destroy(VideoInputData *video_input_data); - -/* - * Signal to all the users of the circular buffer in the VideoInputData - * which the current node is the last node to consume. - * - * @param video_input_data [in] the structure to be signaled on. - */ -void dc_video_input_data_end_signal(VideoInputData *video_input_data); - -#endif /* VIDEO_DATA_H_ */ diff --git a/applications/dashcast/video_decoder.c b/applications/dashcast/video_decoder.c deleted file mode 100644 index 566e6cd..0000000 --- a/applications/dashcast/video_decoder.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 "video_decoder.h" -#include -#include - - -//#define DASHCAST_DEBUG_TIME_ - - -int dc_video_decoder_open(VideoInputFile *video_input_file, VideoDataConf *video_data_conf, int mode, int no_loop, int nb_consumers) -{ - s32 ret; - u32 i; - s32 open_res; - AVInputFormat *in_fmt = NULL; - AVDictionary *options = NULL; - AVCodecContext *codec_ctx; - AVCodec *codec; - - memset(video_input_file, 0, sizeof(VideoInputFile)); - - if (video_data_conf->width > 0 && video_data_conf->height > 0) { - char vres[16]; - snprintf(vres, sizeof(vres), "%dx%d", video_data_conf->width, video_data_conf->height); - ret = av_dict_set(&options, "video_size", vres, 0); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set video size %s.\n", vres)); - return -1; - } - } - - if (video_data_conf->framerate > 0) { - char vfr[16]; - snprintf(vfr, sizeof(vfr), "%d", video_data_conf->framerate); - ret = av_dict_set(&options, "framerate", vfr, 0); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set video framerate %s.\n", vfr)); - return -1; - } - } - - if (strlen(video_data_conf->pixel_format)) { - ret = av_dict_set(&options, "pixel_format", video_data_conf->pixel_format, 0); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set pixel format %s.\n", video_data_conf->pixel_format)); - return -1; - } - } - -#ifndef WIN32 - if (strcmp(video_data_conf->v4l2f, "") != 0) { - ret = av_dict_set(&options, "input_format", video_data_conf->v4l2f, 0); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set input format %s.\n", video_data_conf->v4l2f)); - return -1; - } - } -#endif - - if (strcmp(video_data_conf->format, "") != 0) { - in_fmt = av_find_input_format(video_data_conf->format); - if (in_fmt == NULL) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find the format %s.\n", video_data_conf->format)); - return -1; - } - } - - video_input_file->av_fmt_ctx = NULL; - - if (video_data_conf->demux_buffer_size) { - char szBufSize[100]; - sprintf(szBufSize, "%d", video_data_conf->demux_buffer_size); - ret = av_dict_set(&options, "buffer_size", szBufSize, 0); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set demuxer's input buffer size.\n")); - return -1; - } - } - - /* Open video */ - open_res = avformat_open_input(&video_input_file->av_fmt_ctx, video_data_conf->filename, in_fmt, options ? &options : NULL); - if ( (open_res < 0) && !stricmp(video_data_conf->filename, "screen-capture-recorder") ) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Buggy screen capture input (open failed with code %d), retrying without specifying resolution\n", open_res)); - av_dict_set(&options, "video_size", NULL, 0); - open_res = avformat_open_input(&video_input_file->av_fmt_ctx, video_data_conf->filename, in_fmt, options ? &options : NULL); - } - - if ( (open_res < 0) && options) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error %d opening input - retrying without options\n", open_res)); - av_dict_free(&options); - open_res = avformat_open_input(&video_input_file->av_fmt_ctx, video_data_conf->filename, in_fmt, NULL); - } - - if (open_res < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open file %s\n", video_data_conf->filename)); - return -1; - } - - /* Retrieve stream information */ - if (avformat_find_stream_info(video_input_file->av_fmt_ctx, NULL) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find stream information\n")); - return -1; - } - - av_dump_format(video_input_file->av_fmt_ctx, 0, video_data_conf->filename, 0); - - /* Find the first video stream */ - video_input_file->vstream_idx = -1; - for (i = 0; i < video_input_file->av_fmt_ctx->nb_streams; i++) { - if (video_input_file->av_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - video_input_file->vstream_idx = i; - break; - } - } - if (video_input_file->vstream_idx == -1) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find a video stream\n")); - return -1; - } - - /* Get a pointer to the codec context for the video stream */ - codec_ctx = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->codec; - - /* Find the decoder for the video stream */ - codec = avcodec_find_decoder(codec_ctx->codec_id); - if (codec == NULL) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Codec is not supported.\n")); - if (!video_input_file->av_fmt_ctx_ref_cnt) - avformat_close_input(&video_input_file->av_fmt_ctx); - return -1; - } - - /* Open codec */ - if (avcodec_open2(codec_ctx, codec, NULL) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open codec.\n")); - if (!video_input_file->av_fmt_ctx_ref_cnt) - avformat_close_input(&video_input_file->av_fmt_ctx); - return -1; - } - - video_input_file->width = codec_ctx->width; - video_input_file->height = codec_ctx->height; - video_input_file->sar = codec_ctx->sample_aspect_ratio; - - video_input_file->pix_fmt = codec_ctx->pix_fmt; - if (codec_ctx->time_base.num==1) { - GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("AVCTX give frame duration of %d/%d - keeping requested rate %d, but this may result in unexpected behaviour.\n", codec_ctx->time_base.num, codec_ctx->time_base.den, video_data_conf->framerate )); - - if (codec_ctx->time_base.den==1000000) { - codec_ctx->time_base.num = codec_ctx->time_base.den / video_data_conf->framerate; - } - } - else if (video_data_conf->framerate >= 0 && codec_ctx->time_base.num) { - video_data_conf->framerate = codec_ctx->time_base.den / codec_ctx->time_base.num; - } - if (video_data_conf->framerate <= 1 || video_data_conf->framerate > 1000) { - const int num = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->avg_frame_rate.num; - const int den = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->avg_frame_rate.den == 0 ? 1 : video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->avg_frame_rate.den; - video_data_conf->framerate = num / den; - if (video_data_conf->framerate / 1000 != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Framerate %d was divided by 1000: %d\n", video_data_conf->framerate, video_data_conf->framerate/1000)); - video_data_conf->framerate = video_data_conf->framerate / 1000; - } - - if (video_data_conf->framerate <= 1 || video_data_conf->framerate > 1000) { - video_data_conf->framerate = num / den; - if (video_data_conf->framerate / 1000 != 0) { - video_data_conf->framerate = video_data_conf->framerate / 1000; - } - } - } - - if (video_data_conf->framerate <= 1 || video_data_conf->framerate > 1000) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Invalid input framerate %d (AVCTX timebase is %d/%d).\n", video_data_conf->framerate, codec_ctx->time_base.num, codec_ctx->time_base.den)); - return -1; - } - - video_data_conf->time_base = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->time_base; - video_input_file->mode = mode; - video_input_file->no_loop = no_loop; - video_input_file->nb_consumers = nb_consumers; - return 0; -} - -int dc_video_decoder_read(VideoInputFile *video_input_file, VideoInputData *video_input_data, int source_number, int use_source_timing, int is_live_capture, const int *exit_signal_addr) -{ -#ifdef DASHCAST_DEBUG_TIME_ - struct timeval start, end; - long elapsed_time; -#endif - AVPacket packet; - int ret, got_frame, already_locked = 0; - AVCodecContext *codec_ctx; - VideoDataNode *video_data_node; - - /* Get a pointer to the codec context for the video stream */ - codec_ctx = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->codec; - - /* Read frames */ - while (1) { -#ifdef DASHCAST_DEBUG_TIME_ - gf_gettimeofday(&start, NULL); -#endif - memset(&packet, 0, sizeof(AVPacket)); - ret = av_read_frame(video_input_file->av_fmt_ctx, &packet); -#ifdef DASHCAST_DEBUG_TIME_ - gf_gettimeofday(&end, NULL); - elapsed_time = (end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec); - fprintf(stdout, "fps: %f\n", 1000000.0/elapsed_time); -#endif - - /* If we demux for the audio thread, send the packet to the audio */ - if (video_input_file->av_fmt_ctx_ref_cnt && ((packet.stream_index != video_input_file->vstream_idx) || (ret == AVERROR_EOF))) { - AVPacket *packet_copy = NULL; - if (ret != AVERROR_EOF) { - GF_SAFEALLOC(packet_copy, AVPacket); - if (packet_copy) - memcpy(packet_copy, &packet, sizeof(AVPacket)); - } - - assert(video_input_file->av_pkt_list); - gf_mx_p(video_input_file->av_pkt_list_mutex); - gf_list_add(video_input_file->av_pkt_list, packet_copy); - gf_mx_v(video_input_file->av_pkt_list_mutex); - - if (ret != AVERROR_EOF) { - continue; - } - } - - if (ret == AVERROR_EOF) { - if (video_input_file->mode == LIVE_MEDIA && video_input_file->no_loop == 0) { - av_seek_frame(video_input_file->av_fmt_ctx, video_input_file->vstream_idx, 0, 0); - av_free_packet(&packet); - continue; - } - - dc_producer_lock(&video_input_data->producer, &video_input_data->circular_buf); - dc_producer_unlock_previous(&video_input_data->producer, &video_input_data->circular_buf); - video_data_node = (VideoDataNode *) dc_producer_produce(&video_input_data->producer, &video_input_data->circular_buf); - video_data_node->source_number = source_number; - /* Flush decoder */ - memset(&packet, 0, sizeof(AVPacket)); -#ifndef FF_API_AVFRAME_LAVC - avcodec_get_frame_defaults(video_data_node->vframe); -#else - av_frame_unref(video_data_node->vframe); -#endif - - avcodec_decode_video2(codec_ctx, video_data_node->vframe, &got_frame, &packet); - if (got_frame) { - dc_producer_advance(&video_input_data->producer, &video_input_data->circular_buf); - return 0; - } - - dc_producer_end_signal(&video_input_data->producer, &video_input_data->circular_buf); - dc_producer_unlock(&video_input_data->producer, &video_input_data->circular_buf); - return -2; - } - else if (ret < 0) - { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot read video frame.\n")); - continue; - } - - /* Is this a packet from the video stream? */ - if (packet.stream_index == video_input_file->vstream_idx) { - u32 nb_retry = 10; - while (!already_locked) { - if (dc_producer_lock(&video_input_data->producer, &video_input_data->circular_buf) < 0) { - if (!nb_retry) break; - gf_sleep(10); - nb_retry--; - continue; - } - dc_producer_unlock_previous(&video_input_data->producer, &video_input_data->circular_buf); - already_locked = 1; - } - if (!already_locked) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[dashcast] Live system dropped a video frame\n")); - continue; - } - - video_data_node = (VideoDataNode *) dc_producer_produce(&video_input_data->producer, &video_input_data->circular_buf); - video_data_node->source_number = source_number; - - /* Set video frame to default */ -#ifndef FF_API_AVFRAME_LAVC - avcodec_get_frame_defaults(video_data_node->vframe); -#else - av_frame_unref(video_data_node->vframe); -#endif - - video_data_node->frame_ntp = gf_net_get_ntp_ts(); - video_data_node->frame_utc = gf_net_get_utc(); - - /* Decode video frame */ - if (avcodec_decode_video2(codec_ctx, video_data_node->vframe, &got_frame, &packet) < 0) { - av_free_packet(&packet); - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while decoding video.\n")); - dc_producer_end_signal(&video_input_data->producer, &video_input_data->circular_buf); - dc_producer_unlock(&video_input_data->producer, &video_input_data->circular_buf); - return -1; - } - - /* Did we get a video frame? */ - if (got_frame) { - if (use_source_timing && is_live_capture) { - u64 pts; - if (video_input_file->pts_init == 0) { - video_input_file->pts_init = 1; - video_input_file->utc_at_init = gf_net_get_utc(); - video_input_file->first_pts = packet.pts; - video_input_file->prev_pts = 0; - video_input_data->frame_duration = 0; - } -#if 0 - if (video_input_file->pts_init && (video_input_file->pts_init!=3) ) { - if (packet.pts==AV_NOPTS_VALUE) { - video_input_file->pts_init=1; - } else if (video_input_file->pts_init==1) { - video_input_file->pts_init=2; - video_input_file->pts_dur_estimate = packet.pts; - } else if (video_input_file->pts_init==2) { - video_input_file->pts_init=3; - video_input_data->frame_duration = packet.pts - video_input_file->pts_dur_estimate; - video_input_file->sync_tolerance = 9*video_input_data->frame_duration/5; - //TODO - check with audio if sync is OK - } - } -#endif - - //move to 0-based PTS - if (packet.pts!=AV_NOPTS_VALUE) { - pts = packet.pts - video_input_file->first_pts; - } else { - pts = video_input_file->prev_pts + video_input_data->frame_duration; - } - - //check for drop frames -#ifndef GPAC_DISABLE_LOG - if (0 && gf_log_tool_level_on(GF_LOG_DASH, GF_LOG_WARNING)) { - if (pts - video_input_file->prev_pts > video_input_file->sync_tolerance) { - u32 nb_lost=0; - while (video_input_file->prev_pts + video_input_data->frame_duration + video_input_file->sync_tolerance < pts) { - video_input_file->prev_pts += video_input_data->frame_duration; - nb_lost++; - } - if (nb_lost) { - GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DashCast] Capture lost %d video frames \n", nb_lost)); - } - } - } -#endif - -#if 1 - if ((pts != video_input_file->prev_pts) && (video_input_file->pts_init == 1)) { - video_input_file->pts_init = 2; - video_input_data->frame_duration = pts - video_input_file->prev_pts; - video_input_file->sync_tolerance = 9*video_input_data->frame_duration/5; - } -#endif - - video_input_file->prev_pts = pts; - video_data_node->vframe->pts = pts; - } - - if (video_data_node->vframe->pts==AV_NOPTS_VALUE) { - if (!use_source_timing) { - video_data_node->vframe->pts = video_input_file->frame_decoded; - } else { - video_data_node->vframe->pts = video_data_node->vframe->pkt_pts; - } - } - video_input_file->frame_decoded++; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Video Frame TS "LLU" decoded at UTC "LLU" ms (frame duration %d)\n", video_data_node->vframe->pts, gf_net_get_utc(), video_input_data->frame_duration)); - - // For a decode/encode process we must free this memory. - //But if the input is raw and there is no need to decode then - // the packet is directly passed for decoded frame. We must wait until rescale is done before freeing it - - if (codec_ctx->codec->id == CODEC_ID_RAWVIDEO) { - if (is_live_capture && !video_input_data->frame_duration) { - } else { - video_data_node->nb_raw_frames_ref = video_input_file->nb_consumers; - - video_data_node->raw_packet = packet; - - dc_producer_advance(&video_input_data->producer, &video_input_data->circular_buf); - while (video_data_node->nb_raw_frames_ref && ! *exit_signal_addr) { - gf_sleep(0); - } - } - } else { - dc_producer_advance(&video_input_data->producer, &video_input_data->circular_buf); - av_free_packet(&packet); - } - return 0; - - } - } - - /* Free the packet that was allocated by av_read_frame */ - av_free_packet(&packet); - } - - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Unknown error while reading video frame.\n")); - return -1; -} - -void dc_video_decoder_close(VideoInputFile *video_input_file) -{ - /* Close the video format context */ - if (!video_input_file->av_fmt_ctx_ref_cnt) - avformat_close_input(&video_input_file->av_fmt_ctx); - - video_input_file->av_pkt_list = NULL; - video_input_file->av_pkt_list_mutex = NULL; -} diff --git a/applications/dashcast/video_encoder.c b/applications/dashcast/video_encoder.c deleted file mode 100644 index 875e0bd..0000000 --- a/applications/dashcast/video_encoder.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 "video_encoder.h" -#include "libavutil/opt.h" -#include "libavdevice/avdevice.h" - - -#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) - -#define _TOSTR(_val) #_val -#define TOSTR(_val) _TOSTR(_val) - -#endif - - -//#define DEBUG 1 - - -/** - * A function which pushes argument to a libav codec using its private data. - * param priv_data - * param options a list of space separated and ':' affected options (e.g. "a:b c:d e:f"). @options be non NULL. - */ -void build_dict(void *priv_data, const char *options) { - char *opt = gf_strdup(options); - char *tok = strtok(opt, "="); - char *tokval = NULL; - while (tok && (tokval=strtok(NULL, " "))) { - if (av_opt_set(priv_data, tok, tokval, 0) < 0) - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Unknown custom option \"%s\" with value \"%s\" in %s\n", tok, tokval, options)); - tok = strtok(NULL, "="); - } - gf_free(opt); -} - -int dc_video_encoder_open(VideoOutputFile *video_output_file, VideoDataConf *video_data_conf, Bool use_source_timing, AVRational sar) -{ - video_output_file->vbuf_size = 9 * video_data_conf->width * video_data_conf->height + 10000; - video_output_file->vbuf = (uint8_t *) av_malloc(video_output_file->vbuf_size); - video_output_file->video_data_conf = video_data_conf; - - video_output_file->codec = avcodec_find_encoder_by_name(video_data_conf->codec); - if (video_output_file->codec == NULL) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Output video codec %s not found\n", video_data_conf->codec)); - return -1; - } - - video_output_file->codec_ctx = avcodec_alloc_context3(video_output_file->codec); - - video_output_file->codec_ctx->codec_id = video_output_file->codec->id; - video_output_file->codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; - video_output_file->codec_ctx->bit_rate = video_data_conf->bitrate; - video_output_file->codec_ctx->width = video_data_conf->width; - video_output_file->codec_ctx->height = video_data_conf->height; - video_output_file->codec_ctx->sample_aspect_ratio = sar; - - video_output_file->codec_ctx->time_base.num = 1; - video_output_file->codec_ctx->time_base.den = video_output_file->gop_size ? video_output_file->gop_size : video_data_conf->framerate; - - video_output_file->use_source_timing = use_source_timing; - if (use_source_timing) { - //for avcodec to do rate allocation, we need to have ctx->timebase == 1/framerate - video_output_file->codec_ctx->time_base.den = video_data_conf->time_base.den; - video_output_file->codec_ctx->time_base.num = video_data_conf->time_base.num * video_data_conf->time_base.den / video_data_conf->framerate; - } - video_output_file->codec_ctx->pix_fmt = PIX_FMT_YUV420P; - video_output_file->codec_ctx->gop_size = video_data_conf->framerate; - -// video_output_file->codec_ctx->codec_id = video_codec->id; -// video_output_file->codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; -// video_output_file->codec_ctx->bit_rate = video_data_conf->bitrate; -// video_output_file->codec_ctx->width = video_data_conf->width; -// video_output_file->codec_ctx->height = video_data_conf->height; -// video_output_file->codec_ctx->time_base = (AVRational) {1 , -// video_output_file->video_data_conf->framerate}; -// video_output_file->codec_ctx->codec->pix_fmt = PIX_FMT_YUV420P; - video_output_file->codec_ctx->gop_size = video_data_conf->framerate; -// -// av_opt_set(video_output_file->codec_ctx->priv_data, "preset", "ultrafast", 0); -// av_opt_set(video_output_file->codec_ctx->priv_data, "tune", "zerolatency", 0); - - /* - video_output_file->codec_ctx->max_b_frames = 0; - video_output_file->codec_ctx->thread_count = 1; - video_output_file->codec_ctx->delay = 0; - video_output_file->codec_ctx->rc_lookahead = 0; - */ - - /* - * video_stream->codec->gosize = video_output_file->vfr; - * videoStream->codec->gosize = 1; - * video_stream->codec->rc_lookahead = 0; - * videoStream->time_base = (AVRational) {1 , 1000000}; - * videoStream->r_frame_rate = (AVRational) {outVideoCtx->video_framerate, 1}; - * av_opt_set(videoStream->codec->priv_data, "preset", "slow", 0); - * videoStream->codec->me_range = 16; - * videoStream->codec->max_qdiff = 4; - * videoStream->codec->qmin = 10; - * videoStream->codec->qmax = 51; - * videoStream->codec->qcompress = 0.6; - * videoStream->codec->profile = FF_PROFILE_H264_BASELINE; - * videoStream->codec->level = 10; - * - */ - - if ( strlen(video_data_conf->custom) ) { - build_dict(video_output_file->codec_ctx->priv_data, video_data_conf->custom); - } else if (video_data_conf->low_delay) { - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video Encoder: applying default options (preset=ultrafast tune=zerolatency)\n")); - av_opt_set(video_output_file->codec_ctx->priv_data, "vprofile", "baseline", 0); - av_opt_set(video_output_file->codec_ctx->priv_data, "preset", "ultrafast", 0); - av_opt_set(video_output_file->codec_ctx->priv_data, "tune", "zerolatency", 0); - if (strstr(video_data_conf->codec, "264")) { - av_opt_set(video_output_file->codec_ctx->priv_data, "x264opts", "no-mbtree:sliced-threads:sync-lookahead=0", 0); - } - } - - if (video_output_file->gdr) { - av_opt_set_int(video_output_file->codec_ctx->priv_data, "intra-refresh", 1, 0); - av_opt_set_int(video_output_file->codec_ctx->priv_data, "key-int", video_output_file->gdr, 0); - } - - //the global header gives access to the extradata (SPS/PPS) - video_output_file->codec_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; - - video_output_file->vstream_idx = 0;//video_stream->index; - - /* open the video codec - options are passed thru video_output_file->codec_ctx->priv_data */ - if (avcodec_open2(video_output_file->codec_ctx, video_output_file->codec, NULL) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video codec\n")); - return -1; - } - - video_output_file->rep_id = video_data_conf->filename; - return 0; -} - -int dc_video_encoder_encode(VideoOutputFile *video_output_file, VideoScaledData *video_scaled_data) -{ - VideoScaledDataNode *video_data_node; - int ret; - u64 time_spent; - int got_packet = 0; - AVPacket pkt; - - AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; - - //FIXME: deadlock when pressing 'q' with BigBuckBunny_640x360.m4v - ret = dc_consumer_lock(&video_output_file->consumer, &video_scaled_data->circular_buf); - if (ret < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Video encoder got an end of buffer!\n")); - return -2; - } - - if (video_scaled_data->circular_buf.size > 1) - dc_consumer_unlock_previous(&video_output_file->consumer, &video_scaled_data->circular_buf); - - video_data_node = (VideoScaledDataNode*)dc_consumer_consume(&video_output_file->consumer, &video_scaled_data->circular_buf); - - /* - * Set PTS (method 1) - */ - if (!video_output_file->use_source_timing) { - video_data_node->vframe->pts = video_codec_ctx->frame_number; - } - - time_spent = gf_sys_clock_high_res(); - /* Encoding video */ - av_init_packet(&pkt); - pkt.data = video_output_file->vbuf; - pkt.size = video_output_file->vbuf_size; - pkt.pts = pkt.dts = video_data_node->vframe->pkt_dts = video_data_node->vframe->pkt_pts = video_data_node->vframe->pts; - video_data_node->vframe->pict_type = 0; - video_data_node->vframe->width = video_codec_ctx->width; - video_data_node->vframe->height = video_codec_ctx->height; - video_data_node->vframe->format = video_codec_ctx->pix_fmt; - - -#ifdef LIBAV_ENCODE_OLD - if (!video_output_file->segment_started) - video_data_node->vframe->pict_type = FF_I_TYPE; - - video_output_file->encoded_frame_size = avcodec_encode_video(video_codec_ctx, video_output_file->vbuf, video_output_file->vbuf_size, video_data_node->vframe); - got_packet = video_output_file->encoded_frame_size>=0 ? 1 : 0; -#else - //this is correct but unfortunately doesn't work with some versions of FFMPEG (output is just grey video ...) - if (!video_output_file->segment_started) - video_data_node->vframe->pict_type = AV_PICTURE_TYPE_I; - - video_output_file->encoded_frame_size = avcodec_encode_video2(video_codec_ctx, &pkt, video_data_node->vframe, &got_packet); -#endif - - time_spent = gf_sys_clock_high_res() - time_spent; - //this is not true with libav ! -#ifndef GPAC_USE_LIBAV - if (video_output_file->encoded_frame_size >= 0) - video_output_file->encoded_frame_size = pkt.size; -#else - if (got_packet) - video_output_file->encoded_frame_size = pkt.size; -#endif - if (video_output_file->encoded_frame_size >= 0) { - if (got_packet) { - video_codec_ctx->coded_frame->pts = video_codec_ctx->coded_frame->pkt_pts = pkt.pts; - video_codec_ctx->coded_frame->pkt_dts = pkt.dts; - video_codec_ctx->coded_frame->key_frame = (pkt.flags & AV_PKT_FLAG_KEY) ? 1 : 0; - video_output_file->frame_ntp = video_data_node->frame_ntp; - video_output_file->frame_utc = video_data_node->frame_utc; - } - } - - dc_consumer_advance(&video_output_file->consumer); - - if (video_scaled_data->circular_buf.size == 1) - dc_consumer_unlock_previous(&video_output_file->consumer, &video_scaled_data->circular_buf); - - if (video_output_file->encoded_frame_size < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error occured while encoding video frame.\n")); - return -1; - } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Video %s Frame TS "LLU" encoded at UTC "LLU" ms in "LLU" us\n", video_output_file->rep_id, /*video_data_node->source_number, */video_data_node->vframe->pts, gf_net_get_utc(), time_spent )); - - /* if zero size, it means the image was buffered */ -// if (out_size > 0) { -// av_init_packet(&pkt); -// pkt.data = NULL; -// pkt.size = 0; -// -// if (video_codec_ctx->coded_frame->pts != AV_NOPTS_VALUE) { -// pkt.pts = av_rescale_q(video_codec_ctx->coded_frame->pts, -// video_codec_ctx->time_base, video_stream->time_base); -// } -// -// -// if (video_codec_ctx->coded_frame->key_frame) -// pkt.flags |= AV_PKT_FLAG_KEY; -// -// pkt.stream_index = video_stream->index; -// pkt.data = video_output_file->vbuf; -// pkt.size = out_size; -// -// // write the compressed frame in the media file -// if (av_interleaved_write_frame(video_output_file->av_fmt_ctx, &pkt) -// != 0) { -// GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Writing frame is not successful\n")); -// return -1; -// } -// -// av_free_packet(&pkt); -// -// } - - return video_output_file->encoded_frame_size; -} - -void dc_video_encoder_close(VideoOutputFile *video_output_file) -{ -// int i; -// -// // free the streams -// for (i = 0; i < video_output_file->av_fmt_ctx->nb_streams; i++) { -// avcodec_close(video_output_file->av_fmt_ctx->streams[i]->codec); -// av_freep(&video_output_file->av_fmt_ctx->streams[i]->info); -// } - av_free(video_output_file->vbuf); - avcodec_close(video_output_file->codec_ctx); - av_free(video_output_file->codec_ctx); -} diff --git a/applications/dashcast/video_muxer.c b/applications/dashcast/video_muxer.c deleted file mode 100644 index b6693bb..0000000 --- a/applications/dashcast/video_muxer.c +++ /dev/null @@ -1,973 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Arash Shafiei - * Copyright (c) Telecom ParisTech 2000-2013 - * All rights reserved - * - * This file is part of GPAC / dashcast - * - * 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 "video_muxer.h" -#include "libavutil/opt.h" -#include - - -/** - * A function which takes FFmpeg H264 extradata (SPS/PPS) and bring them ready to be pushed to the MP4 muxer. - * @param extradata - * @param extradata_size - * @param dstcfg - * @returns GF_OK is the extradata was parsed and is valid, other values otherwise. - */ -static GF_Err avc_import_ffextradata(const u8 *extradata, const u64 extradata_size, GF_AVCConfig *dstcfg) -{ -#ifdef GPAC_DISABLE_AV_PARSERS - return GF_OK; -#else - u8 nal_size; - AVCState avc; - GF_BitStream *bs; - if (!extradata || (extradata_size < sizeof(u32))) - return GF_BAD_PARAM; - bs = gf_bs_new((const char *) extradata, extradata_size, GF_BITSTREAM_READ); - if (!bs) - return GF_BAD_PARAM; - if (gf_bs_read_u32(bs) != 0x00000001) { - gf_bs_del(bs); - return GF_BAD_PARAM; - } - - //SPS - { - s32 idx; - char *buffer = NULL; - const u64 nal_start = 4; - nal_size = gf_media_nalu_next_start_code_bs(bs); - if (nal_start + nal_size > extradata_size) { - gf_bs_del(bs); - return GF_BAD_PARAM; - } - buffer = (char*)gf_malloc(nal_size); - gf_bs_read_data(bs, buffer, nal_size); - gf_bs_seek(bs, nal_start); - if ((gf_bs_read_u8(bs) & 0x1F) != GF_AVC_NALU_SEQ_PARAM) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - idx = gf_media_avc_read_sps(buffer, nal_size, &avc, 0, NULL); - if (idx < 0) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - 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; - dstcfg->chroma_format = avc.sps[idx].chroma_format; - dstcfg->luma_bit_depth = 8 + avc.sps[idx].luma_bit_depth_m8; - dstcfg->chroma_bit_depth = 8 + avc.sps[idx].chroma_bit_depth_m8; - - { - GF_AVCConfigSlot *slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - slc->size = nal_size; - slc->id = idx; - slc->data = buffer; - gf_list_add(dstcfg->sequenceParameterSets, slc); - } - } - - //PPS - { - s32 idx; - char *buffer = NULL; - const u64 nal_start = 4 + nal_size + 4; - gf_bs_seek(bs, nal_start); - nal_size = gf_media_nalu_next_start_code_bs(bs); - if (nal_start + nal_size > extradata_size) { - gf_bs_del(bs); - return GF_BAD_PARAM; - } - buffer = (char*)gf_malloc(nal_size); - gf_bs_read_data(bs, buffer, nal_size); - gf_bs_seek(bs, nal_start); - if ((gf_bs_read_u8(bs) & 0x1F) != GF_AVC_NALU_PIC_PARAM) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - idx = gf_media_avc_read_pps(buffer, nal_size, &avc); - if (idx < 0) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - { - GF_AVCConfigSlot *slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - slc->size = nal_size; - slc->id = idx; - slc->data = buffer; - gf_list_add(dstcfg->pictureParameterSets, slc); - } - } - - gf_bs_del(bs); - return GF_OK; -#endif -} - -/** - * A function which takes FFmpeg H265 extradata (SPS/PPS) and bring them ready to be pushed to the MP4 muxer. - * @param extradata - * @param extradata_size - * @param dstcfg - * @returns GF_OK is the extradata was parsed and is valid, other values otherwise. - */ -static GF_Err hevc_import_ffextradata(const u8 *extradata, const u64 extradata_size, GF_HEVCConfig *dst_cfg) -{ -#ifdef GPAC_DISABLE_AV_PARSERS - return GF_OK; -#else - HEVCState hevc; - GF_HEVCParamArray *vpss = NULL, *spss = NULL, *ppss = NULL, *seis = NULL; - GF_BitStream *bs; - char *buffer = NULL; - u32 buffer_size = 0; - if (!extradata || (extradata_size < sizeof(u32))) - return GF_BAD_PARAM; - bs = gf_bs_new((const char *) extradata, extradata_size, GF_BITSTREAM_READ); - if (!bs) - return GF_BAD_PARAM; - - memset(&hevc, 0, sizeof(HEVCState)); - hevc.sps_active_idx = -1; - - while (gf_bs_available(bs)) { - s32 idx; - GF_AVCConfigSlot *slc; - u8 nal_unit_type, temporal_id, layer_id; - u64 nal_start, start_code; - u32 nal_size; - - start_code = gf_bs_read_u32(bs); - if (start_code>>8 == 0x000001) { - nal_start = gf_bs_get_position(bs) - 1; - gf_bs_seek(bs, nal_start); - start_code = 1; - } - if (start_code != 0x00000001) { - gf_bs_del(bs); - if (buffer) gf_free(buffer); - if (vpss && spss && ppss) return GF_OK; - return GF_BAD_PARAM; - } - nal_start = gf_bs_get_position(bs); - nal_size = gf_media_nalu_next_start_code_bs(bs); - if (nal_start + nal_size > extradata_size) { - gf_bs_del(bs); - return GF_BAD_PARAM; - } - - if (nal_size > buffer_size) { - buffer = (char*)gf_realloc(buffer, nal_size); - buffer_size = nal_size; - } - gf_bs_read_data(bs, buffer, nal_size); - - gf_media_hevc_parse_nalu(buffer, nal_size, &hevc, &nal_unit_type, &temporal_id, &layer_id); - if (layer_id) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - switch (nal_unit_type) { - case GF_HEVC_NALU_VID_PARAM: - idx = gf_media_hevc_read_vps(buffer, nal_size , &hevc); - if (idx < 0) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - assert(hevc.vps[idx].state == 1); //we don't expect multiple VPS - if (hevc.vps[idx].state == 1) { - hevc.vps[idx].state = 2; - hevc.vps[idx].crc = gf_crc_32(buffer, nal_size); - - dst_cfg->avgFrameRate = hevc.vps[idx].rates[0].avg_pic_rate; - dst_cfg->constantFrameRate = hevc.vps[idx].rates[0].constand_pic_rate_idc; - dst_cfg->numTemporalLayers = hevc.vps[idx].max_sub_layers; - dst_cfg->temporalIdNested = hevc.vps[idx].temporal_id_nesting; - - if (!vpss) { - GF_SAFEALLOC(vpss, GF_HEVCParamArray); - if (vpss) { - vpss->nalus = gf_list_new(); - gf_list_add(dst_cfg->param_array, vpss); - vpss->array_completeness = 1; - vpss->type = GF_HEVC_NALU_VID_PARAM; - } - } - - slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - if (slc) { - slc->size = nal_size; - slc->id = idx; - slc->data = (char*)gf_malloc(sizeof(char)*slc->size); - if (slc->data) - memcpy(slc->data, buffer, sizeof(char)*slc->size); - - if (vpss) - gf_list_add(vpss->nalus, slc); - } - } - break; - case GF_HEVC_NALU_SEQ_PARAM: - idx = gf_media_hevc_read_sps(buffer, nal_size, &hevc); - if (idx < 0) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - assert(!(hevc.sps[idx].state & AVC_SPS_DECLARED)); //we don't expect multiple SPS - if ((hevc.sps[idx].state & AVC_SPS_PARSED) && !(hevc.sps[idx].state & AVC_SPS_DECLARED)) { - hevc.sps[idx].state |= AVC_SPS_DECLARED; - hevc.sps[idx].crc = gf_crc_32(buffer, nal_size); - } - - dst_cfg->configurationVersion = 1; - dst_cfg->profile_space = hevc.sps[idx].ptl.profile_space; - dst_cfg->tier_flag = hevc.sps[idx].ptl.tier_flag; - dst_cfg->profile_idc = hevc.sps[idx].ptl.profile_idc; - dst_cfg->general_profile_compatibility_flags = hevc.sps[idx].ptl.profile_compatibility_flag; - dst_cfg->progressive_source_flag = hevc.sps[idx].ptl.general_progressive_source_flag; - dst_cfg->interlaced_source_flag = hevc.sps[idx].ptl.general_interlaced_source_flag; - dst_cfg->non_packed_constraint_flag = hevc.sps[idx].ptl.general_non_packed_constraint_flag; - dst_cfg->frame_only_constraint_flag = hevc.sps[idx].ptl.general_frame_only_constraint_flag; - - dst_cfg->constraint_indicator_flags = hevc.sps[idx].ptl.general_reserved_44bits; - dst_cfg->level_idc = hevc.sps[idx].ptl.level_idc; - - dst_cfg->chromaFormat = hevc.sps[idx].chroma_format_idc; - dst_cfg->luma_bit_depth = hevc.sps[idx].bit_depth_luma; - dst_cfg->chroma_bit_depth = hevc.sps[idx].bit_depth_chroma; - - if (!spss) { - GF_SAFEALLOC(spss, GF_HEVCParamArray); - if (spss) { - spss->nalus = gf_list_new(); - gf_list_add(dst_cfg->param_array, spss); - spss->array_completeness = 1; - spss->type = GF_HEVC_NALU_SEQ_PARAM; - } - } - - slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - if (slc) { - slc->size = nal_size; - slc->id = idx; - slc->data = (char*)gf_malloc(sizeof(char)*slc->size); - if (slc->data) - memcpy(slc->data, buffer, sizeof(char)*slc->size); - if (spss) - gf_list_add(spss->nalus, slc); - } - break; - case GF_HEVC_NALU_PIC_PARAM: - idx = gf_media_hevc_read_pps(buffer, nal_size, &hevc); - if (idx < 0) { - gf_bs_del(bs); - gf_free(buffer); - return GF_BAD_PARAM; - } - - assert(hevc.pps[idx].state == 1); //we don't expect multiple PPS - if (hevc.pps[idx].state == 1) { - hevc.pps[idx].state = 2; - hevc.pps[idx].crc = gf_crc_32(buffer, nal_size); - - if (!ppss) { - GF_SAFEALLOC(ppss, GF_HEVCParamArray); - if (ppss) { - ppss->nalus = gf_list_new(); - gf_list_add(dst_cfg->param_array, ppss); - ppss->array_completeness = 1; - ppss->type = GF_HEVC_NALU_PIC_PARAM; - } - } - - slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - if (slc) { - slc->size = nal_size; - slc->id = idx; - slc->data = (char*)gf_malloc(sizeof(char)*slc->size); - if (slc->data) - memcpy(slc->data, buffer, sizeof(char)*slc->size); - - if (ppss) - gf_list_add(ppss->nalus, slc); - } - } - break; - case GF_HEVC_NALU_SEI_PREFIX: - if (!seis) { - GF_SAFEALLOC(seis, GF_HEVCParamArray); - if (seis) { - seis->nalus = gf_list_new(); - seis->array_completeness = 0; - seis->type = GF_HEVC_NALU_SEI_PREFIX; - } - } - slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - if (slc) { - slc->size = nal_size; - slc->data = (char*)gf_malloc(sizeof(char)*slc->size); - if (slc->data) - memcpy(slc->data, buffer, sizeof(char)*slc->size); - if (seis) - gf_list_add(seis->nalus, slc); - } - break; - default: - break; - } - } - - gf_bs_del(bs); - if (buffer) gf_free(buffer); - - return GF_OK; -#endif -} - -#ifndef GPAC_DISABLE_ISOM - -static GF_Err dc_gpac_video_write_config(VideoOutputFile *video_output_file, u32 *di, u32 track) { - GF_Err ret; - if (video_output_file->codec_ctx->codec_id == CODEC_ID_H264) { - GF_AVCConfig *avccfg; - avccfg = gf_odf_avc_cfg_new(); - if (!avccfg) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create AVCConfig\n")); - return GF_OUT_OF_MEM; - } - - ret = avc_import_ffextradata(video_output_file->codec_ctx->extradata, video_output_file->codec_ctx->extradata_size, avccfg); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot parse AVC/H264 SPS/PPS\n")); - gf_odf_avc_cfg_del(avccfg); - return ret; - } - - ret = gf_isom_avc_config_new(video_output_file->isof, track, avccfg, NULL, NULL, di); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_avc_config_new\n", gf_error_to_string(ret))); - return ret; - } - - gf_odf_avc_cfg_del(avccfg); - - //inband SPS/PPS - if (video_output_file->muxer_type == GPAC_INIT_VIDEO_MUXER_AVC3) { - ret = gf_isom_avc_set_inband_config(video_output_file->isof, track, 1); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_avc_set_inband_config\n", gf_error_to_string(ret))); - return ret; - } - } - } else if (!strcmp(video_output_file->codec_ctx->codec->name, "libx265")) { //FIXME CODEC_ID_HEVC would break on old releases - GF_HEVCConfig *hevccfg = gf_odf_hevc_cfg_new(); - if (!hevccfg) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create HEVCConfig\n")); - return GF_OUT_OF_MEM; - } - - ret = hevc_import_ffextradata(video_output_file->codec_ctx->extradata, video_output_file->codec_ctx->extradata_size, hevccfg); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot parse HEVC/H265 SPS/PPS\n")); - gf_odf_hevc_cfg_del(hevccfg); - return ret; - } - - ret = gf_isom_hevc_config_new(video_output_file->isof, track, hevccfg, NULL, NULL, di); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_hevc_config_new\n", gf_error_to_string(ret))); - return ret; - } - - gf_odf_hevc_cfg_del(hevccfg); - - //inband SPS/PPS - if (video_output_file->muxer_type == GPAC_INIT_VIDEO_MUXER_AVC3) { - ret = gf_isom_hevc_set_inband_config(video_output_file->isof, track, 1); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_hevc_set_inband_config\n", gf_error_to_string(ret))); - return ret; - } - } - } - - return GF_OK; -} - -int dc_gpac_video_moov_create(VideoOutputFile *video_output_file, char *filename) -{ - GF_Err ret; - AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; - u32 di=1, track; - - //TODO: For the moment it is fixed - //u32 sample_dur = video_output_file->codec_ctx->time_base.den; - - //int64_t profile = 0; - //av_opt_get_int(video_output_file->codec_ctx->priv_data, "level", AV_OPT_SEARCH_CHILDREN, &profile); - - video_output_file->isof = gf_isom_open(filename, GF_ISOM_OPEN_WRITE, NULL); - if (!video_output_file->isof) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open iso file %s\n", filename)); - return -1; - } - //gf_isom_store_movie_config(video_output_file->isof, 0); - track = gf_isom_new_track(video_output_file->isof, 0, GF_ISOM_MEDIA_VISUAL, video_codec_ctx->time_base.den); - video_output_file->trackID = gf_isom_get_track_id(video_output_file->isof, track); - - video_output_file->timescale = video_codec_ctx->time_base.den; - if (!video_output_file->frame_dur) - video_output_file->frame_dur = video_codec_ctx->time_base.num; - - if (!track) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create new track\n")); - return -1; - } - - ret = gf_isom_set_track_enabled(video_output_file->isof, track, 1); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret))); - return -1; - } - - ret = dc_gpac_video_write_config(video_output_file, &di, track); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: dc_gpac_video_write_config\n", gf_error_to_string(ret))); - return -1; - } - - gf_isom_set_visual_info(video_output_file->isof, track, di, video_codec_ctx->width, video_codec_ctx->height); - gf_isom_set_sync_table(video_output_file->isof, track); - - ret = gf_isom_setup_track_fragment(video_output_file->isof, track, 1, video_output_file->use_source_timing ? (u32) video_output_file->frame_dur : 1, 0, 0, 0, 0); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret))); - return -1; - } - - ret = gf_isom_finalize_for_fragment(video_output_file->isof, track); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); - return -1; - } - - ret = gf_media_get_rfc_6381_codec_name(video_output_file->isof, track, video_output_file->video_data_conf->codec6381, GF_FALSE, GF_FALSE); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); - return -1; - } - - return 0; -} - -int dc_gpac_video_isom_open_seg(VideoOutputFile *video_output_file, char *filename) -{ - GF_Err ret; - ret = gf_isom_start_segment(video_output_file->isof, filename, 1); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_start_segment\n", gf_error_to_string(ret))); - return -1; - } - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Opening new segment %s at UTC "LLU" ms\n", filename, gf_net_get_utc() )); - return 0; -} - -int dc_gpac_video_isom_write(VideoOutputFile *video_output_file) -{ - GF_Err ret; - AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; - - u32 sc_size = 0; - u32 nalu_size = 0; - - u32 buf_len = video_output_file->encoded_frame_size; - u8 *buf_ptr = video_output_file->vbuf; - - GF_BitStream *out_bs = gf_bs_new(NULL, 2 * buf_len, GF_BITSTREAM_WRITE); - nalu_size = gf_media_nalu_next_start_code(buf_ptr, buf_len, &sc_size); - if (nalu_size != 0) { - gf_bs_write_u32(out_bs, nalu_size); - gf_bs_write_data(out_bs, (const char*) buf_ptr, nalu_size); - } - if (sc_size) { - buf_ptr += (nalu_size + sc_size); - buf_len -= (nalu_size + sc_size); - } - - while (buf_len) { - nalu_size = gf_media_nalu_next_start_code(buf_ptr, buf_len, &sc_size); - if (nalu_size != 0) { - gf_bs_write_u32(out_bs, nalu_size); - gf_bs_write_data(out_bs, (const char*) buf_ptr, nalu_size); - } - - buf_ptr += nalu_size; - - if (!sc_size || (buf_len < nalu_size + sc_size)) - break; - buf_len -= nalu_size + sc_size; - buf_ptr += sc_size; - } - - gf_bs_get_content(out_bs, &video_output_file->sample->data, &video_output_file->sample->dataLength); - //video_output_file->sample->data = //(char *) (video_output_file->vbuf + nalu_size + sc_size); - //video_output_file->sample->dataLength = //video_output_file->encoded_frame_size - (sc_size + nalu_size); - - video_output_file->sample->DTS = video_codec_ctx->coded_frame->pkt_dts; - video_output_file->sample->CTS_Offset = (s32) (video_codec_ctx->coded_frame->pts - video_output_file->sample->DTS); - video_output_file->sample->IsRAP = video_codec_ctx->coded_frame->key_frame; - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Isom Write: RAP %d , DTS "LLD" CTS offset %d \n", video_output_file->sample->IsRAP, video_output_file->sample->DTS, video_output_file->sample->CTS_Offset)); - - ret = gf_isom_fragment_add_sample(video_output_file->isof, video_output_file->trackID, video_output_file->sample, 1, video_output_file->use_source_timing ? (u32) video_output_file->frame_dur : 1, 0, 0, 0); - if (ret != GF_OK) { - gf_bs_del(out_bs); - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_fragment_add_sample\n", gf_error_to_string(ret))); - return -1; - } - - //free data but keep sample structure alive - gf_free(video_output_file->sample->data); - video_output_file->sample->data = NULL; - video_output_file->sample->dataLength = 0; - - gf_bs_del(out_bs); - return 0; -} - -int dc_gpac_video_isom_close_seg(VideoOutputFile *video_output_file) -{ - GF_Err ret; - ret = gf_isom_close_segment(video_output_file->isof, 0, 0, 0, 0, 0, 0, 1, video_output_file->seg_marker, NULL, NULL); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close_segment\n", gf_error_to_string(ret))); - return -1; - } - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Rep %s Closing segment at UTC "LLU" ms\n", video_output_file->rep_id, gf_net_get_utc() )); - - return 0; -} - -int dc_gpac_video_isom_close(VideoOutputFile *video_output_file) -{ - GF_Err ret; - ret = gf_isom_close(video_output_file->isof); - if (ret != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close\n", gf_error_to_string(ret))); - return -1; - } - - return 0; -} - -#endif - - -int dc_raw_h264_open(VideoOutputFile *video_output_file, char *filename) -{ - video_output_file->file = gf_fopen(filename, "w"); - return 0; -} - -int dc_raw_h264_write(VideoOutputFile *video_output_file) -{ - fwrite(video_output_file->vbuf, video_output_file->encoded_frame_size, 1, video_output_file->file); - return 0; -} - -int dc_raw_h264_close(VideoOutputFile *video_output_file) -{ - gf_fclose(video_output_file->file); - return 0; -} - -int dc_ffmpeg_video_muxer_open(VideoOutputFile *video_output_file, char *filename) -{ - AVStream *video_stream; - AVOutputFormat *output_fmt; - - AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; - video_output_file->av_fmt_ctx = NULL; - -// video_output_file->vbr = video_data_conf->bitrate; -// video_output_file->vfr = video_data_conf->framerate; -// video_output_file->width = video_data_conf->width; -// video_output_file->height = video_data_conf->height; -// strcpy(video_output_file->filename, video_data_conf->filename); -// strcpy(video_output_file->codec, video_data_conf->codec); - - /* Find output format */ - output_fmt = av_guess_format(NULL, filename, NULL); - if (!output_fmt) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find suitable output format\n")); - return -1; - } - - video_output_file->av_fmt_ctx = avformat_alloc_context(); - if (!video_output_file->av_fmt_ctx) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate memory for pOutVideoFormatCtx\n")); - return -1; - } - - video_output_file->av_fmt_ctx->oformat = output_fmt; - strcpy(video_output_file->av_fmt_ctx->filename, filename); - - /* Open the output file */ - if (!(output_fmt->flags & AVFMT_NOFILE)) { - if (avio_open(&video_output_file->av_fmt_ctx->pb, filename, URL_WRONLY) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot not open '%s'\n", filename)); - return -1; - } - } - - video_stream = avformat_new_stream(video_output_file->av_fmt_ctx, - video_output_file->codec); - if (!video_stream) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create output video stream\n")); - return -1; - } - - //video_stream->codec = video_output_file->codec_ctx; - - video_stream->codec->codec_id = video_output_file->codec->id; - video_stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - video_stream->codec->bit_rate = video_codec_ctx->bit_rate; //video_output_file->video_data_conf->bitrate; - video_stream->codec->width = video_codec_ctx->width; //video_output_file->video_data_conf->width; - video_stream->codec->height = video_codec_ctx->height; //video_output_file->video_data_conf->height; - - video_stream->codec->time_base = video_codec_ctx->time_base; - - video_stream->codec->pix_fmt = PIX_FMT_YUV420P; - video_stream->codec->gop_size = video_codec_ctx->time_base.den; //video_output_file->video_data_conf->framerate; - - av_opt_set(video_stream->codec->priv_data, "preset", "ultrafast", 0); - av_opt_set(video_stream->codec->priv_data, "tune", "zerolatency", 0); - - /* open the video codec */ - if (avcodec_open2(video_stream->codec, video_output_file->codec, NULL) < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video codec\n")); - return -1; - } - - avformat_write_header(video_output_file->av_fmt_ctx, NULL); - - video_output_file->timescale = video_codec_ctx->time_base.den; - return 0; -} - -int dc_ffmpeg_video_muxer_write(VideoOutputFile *video_output_file) -{ - AVPacket pkt; - AVStream *video_stream = video_output_file->av_fmt_ctx->streams[video_output_file->vstream_idx]; - AVCodecContext *video_codec_ctx = video_stream->codec; - - av_init_packet(&pkt); - pkt.data = NULL; - pkt.size = 0; - - if (video_codec_ctx->coded_frame->pts != AV_NOPTS_VALUE) { - pkt.pts = av_rescale_q(video_codec_ctx->coded_frame->pts, video_codec_ctx->time_base, video_stream->time_base); - } - - if (video_codec_ctx->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - - pkt.stream_index = video_stream->index; - pkt.data = video_output_file->vbuf; - pkt.size = video_output_file->encoded_frame_size; - - // write the compressed frame in the media file - if (av_interleaved_write_frame(video_output_file->av_fmt_ctx, &pkt) != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Writing frame is not successful\n")); - return -1; - } - - av_free_packet(&pkt); - - return 0; -} - -int dc_ffmpeg_video_muxer_close(VideoOutputFile *video_output_file) -{ - u32 i; - - av_write_trailer(video_output_file->av_fmt_ctx); - - avio_close(video_output_file->av_fmt_ctx->pb); - - // free the streams - for (i = 0; i < video_output_file->av_fmt_ctx->nb_streams; i++) { - avcodec_close(video_output_file->av_fmt_ctx->streams[i]->codec); - av_freep(&video_output_file->av_fmt_ctx->streams[i]->info); - } - - //video_output_file->av_fmt_ctx->streams[video_output_file->vstream_idx]->codec = NULL; - avformat_free_context(video_output_file->av_fmt_ctx); - - return 0; -} - -int dc_video_muxer_init(VideoOutputFile *video_output_file, VideoDataConf *video_data_conf, VideoMuxerType muxer_type, int frame_per_segment, int frame_per_fragment, u32 seg_marker, int gdr, int seg_dur, int frag_dur, int frame_dur, int gop_size, int video_cb_size) -{ - char name[GF_MAX_PATH]; - memset(video_output_file, 0, sizeof(VideoOutputFile)); - snprintf(name, sizeof(name), "video encoder %s", video_data_conf->filename); - dc_consumer_init(&video_output_file->consumer, video_cb_size, name); - -#ifndef GPAC_DISABLE_ISOM - video_output_file->sample = gf_isom_sample_new(); - video_output_file->isof = NULL; -#endif - - video_output_file->muxer_type = muxer_type; - - video_output_file->frame_per_segment = frame_per_segment; - video_output_file->frame_per_fragment = frame_per_fragment; - - video_output_file->seg_dur = seg_dur; - video_output_file->frag_dur = frag_dur; - - video_output_file->seg_marker = seg_marker; - video_output_file->gdr = gdr; - video_output_file->gop_size = gop_size; - video_output_file->frame_dur = frame_dur; - - return 0; -} - -int dc_video_muxer_free(VideoOutputFile *video_output_file) -{ -#ifndef GPAC_DISABLE_ISOM - if (video_output_file->isof != NULL) { - gf_isom_close(video_output_file->isof); - } - - gf_isom_sample_del(&video_output_file->sample); -#endif - return 0; -} - -GF_Err dc_video_muxer_open(VideoOutputFile *video_output_file, char *directory, char *id_name, int seg) -{ - char name[GF_MAX_PATH]; - - switch (video_output_file->muxer_type) { - case FFMPEG_VIDEO_MUXER: - snprintf(name, sizeof(name), "%s/%s_%d_ffmpeg.mp4", directory, id_name, seg); - return dc_ffmpeg_video_muxer_open(video_output_file, name); - case RAW_VIDEO_H264: - snprintf(name, sizeof(name), "%s/%s_%d.264", directory, id_name, seg); - return dc_raw_h264_open(video_output_file, name); -#ifndef GPAC_DISABLE_ISOM - case GPAC_VIDEO_MUXER: - snprintf(name, sizeof(name), "%s/%s_%d_gpac.mp4", directory, id_name, seg); - dc_gpac_video_moov_create(video_output_file, name); - return dc_gpac_video_isom_open_seg(video_output_file, NULL); - case GPAC_INIT_VIDEO_MUXER_AVC1: - if (seg == 1) { - snprintf(name, sizeof(name), "%s/%s_init_gpac.mp4", directory, id_name); - dc_gpac_video_moov_create(video_output_file, name); - video_output_file->first_dts_in_fragment = 0; - } - snprintf(name, sizeof(name), "%s/%s_%d_gpac.m4s", directory, id_name, seg); - return dc_gpac_video_isom_open_seg(video_output_file, name); - case GPAC_INIT_VIDEO_MUXER_AVC3: - if (seg == 0) { - snprintf(name, sizeof(name), "%s/%s_init_gpac.mp4", directory, id_name); - dc_gpac_video_moov_create(video_output_file, name); - video_output_file->first_dts_in_fragment = 0; - } - snprintf(name, sizeof(name), "%s/%s_%d_gpac.m4s", directory, id_name, seg); - return dc_gpac_video_isom_open_seg(video_output_file, name); -#endif - default: - return GF_BAD_PARAM; - }; - - return -2; -} - -int dc_video_muxer_write(VideoOutputFile *video_output_file, int frame_nb, Bool insert_ntp) -{ - Bool segment_close = GF_FALSE; - Bool fragment_close = GF_FALSE; - switch (video_output_file->muxer_type) { - case FFMPEG_VIDEO_MUXER: - return dc_ffmpeg_video_muxer_write(video_output_file); - case RAW_VIDEO_H264: - return dc_raw_h264_write(video_output_file); -#ifndef GPAC_DISABLE_ISOM - case GPAC_VIDEO_MUXER: - case GPAC_INIT_VIDEO_MUXER_AVC1: - case GPAC_INIT_VIDEO_MUXER_AVC3: - if (video_output_file->use_source_timing) { - GF_Err ret; - if (!video_output_file->fragment_started) { - video_output_file->fragment_started = 1; - ret = gf_isom_start_fragment(video_output_file->isof, 1); - if (ret < 0) - return -1; - - - //insert UTC for each fragment - if (insert_ntp) { - gf_isom_set_fragment_reference_time(video_output_file->isof, video_output_file->trackID, video_output_file->frame_ntp, video_output_file->codec_ctx->coded_frame->pts); - } - - video_output_file->first_dts_in_fragment = video_output_file->codec_ctx->coded_frame->pkt_dts; - if (!video_output_file->segment_started) { - video_output_file->pts_at_segment_start = video_output_file->codec_ctx->coded_frame->pts; - video_output_file->segment_started = 1; - if (!video_output_file->nb_segments) { - video_output_file->pts_at_first_segment = video_output_file->pts_at_segment_start; - } - -#ifndef GPAC_DISABLE_LOG - if (insert_ntp && gf_log_tool_level_on(GF_LOG_DASH, GF_LOG_INFO)) { - if (!video_output_file->ntp_at_first_dts) { - video_output_file->ntp_at_first_dts = video_output_file->frame_ntp; - } else { - s32 ntp_diff = gf_net_get_ntp_diff_ms(video_output_file->ntp_at_first_dts); - s32 ts_diff = (s32) ( 1000 * (video_output_file->codec_ctx->coded_frame->pts - video_output_file->pts_at_first_segment) / video_output_file->timescale ); - - s32 diff_ms = ts_diff - ntp_diff; - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Video Segment start NTP diff: %d ms TS diff: %d ms drift: %d ms\n", ntp_diff, ts_diff, diff_ms)); - } - } -#endif - } - gf_isom_set_traf_base_media_decode_time(video_output_file->isof, video_output_file->trackID, video_output_file->first_dts_in_fragment); - } - - if (dc_gpac_video_isom_write(video_output_file) < 0) { - return -1; - } - video_output_file->last_pts = video_output_file->codec_ctx->coded_frame->pts; - video_output_file->last_dts = video_output_file->codec_ctx->coded_frame->pkt_dts; - GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] PTS: "LLU", DTS: "LLU", first DTS in frag: "LLU", timescale: %d, frag dur: %d\n", video_output_file->last_pts, video_output_file->last_dts, video_output_file->first_dts_in_fragment, video_output_file->timescale, video_output_file->frag_dur)); - - //we may have rounding errors on the input PTS :( add half frame dur safety - //flush segments based on the cumultated duration , to avoid drift - /* Check why segment tests work on PTS while fragment tests work on DTS ? */ - /* Check why fragment closing is not tested based on accumulation of fragment duration to avoid drifts */ - segment_close = ((video_output_file->last_pts - video_output_file->pts_at_first_segment + video_output_file->frame_dur) * 1000 >= - (video_output_file->nb_segments+1)*video_output_file->seg_dur * (u64)video_output_file->timescale); -#if 0 - segment_close = ((video_output_file->last_pts - video_output_file->pts_at_segment_start + 3*video_output_file->frame_dur/2) * 1000 >= - (video_output_file->seg_dur * (u64)video_output_file->timescale); -#endif - //flush fragment if adding next frame will exceed target duration by half the frame duration - fragment_close = ((video_output_file->last_dts - video_output_file->first_dts_in_fragment + 3 * video_output_file->frame_dur / 2) * 1000 >= - (video_output_file->frag_dur * (u64)video_output_file->timescale)); - - if (segment_close || fragment_close) { - gf_isom_flush_fragments(video_output_file->isof, 1); - video_output_file->fragment_started = 0; - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Flushed fragment at UTC "LLU" ms - First DTS "LLU" last PTS "LLU" - First Segment PTS "LLU" timescale %d\n", gf_net_get_utc(), video_output_file->first_dts_in_fragment, video_output_file->codec_ctx->coded_frame->pts, video_output_file->pts_at_segment_start, video_output_file->timescale)); - } - - if (segment_close) { - return 1; - } - return 0; - } - - if (frame_nb % video_output_file->frame_per_fragment == 0) { - gf_isom_start_fragment(video_output_file->isof, 1); - - if (!video_output_file->segment_started) { - video_output_file->pts_at_segment_start = video_output_file->codec_ctx->coded_frame->pts; - video_output_file->segment_started = 1; - - if (insert_ntp) { - gf_isom_set_fragment_reference_time(video_output_file->isof, video_output_file->trackID, video_output_file->frame_ntp, video_output_file->pts_at_segment_start); - } - } - - - gf_isom_set_traf_base_media_decode_time(video_output_file->isof, video_output_file->trackID, video_output_file->first_dts_in_fragment); - video_output_file->first_dts_in_fragment += video_output_file->frame_per_fragment; - } - - dc_gpac_video_isom_write(video_output_file); - - if (frame_nb % video_output_file->frame_per_fragment == video_output_file->frame_per_fragment - 1) { - gf_isom_flush_fragments(video_output_file->isof, 1); - GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Flushed fragment to disk at UTC "LLU" ms - last coded frame PTS "LLU"\n", gf_net_get_utc(), video_output_file->codec_ctx->coded_frame->pts)); - } - - if (frame_nb + 1 == video_output_file->frame_per_segment) - return 1; - - return 0; -#endif - - default: - return -2; - } - - return -2; -} - -int dc_video_muxer_close(VideoOutputFile *video_output_file) -{ - video_output_file->fragment_started = video_output_file->segment_started = 0; - video_output_file->nb_segments++; - - switch (video_output_file->muxer_type) { - case FFMPEG_VIDEO_MUXER: - return dc_ffmpeg_video_muxer_close(video_output_file); - case RAW_VIDEO_H264: - return dc_raw_h264_close(video_output_file); -#ifndef GPAC_DISABLE_ISOM - case GPAC_VIDEO_MUXER: - dc_gpac_video_isom_close_seg(video_output_file); - return dc_gpac_video_isom_close(video_output_file); - case GPAC_INIT_VIDEO_MUXER_AVC1: - case GPAC_INIT_VIDEO_MUXER_AVC3: - return dc_gpac_video_isom_close_seg(video_output_file); -#endif - default: - return -2; - } - - return -2; -} diff --git a/applications/deprecated/mp42ts/Makefile b/applications/deprecated/mp42ts/Makefile new file mode 100644 index 0000000..b069bf6 --- /dev/null +++ b/applications/deprecated/mp42ts/Makefile @@ -0,0 +1,70 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/applications/mp42ts + +CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" + +ifeq ($(DEBUGBUILD),yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD),yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LINKFLAGS=-L../../bin/gcc +ifeq ($(CONFIG_WIN32),yes) +EXE=.exe +PROG=MP42TS$(EXE) +else +EXT= +PROG=MP42TS +endif + +ifeq ($(STATICBUILD),yes) +##include static modules and other deps for libgpac +include ../../static.mak + +#FIXME we have to disable AAC+bifs support in mp42ts since it reuses things from aac_in already in libgpac ... +ifeq ($(STATIC_MODULES),yes) +CFLAGS+=-DGPAC_DISABLE_PLAYER +endif + +LINKFLAGS+=-lgpac_static +LINKFLAGS+= $(GPAC_SH_FLAGS) +LINKFLAGS+=$(EXTRALIBS) +else +LINKFLAGS+=-lgpac +ifeq ($(CONFIG_DARWIN),yes) +#LINKFLAGS+= -Wl,-rpath,'@loader_path' +else +LINKFLAGS+= -Wl,-rpath,'$$ORIGIN' -Wl,-rpath-link,../../bin/gcc +endif +endif + + +#common objs - insert after ../static if any to overwrite list of objects +OBJS= main.o + +SRCS := $(OBJS:.o=.c) + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) $(LDFLAGS) + +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 .depend diff --git a/applications/deprecated/mp42ts/main.c b/applications/deprecated/mp42ts/main.c new file mode 100644 index 0000000..a1465fb --- /dev/null +++ b/applications/deprecated/mp42ts/main.c @@ -0,0 +1,2932 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre, Cyril Concolato, Romain Bouqueau + * Copyright (c) Telecom ParisTech 2005-2012 + * All rights reserved + * + * This file is part of GPAC / mp4-to-ts (mp42ts) application + * + * 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 +#include + +#ifndef GPAC_DISABLE_STREAMING +#include +#endif + +#ifndef GPAC_DISABLE_SENG +#include +#endif + +#ifndef GPAC_DISABLE_TTXT +#include +#endif + + +#ifdef GPAC_DISABLE_MPEG2TS_MUX +#error "Cannot compile MP42TS if GPAC is not built with MPEG2-TS Muxing support" +#endif + +#define MP42TS_PRINT_TIME_MS 500 /*refresh printed info every CLOCK_REFRESH ms*/ +#define MP42TS_VIDEO_FREQ 1000 /*meant to send AVC IDR only every CLOCK_REFRESH ms*/ + +#define GPAC_DISABLE_PLAYER + + +s32 temi_id_1 = -1; +s32 temi_id_2 = -1; + +u32 temi_url_insertion_delay = 1000; +u32 temi_offset = 0; +Bool temi_disable_loop = GF_FALSE; + +Double temi_period=0; +Bool request_temi_toggle = GF_FALSE; +Bool temi_on = GF_TRUE; +Bool temi_single_toggle = GF_FALSE; +u64 temi_period_last_dts = 0; +FILE *logfile = NULL; + +//no longer supported for filters +#define GPAC_DISABLE_PLAYER + + +static void usage() +{ + fprintf(stderr, "mp42ts [options]\n" + "\n" + "Inputs:\n" + "-src filename[:OPTS] specifies an input file used for a TS service\n" + " * currently only supports ISO files and SDP files\n" + " * can be used several times, once for each program\n" + "By default each source is a program in a TS. \n" + "Source options are colon-separated list of options, as follows:\n" + "ID=N specifies the program ID for this source.\n" + " All sources with the same ID will be added to the same program\n" + "name=STR program name, as used in DVB service description table\n" + "provider=STR provider name, as used in DVB service description table\n" + "disc the first packet of each stream will have the discontinuity marker set\n" + "pmt=N sets version number of the PMT\n" + + "\n" + "-prog filename same as -src filename\n" + "\n" + "Destinations:\n" + "Several destinations may be specified as follows, at least one is mandatory\n" + "-dst-udp UDP_address:port (multicast or unicast)\n" + "-dst-rtp RTP_address:port\n" + "-dst-file filename\n" + "The following parameters may be specified when -dst-file is used\n" + "-segment-dir dir server local directory to store segments (ends with a '/')\n" + "-segment-duration dur segment duration in seconds\n" + "-segment-manifest file m3u8 file basename\n" + "-segment-http-prefix p client address for accessing server segments\n" + "-segment-number n number of segments to list in the manifest\n" + "\n" + "Basic options:\n" + "-rate R specifies target rate in kbps of the multiplex (optional)\n" + "-real-time specifies the muxer will work in real-time mode\n" + " * if not specified, the muxer will generate the TS as quickly as possible\n" + " * automatically set for SDP or BT input\n" + "-pcr-init V sets initial value V for PCR - if not set, random value is used\n" + "-pcr-offset V offsets all timestamps from PCR by V, in 90kHz. Default value is computed based on input media.\n" + "-psi-rate V sets PSI refresh rate V in ms (default 100ms).\n" + " * If 0, PSI data is only send once at the beginning or before each IDR when -rap option is set.\n" + " * This should be set to 0 for DASH streams.\n" + "-time n request the muxer to stop after n ms\n" + "-single-au forces 1 PES = 1 AU (disabled by default)\n" + "-multi-au forces 1 PES = N AU for all streams (disabled by default).\n" + " By default, audio streams pack N AUs in one PES but video and systems data use 1 AU per PES.\n" + "-rap forces RAP/IDR to be aligned with PES start for video streams (disabled by default)\n" + " in this mode, PAT, PMT and PCR will be inserted before the first TS packet of the RAP PES\n" + "-flush-rap same as -rap but flushes all other streams (sends remaining PES packets) before inserting PAT/PMT\n" + "-nb-pack N specifies to pack up to N TS packets together before sending on network or writing to file\n" + "-pcr-ms N sets max interval in ms between 2 PCR. Default is 100 ms or at each PES header\n" + "-force-pcr-only allows sending PCR-only packets to enforce the requested PCR rate - STILL EXPERIMENTAL.\n" + "-ttl N specifies Time-To-Live for multicast. Default is 1.\n" + "-ifce IPIFCE specifies default IP interface to use. Default is IF_ANY.\n" + "-temi [URL] Inserts TEMI time codes in adaptation field. URL is optional, and can be a number for external timeline IDs\n" + "-temi-delay DelayMS Specifies delay between two TEMI url descriptors (default is 1000)\n" + "-temi-offset OffsetMS Specifies an offset in ms to add to TEMI (by default TEMI starts at 0)\n" + "-temi-noloop Do not restart the TEMI timeline at the end of the source\n" + "-temi2 ID Inserts a secondary TEMI time codes in adaptation field of the audio PID if any. ID shall be set to the desired external timeline IDs\n" + "-insert-ntp Inserts NTP timestamp in TEMI timeline descriptor\n" + "-sdt-rate MS Gives the SDT carrousel rate in milliseconds. If 0 (default), SDT is not sent\n" + "\n" + "MPEG-4/T-DMB options:\n" + "-bifs-src filename update file: must be either an .sdp or a .bt file\n" + "-audio url may be mp3/udp or aac/http (shoutcast/icecast)\n" + "-video url shall be a raw h264 frame\n" + "-mpeg4-carousel n carousel period in ms\n" + "-mpeg4 or -4on2 forces usage of MPEG-4 signaling (IOD and SL Config)\n" + "-4over2 same as -4on2 and uses PMT to carry OD Updates\n" + "-bifs-pes carries BIFS over PES instead of sections\n" + "-bifs-pes-ex carries BIFS over PES without writing timestamps in SL\n" + "\n" + "Misc options\n" +#ifdef GPAC_MEMORY_TRACKING + "-mem-track enables memory tracker\n" + "-mem-track-stack enables memory tracker stack dumping\n" +#endif + "-h or -help print this screen\n" + "-hc print libgpac options\n" + "\n" + "GPAC version %s\n" + "(c) Telecom ParisTech 2000-2018 - Licence LGPL v2\n" + "GPAC Configuration: " GPAC_CONFIGURATION "\n" + "Features: %s %s\n\n", gf_gpac_version(), gf_enabled_features(), gf_disabled_features() + ); +} + + +#define MAX_MUX_SRC_PROG 100 +typedef struct +{ + +#ifndef GPAC_DISABLE_ISOM + GF_ISOFile *mp4; +#endif + + u32 nb_streams, pcr_idx; + GF_ESInterface streams[40]; + GF_Descriptor *iod; +#ifndef GPAC_DISABLE_SENG + GF_SceneEngine *seng; +#endif + GF_Thread *th; + char *bifs_src_name; + u32 rate; + Bool repeat; + u32 mpeg4_signaling; + Bool audio_configured; + u64 samples_done, samples_count; + u32 nb_real_streams; + Bool real_time; + GF_List *od_updates; + + u32 max_sample_size; + + char program_name[20]; + char provider_name[20]; + u32 ID; + Bool is_not_program_declaration; + Bool set_disc; + u32 pmt_version; + + Double last_ntp; +} M2TSSource; + +#ifndef GPAC_DISABLE_ISOM +typedef struct +{ + GF_ISOFile *mp4; + u32 track, sample_number, sample_count; + u32 mstype, mtype; + GF_ISOSample *sample; + /*refresh rate for images*/ + u32 image_repeat_ms, nb_repeat_last; + void *dsi; + u32 dsi_size; + + void *dsi_and_rap; + Bool loop; + Bool is_repeat; + s64 ts_offset, cts_dts_shift; + M2TSSource *source; + + const char *temi_url; + u32 last_temi_url, timeline_id; + Bool insert_ntp; + +} GF_ESIMP4; +#endif + +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; + +typedef struct +{ + u32 size; + char *data; +} GF_SimpleDataDescriptor; + +//TODO: find a clean way to save this data +#ifndef GPAC_DISABLE_PLAYER +static u32 audio_OD_stream_id = (u32)-1; +#endif + +#define AUDIO_OD_ESID 100 +#define AUDIO_DATA_ESID 101 +#define VIDEO_DATA_ESID 105 + +/*output types*/ +enum +{ + GF_MP42TS_FILE, /*open mpeg2ts file*/ + GF_MP42TS_UDP, /*open udp socket*/ + GF_MP42TS_RTP, /*open rtp socket*/ +#ifndef GPAC_DISABLE_PLAYER + GF_MP42TS_HTTP, /*open http downloader*/ +#endif +}; + +static u32 format_af_descriptor(char *af_data, u32 timeline_id, u64 timecode, u32 timescale, u64 ntp, const char *temi_url, u32 *last_url_time) +{ + u32 res; + u32 len; + u32 last_time=0; + GF_BitStream *bs = gf_bs_new(af_data, 188, GF_BITSTREAM_WRITE); + + if (ntp) { + last_time = 1000*(ntp>>32); + last_time += 1000*(ntp&0xFFFFFFFF)/0xFFFFFFFF; + } else if (timescale) { + last_time = (u32) (1000*timecode/timescale); + } + if (temi_url && (!*last_url_time || (last_time - *last_url_time + 1 >= temi_url_insertion_delay)) ) { + *last_url_time = last_time + 1; + len = 0; + gf_bs_write_int(bs, GF_M2TS_AFDESC_LOCATION_DESCRIPTOR, 8); + gf_bs_write_int(bs, len, 8); + + gf_bs_write_int(bs, 0, 1); //force_reload + gf_bs_write_int(bs, 0, 1); //is_announcement + gf_bs_write_int(bs, 0, 1); //splicing_flag + gf_bs_write_int(bs, 0, 1); //use_base_temi_url + gf_bs_write_int(bs, 0xFF, 5); //reserved + gf_bs_write_int(bs, timeline_id, 7); //timeline_id + + if (temi_url) { + char *url = (char *)temi_url; + if (!strnicmp(temi_url, "http://", 7)) { + gf_bs_write_int(bs, 1, 8); //url_scheme + url = (char *) temi_url + 7; + } else if (!strnicmp(temi_url, "https://", 8)) { + gf_bs_write_int(bs, 2, 8); //url_scheme + url = (char *) temi_url + 8; + } else { + gf_bs_write_int(bs, 0, 8); //url_scheme + } + gf_bs_write_u8(bs, (u32) strlen(url)); //url_path_len + gf_bs_write_data(bs, url, (u32) strlen(url) ); //url + gf_bs_write_u8(bs, 0); //nb_addons + } + //rewrite len + len = (u32) gf_bs_get_position(bs) - 2; + af_data[1] = len; + } + + if (timescale || ntp) { + Bool use64 = (timecode > 0xFFFFFFFFUL) ? GF_TRUE : GF_FALSE; + len = 3; //3 bytes flags + + if (timescale) len += 4 + (use64 ? 8 : 4); + if (ntp) len += 8; + + //write timeline descriptor + gf_bs_write_int(bs, GF_M2TS_AFDESC_TIMELINE_DESCRIPTOR, 8); + gf_bs_write_int(bs, len, 8); + + gf_bs_write_int(bs, timescale ? (use64 ? 2 : 1) : 0, 2); //has_timestamp + gf_bs_write_int(bs, ntp ? 1 : 0, 1); //has_ntp + gf_bs_write_int(bs, 0, 1); //has_ptp + gf_bs_write_int(bs, 0, 2); //has_timecode + gf_bs_write_int(bs, 0, 1); //force_reload + gf_bs_write_int(bs, 0, 1); //paused + gf_bs_write_int(bs, 0, 1); //discontinuity + gf_bs_write_int(bs, 0xFF, 7); //reserved + gf_bs_write_int(bs, timeline_id, 8); //timeline_id + if (timescale) { + gf_bs_write_u32(bs, timescale); //timescale + if (use64) + gf_bs_write_u64(bs, timecode); //timestamp + else + gf_bs_write_u32(bs, (u32) timecode); //timestamp + } + if (ntp) { + gf_bs_write_u64(bs, ntp); //ntp + } + } + res = (u32) gf_bs_get_position(bs); + gf_bs_del(bs); + return res; +} + +#ifndef GPAC_DISABLE_ISOM + +static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) +{ + char af_data[188]; + GF_ESIMP4 *priv = (GF_ESIMP4 *)ifce->input_udta; + if (!priv) return GF_BAD_PARAM; + + switch (act_type) { + case GF_ESI_INPUT_DATA_FLUSH: + { + GF_ESIPacket pck; +#ifndef GPAC_DISABLE_TTXT + GF_List *cues = NULL; +#endif + 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; + } + + memset(&pck, 0, sizeof(GF_ESIPacket)); + + pck.flags = GF_ESI_DATA_AU_START | GF_ESI_DATA_HAS_CTS; + if (priv->sample->IsRAP) pck.sap_type = priv->sample->IsRAP; + pck.cts = priv->sample->DTS + priv->ts_offset; + if (priv->is_repeat) pck.flags |= GF_ESI_DATA_REPEAT; + + if (priv->timeline_id) { + Bool deactivate_temi=GF_FALSE; + u64 ntp=0; + u64 tc = priv->sample->DTS + priv->sample->CTS_Offset + priv->cts_dts_shift; + Bool insert_temi=GF_FALSE; + if (temi_disable_loop) { + tc += priv->ts_offset; + } + + if (temi_offset) { + tc += ((u64) temi_offset) * ifce->timescale / 1000; + } + + if (priv->insert_ntp) { + u32 sec, frac; + gf_net_get_ntp(&sec, &frac); + ntp = sec; + ntp <<= 32; + ntp |= frac; + } + if (!temi_period) { + //toggle temi at RAP POINTS ONLY + if (request_temi_toggle && priv->sample->IsRAP) { + temi_on = !temi_on; + if (!temi_on) { + deactivate_temi = GF_TRUE; + } + fprintf(stderr, "Turning TEMI %st at DTS "LLU" (%g sec)\n", temi_on ? "on" : "off" , priv->sample->DTS, ((Double)priv->sample->DTS)/ifce->timescale); + request_temi_toggle = GF_FALSE; + } + insert_temi = temi_on; + } else { + + if (!temi_on) { + if (priv->sample->IsRAP && ((priv->sample->DTS - temi_period_last_dts) >= temi_period * ifce->timescale)) { + temi_on = GF_TRUE; + temi_period_last_dts = priv->sample->DTS; + fprintf(stderr, "Turning TEMI on at DTS "LLU" (%g sec)\n", priv->sample->DTS, ((Double)priv->sample->DTS)/ifce->timescale); + } + } else { + if (!temi_single_toggle && priv->sample->IsRAP && ((priv->sample->DTS - temi_period_last_dts) >= temi_period * ifce->timescale)) { + temi_on = GF_FALSE; + temi_period_last_dts = priv->sample->DTS; + fprintf(stderr, "Turning TEMI off at DTS "LLU" (%g sec)\n", priv->sample->DTS, ((Double)priv->sample->DTS)/ifce->timescale); + deactivate_temi = GF_TRUE; + } + } + insert_temi = temi_on; + } + + if (insert_temi) { + pck.mpeg2_af_descriptors_size = format_af_descriptor(af_data, priv->timeline_id - 1, tc, ifce->timescale, ntp, priv->temi_url, &priv->last_temi_url); + pck.mpeg2_af_descriptors = af_data; + } else if (deactivate_temi) { + pck.mpeg2_af_descriptors_size = format_af_descriptor(af_data, priv->timeline_id - 1, 0, 0, 0, "", &priv->last_temi_url); + pck.mpeg2_af_descriptors = af_data; + } + } + + if (priv->nb_repeat_last) { + pck.cts += priv->nb_repeat_last*ifce->timescale * priv->image_repeat_ms / 1000; + } + + pck.dts = pck.cts; + if (priv->cts_dts_shift) { + pck.cts += + priv->cts_dts_shift; + pck.flags |= GF_ESI_DATA_HAS_DTS; + } + + if (priv->sample->CTS_Offset) { + pck.cts += priv->sample->CTS_Offset; + pck.flags |= GF_ESI_DATA_HAS_DTS; + } + + if (priv->sample->IsRAP && priv->dsi && priv->dsi_size) { + pck.data = (char*)priv->dsi; + pck.data_len = priv->dsi_size; + ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + pck.flags &= ~GF_ESI_DATA_AU_START; + } + + pck.flags |= GF_ESI_DATA_AU_END; + pck.data = priv->sample->data; + pck.data_len = priv->sample->dataLength; + pck.duration = gf_isom_get_sample_duration(priv->mp4, priv->track, priv->sample_number+1); +#ifndef GPAC_DISABLE_TTXT + if (priv->mtype==GF_ISOM_MEDIA_TEXT && priv->mstype==GF_ISOM_SUBTYPE_WVTT) { + u64 start; + GF_WebVTTCue *cue; + GF_List *gf_webvtt_parse_iso_cues(GF_ISOSample *iso_sample, u64 start); + start = (priv->sample->DTS * 1000) / ifce->timescale; + cues = gf_webvtt_parse_iso_cues(priv->sample, start); + if (gf_list_count(cues)>1) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] More than one cue in sample\n")); + } + cue = (GF_WebVTTCue *)gf_list_get(cues, 0); + if (cue) { + pck.data = cue->text; + pck.data_len = (u32)strlen(cue->text)+1; + } else { + pck.data = NULL; + pck.data_len = 0; + } + } +#endif + ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] Track %d: sample %d CTS %d\n", priv->track, priv->sample_number+1, pck.cts)); + +#ifndef GPAC_DISABLE_VTT + if (cues) { + while (gf_list_count(cues)) { + GF_WebVTTCue *cue = (GF_WebVTTCue *)gf_list_get(cues, 0); + gf_list_rem(cues, 0); + gf_webvtt_cue_del(cue); + } + gf_list_del(cues); + cues = NULL; + } +#endif + gf_isom_sample_del(&priv->sample); + priv->sample_number++; + + if (!priv->source->real_time && !priv->is_repeat) { + priv->source->samples_done++; + gf_set_progress("MPEG-2 TS Muxing", priv->source->samples_done, priv->source->samples_count); + } + + 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; + priv->is_repeat = (priv->sample_count==1) ? GF_TRUE : GF_FALSE; + } + else if (priv->image_repeat_ms && priv->source->nb_real_streams) { + priv->nb_repeat_last++; + priv->sample_number--; + priv->is_repeat = GF_TRUE; + } else { + if (!(ifce->caps & GF_ESI_STREAM_IS_OVER)) { + ifce->caps |= GF_ESI_STREAM_IS_OVER; + if (priv->sample_count>1) { + assert(priv->source->nb_real_streams); + priv->source->nb_real_streams--; + } + } + } + } + } + return GF_OK; + + case GF_ESI_INPUT_DESTROY: + 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: + return GF_BAD_PARAM; + } +} + +static void fill_isom_es_ifce(M2TSSource *source, GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_num, u32 bifs_use_pes, Bool compute_max_size) +{ + GF_ESIMP4 *priv; + char *_lan; + GF_ESD *esd; + Bool is_hevc=GF_FALSE; + u64 avg_rate, duration; + s32 ref_count; + s64 mediaOffset; + + GF_SAFEALLOC(priv, GF_ESIMP4); + if (!priv) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate MP4 input handler\n")); + return; + } + + priv->mp4 = mp4; + priv->track = track_num; + priv->mtype = gf_isom_get_media_type(priv->mp4, priv->track); + priv->mstype = gf_isom_get_media_subtype(priv->mp4, priv->track, 1); + priv->loop = source->real_time ? GF_TRUE : GF_FALSE; + priv->sample_count = gf_isom_get_sample_count(mp4, track_num); + source->samples_count += priv->sample_count; + if (priv->sample_count>1) + source->nb_real_streams++; + + priv->source = source; + memset(ifce, 0, sizeof(GF_ESInterface)); + ifce->stream_id = gf_isom_get_track_id(mp4, track_num); + + esd = gf_media_map_esd(mp4, track_num, 0); + + if (esd) { + ifce->stream_type = esd->decoderConfig->streamType; + ifce->object_type_indication = esd->decoderConfig->objectTypeIndication; + if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->dataLength) { + switch (esd->decoderConfig->objectTypeIndication) { + case GF_CODECID_AAC_MPEG4: + case GF_CODECID_AAC_MPEG2_MP: + case GF_CODECID_AAC_MPEG2_LCP: + case GF_CODECID_AAC_MPEG2_SSRP: + case GF_CODECID_MPEG4_PART2: + ifce->decoder_config = (char *)gf_malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); + ifce->decoder_config_size = esd->decoderConfig->decoderSpecificInfo->dataLength; + memcpy(ifce->decoder_config, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + if (esd->decoderConfig->objectTypeIndication == GF_CODECID_MPEG4_PART2) { + priv->dsi = (char *)gf_malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); + priv->dsi_size = esd->decoderConfig->decoderSpecificInfo->dataLength; + memcpy(priv->dsi, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + } + break; + case GF_CODECID_HEVC: + case GF_CODECID_LHVC: + is_hevc=GF_TRUE; + case GF_CODECID_AVC: + case GF_CODECID_SVC: + case GF_CODECID_MVC: + gf_isom_set_nalu_extract_mode(mp4, track_num, GF_ISOM_NALU_EXTRACT_LAYER_ONLY | GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG | GF_ISOM_NALU_EXTRACT_ANNEXB_FLAG | GF_ISOM_NALU_EXTRACT_VDRD_FLAG); + break; + case GF_CODECID_WEBVTT: + ifce->decoder_config = (char *)gf_malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); + ifce->decoder_config_size = esd->decoderConfig->decoderSpecificInfo->dataLength; + memcpy(ifce->decoder_config, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + break; + } + } + gf_odf_desc_del((GF_Descriptor *)esd); + } + gf_isom_get_media_language(mp4, track_num, &_lan); + if (!_lan || !strcmp(_lan, "und")) { + ifce->lang = 0; + } else { + ifce->lang = GF_4CC(_lan[0],_lan[1],_lan[2],' '); + } + if (_lan) { + gf_free(_lan); + } + + ifce->timescale = gf_isom_get_media_timescale(mp4, track_num); + ifce->duration = gf_isom_get_media_timescale(mp4, track_num); + avg_rate = gf_isom_get_media_data_size(mp4, track_num); + if (!avg_rate) return; + avg_rate *= ifce->timescale * 8; + if (0!=(duration=gf_isom_get_media_duration(mp4, track_num))) + avg_rate /= duration; + + ifce->bit_rate = (u32) avg_rate; + ifce->duration = (Double) (s64) gf_isom_get_media_duration(mp4, track_num); + ifce->duration /= ifce->timescale; + + GF_SAFEALLOC(ifce->sl_config, GF_SLConfig); + if (!ifce->sl_config) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate interface SLConfig\n")); + return; + } + + ifce->sl_config->tag = GF_ODF_SLC_TAG; + ifce->sl_config->useAccessUnitStartFlag = 1; + ifce->sl_config->useAccessUnitEndFlag = 1; + ifce->sl_config->useRandomAccessPointFlag = 1; + ifce->sl_config->useTimestampsFlag = 1; + ifce->sl_config->timestampLength = 33; + ifce->sl_config->timestampResolution = ifce->timescale; + + /*test mode in which time stamps are 90khz and not coded but copied over from PES header*/ + if (bifs_use_pes==2) { + ifce->sl_config->timestampLength = 0; + ifce->sl_config->timestampResolution = 90000; + } + +#ifdef GPAC_DISABLE_ISOM_WRITE + fprintf(stderr, "Warning: GPAC was compiled without ISOM Write support, can't set SL Config!\n"); +#else + gf_isom_set_extraction_slc(mp4, track_num, 1, ifce->sl_config); +#endif + + ifce->input_ctrl = mp4_input_ctrl; + if (priv != ifce->input_udta) { + if (ifce->input_udta) + gf_free(ifce->input_udta); + ifce->input_udta = priv; + } + + + if (! gf_isom_get_edit_list_type(mp4, track_num, &mediaOffset)) { + priv->ts_offset = mediaOffset; + } + + if (gf_isom_has_time_offset(mp4, track_num)==2) { + priv->cts_dts_shift = gf_isom_get_cts_to_dts_shift(mp4, track_num); + } + + ifce->depends_on_stream = 0; + ref_count = gf_isom_get_reference_count(mp4, track_num, GF_ISOM_REF_SCAL); + if (ref_count > 0) { + gf_isom_get_reference_ID(mp4, track_num, GF_ISOM_REF_SCAL, (u32) ref_count, &ifce->depends_on_stream); + } else if (is_hevc) { + ref_count = gf_isom_get_reference_count(mp4, track_num, GF_ISOM_REF_BASE); + if (ref_count > 0) { + gf_isom_get_reference_ID(mp4, track_num, GF_ISOM_REF_BASE, (u32) ref_count, &ifce->depends_on_stream); + } + } + + if (compute_max_size) { + u32 i; + for (i=0; i < priv->sample_count; i++) { + u32 s = gf_isom_get_sample_size(mp4, track_num, i+1); + if (s>source->max_sample_size) source->max_sample_size = s; + } + } + +} + +#endif //GPAC_DISABLE_ISOM + + +#ifndef GPAC_DISABLE_SENG +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 + if (ifce->input_udta) + gf_free(ifce->input_udta); + ifce->input_udta = NULL; + return GF_OK; + } + + return GF_OK; +} +#endif + + +#ifndef GPAC_DISABLE_STREAMING +typedef struct +{ + /*RTP channel*/ + GF_RTPChannel *rtp_ch; + + /*depacketizer*/ + GF_RTPDepacketizer *depacketizer; + + GF_ESIPacket pck; + + GF_ESInterface *ifce; + + Bool cat_dsi, is_264; + void *dsi_and_rap; + u32 avc_dsi_size; + + Bool use_carousel; + u32 au_sn; + + s64 ts_offset; + Bool rtcp_init; + M2TSSource *source; + + u32 min_dts_inc; + u64 prev_cts; + u64 prev_dts; +} GF_ESIRTP; + +static GF_Err rtp_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) +{ + u32 size, PayloadStart; + GF_Err e; + GF_RTPHeader hdr; + char buffer[8000]; + GF_ESIRTP *rtp = (GF_ESIRTP*)ifce->input_udta; + + if (!ifce->input_udta) return GF_BAD_PARAM; + + switch (act_type) { + case GF_ESI_INPUT_DATA_FLUSH: + /*flush rtcp channel*/ + while (1) { + Bool has_sr = GF_FALSE; + size = gf_rtp_read_rtcp(rtp->rtp_ch, buffer, 8000); + if (!size) break; + e = gf_rtp_decode_rtcp(rtp->rtp_ch, buffer, size, &has_sr); + + if (e == GF_EOS) ifce->caps |= GF_ESI_STREAM_IS_OVER; + + if (has_sr && !rtp->rtcp_init) { + Double time = rtp->rtp_ch->last_SR_NTP_sec; + time += ((Double)rtp->rtp_ch->last_SR_NTP_frac)/0xFFFFFFFF; + if (!rtp->source->last_ntp) { + rtp->source->last_ntp = time; + } + if (time >= rtp->source->last_ntp) { + time -= rtp->source->last_ntp; + } else { + time = 0; + } + rtp->ts_offset = rtp->rtp_ch->last_SR_rtp_time; + rtp->ts_offset -= (s64) (time * rtp->rtp_ch->TimeScale); + rtp->rtcp_init = GF_TRUE; + } + } + /*flush rtp channel*/ + while (1) { + size = gf_rtp_read_rtp(rtp->rtp_ch, buffer, 8000); + if (!size) break; + e = gf_rtp_decode_rtp(rtp->rtp_ch, buffer, size, &hdr, &PayloadStart); + if (e) return e; + gf_rtp_depacketizer_process(rtp->depacketizer, &hdr, buffer + PayloadStart, size - PayloadStart); + } + return GF_OK; + case GF_ESI_INPUT_DESTROY: + gf_rtp_depacketizer_del(rtp->depacketizer); + if (rtp->dsi_and_rap) gf_free(rtp->dsi_and_rap); + gf_rtp_del(rtp->rtp_ch); + gf_free(rtp); + + if (ifce->decoder_config) { + gf_free(ifce->decoder_config); + ifce->decoder_config = NULL; + } + ifce->input_udta = NULL; + return GF_OK; + } + return GF_OK; +} + +static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader *hdr, GF_Err e) +{ + GF_ESIRTP *rtp = (GF_ESIRTP*)udta; + + /*sync not found yet, cannot start (since we don't support PCR discontinuities yet ...)*/ + if (!rtp->rtcp_init) return; + + /*try to compute a DTS*/ + if (hdr->accessUnitStartFlag && !hdr->decodingTimeStampFlag) { + if (!rtp->prev_cts) { + rtp->prev_cts = rtp->prev_dts = hdr->compositionTimeStamp; + } + + if (hdr->compositionTimeStamp > rtp->prev_cts) { + u32 diff = (u32) (hdr->compositionTimeStamp - rtp->prev_cts); + if (!rtp->min_dts_inc || (rtp->min_dts_inc > diff)) { + rtp->min_dts_inc = diff; + rtp->prev_dts = hdr->compositionTimeStamp - diff; + } + } + hdr->decodingTimeStampFlag = 1; + hdr->decodingTimeStamp = rtp->prev_dts + rtp->min_dts_inc; + rtp->prev_dts += rtp->min_dts_inc; + if (hdr->compositionTimeStamp < hdr->decodingTimeStamp) { + hdr->decodingTimeStamp = hdr->compositionTimeStamp; + } + } + + rtp->pck.data = payload; + rtp->pck.data_len = size; + rtp->pck.dts = hdr->decodingTimeStamp + rtp->ts_offset; + rtp->pck.cts = hdr->compositionTimeStamp + rtp->ts_offset; + rtp->pck.flags = 0; + if (hdr->compositionTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_CTS; + if (hdr->decodingTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_DTS; + if (hdr->accessUnitStartFlag) rtp->pck.flags |= GF_ESI_DATA_AU_START; + if (hdr->accessUnitEndFlag) rtp->pck.flags |= GF_ESI_DATA_AU_END; + if (hdr->randomAccessPointFlag) rtp->pck.sap_type = 1; + + if (rtp->use_carousel) { + if ((hdr->AU_sequenceNumber==rtp->au_sn) && hdr->randomAccessPointFlag) rtp->pck.flags |= GF_ESI_DATA_REPEAT; + rtp->au_sn = hdr->AU_sequenceNumber; + } + + if (rtp->is_264) { + if (!payload) return; + + /*send a NALU delim: copy over NAL ref idc*/ + if (hdr->accessUnitStartFlag) { + char sc[6]; + sc[0] = sc[1] = sc[2] = 0; + sc[3] = 1; + sc[4] = (payload[4] & 0x60) | GF_AVC_NALU_ACCESS_UNIT; + sc[5] = 0xF0 /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/; + + rtp->pck.data = sc; + rtp->pck.data_len = 6; + rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); + + rtp->pck.flags &= ~GF_ESI_DATA_AU_START; + + /*since we don't inspect the RTP content, we can only concatenate SPS and PPS indicated in SDP*/ + if (hdr->randomAccessPointFlag && rtp->dsi_and_rap) { + rtp->pck.data = (char*)rtp->dsi_and_rap; + rtp->pck.data_len = rtp->avc_dsi_size; + + rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); + } + + rtp->pck.data = payload; + rtp->pck.data_len = size; + } + + rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); + } else { + if (rtp->cat_dsi && hdr->randomAccessPointFlag && hdr->accessUnitStartFlag) { + if (rtp->dsi_and_rap) gf_free(rtp->dsi_and_rap); + rtp->pck.data_len = size + rtp->depacketizer->sl_map.configSize; + rtp->dsi_and_rap = gf_malloc(sizeof(char)*(rtp->pck.data_len)); + memcpy(rtp->dsi_and_rap, rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize); + memcpy((char *) rtp->dsi_and_rap + rtp->depacketizer->sl_map.configSize, payload, size); + rtp->pck.data = (char*)rtp->dsi_and_rap; + } + rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); + } +} + +static void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp, M2TSSource *source) +{ + u32 i; + GF_Err e; + GF_X_Attribute*att; + GF_ESIRTP *rtp; + GF_RTPMap*map; + GF_SDPConnection *conn; + GF_RTSPTransport trans; + + /*check connection*/ + conn = sdp->c_connection; + if (!conn) conn = (GF_SDPConnection*)gf_list_get(media->Connections, 0); + + /*check payload type*/ + map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0); + GF_SAFEALLOC(rtp, GF_ESIRTP); + if (!rtp) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate RTP input handler\n")); + return; + } + + memset(ifce, 0, sizeof(GF_ESInterface)); + rtp->rtp_ch = gf_rtp_new(); + i=0; + while ((att = (GF_X_Attribute*)gf_list_enum(media->Attributes, &i))) { + if (!stricmp(att->Name, "mpeg4-esid") && att->Value) ifce->stream_id = atoi(att->Value); + } + + memset(&trans, 0, sizeof(GF_RTSPTransport)); + trans.Profile = media->Profile; + trans.source = conn ? conn->host : sdp->o_address; + trans.IsUnicast = gf_sk_is_multicast_address(trans.source) ? GF_FALSE : GF_TRUE; + if (!trans.IsUnicast) { + trans.port_first = media->PortNumber; + trans.port_last = media->PortNumber + 1; + trans.TTL = conn ? conn->TTL : 0; + } else { + trans.client_port_first = media->PortNumber; + trans.client_port_last = media->PortNumber + 1; + } + + if (gf_rtp_setup_transport(rtp->rtp_ch, &trans, NULL) != GF_OK) { + gf_rtp_del(rtp->rtp_ch); + fprintf(stderr, "Cannot initialize RTP transport\n"); + return; + } + /*setup depacketizer*/ + rtp->depacketizer = gf_rtp_depacketizer_new(media, rtp_sl_packet_cbk, rtp); + if (!rtp->depacketizer) { + gf_rtp_del(rtp->rtp_ch); + fprintf(stderr, "Cannot create RTP depacketizer\n"); + return; + } + /*setup channel*/ + gf_rtp_setup_payload(rtp->rtp_ch, map->PayloadType, map->ClockRate); + ifce->input_udta = rtp; + ifce->input_ctrl = rtp_input_ctrl; + rtp->ifce = ifce; + rtp->source = source; + + ifce->object_type_indication = rtp->depacketizer->sl_map.CodecID; + 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 GF_CODECID_MPEG4_PART2: + rtp->cat_dsi = GF_TRUE; + break; + case GF_CODECID_AVC: + case GF_CODECID_SVC: + case GF_CODECID_MVC: + rtp->is_264 = GF_TRUE; + rtp->depacketizer->flags |= GF_RTP_AVC_USE_ANNEX_B; + { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_AVCConfig *avccfg = gf_odf_avc_cfg_read(rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize); + if (avccfg) { + GF_AVCConfigSlot *slc; + u32 i; + GF_BitStream *bs; + + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + for (i=0; isequenceParameterSets); i++) { + slc = (GF_AVCConfigSlot*)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_AVCConfigSlot*)gf_list_get(avccfg->pictureParameterSets, i); + gf_bs_write_u32(bs, 1); + gf_bs_write_data(bs, slc->data, slc->size); + } + gf_bs_get_content(bs, (char **) &rtp->dsi_and_rap, &rtp->avc_dsi_size); + gf_bs_del(bs); + } + gf_odf_avc_cfg_del(avccfg); +#endif + } + break; + case GF_CODECID_AAC_MPEG4: + ifce->decoder_config = (char*)gf_malloc(sizeof(char) * rtp->depacketizer->sl_map.configSize); + ifce->decoder_config_size = rtp->depacketizer->sl_map.configSize; + memcpy(ifce->decoder_config, rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize); + break; + } + } + if (rtp->depacketizer->sl_map.StreamStateIndication) { + rtp->use_carousel = GF_TRUE; + rtp->au_sn=0; + } + + gf_rtp_depacketizer_reset(rtp->depacketizer, GF_TRUE); + e = gf_rtp_initialize(rtp->rtp_ch, 0x100000ul, GF_FALSE, 0, 10, 200, NULL); + if (e!=GF_OK) { + gf_rtp_del(rtp->rtp_ch); + fprintf(stderr, "Cannot initialize RTP channel: %s\n", gf_error_to_string(e)); + return; + } + fprintf(stderr, "RTP interface initialized\n"); +} +#endif /*GPAC_DISABLE_STREAMING*/ + +#ifndef GPAC_DISABLE_SENG +static GF_Err void_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) +{ + return GF_OK; +} +#endif + +/*AAC import features*/ +#ifndef GPAC_DISABLE_PLAYER + +void *audio_prog = NULL; +static void SampleCallBack(void *calling_object, u16 ESID, char *data, u32 size, u64 ts); +#define DONT_USE_TERMINAL_MODULE_API +#include "../../modules/aac_in/aac_in.c" +AACReader *aac_reader = NULL; +u64 audio_discontinuity_offset = 0; + +/*create an OD codec and encode the descriptor*/ +static GF_Err encode_audio_desc(GF_ESD *esd, GF_SimpleDataDescriptor *audio_desc) +{ + GF_Err e; + GF_ODCodec *odc = gf_odf_codec_new(); + GF_ODUpdate *od_com = (GF_ODUpdate*)gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); + GF_ObjectDescriptor *od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); + assert( esd ); + assert( audio_desc ); + gf_list_add(od->ESDescriptors, esd); + od->objectDescriptorID = AUDIO_DATA_ESID; + gf_list_add(od_com->objectDescriptors, od); + + e = gf_odf_codec_add_com(odc, (GF_ODCom*)od_com); + if (e) { + fprintf(stderr, "Audio input error add the command to be encoded\n"); + return e; + } + e = gf_odf_codec_encode(odc, 0); + if (e) { + fprintf(stderr, "Audio input error encoding the descriptor\n"); + return e; + } + e = gf_odf_codec_get_au(odc, &audio_desc->data, &audio_desc->size); + if (e) { + fprintf(stderr, "Audio input error getting the descriptor\n"); + return e; + } + e = gf_odf_com_del((GF_ODCom**)&od_com); + if (e) { + fprintf(stderr, "Audio input error deleting the command\n"); + return e; + } + gf_odf_codec_del(odc); + + return GF_OK; +} + +#endif + + +static void SampleCallBack(void *calling_object, u16 ESID, char *data, u32 size, u64 ts) +{ + u32 i; + //fprintf(stderr, "update: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); + + if (calling_object) { + M2TSSource *source = (M2TSSource *)calling_object; + +#ifndef GPAC_DISABLE_PLAYER + if (ESID == AUDIO_DATA_ESID) { + if (audio_OD_stream_id != (u32)-1) { + /*this is the first time we get some audio data. Therefore we are sure we can retrieve the audio descriptor. Then we'll + send it by calling this callback recursively so that a player gets the audio descriptor before audio data. + Hack: the descriptor is carried thru the input_udta, you shall delete it*/ + GF_SimpleDataDescriptor *audio_desc = source->streams[audio_OD_stream_id].input_udta; + if (audio_desc && !audio_desc->data) /*intended for HTTP/AAC: an empty descriptor was set (vs already filled for RTP/UDP MP3)*/ + { + /*get the audio descriptor and encode it*/ + GF_ESD *esd = AAC_GetESD(aac_reader); + assert(esd->slConfig->timestampResolution); + esd->slConfig->useAccessUnitStartFlag = 1; + esd->slConfig->useAccessUnitEndFlag = 1; + esd->slConfig->useTimestampsFlag = 1; + esd->slConfig->timestampLength = 33; + /*audio stream, all samples are RAPs*/ + esd->slConfig->useRandomAccessPointFlag = 0; + esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; + for (i=0; inb_streams; i++) { + if (source->streams[i].stream_id == AUDIO_DATA_ESID) { + GF_Err e; + source->streams[i].timescale = esd->slConfig->timestampResolution; + e = gf_m2ts_program_stream_update_ts_scale(&source->streams[i], esd->slConfig->timestampResolution); + if (e != GF_OK) { + fprintf(stderr, "Failed updating TS program timescale\n"); + } + else if (!source->streams[i].sl_config) + source->streams[i].sl_config = (GF_SLConfig *)gf_odf_desc_new(GF_ODF_SLC_TAG); + + memcpy(source->streams[i].sl_config, esd->slConfig, sizeof(GF_SLConfig)); + break; + } + } + esd->ESID = AUDIO_DATA_ESID; + assert(audio_OD_stream_id != (u32)-1); + encode_audio_desc(esd, audio_desc); + + /*build the ESI*/ + { + /*audio OD descriptor: rap=1 and vers_inc=0*/ + GF_SAFEALLOC(source->streams[audio_OD_stream_id].input_udta, GF_ESIStream); + if (!source->streams[audio_OD_stream_id].input_udta) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate aac input handler\n")); + return; + } + ((GF_ESIStream*)source->streams[audio_OD_stream_id].input_udta)->rap = 1; + + /*we have the descriptor; now call this callback recursively so that a player gets the audio descriptor before audio data.*/ + source->repeat = 1; + SampleCallBack(source, AUDIO_OD_ESID, audio_desc->data, audio_desc->size, 0/*gf_m2ts_get_sys_clock(muxer)*/); + source->repeat = 0; + + /*clean*/ + gf_free(audio_desc->data); + gf_free(audio_desc); + gf_free(source->streams[audio_OD_stream_id].input_udta); + source->streams[audio_OD_stream_id].input_udta = NULL; + } + } + } + /*update the timescale if needed*/ + else if (!source->audio_configured) { + GF_ESD *esd = AAC_GetESD(aac_reader); + assert(esd->slConfig->timestampResolution); + for (i=0; inb_streams; i++) { + if (source->streams[i].stream_id == AUDIO_DATA_ESID) { + GF_Err e; + source->streams[i].timescale = esd->slConfig->timestampResolution; + source->streams[i].decoder_config = esd->decoderConfig->decoderSpecificInfo->data; + source->streams[i].decoder_config_size = esd->decoderConfig->decoderSpecificInfo->dataLength; + esd->decoderConfig->decoderSpecificInfo->data = NULL; + esd->decoderConfig->decoderSpecificInfo->dataLength = 0; + e = gf_m2ts_program_stream_update_ts_scale(&source->streams[i], esd->slConfig->timestampResolution); + if (!e) + source->audio_configured = 1; + break; + } + } + gf_odf_desc_del((GF_Descriptor *)esd); + } + + /*overwrite timing as it is flushed to 0 on discontinuities*/ + ts += audio_discontinuity_offset; + } +#endif + i=0; + while (inb_streams) { + if (source->streams[i].output_ctrl==NULL) { + fprintf(stderr, "MULTIPLEX NOT YET CREATED\n"); + return; + } + if (source->streams[i].stream_id == ESID) { + GF_ESIStream *priv = (GF_ESIStream *)source->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_HAS_DTS; + pck.flags |= GF_ESI_DATA_AU_START; + pck.flags |= GF_ESI_DATA_AU_END; + if (ts) pck.cts = pck.dts = ts; + + if (priv->rap) + pck.sap_type = 1; + if (source->repeat || !priv->vers_inc) { + pck.flags |= GF_ESI_DATA_REPEAT; + fprintf(stderr, "RAP carousel from scene engine sent: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); + } else { + if (ESID != AUDIO_DATA_ESID && ESID != VIDEO_DATA_ESID) /*don't log A/V inputs*/ + fprintf(stderr, "Update from scene engine sent: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); + } + source->streams[i].output_ctrl(&source->streams[i], GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + return; + } + i++; + } + } + return; +} + +//static gf_seng_callback * SampleCallBack = &mySampleCallBack; + + +static volatile Bool run = 1; + +#ifndef GPAC_DISABLE_SENG +static GF_ESIStream * set_broadcast_params(M2TSSource *source, 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 (source->streams[i].stream_id == esid) { + priv = (GF_ESIStream *)source->streams[i].input_udta; + esi = &source->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(source->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; +} +#endif + +#ifndef GPAC_DISABLE_SENG + +static u32 seng_output(void *param) +{ + GF_Err e; + u64 last_src_modif, mod_time; + M2TSSource *source = (M2TSSource *)param; + GF_SceneEngine *seng = source->seng; +#ifndef GPAC_DISABLE_PLAYER + GF_SimpleDataDescriptor *audio_desc; +#endif + Bool update_context=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; + e = GF_OK; + gf_sleep(2000); /*TODO: events instead? What are we waiting for?*/ + gf_seng_encode_context(seng, SampleCallBack); + + last_src_modif = source->bifs_src_name ? gf_file_modification_time(source->bifs_src_name) : 0; + + /*send the audio descriptor*/ +#ifndef GPAC_DISABLE_PLAYER + if (source->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_FULL && audio_OD_stream_id!=(u32)-1) { + audio_desc = source->streams[audio_OD_stream_id].input_udta; + if (audio_desc && audio_desc->data) /*RTP/UDP + MP3 case*/ + { + assert(audio_OD_stream_id != (u32)-1); + assert(!aac_reader); /*incompatible with AAC*/ + source->repeat = 1; + SampleCallBack(source, AUDIO_OD_ESID, audio_desc->data, audio_desc->size, 0/*gf_m2ts_get_sys_clock(muxer)*/); + source->repeat = 0; + gf_free(audio_desc->data); + gf_free(audio_desc); + source->streams[audio_OD_stream_id].input_udta = NULL; + } + } +#endif + + while (run) { + if (!gf_prompt_has_input()) { + if (source->bifs_src_name) { + mod_time = gf_file_modification_time(source->bifs_src_name); + if (mod_time != last_src_modif) { + FILE *srcf; + char flag_buf[201], *flag; + fprintf(stderr, "Update file modified - processing\n"); + last_src_modif = mod_time; + + srcf = gf_fopen(source->bifs_src_name, "rt"); + if (!srcf) continue; + + /*checks if we have a broadcast config*/ + if (!fgets(flag_buf, 200, srcf)) + flag_buf[0] = '\0'; + gf_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(source, 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, source->bifs_src_name, SampleCallBack); + if (e) { + fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); + } else + gf_seng_aggregate_context(seng, 0); + + update_context=1; + + + + } + } + if (update_context) { + source->repeat = 1; + e = gf_seng_encode_context(seng, SampleCallBack); + source->repeat = 0; + update_context = 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(stderr, "Enter command to send:\n"); + fflush(stdin); + szCom[0] = 0; + if (1 > scanf("%[^\t\n]", szCom)) { + fprintf(stderr, "No command has been properly entered, aborting.\n"); + break; + } + e = gf_seng_encode_from_string(seng, 0, 0, szCom, SampleCallBack); + if (e) { + fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); + } + update_context=1; + } + break; + case 'p': + { + char rad[GF_MAX_PATH]; + fprintf(stderr, "Enter output file name - \"std\" for stderr: "); + if (1 > scanf("%s", rad)) { + fprintf(stderr, "No outfile name has been entered, aborting.\n"); + break; + } + e = gf_seng_save_context(seng, !strcmp(rad, "std") ? NULL : rad); + fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e)); + } + break; + case 'q': + { + run = 0; + } + } + e = GF_OK; + } + } + + + return e ? 1 : 0; +} + +void fill_seng_es_ifce(GF_ESInterface *ifce, u32 i, GF_SceneEngine *seng, u32 period) +{ + GF_Err e = GF_OK; + u32 len; + GF_ESIStream *stream; + char *config_buffer = NULL; + + memset(ifce, 0, sizeof(GF_ESInterface)); + e = gf_seng_get_stream_config(seng, i, (u16*) &(ifce->stream_id), &config_buffer, &len, (u32*) &(ifce->stream_type), (u32*) &(ifce->object_type_indication), &(ifce->timescale)); + if (e) { + fprintf(stderr, "Cannot set the stream config for stream %d to %d: %s\n", ifce->stream_id, period, gf_error_to_string(e)); + } + + ifce->repeat_rate = period; + GF_SAFEALLOC(stream, GF_ESIStream); + if (!stream) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate SENG input handler\n")); + return; + } + + stream->rap = 1; + if (ifce->input_udta) + gf_free(ifce->input_udta); + ifce->input_udta = stream; + + //fprintf(stderr, "Caroussel period: %d\n", period); +// e = gf_seng_set_carousel_time(seng, ifce->stream_id, period); + if (e) { + fprintf(stderr, "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; + +} +#endif + +static Bool open_source(M2TSSource *source, char *src, u32 carousel_rate, u32 mpeg4_signaling, char *update, char *audio_input_ip, u16 audio_input_port, char *video_buffer, Bool force_real_time, u32 bifs_use_pes, const char *temi_url, Bool compute_max_size, Bool insert_ntp) +{ +#ifndef GPAC_DISABLE_STREAMING + GF_SDPInfo *sdp; +#endif + + memset(source, 0, sizeof(M2TSSource)); + source->mpeg4_signaling = mpeg4_signaling; + + /*open ISO file*/ +#ifndef GPAC_DISABLE_ISOM + if (gf_isom_probe_file(src)) { + u32 i; + u32 nb_tracks; + Bool has_bifs_od = 0; + Bool temi_assigned = 0; + u32 first_audio = 0; + u32 first_other = 0; + s64 min_offset = 0; + u32 min_offset_timescale = 0; + source->mp4 = gf_isom_open(src, GF_ISOM_OPEN_READ, 0); + if (!source->mp4) + return GF_FALSE; + source->nb_streams = 0; + source->real_time = force_real_time; + /*on MPEG-2 TS, carry 3GPP timed text as MPEG-4 Part17*/ + gf_isom_text_set_streaming_mode(source->mp4, 1); + nb_tracks = gf_isom_get_track_count(source->mp4); + + for (i=0; imp4, i+1) == GF_ISOM_MEDIA_HINT) + continue; + + fill_isom_es_ifce(source, &source->streams[i], source->mp4, i+1, bifs_use_pes, compute_max_size); + if (!source->streams[i].input_udta) continue; + if (min_offset > ((GF_ESIMP4 *)source->streams[i].input_udta)->ts_offset) { + min_offset = ((GF_ESIMP4 *)source->streams[i].input_udta)->ts_offset; + min_offset_timescale = source->streams[i].timescale; + } + + switch(source->streams[i].stream_type) { + case GF_STREAM_OD: + has_bifs_od = 1; + source->streams[i].repeat_rate = carousel_rate; + break; + case GF_STREAM_SCENE: + has_bifs_od = 1; + source->streams[i].repeat_rate = carousel_rate; + break; + case GF_STREAM_VISUAL: + /*turn on image repeat*/ + switch (source->streams[i].object_type_indication) { + case GF_CODECID_JPEG: + case GF_CODECID_PNG: + ((GF_ESIMP4 *)source->streams[i].input_udta)->image_repeat_ms = carousel_rate; + break; + default: + check_deps = 1; + if (gf_isom_get_sample_count(source->mp4, i+1)>1) { + /*get first visual stream as PCR*/ + if (!source->pcr_idx) { + source->pcr_idx = i+1; + if ((temi_id_1>=0) || (temi_id_2>=0)) { + temi_assigned = GF_TRUE; + ((GF_ESIMP4 *)source->streams[i].input_udta)->timeline_id = (u32) ( (temi_id_1>=0) ? temi_id_1 + 1 : temi_id_2 + 1 ); + ((GF_ESIMP4 *)source->streams[i].input_udta)->insert_ntp = insert_ntp; + + if (temi_url && (temi_id_1>=0)) + ((GF_ESIMP4 *)source->streams[i].input_udta)->temi_url = temi_url; + + if (temi_id_1>=0) temi_id_1 = -1; + else temi_id_2 = -1; + } + } + } + break; + } + break; + case GF_STREAM_AUDIO: + if (!first_audio) first_audio = i+1; + check_deps = 1; + break; + default: + /*log not supported stream type: %s*/ + break; + } + source->nb_streams++; + if (gf_isom_get_sample_count(source->mp4, i+1)>1) first_other = i+1; + + if (check_deps) { + u32 k; + Bool found_dep = 0; + for (k=0; kmp4, k+1) != GF_ISOM_MEDIA_OD) + continue; + + /*this stream is not refered to by any OD, send as regular PES*/ + if (gf_isom_has_track_reference(source->mp4, k+1, GF_ISOM_REF_OD, gf_isom_get_track_id(source->mp4, i+1) )==1) { + found_dep = 1; + break; + } + } + if (!found_dep) { + source->streams[i].caps |= GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS; + } + } + } + if (has_bifs_od && !source->mpeg4_signaling) source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; + if ( !temi_assigned && first_audio && ((temi_id_1>=0) || (temi_id_2>=0) ) ) { + ((GF_ESIMP4 *)source->streams[first_audio-1].input_udta)->timeline_id = (u32) ( (temi_id_1>=0) ? temi_id_1 + 1 : temi_id_2 + 1 ); + ((GF_ESIMP4 *)source->streams[first_audio-1].input_udta)->insert_ntp = insert_ntp; + + if (temi_url && (temi_id_1>=0) ) + ((GF_ESIMP4 *)source->streams[first_audio-1].input_udta)->temi_url = temi_url; + + if (temi_id_1>=0) temi_id_1 = -1; + else temi_id_2 = -1; + } + + /*if no visual PCR found, use first audio*/ + if (!source->pcr_idx) source->pcr_idx = first_audio; + if (!source->pcr_idx) source->pcr_idx = first_other; + if (source->pcr_idx) { + GF_ESIMP4 *priv; + source->pcr_idx-=1; + priv = source->streams[source->pcr_idx].input_udta; + gf_isom_set_default_sync_track(source->mp4, priv->track); + } + + if (min_offset < 0) { + for (i=0; inb_streams; i++) { + Double scale = source->streams[i].timescale; + scale /= min_offset_timescale; + ((GF_ESIMP4 *)source->streams[i].input_udta)->ts_offset += (s64) (-min_offset * scale); + } + } + + source->iod = gf_isom_get_root_od(source->mp4); + if (source->iod) { + GF_ObjectDescriptor*iod = (GF_ObjectDescriptor*)source->iod; + if (gf_list_count( ((GF_ObjectDescriptor*)source->iod)->ESDescriptors) == 0) { + gf_odf_desc_del(source->iod); + source->iod = NULL; + } else { + fprintf(stderr, "IOD found for program %s\n", src); + + /*if using 4over2, get rid of OD tracks*/ + if (source->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_SCENE) { + for (i=0; iESDescriptors); i++) { + u32 track_num, k; + GF_M2TSDescriptor *oddesc; + GF_ISOSample *sample; + GF_ESD *esd = gf_list_get(iod->ESDescriptors, i); + if (esd->decoderConfig->streamType!=GF_STREAM_OD) continue; + track_num = gf_isom_get_track_by_id(source->mp4, esd->ESID); + if (gf_isom_get_sample_count(source->mp4, track_num)>1) continue; + + sample = gf_isom_get_sample(source->mp4, track_num, 1, NULL); + if (sample->dataLength >= 255-2) { + gf_isom_sample_del(&sample); + continue; + } + /*rewrite ESD dependencies*/ + for (k=0; kESDescriptors); k++) { + GF_ESD *dep_esd = gf_list_get(iod->ESDescriptors, k); + if (dep_esd->dependsOnESID==esd->ESID) dep_esd->dependsOnESID = esd->dependsOnESID; + } + + for (k=0; knb_streams; k++) { + if (source->streams[k].stream_id==esd->ESID) { + source->streams[k].stream_type = 0; + break; + } + } + + if (!source->od_updates) source->od_updates = gf_list_new(); + GF_SAFEALLOC(oddesc, GF_M2TSDescriptor); + oddesc->data_len = sample->dataLength; + oddesc->data = sample->data; + oddesc->tag = GF_M2TS_MPEG4_ODUPDATE_DESCRIPTOR; + sample->data = NULL; + gf_isom_sample_del(&sample); + gf_list_add(source->od_updates, oddesc); + + gf_list_rem(iod->ESDescriptors, i); + i--; + gf_odf_desc_del((GF_Descriptor *) esd); + source->samples_count--; + } + } + + } + } + return 1; + } +#endif + + +#ifndef GPAC_DISABLE_STREAMING + /*open SDP file*/ + if (strstr(src, ".sdp")) { + GF_X_Attribute *att; + char *sdp_buf; + u32 sdp_size, i; + GF_Err e; + + e = gf_file_load_data(src, (u8 **) &sdp_buf, &sdp_size); + if (e) { + fprintf(stderr, "Error opening %s\n", src); + return 0; + } + + sdp = gf_sdp_info_new(); + e = gf_sdp_info_parse(sdp, sdp_buf, sdp_size); + 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 = (u32) strlen(buf64) - 1; + size = gf_base64_decode(buf64, size64, buf, 2000); + + gf_odf_desc_read(buf, size, &source->iod); + break; + } + + source->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(&source->streams[i], media, sdp, source); + switch(source->streams[i].stream_type) { + case GF_STREAM_OD: + case GF_STREAM_SCENE: + source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; + source->streams[i].repeat_rate = carousel_rate; + break; + } + if (!source->pcr_idx && (source->streams[i].stream_type == GF_STREAM_VISUAL)) { + source->pcr_idx = i+1; + } + } + + if (source->pcr_idx) source->pcr_idx-=1; + gf_sdp_info_del(sdp); + + return 2; + } else +#endif /*GPAC_DISABLE_STREAMING*/ + +#ifndef GPAC_DISABLE_SENG + if (strstr(src, ".bt")) //open .bt file + { + u32 i; + u32 load_type=0; + source->seng = gf_seng_init(source, src, load_type, NULL, (load_type == GF_SM_LOAD_DIMS) ? 1 : 0); + if (!source->seng) { + fprintf(stderr, "Cannot create scene engine\n"); + exit(1); + } + else { + fprintf(stderr, "Scene engine created.\n"); + } + assert( source ); + assert( source->seng); + source->iod = gf_seng_get_iod(source->seng); + if (! source->iod) { + fprintf(stderr, __FILE__": No IOD\n"); + } + + source->nb_streams = gf_seng_get_stream_count(source->seng); + source->rate = carousel_rate; + source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; + + for (i=0; inb_streams; i++) { + fill_seng_es_ifce(&source->streams[i], i, source->seng, source->rate); + //fprintf(stderr, "Fill interface\n"); + if (!source->pcr_idx && (source->streams[i].stream_type == GF_STREAM_AUDIO)) { + source->pcr_idx = i+1; + } + } + +#ifndef GPAC_DISABLE_PLAYER + /*when an audio input is present, declare it and store OD + ESD_U*/ + if (audio_input_ip) { + /*add the audio program*/ + source->pcr_idx = source->nb_streams; + source->streams[source->nb_streams].stream_type = GF_STREAM_AUDIO; + /*hack: http urls are not decomposed therefore audio_input_port remains null*/ + if (audio_input_port) { /*UDP/RTP*/ + source->streams[source->nb_streams].object_type_indication = GF_CODECID_MPEG_AUDIO; + } else { /*HTTP*/ + aac_reader->oti = source->streams[source->nb_streams].object_type_indication = GF_CODECID_AAC_MPEG4; + } + source->streams[source->nb_streams].input_ctrl = void_input_ctrl; + source->streams[source->nb_streams].stream_id = AUDIO_DATA_ESID; + source->streams[source->nb_streams].timescale = 1000; + + GF_SAFEALLOC(source->streams[source->nb_streams].input_udta, GF_ESIStream); + if (!source->streams[source->nb_streams].input_udta) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate audio input handler\n")); + return 0; + } + + ((GF_ESIStream*)source->streams[source->nb_streams].input_udta)->vers_inc = 1; /*increment version number at every audio update*/ + assert( source ); + //assert( source->iod); + if (source->iod && ((source->iod->tag!=GF_ODF_IOD_TAG) || (mpeg4_signaling != GF_M2TS_MPEG4_SIGNALING_SCENE))) { + /*create the descriptor*/ + GF_ESD *esd; + GF_SimpleDataDescriptor *audio_desc; + GF_SAFEALLOC(audio_desc, GF_SimpleDataDescriptor); + if (audio_input_port) { /*UDP/RTP*/ + esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = source->streams[source->nb_streams].stream_type; + esd->decoderConfig->objectTypeIndication = source->streams[source->nb_streams].object_type_indication; + } else { /*HTTP*/ + esd = AAC_GetESD(aac_reader); /*in case of AAC, we have to wait the first ADTS chunk*/ + } + assert( esd ); + esd->ESID = source->streams[source->nb_streams].stream_id; + if (esd->slConfig->timestampResolution) /*in case of AAC, we have to wait the first ADTS chunk*/ + encode_audio_desc(esd, audio_desc); + else + gf_odf_desc_del((GF_Descriptor *)esd); + + /*find the audio OD stream and attach its descriptor*/ + for (i=0; inb_streams; i++) { + if (source->streams[i].stream_id == AUDIO_OD_ESID) { + if (source->streams[i].input_udta) + gf_free(source->streams[i].input_udta); + source->streams[i].input_udta = (void*)audio_desc; /*Hack: the real input_udta type (for our SampleCallBack function) is GF_ESIStream*/ + audio_OD_stream_id = i; + break; + } + } + if (audio_OD_stream_id == (u32)-1) { + fprintf(stderr, "Error: could not find an audio OD stream with ESID=100 in '%s'\n", src); + return 0; + } + } else { + source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_SCENE; + } + source->nb_streams++; + } +#endif + + /*when an audio input is present, declare it and store OD + ESD_U*/ + if (video_buffer) { + /*add the video program*/ + source->streams[source->nb_streams].stream_type = GF_STREAM_VISUAL; + source->streams[source->nb_streams].object_type_indication = GF_CODECID_AVC; + source->streams[source->nb_streams].input_ctrl = void_input_ctrl; + source->streams[source->nb_streams].stream_id = VIDEO_DATA_ESID; + source->streams[source->nb_streams].timescale = 1000; + + GF_SAFEALLOC(source->streams[source->nb_streams].input_udta, GF_ESIStream); + if (!source->streams[source->nb_streams].input_udta) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate video input handler\n")); + return 0; + } + ((GF_ESIStream*)source->streams[source->nb_streams].input_udta)->vers_inc = 1; /*increment version number at every video update*/ + assert(source); + + if (source->iod && ((source->iod->tag!=GF_ODF_IOD_TAG) || (mpeg4_signaling != GF_M2TS_MPEG4_SIGNALING_SCENE))) { + assert(0); /*TODO*/ +#if 0 + /*create the descriptor*/ + GF_ESD *esd; + GF_SimpleDataDescriptor *video_desc; + GF_SAFEALLOC(video_desc, GF_SimpleDataDescriptor); + esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = source->streams[source->nb_streams].stream_type; + esd->decoderConfig->objectTypeIndication = source->streams[source->nb_streams].object_type_indication; + esd->ESID = source->streams[source->nb_streams].stream_id; + + /*find the audio OD stream and attach its descriptor*/ + for (i=0; inb_streams; i++) { + if (source->streams[i].stream_id == 103/*TODO: VIDEO_OD_ESID*/) { + if (source->streams[i].input_udta) + gf_free(source->streams[i].input_udta); + source->streams[i].input_udta = (void*)video_desc; + audio_OD_stream_id = i; + break; + } + } + if (audio_OD_stream_id == (u32)-1) { + fprintf(stderr, "Error: could not find an audio OD stream with ESID=100 in '%s'\n", src); + return 0; + } +#endif + } else { + assert (source->mpeg4_signaling == GF_M2TS_MPEG4_SIGNALING_SCENE); + } + + source->nb_streams++; + } + + if (!source->pcr_idx) source->pcr_idx=1; + source->th = gf_th_new("Carousel"); + source->bifs_src_name = update; + gf_th_run(source->th, seng_output, source); + return 1; + } else +#endif + { + FILE *f = gf_fopen(src, "rt"); + if (f) { + gf_fclose(f); + fprintf(stderr, "Error opening %s - not a supported input media, skipping.\n", src); + } else { + fprintf(stderr, "Error opening %s - no such file.\n", src); + } + return 0; + } +} + +#ifdef GPAC_MEMORY_TRACKING +GF_MemTrackerType mem_track = GF_MemTrackerNone; +#endif + +/*macro to keep retro compatibility with '=' and spaces in parse_args*/ +#define CHECK_PARAM(param) (!strnicmp(arg, param, strlen(param)) \ + && ( ((arg[strlen(param)] == '=') && (next_arg = arg+strlen(param)+1)) \ + || ((strlen(arg) == strlen(param)) && ++i && (i0xFF) { + fprintf(stderr, "TEMI external timeline IDs shall be in the range [0x80, 0xFF], but %d was specified\n", temi_id); + return GF_BAD_PARAM; + } + } + if (!temi_id) { + *temi_url = next_arg; + if (strlen(next_arg) > 150) { + fprintf(stderr, "URLs longer than 150 bytes are not currently supported\n"); + return GF_NOT_SUPPORTED; + } + temi_id_1 = 0; + } else { + temi_id_1 = temi_id; + *temi_url = NULL; + } + } + } else if (CHECK_PARAM("-temi2")) { + u32 temi_id = 0; + if (next_arg[0]=='-') { + fprintf(stderr, "No ID for secondary external TEMI timeline specified\n"); + return GF_BAD_PARAM; + } + if (sscanf(next_arg, "%d", &temi_id) == 1) { + if (temi_id < 0x80 || temi_id>0xFF) { + fprintf(stderr, "TEMI external timeline IDs shall be in the range [0x80, 0xFF], but %d was specified\n", temi_id); + return GF_BAD_PARAM; + } + temi_id_2 = temi_id; + } else { + fprintf(stderr, "No ID for secondary external TEMI timeline specified\n"); + return GF_BAD_PARAM; + } + } else if (CHECK_PARAM("-temi-delay")) { + temi_url_insertion_delay = atoi(next_arg); + } else if (CHECK_PARAM("-temi-offset")) { + temi_offset = atoi(next_arg); + } else if (!stricmp(arg, "-temi-noloop")) { + temi_disable_loop = 1; + } else if (!stricmp(arg, "-temi-off")) { + temi_on = GF_FALSE; + } else if (CHECK_PARAM("-temi-period")) { + temi_period = atof(next_arg); + if (temi_period<0) { + temi_period *= -1; + temi_single_toggle = GF_TRUE; + } + } else if (!stricmp(arg, "-insert-ntp")) { + insert_ntp = GF_TRUE; + } + else if (CHECK_PARAM("-dst-udp")) { + char *sep = strchr(next_arg, ':'); + dst_found = 1; + *real_time=1; + if (sep) { + *output_port = atoi(sep+1); + sep[0]=0; + *udp_out = gf_strdup(next_arg); + sep[0]=':'; + } else { + *udp_out = gf_strdup(next_arg); + } + } + else if (CHECK_PARAM("-dst-rtp")) { + char *sep = strchr(next_arg, ':'); + dst_found = 1; + *real_time=1; + if (sep) { + *output_port = atoi(sep+1); + sep[0]=0; + *rtp_out = gf_strdup(next_arg); + sep[0]=':'; + } else { + *rtp_out = gf_strdup(next_arg); + } + } else if (CHECK_PARAM("-src")) { //second pass arguments + } else if (CHECK_PARAM("-prog")) { //second pass arguments + } else { + u32 res = gf_sys_is_gpac_arg(arg); + if (!res) { + error_msg = "unknown option"; + goto error; + } else if (res==2) { + if (!strchr(arg, '=')) i++; + } + } + } + + if (*real_time) force_real_time = 1; + rate_found = 1; + + /*second pass: open sources*/ + for (i=1; i=0) gf_m2ts_mux_set_initial_pcr(muxer, (u64) pcr_init_val); + gf_m2ts_mux_set_pcr_max_interval(muxer, pcr_ms); + gf_m2ts_mux_enable_pcr_only_packets(muxer, enable_forced_pcr); + + + if (ts_out != NULL) { + if (segment_duration) { + strcpy(segment_prefix, ts_out); + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); + } else { + sprintf(segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index); + } + } else { + sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); + } + ts_out = gf_strdup(segment_name); + if (!segment_manifest) { + sprintf(segment_manifest_default, "%s.m3u8", segment_prefix); + segment_manifest = segment_manifest_default; + } + //write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index, 0, 0); + } + if (!strcmp(ts_out, "stdout") || !strcmp(ts_out, "-") ) { + ts_output_file = stdout; + is_stdout = GF_TRUE; + } else { + ts_output_file = gf_fopen(ts_out, "wb"); + is_stdout = GF_FALSE; + } + if (!ts_output_file) { + fprintf(stderr, "Error opening %s\n", ts_out); + goto exit; + } + } + if (udp_out != NULL) { + ts_output_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); + if (gf_sk_is_multicast_address((char *)udp_out)) { + e = gf_sk_setup_multicast(ts_output_udp_sk, (char *)udp_out, output_port, ttl, 0, (char *) ip_ifce); + } else { + e = gf_sk_bind(ts_output_udp_sk, ip_ifce, output_port, (char *)udp_out, output_port, GF_SOCK_REUSE_PORT); + } + if (e) { + fprintf(stderr, "Error initializing UDP socket: %s\n", gf_error_to_string(e)); + goto exit; + } + } +#ifndef GPAC_DISABLE_STREAMING + if (rtp_out != NULL) { + ts_output_rtp = gf_rtp_new(); + gf_rtp_set_ports(ts_output_rtp, output_port); + memset(&tr, 0, sizeof(GF_RTSPTransport)); + tr.IsUnicast = gf_sk_is_multicast_address((char *)rtp_out) ? 0 : 1; + tr.Profile="RTP/AVP"; + tr.destination = (char *)rtp_out; + tr.source = "0.0.0.0"; + tr.IsRecord = 0; + tr.Append = 0; + tr.SSRC = rand(); + tr.port_first = output_port; + tr.port_last = output_port+1; + if (tr.IsUnicast) { + tr.client_port_first = output_port; + tr.client_port_last = output_port+1; + } else { + tr.source = (char *)rtp_out; + tr.TTL = ttl; + } + e = gf_rtp_setup_transport(ts_output_rtp, &tr, (char *)ts_out); + if (e != GF_OK) { + fprintf(stderr, "Cannot setup RTP transport info : %s\n", gf_error_to_string(e)); + goto exit; + } + e = gf_rtp_initialize(ts_output_rtp, 0, 1, 1500, 0, 0, (char *) ip_ifce); + if (e != GF_OK) { + fprintf(stderr, "Cannot initialize RTP sockets : %s\n", gf_error_to_string(e)); + goto exit; + } + memset(&hdr, 0, sizeof(GF_RTPHeader)); + hdr.Version = 2; + hdr.PayloadType = 33; /*MP2T*/ + hdr.SSRC = tr.SSRC; + hdr.Marker = 0; + } +#endif /*GPAC_DISABLE_STREAMING*/ + + /************************************/ + /* create streaming audio input */ + /************************************/ + if (audio_input_ip) + switch(audio_input_type) { + case GF_MP42TS_UDP: + audio_input_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); + if (gf_sk_is_multicast_address((char *)audio_input_ip)) { + e = gf_sk_setup_multicast(audio_input_udp_sk, (char *)audio_input_ip, audio_input_port, 32, 0, NULL); + } else { + e = gf_sk_bind(audio_input_udp_sk, NULL, audio_input_port, (char *)audio_input_ip, audio_input_port, GF_SOCK_REUSE_PORT); + } + if (e) { + fprintf(stderr, "Error initializing UDP socket for %s:%d : %s\n", audio_input_ip, audio_input_port, gf_error_to_string(e)); + goto exit; + } + gf_sk_set_buffer_size(audio_input_udp_sk, 0, GF_M2TS_UDP_BUFFER_SIZE); + gf_sk_set_block_mode(audio_input_udp_sk, 0); + + /*allocate data buffer*/ + audio_input_buffer = (char*)gf_malloc(audio_input_buffer_length); + assert(audio_input_buffer); + break; + case GF_MP42TS_RTP: + /*TODO: not implemented*/ + assert(0); + break; +#ifndef GPAC_DISABLE_PLAYER + case GF_MP42TS_HTTP: + audio_prog = (void*)&sources[nb_sources-1]; + aac_download_file(aac_reader, audio_input_ip); + break; +#endif + case GF_MP42TS_FILE: + assert(0); /*audio live input is restricted to realtime/streaming*/ + break; + default: + assert(0); + } + + if (!nb_sources) { + fprintf(stderr, "No program to mux, quitting.\n"); + } + + for (i=0; iiod = sources[i].iod; + if (sources[i].od_updates) { + program->loop_descriptors = sources[i].od_updates; + sources[i].od_updates = NULL; + } + } else { + program = gf_m2ts_mux_program_find(muxer, sources[i].ID); + } + if (!program) continue; + + for (j=0; jstart_pes_at_rap = 1; + } + + cur_pid += sources[i].nb_streams; + while (cur_pid % 10) + cur_pid ++; + + if (sources[i].program_name[0] || sources[i].provider_name[0] ) gf_m2ts_mux_program_set_name(program, sources[i].program_name, sources[i].provider_name); + } + muxer->flush_pes_at_rap = (split_rap == 2) ? GF_TRUE : GF_FALSE; + + if (sdt_refresh_rate) { + gf_m2ts_mux_enable_sdt(muxer, sdt_refresh_rate); + } + gf_m2ts_mux_update_config(muxer, 1); + + if (nb_pck_pack>1) { + ts_pack_buffer = gf_malloc(sizeof(char) * 188 * nb_pck_pack); + } + + /*****************/ + /* main loop */ + /*****************/ + last_print_time = gf_sys_clock(); + while (run) { + u32 status; + + /*check for some audio input from the network*/ + if (audio_input_ip) { + u32 read; + switch (audio_input_type) { + case GF_MP42TS_UDP: + case GF_MP42TS_RTP: + /*e =*/ + gf_sk_receive(audio_input_udp_sk, audio_input_buffer, audio_input_buffer_length, &read); + if (read) { + SampleCallBack((void*)&sources[nb_sources-1], AUDIO_DATA_ESID, audio_input_buffer, read, gf_m2ts_get_sys_clock(muxer)); + } + break; +#ifndef GPAC_DISABLE_PLAYER + case GF_MP42TS_HTTP: + /*nothing to do: AAC_OnLiveData is called automatically*/ + /*check we're still alive*/ + if (gf_dm_is_thread_dead(aac_reader->dnload)) { + GF_ESD *esd; + aac_download_file(aac_reader, audio_input_ip); + esd = AAC_GetESD(aac_reader); + if (!esd) + break; + assert(esd->slConfig->timestampResolution); /*if we don't have this value we won't be able to adjust the timestamps within the MPEG2-TS*/ + if (esd->slConfig->timestampResolution) + audio_discontinuity_offset = gf_m2ts_get_sys_clock(muxer) * (u64)esd->slConfig->timestampResolution / 1000; + gf_odf_desc_del((GF_Descriptor *)esd); + } + break; +#endif + default: + assert(0); + } + } + + /*flush all packets*/ + nb_pck_in_pack=0; + while ((ts_pck = gf_m2ts_mux_process(muxer, &status, &usec_till_next)) != NULL) { + + if (ts_pack_buffer) { + memcpy(ts_pack_buffer + 188 * nb_pck_in_pack, ts_pck, 188); + nb_pck_in_pack++; + + if (nb_pck_in_pack < nb_pck_pack) + continue; + + ts_pck = (const char *) ts_pack_buffer; + } else { + nb_pck_in_pack = 1; + } + +call_flush: + if (ts_output_file != NULL) { + gf_fwrite(ts_pck, 1, 188 * nb_pck_in_pack, ts_output_file); + if (segment_duration && (muxer->time.sec > prev_seg_time.sec + segment_duration)) { + prev_seg_time = muxer->time; + gf_fclose(ts_output_file); + segment_index++; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); + } else { + sprintf(segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index); + } + } else { + sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); + } + ts_output_file = gf_fopen(segment_name, "wb"); + if (!ts_output_file) { + fprintf(stderr, "Error opening %s\n", segment_name); + goto exit; + } + /* delete the oldest segment */ + if (segment_number && ((s32) (segment_index - segment_number - 1) >= 0)) { + char old_segment_name[GF_MAX_PATH]; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(old_segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); + } else { + sprintf(old_segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); + } + } else { + sprintf(old_segment_name, "%s_%d.ts", segment_prefix, segment_index - segment_number - 1); + } + gf_delete_file(old_segment_name); + } + write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, +// (segment_index >= segment_number/2 ? segment_index - segment_number/2 : 0), segment_index >1 ? segment_index-1 : 0, 0); + ( (segment_index > segment_number ) ? segment_index - segment_number : 0), segment_index >1 ? segment_index-1 : 0, 0); + } + } + + if (ts_output_udp_sk != NULL) { + e = gf_sk_send(ts_output_udp_sk, (char*)ts_pck, 188 * nb_pck_in_pack); + if (e) { + fprintf(stderr, "Error %s sending UDP packet\n", gf_error_to_string(e)); + } + } +#ifndef GPAC_DISABLE_STREAMING + if (ts_output_rtp != NULL) { + u32 ts; + 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_output_rtp, &hdr, (char*)ts_pck, 188 * nb_pck_in_pack, 0); + if (e) { + fprintf(stderr, "Error %s sending RTP packet\n", gf_error_to_string(e)); + } + } +#endif + + nb_pck_in_pack = 0; + + if (status>=GF_M2TS_STATE_PADDING) { + break; + } + } + if (nb_pck_in_pack) { + ts_pck = (const char *) ts_pack_buffer; + goto call_flush; + } + + /*push video*/ + { + u32 now=gf_sys_clock(); + if (now/MP42TS_VIDEO_FREQ != last_video_time/MP42TS_VIDEO_FREQ) { + /*should use carrousel behaviour instead of being pushed manually*/ + if (video_buffer) + SampleCallBack((void*)&sources[nb_sources-1], VIDEO_DATA_ESID, video_buffer, video_buffer_size, gf_m2ts_get_sys_clock(muxer)+1000/*try buffering due to VLC msg*/); + last_video_time = now; + } + } + + if (real_time) { + /*refresh every MP42TS_PRINT_TIME_MS ms*/ + u32 now=gf_sys_clock(); + if (now > last_print_time + MP42TS_PRINT_TIME_MS) { + last_print_time = now; + fprintf(stderr, "M2TS: time % 6d - TS time % 6d - bitrate % 8d\r", gf_m2ts_get_sys_clock(muxer), gf_m2ts_get_ts_clock(muxer), muxer->average_birate_kbps); + + if (gf_prompt_has_input()) { + char c = gf_prompt_get_char(); + if (c=='q') break; + else if (c=='t') request_temi_toggle = GF_TRUE; + } + } + if (status == GF_M2TS_STATE_IDLE) { +#if 0 + /*wait till next packet is ready to be sent*/ + if (usec_till_next>1000) { + //fprintf(stderr, "%d usec till next packet\n", usec_till_next); + gf_sleep(usec_till_next / 1000); + } +#else + //we don't have enough precision on usec counting and we end up eating one core on most machines, so let's just sleep + //one second whenever we are idle - it's maybe too much but the muxer will catchup afterwards + gf_sleep(1); +#endif + } + } + + + if (run_time) { + if (gf_m2ts_get_ts_clock(muxer) > run_time) { + fprintf(stderr, "Stopping multiplex at %d ms (requested runtime %d ms)\n", gf_m2ts_get_ts_clock(muxer), run_time); + break; + } + } + if (status==GF_M2TS_STATE_EOS) { + break; + } + } + + { + u64 bits = muxer->tot_pck_sent*8*188; + u64 dur_ms = gf_m2ts_get_ts_clock(muxer); + if (!dur_ms) dur_ms = 1; + fprintf(stderr, "Done muxing - %.02f sec - %sbitrate %d kbps "LLD" packets written\n", ((Double) dur_ms)/1000.0,mux_rate ? "" : "average ", (u32) (bits/dur_ms), muxer->tot_pck_sent); + fprintf(stderr, " Padding: "LLD" packets (%g kbps) - "LLD" PES padded bytes (%g kbps)\n", muxer->tot_pad_sent, (Double) (muxer->tot_pad_sent*188*8.0/dur_ms) , muxer->tot_pes_pad_bytes, (Double) (muxer->tot_pes_pad_bytes*8.0/dur_ms) ); + } + +exit: + if (ts_pack_buffer) gf_free(ts_pack_buffer); + run = 0; + if (segment_duration) { + write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index - segment_number, segment_index, 1); + } + if (ts_output_file && !is_stdout) gf_fclose(ts_output_file); + if (ts_output_udp_sk) gf_sk_del(ts_output_udp_sk); +#ifndef GPAC_DISABLE_STREAMING + if (ts_output_rtp) gf_rtp_del(ts_output_rtp); +#endif + if (ts_out) gf_free(ts_out); + if (audio_input_udp_sk) gf_sk_del(audio_input_udp_sk); + if (audio_input_buffer) gf_free (audio_input_buffer); + if (video_buffer) gf_free(video_buffer); + if (udp_out) gf_free(udp_out); +#ifndef GPAC_DISABLE_STREAMING + if (rtp_out) gf_free(rtp_out); +#endif + if (muxer) gf_m2ts_mux_del(muxer); + + for (i=0; i + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0} + + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + Application + false + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + false + false + + + + .\obj\mp42ts_deb\mp42ts.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + %(AdditionalLibraryDirectories) + true + $(IntDir)$(ProjectName).pdb + Console + MachineX86 + + + true + + + + + .\obj\mp42ts_deb\mp42ts.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + + + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + ProgramDatabase + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + %(AdditionalLibraryDirectories) + true + $(IntDir)$(ProjectName).pdb + Console + + + true + + + + + .\obj\mp42ts_rel\mp42ts.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + .\obj\mp42ts_rel/$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + %(AdditionalLibraryDirectories) + $(IntDir)$(ProjectName).pdb + Console + MachineX86 + + + true + + + + + .\obj\mp42ts_rel\mp42ts.tlb + + + + + Full + AnySuitable + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + .\obj\mp42ts_rel/$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + %(AdditionalLibraryDirectories) + $(IntDir)$(ProjectName).pdb + Console + + + true + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + {d3540754-e0cf-4604-ac11-82de9bd4d814} + true + true + false + true + false + + + + + + \ No newline at end of file diff --git a/applications/deprecated/old_arch/GPAX/GPAX.cpp b/applications/deprecated/old_arch/GPAX/GPAX.cpp new file mode 100644 index 0000000..773b335 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.cpp @@ -0,0 +1,76 @@ +// GPAX.cpp : Implementation of DLL Exports. + + +// Note: Proxy/Stub Information +// To build a separate proxy/stub DLL, +// run nmake -f GPAXps.mk in the project directory. + +#include "stdafx.h" +#include "resource.h" +#include +#include "GPAX.h" + +#include "GPAX_i.c" +#include "GPAXPlugin.h" + + +CComModule _Module; + +BEGIN_OBJECT_MAP(ObjectMap) +OBJECT_ENTRY(CLSID_GPAX, CGPAXPlugin) +END_OBJECT_MAP() + +///////////////////////////////////////////////////////////////////////////// +// DLL Entry Point + +extern "C" +#ifdef _WIN32_WCE +BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +#else +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) +#endif +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + _Module.Init(ObjectMap, (HINSTANCE) hInstance, &LIBID_GPAXLib); + DisableThreadLibraryCalls((HINSTANCE) hInstance); + } + else if (dwReason == DLL_PROCESS_DETACH) + _Module.Term(); + return TRUE; // ok +} + +///////////////////////////////////////////////////////////////////////////// +// Used to determine whether the DLL can be unloaded by OLE + +STDAPI DllCanUnloadNow(void) +{ + return (_Module.GetLockCount()==0) ? S_OK : S_FALSE; +} + +///////////////////////////////////////////////////////////////////////////// +// Returns a class factory to create an object of the requested type + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + return _Module.GetClassObject(rclsid, riid, ppv); +} + +///////////////////////////////////////////////////////////////////////////// +// DllRegisterServer - Adds entries to the system registry + +STDAPI DllRegisterServer(void) +{ + // registers object, typelib and all interfaces in typelib + return _Module.RegisterServer(TRUE); +} + +///////////////////////////////////////////////////////////////////////////// +// DllUnregisterServer - Removes entries from the system registry + +STDAPI DllUnregisterServer(void) +{ + return _Module.UnregisterServer(TRUE); +} + + diff --git a/applications/deprecated/old_arch/GPAX/GPAX.def b/applications/deprecated/old_arch/GPAX/GPAX.def new file mode 100644 index 0000000..f61476d --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.def @@ -0,0 +1,9 @@ +; GPAX.def : Declares the module parameters. + +LIBRARY "GPAX.dll" + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE diff --git a/applications/deprecated/old_arch/GPAX/GPAX.dsp b/applications/deprecated/old_arch/GPAX/GPAX.dsp new file mode 100644 index 0000000..ac3d1a3 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.dsp @@ -0,0 +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 diff --git a/applications/deprecated/old_arch/GPAX/GPAX.h b/applications/deprecated/old_arch/GPAX/GPAX.h new file mode 100644 index 0000000..05400b7 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.h @@ -0,0 +1,570 @@ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + +/* File created by MIDL compiler version 5.03.0286 */ +/* at Thu Jul 20 19:14:15 2006 + */ +/* Compiler settings for \CVS\gpac\applications\GPAX\GPAX.idl: + Oicf (OptLev=i2), W1, Zp8, env=Win32 (32b run), ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 440 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __GPAX_h__ +#define __GPAX_h__ + +/* Forward Declarations */ + +#ifndef __IGPAX_FWD_DEFINED__ +#define __IGPAX_FWD_DEFINED__ +typedef interface IGPAX IGPAX; +#endif /* __IGPAX_FWD_DEFINED__ */ + + +#ifndef __IGPAXEvents_FWD_DEFINED__ +#define __IGPAXEvents_FWD_DEFINED__ +typedef interface IGPAXEvents IGPAXEvents; +#endif /* __IGPAXEvents_FWD_DEFINED__ */ + + +#ifndef __GPAX_FWD_DEFINED__ +#define __GPAX_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class GPAX GPAX; +#else +typedef struct GPAX GPAX; +#endif /* __cplusplus */ + +#endif /* __GPAX_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void __RPC_FAR * ); + + +#ifndef __GPAXLib_LIBRARY_DEFINED__ +#define __GPAXLib_LIBRARY_DEFINED__ + +/* library GPAXLib */ +/* [helpstring][version][uuid] */ + + + +#define DISPID_SRC ( 100 ) + +#define DISPID_AutoStart ( 101 ) + +#define DISPID_DownloadProgress ( 102 ) + +#define DISPID_PlayEvent ( 100 ) + +#define DISPID_PauseEvent ( 101 ) + +#define DISPID_StopEvent ( 102 ) + + +EXTERN_C const IID LIBID_GPAXLib; + +#ifndef __IGPAX_INTERFACE_DEFINED__ +#define __IGPAX_INTERFACE_DEFINED__ + +/* interface IGPAX */ +/* [object][oleautomation][hidden][dual][helpstring][uuid] */ + + +EXTERN_C const IID IID_IGPAX; + +#if defined(__cplusplus) && !defined(CINTERFACE) + +MIDL_INTERFACE("E2A9A937-BB35-47E0-8942-964806299AB4") +IGPAX : +public IDispatch +{ +public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Play( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Pause( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Stop( void) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Update( + /* [in] */ BSTR mtype, + /* [in] */ BSTR updates) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE QualitySwitch( + /* [in] */ INT switchUp) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetURL( + /* [in] */ BSTR url) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_src( + /* [retval][out] */ BSTR __RPC_FAR *url) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_src( + /* [in] */ BSTR url) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_AutoStart( + /* [retval][out] */ VARIANT_BOOL __RPC_FAR *autoplay) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_AutoStart( + /* [in] */ VARIANT_BOOL autoplay) = 0; + + virtual /* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE get_DownloadProgress( + /* [retval][out] */ INT __RPC_FAR *downloadProgress) = 0; + + virtual /* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE put_DownloadProgress( + /* [in] */ INT downloadProgress) = 0; + +}; + +#else /* C style interface */ + +typedef struct IGPAXVtbl +{ + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + IGPAX __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + IGPAX __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + IGPAX __RPC_FAR * This); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )( + IGPAX __RPC_FAR * This, + /* [out] */ UINT __RPC_FAR *pctinfo); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )( + IGPAX __RPC_FAR * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )( + IGPAX __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID __RPC_FAR *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )( + IGPAX __RPC_FAR * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, + /* [out] */ VARIANT __RPC_FAR *pVarResult, + /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, + /* [out] */ UINT __RPC_FAR *puArgErr); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Play )( + IGPAX __RPC_FAR * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Pause )( + IGPAX __RPC_FAR * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Stop )( + IGPAX __RPC_FAR * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Update )( + IGPAX __RPC_FAR * This, + /* [in] */ BSTR mtype, + /* [in] */ BSTR updates); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QualitySwitch )( + IGPAX __RPC_FAR * This, + /* [in] */ INT switchUp); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetURL )( + IGPAX __RPC_FAR * This, + /* [in] */ BSTR url); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_src )( + IGPAX __RPC_FAR * This, + /* [retval][out] */ BSTR __RPC_FAR *url); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_src )( + IGPAX __RPC_FAR * This, + /* [in] */ BSTR url); + + /* [helpstring][propget][id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_AutoStart )( + IGPAX __RPC_FAR * This, + /* [retval][out] */ VARIANT_BOOL __RPC_FAR *autoplay); + + /* [helpstring][propput][id] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_AutoStart )( + IGPAX __RPC_FAR * This, + /* [in] */ VARIANT_BOOL autoplay); + + END_INTERFACE +} IGPAXVtbl; + +interface IGPAX +{ + CONST_VTBL struct IGPAXVtbl __RPC_FAR *lpVtbl; +}; + + + +#ifdef COBJMACROS + + +#define IGPAX_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IGPAX_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IGPAX_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IGPAX_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define IGPAX_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define IGPAX_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define IGPAX_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + + +#define IGPAX_Play(This) \ + (This)->lpVtbl -> Play(This) + +#define IGPAX_Pause(This) \ + (This)->lpVtbl -> Pause(This) + +#define IGPAX_Stop(This) \ + (This)->lpVtbl -> Stop(This) + +#define IGPAX_Update(This,mtype,updates) \ + (This)->lpVtbl -> Update(This,mtype,updates) + +#define IGPAX_QualitySwitch(This,switchUp) \ + (This)->lpVtbl -> QualitySwitch(This,switchUp) + +#define IGPAX_SetURL(This,url) \ + (This)->lpVtbl -> SetURL(This,url) + +#define IGPAX_get_src(This,url) \ + (This)->lpVtbl -> get_src(This,url) + +#define IGPAX_put_src(This,url) \ + (This)->lpVtbl -> put_src(This,url) + +#define IGPAX_get_AutoStart(This,autoplay) \ + (This)->lpVtbl -> get_AutoStart(This,autoplay) + +#define IGPAX_put_AutoStart(This,autoplay) \ + (This)->lpVtbl -> put_AutoStart(This,autoplay) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IGPAX_Play_Proxy( + IGPAX __RPC_FAR * This); + + +void __RPC_STUB IGPAX_Play_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IGPAX_Pause_Proxy( + IGPAX __RPC_FAR * This); + + +void __RPC_STUB IGPAX_Pause_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IGPAX_Stop_Proxy( + IGPAX __RPC_FAR * This); + + +void __RPC_STUB IGPAX_Stop_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IGPAX_Update_Proxy( + IGPAX __RPC_FAR * This, + /* [in] */ BSTR mtype, + /* [in] */ BSTR updates); + + +void __RPC_STUB IGPAX_Update_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IGPAX_QualitySwitch_Proxy( + IGPAX __RPC_FAR * This, + /* [in] */ INT switchUp); + + +void __RPC_STUB IGPAX_QualitySwitch_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IGPAX_SetURL_Proxy( + IGPAX __RPC_FAR * This, + /* [in] */ BSTR url); + + +void __RPC_STUB IGPAX_SetURL_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IGPAX_get_src_Proxy( + IGPAX __RPC_FAR * This, + /* [retval][out] */ BSTR __RPC_FAR *url); + + +void __RPC_STUB IGPAX_get_src_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IGPAX_put_src_Proxy( + IGPAX __RPC_FAR * This, + /* [in] */ BSTR url); + + +void __RPC_STUB IGPAX_put_src_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IGPAX_get_AutoStart_Proxy( + IGPAX __RPC_FAR * This, + /* [retval][out] */ VARIANT_BOOL __RPC_FAR *autoplay); + + +void __RPC_STUB IGPAX_get_AutoStart_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IGPAX_put_AutoStart_Proxy( + IGPAX __RPC_FAR * This, + /* [in] */ VARIANT_BOOL autoplay); + + +void __RPC_STUB IGPAX_put_AutoStart_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + +/* [helpstring][propget][id] */ HRESULT STDMETHODCALLTYPE IGPAX_get_DownloadProgress_Proxy( + IGPAX __RPC_FAR * This, + /* [retval][out] */ INT __RPC_FAR *autoplay); + + +void __RPC_STUB IGPAX_get_DownloadProgress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][propput][id] */ HRESULT STDMETHODCALLTYPE IGPAX_put_DownloadProgress_Proxy( + IGPAX __RPC_FAR * This, + /* [in] */ INT autoplay); + + +void __RPC_STUB IGPAX_put_DownloadProgress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IGPAX_INTERFACE_DEFINED__ */ + + +#ifndef __IGPAXEvents_DISPINTERFACE_DEFINED__ +#define __IGPAXEvents_DISPINTERFACE_DEFINED__ + +/* dispinterface IGPAXEvents */ +/* [helpstring][uuid] */ + + +EXTERN_C const IID DIID_IGPAXEvents; + +#if defined(__cplusplus) && !defined(CINTERFACE) + +MIDL_INTERFACE("1FDA32FC-4C9A-461F-B33B-0715B0343006") +IGPAXEvents : +public IDispatch +{ +}; + +#else /* C style interface */ + +typedef struct IGPAXEventsVtbl +{ + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + IGPAXEvents __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + IGPAXEvents __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + IGPAXEvents __RPC_FAR * This); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfoCount )( + IGPAXEvents __RPC_FAR * This, + /* [out] */ UINT __RPC_FAR *pctinfo); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetTypeInfo )( + IGPAXEvents __RPC_FAR * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo); + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIDsOfNames )( + IGPAXEvents __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames, + /* [in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID __RPC_FAR *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Invoke )( + IGPAXEvents __RPC_FAR * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams, + /* [out] */ VARIANT __RPC_FAR *pVarResult, + /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo, + /* [out] */ UINT __RPC_FAR *puArgErr); + + END_INTERFACE +} IGPAXEventsVtbl; + +interface IGPAXEvents +{ + CONST_VTBL struct IGPAXEventsVtbl __RPC_FAR *lpVtbl; +}; + + + +#ifdef COBJMACROS + + +#define IGPAXEvents_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IGPAXEvents_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IGPAXEvents_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IGPAXEvents_GetTypeInfoCount(This,pctinfo) \ + (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) + +#define IGPAXEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) + +#define IGPAXEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) + +#define IGPAXEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* __IGPAXEvents_DISPINTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_GPAX; + +#ifdef __cplusplus + +class DECLSPEC_UUID("181D18E6-4DC1-4B55-B72E-BE2A10064995") + GPAX; +#endif +#endif /* __GPAXLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/applications/deprecated/old_arch/GPAX/GPAX.idl b/applications/deprecated/old_arch/GPAX/GPAX.idl new file mode 100644 index 0000000..af76432 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.idl @@ -0,0 +1,92 @@ +// GPAX.idl : IDL source for GPAX.dll +// + +// This file will be processed by the MIDL tool to +// produce the type library (GPAX.tlb) and marshalling code. + +import "oaidl.idl"; +import "ocidl.idl"; +#include "olectl.h" + + +[ + uuid(E64FAC7F-0134-4A75-A7DA-80D53EBC56A6), + version(1.0), + helpstring("GPAX ActiveX Control") +] + +library GPAXLib +{ + importlib("stdole2.tlb"); + + // Forward declare all types defined in this typelib + interface IGPAX; + dispinterface IGPAXEvents; + + const int DISPID_SRC = 100; + const int DISPID_AutoStart = 101; + const int DISPID_DownloadProgress = 102; + + + //IDispatch interface + [ + odl, + uuid(E2A9A937-BB35-47E0-8942-964806299AB4), + helpstring("GPAC ActiveX Control"), + dual, + hidden, + oleautomation + ] + interface IGPAX : IDispatch + { + /*functions*/ + [helpstring("Play Movie")] HRESULT Play(); + [helpstring("Pause/Resume Movie")] HRESULT Pause(); + [helpstring("Stop Movie")] HRESULT Stop(); + [helpstring("Update Scene")] HRESULT Update([in] BSTR mtype, [in] BSTR updates); + [helpstring("Switch Quality")] HRESULT QualitySwitch ([in] int switch_up); + [helpstring("Change URL")] HRESULT SetURL ([in] BSTR url); + + + /*properties*/ + [id(DISPID_SRC), propget, helpstring("Get/Set the media source")] + HRESULT src([out, retval] BSTR* url); + [id(DISPID_SRC), propput, helpstring("Get/Set the media source")] + HRESULT src([in] BSTR url); + + [id(DISPID_AutoStart), propget, helpstring("Get/Set automatic playback upon load")] + HRESULT AutoStart([out, retval] VARIANT_BOOL* autoplay); + [id(DISPID_AutoStart), propput, helpstring("Get/Set automatic playback upon load")] + HRESULT AutoStart([in] VARIANT_BOOL autoplay); + + [id(DISPID_DownloadProgress), propget, helpstring("Get/Set download progress")] + HRESULT DownloadProgress([out, retval] INT* downloadProgress); + [id(DISPID_DownloadProgress), propput, helpstring("Get/Set download progress")] + HRESULT DownloadProgress([in] INT downloadProgress); + }; + + + //event interface + [ + uuid(1FDA32FC-4C9A-461F-B33B-0715B0343006), + helpstring("GPAX Control Events") + ] + dispinterface IGPAXEvents + { + properties: + methods: + }; + + + //AX control + [ + uuid(181D18E6-4DC1-4B55-B72E-BE2A10064995), + helpstring("GPAC Control"), + control + ] + coclass GPAX + { + [default] interface IGPAX; + [default, source] dispinterface IGPAXEvents; + }; +}; diff --git a/applications/deprecated/old_arch/GPAX/GPAX.rc b/applications/deprecated/old_arch/GPAX/GPAX.rc new file mode 100644 index 0000000..374556b --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.rc @@ -0,0 +1,151 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#include + +///////////////////////////////////////////////////////////////////////////// +// Chinese (P.R.C.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +#ifdef _WIN32 +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "1 TYPELIB ""GPAX.tlb""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Chinese (P.R.C.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "ENST\0" + VALUE "FileDescription", "GPAX\0" + VALUE "FileVersion", GPAC_VERSION"\0" + VALUE "InternalName", "GPAX\0" + VALUE "LegalCopyright", "Copyright © 2012-\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "GPAX.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Telecom ParisTech GPAX\0" + VALUE "ProductVersion", GPAC_VERSION"\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_GPAXPLUGIN BITMAP DISCARDABLE "gpax.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// REGISTRY +// + +IDR_GPAXPLUGIN REGISTRY DISCARDABLE "GPAX.rgs" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_PROJNAME "GPAX" + IDS_TITLEGPAXProp "&GPAX" + IDS_HELPFILEGPAXProp "Help File Name" + IDS_DOCSTRINGGPAXProp "URLs setting" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +1 TYPELIB "GPAX.tlb" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/applications/deprecated/old_arch/GPAX/GPAX.rgs b/applications/deprecated/old_arch/GPAX/GPAX.rgs new file mode 100644 index 0000000..2949a85 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.rgs @@ -0,0 +1,175 @@ +HKCR +{ + ForceRemove '.aac' + { + val 'Content Type' = s 'audio/aac' + } + ForceRemove '.amr' + { + val 'Content Type' = s 'audio/amr' + } + ForceRemove '.mp4' + { + val 'Content Type' = s 'application/mp4' + } + ForceRemove '.3gp' + { + val 'Content Type' = s 'video/3gpp' + } + ForceRemove '.3g2' + { + val 'Content Type' = s 'video/3gpp2' + } + ForceRemove '.wrl' + { + val 'Content Type' = s 'model/vrml' + } + ForceRemove '.x3dv' + { + val 'Content Type' = s 'model/x3d+vrml' + } + ForceRemove '.x3d' + { + val 'Content Type' = s 'model/x3d+xml' + } + ForceRemove '.svg' + { + val 'Content Type' = s 'image/svg+xml' + } + ForceRemove '.sdp' + { + val 'Content Type' = s 'application/sdp' + } + + GPAX.GPAXPlugin.1 = s 'GPAC ActiveX' + { + CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + } + GPAX.GPAXPlugin = s 'GPAC ActiveX' + { + CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + CurVer = s 'GPAX.GPAXPlugin.1' + } + NoRemove CLSID + { + ForceRemove {181D18E6-4DC1-4B55-B72E-BE2A10064995} = s 'GPAC ActiveX' + { + ProgID = s 'GPAX.GPAXPlugin.1' + VersionIndependentProgID = s 'GPAX.GPAXPlugin' + ForceRemove 'Programmable' + InprocServer32 = s '%MODULE%' + { + val ThreadingModel = s 'Both' + } + ForceRemove 'Control' + ForceRemove 'Insertable' + ForceRemove 'ToolboxBitmap32' = s '%MODULE%, 101' + 'MiscStatus' = s '0' + { + '1' = s '131473' + } + 'TypeLib' = s '{E64FAC7F-0134-4A75-A7DA-80D53EBC56A6}' + 'Version' = s '1.0' + ForceRemove 'EnableFullPage' + { + ForceRemove .mp4 + ForceRemove .3gp + ForceRemove .3g2 + ForceRemove .wrl + ForceRemove .x3d + ForceRemove .x3dv + ForceRemove .svg + } + } + } + + NoRemove MIME + { + NoRemove Database + { + NoRemove 'Content Type' + { + 'application/x-gpac' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.gpac' + } + 'application/mp4' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.mp4' + } + 'application/sdp' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.sdp' + } + 'audio/aac' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.aac' + } + 'audio/amr' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.amr' + } + 'audio/mp4' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.mp4' + } + 'audio/mpeg' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.mp3' + } + 'image/svg+xml' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.svg' + } + 'model/vrml' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.wrl' + } + 'model/x3d+vrml' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.x3dv' + } + 'model/x3d+xml' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.x3d' + } + 'video/mp4' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.mp4' + } + 'video/3gpp' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.3gp' + } + 'video/3gpp2' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.3g2' + } + 'video/avi' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.avi' + } + 'video/mpeg' + { + val CLSID = s '{181D18E6-4DC1-4B55-B72E-BE2A10064995}' + val Extension = s '.mpg' + } + } + } + } +} diff --git a/applications/deprecated/old_arch/GPAX/GPAX.vcxproj b/applications/deprecated/old_arch/GPAX/GPAX.vcxproj new file mode 100644 index 0000000..be02f4a --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX.vcxproj @@ -0,0 +1,376 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {72486240-A124-496E-A67A-E76FEC7E99BE} + GPAX + + + + DynamicLibrary + false + Dynamic + MultiByte + v140 + + + DynamicLibrary + false + Dynamic + MultiByte + v140 + + + DynamicLibrary + false + Dynamic + MultiByte + v140 + + + DynamicLibrary + false + Dynamic + MultiByte + v140 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + true + true + true + true + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + + + + + + + + + + + + .\obj/w32_deb/GPAX.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ../../include + + + $(OutDir)$(TargetName)$(TargetExt) + true + ../../extra_lib/lib/$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + ..\..\applications\GPAX\GPAX.def + true + $(IntDir)$(ProjectName).pdb + Windows + $(IntDir)$(ProjectName).lib + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + .\obj/w32_deb/GPAX.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + ../../include + + + $(OutDir)$(TargetName)$(TargetExt) + true + ../../extra_lib/lib/$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + ..\..\applications\GPAX\GPAX.def + true + $(IntDir)$(ProjectName).pdb + Windows + $(IntDir)$(ProjectName).lib + %(AdditionalDependencies) + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + .\obj/w32_rel/GPAX.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + ../../include + + + zlib.lib;winmm.lib;ws2_32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ../../extra_lib/lib/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) + ..\..\applications\GPAX\GPAX.def + true + $(IntDir)$(ProjectName).pdb + Windows + false + $(IntDir)$(ProjectName).lib + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + + + + .\obj/w32_rel/GPAX.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + Default + MultiThreadedDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + ProgramDatabase + Default + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + ../../include + + + %(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ../../extra_lib/lib/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) + ..\..\applications\GPAX\GPAX.def + true + $(IntDir)$(ProjectName).pdb + Windows + false + $(IntDir)$(ProjectName).lib + + + true + $(IntDir)$(ProjectName).bsc + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + + + + + + .\GPAX.tlb + .\GPAX.tlb + .\GPAX.tlb + .\GPAX.tlb + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + \gpac\applications\GPAX;$(OUTDIR);%(AdditionalIncludeDirectories) + \gpac\applications\GPAX;$(OUTDIR);%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + \gpac\applications\GPAX;$(OUTDIR);%(AdditionalIncludeDirectories) + \gpac\applications\GPAX;$(OUTDIR);%(AdditionalIncludeDirectories) + + + + + {d3540754-e0cf-4604-ac11-82de9bd4d814} + false + + + + + + \ No newline at end of file diff --git a/applications/deprecated/old_arch/GPAX/GPAXPlugin.cpp b/applications/deprecated/old_arch/GPAX/GPAXPlugin.cpp new file mode 100644 index 0000000..e419862 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAXPlugin.cpp @@ -0,0 +1,710 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / ActiveX control + * + * 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 "stdafx.h" +#include "GPAX.h" +#include "GPAXPlugin.h" +#include +#include +#include +#include + +#ifndef _WIN32_WCE +#include +#include +#endif + +///////////////////////////////////////////////////////////////////////////// +// CGPAXPlugin + +#if 0 +static print_err(char *msg, char *title) +{ + u16 w_msg[1024], w_title[1024]; + CE_CharToWide(msg, w_msg); + CE_CharToWide(title, w_title); + ::MessageBox(NULL, w_msg, w_title, MB_OK); +} +#endif + + +void CGPAXPlugin::SetStatusText(char *msg) +{ +#ifndef _WIN32_WCE + if (m_pBrowser) { + if (msg) { + u16 w_msg[1024]; + gf_utf8_mbstowcs(w_msg, 1024, (const char **)&msg); + m_pBrowser->put_StatusText((BSTR) w_msg); + } else { + m_pBrowser->put_StatusText(L""); + } + } +#endif +} +//GPAC player Event Handler. not yet implemented, just dummies here +Bool CGPAXPlugin::EventProc(GF_Event *evt) +{ + char msg[1024]; + if (!m_term) return GF_FALSE; + + switch (evt->type) { + case GF_EVENT_MESSAGE: + if (evt->message.error) { + sprintf(msg, "(GPAC) %s (%s)", evt->message.message, gf_error_to_string(evt->message.error)); + } else { + sprintf(msg, "(GPAC) %s", evt->message.message); + } + SetStatusText(msg); + break; + case GF_EVENT_PROGRESS: + if (evt->progress.done == evt->progress.total) { + SetStatusText(NULL); + m_iDownload_progress = 100; + } else { + char *szTitle = ""; + if (evt->progress.progress_type==0) szTitle = "Buffer "; + else if (evt->progress.progress_type==1) + { + szTitle = "Download "; + m_iDownload_progress = (int)floor((100.0*evt->progress.done) / evt->progress.total); + } + else if (evt->progress.progress_type==2) szTitle = "Import "; + sprintf(msg, "(GPAC) %s: %02.2f", szTitle, (100.0*evt->progress.done) / evt->progress.total); + SetStatusText(msg); + } + break; + case GF_EVENT_CONNECT: + m_bIsConnected = evt->connect.is_connected; + break; + /*IGNORE any scene size, just work with the size allocated in the parent doc*/ + case GF_EVENT_SCENE_SIZE: + gf_term_set_size(m_term, m_width, m_height); + break; + /*window has been resized (full-screen plugin), resize*/ + case GF_EVENT_SIZE: + m_width = evt->size.width; + m_height = evt->size.height; + gf_term_set_size(m_term, m_width, m_height); + break; + case GF_EVENT_DBLCLICK: + gf_term_set_option(m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(m_term, GF_OPT_FULLSCREEN)); + break; + case GF_EVENT_KEYDOWN: + if ((evt->key.flags & GF_KEY_MOD_ALT)) { + } else { + switch (evt->key.key_code) { + case GF_KEY_HOME: + gf_term_set_option(m_term, GF_OPT_NAVIGATION_TYPE, 1); + break; + 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: + strcpy(msg, evt->navigate.to_url); + SetStatusText(msg); + break; + case GF_EVENT_NAVIGATE: + if (gf_term_is_supported_url(m_term, evt->navigate.to_url, GF_TRUE, GF_TRUE)) { + gf_term_navigate_to(m_term, evt->navigate.to_url); + return GF_TRUE; + } +#ifndef _WIN32_WCE + else if (m_pBrowser) { + u32 i; + const char **sz_ptr; + u16 w_szTar[1024], w_szURL[1024]; + VARIANT target, flags; + flags.intVal = 0; + target.bstrVal = L"_SELF"; + + for (i=0; inavigate.param_count; i++) { + if (!strcmp(evt->navigate.parameters[i], "_parent")) target.bstrVal = L"_PARENT"; + else if (!strcmp(evt->navigate.parameters[i], "_blank")) target.bstrVal = L"_BLANK"; + else if (!strcmp(evt->navigate.parameters[i], "_top")) target.bstrVal = L"_TOP"; + else if (!strcmp(evt->navigate.parameters[i], "_new")) flags.intVal |= navOpenInNewWindow; + else if (!strnicmp(evt->navigate.parameters[i], "_target=", 8)) { + sz_ptr = & evt->navigate.parameters[i]+8; + gf_utf8_mbstowcs(w_szTar, 1024, (const char **)sz_ptr); + target.bstrVal = (BSTR) w_szTar; + } + } + sz_ptr = & evt->navigate.to_url; + gf_utf8_mbstowcs(w_szURL, 1024, (const char **)sz_ptr); + m_pBrowser->Navigate((BSTR) w_szURL, &flags, &target, NULL, NULL);; + return GF_TRUE; + } +#endif + break; + } + return GF_FALSE; +} + +Bool GPAX_EventProc(void *ptr, GF_Event *evt) +{ + CGPAXPlugin *_this = (CGPAXPlugin *)ptr; + return _this->EventProc(evt); +} + +//Read Parameters from pPropBag given by MSIE +Bool CGPAXPlugin::ReadParamString(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog, + WCHAR *name, char *buf, int bufsize) +{ + VARIANT v; + HRESULT hr; + Bool retval = GF_FALSE; + + v.vt = VT_EMPTY; + v.bstrVal = NULL; + hr = pPropBag->Read(name, &v, pErrorLog); + if(SUCCEEDED(hr)) + { + if(v.vt==VT_BSTR && v.bstrVal) + { +// USES_CONVERSION; +// lstrcpyn(buf,OLE2T(v.bstrVal),bufsize); + const u16 *srcp = (const u16 *) v.bstrVal; + size_t len = gf_utf8_wcstombs(buf, bufsize, &srcp); + if (len>=0) { + buf[(u32) len] = 0; + retval = GF_TRUE; + } + } + VariantClear(&v); + } + return retval; +} + +void CGPAXPlugin::LoadDATAUrl() +{ +#ifndef _WIN32_WCE + HRESULT hr; + + if (m_url[0]) return; + /*get parent doc*/ + CComPtr spContainer; + if (m_spClientSite->GetContainer(&spContainer) != S_OK) + return; + CComPtr spDoc = CComQIPtr(spContainer); + CComPtr spColl; + if (spDoc->get_all(&spColl) != S_OK) + return; + /*get HTML in the doc*/ + CComPtr spDisp; + CComPtr sphtmlObjects; + + CComPtr spDispObjects; + if (spColl->tags(CComVariant("OBJECT"), &spDispObjects) != S_OK) + return; + CComPtr spObjs = CComQIPtr(spDispObjects); + + /*browse all objects and find us*/ + long lCount = 0; + spObjs->get_length(&lCount); + for (long lCnt = 0; lCnt < lCount; lCnt++) { + IDispatch *an_obj= NULL; + CComVariant varEmpty; + CComVariant varName; + varName.vt = VT_I4; + varName.lVal = lCnt; + hr = spObjs->item(varName, varEmpty, &an_obj); + varName.Clear(); + varEmpty.Clear(); + if (hr != S_OK) continue; + + /*get the IHTMLObject*/ + IHTMLObjectElement* pObjectElem=NULL; + an_obj->QueryInterface(IID_IHTMLObjectElement, (void**)&pObjectElem); + if (!pObjectElem) continue; + + /*get its parent owner - it MUST be us*/ + IDispatch *disp= NULL; + pObjectElem->get_object(&disp); + if (disp != this) continue; + + BSTR data = NULL; + if ((pObjectElem->get_data(&data) == S_OK) && data) { + const u16 *srcp = (const u16 *) data; + size_t len = gf_utf8_wcstombs(m_url, MAXLEN_URL, &srcp); + if (len>=0) m_url[(u32) len] = 0; + } + SysFreeString(data); + break; + } + + if (m_url) { + UpdateURL(); + } +#endif + +} + +// 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 + +static void gpax_do_log(void *cbk, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list list) +{ + FILE *logs = (FILE *) cbk; + vfprintf(logs, fmt, list); + fflush(logs); +} + +//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; + const char *str; + + if (m_hWnd==NULL) return 0; + + gf_sys_init(GF_MemTrackerNone); + + //Create a structure m_user for initialize the terminal. the parameters to set: + //1)config file path + //2)Modules file path + //3)window handler + //4)EventProc + memset(&m_user, 0, sizeof(m_user)); + + gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR); + + m_user.config = gf_cfg_init(NULL, NULL); + if(!m_user.config) { +#ifdef _WIN32_WCE + ::MessageBox(NULL, _T("GPAC Configuration file not found"), _T("Fatal Error"), MB_OK); +#else + ::MessageBox(NULL, "GPAC Configuration file not found", "Fatal Error", MB_OK); +#endif + goto err_exit; + } + + /*check log file*/ + str = gf_opts_get_key("General", "log-file"); + if (str) { + m_pLogs = gf_fopen(str, "wt"); + if (m_pLogs) gf_log_set_callback(m_pLogs, gpax_do_log); + } + + /*if logs are specified, use them*/ + gf_log_set_tools_levels( gf_cfg_get_key(m_user.config, "General", "Logs") ); + + + str = gf_cfg_get_key(m_user.config, "Core", "ModulesDirectory"); + m_user.modules = gf_modules_new(NULL, m_user.config); + if(!gf_modules_get_count(m_user.modules)) goto err_exit; + + m_user.os_window_handler = m_hWnd; + m_user.opaque = this; + m_user.EventProc = GPAX_EventProc; + + //create a terminal + m_term = gf_term_new(&m_user); + + if (!m_term) goto err_exit; + + gf_term_set_option(m_term, GF_OPT_AUDIO_VOLUME, 100); + + LoadDATAUrl(); + + RECT rc; + ::GetWindowRect(m_hWnd, &rc); + m_width = rc.right-rc.left; + m_height = rc.bottom-rc.top; + if (m_bAutoStart && strlen(m_url)) Play(); + return 0; + + //Error Processing +err_exit: + if(m_user.modules) + gf_modules_del(m_user.modules); + m_user.modules = NULL; + if(m_user.config) + gf_cfg_del(m_user.config); + m_user.config = NULL; + gf_sys_close(); + return 1; +} + +void CGPAXPlugin::UnloadTerm() +{ + if (m_term) { + GF_Terminal *a_term = m_term; + m_term = NULL; + gf_term_del(a_term); + } + if (m_user.modules) gf_modules_del(m_user.modules); + if (m_user.config) gf_cfg_del(m_user.config); + if (m_pLogs) + gf_fclose(m_pLogs); + m_pLogs = NULL; + gf_log_set_callback(NULL, NULL); + memset(&m_user, 0, sizeof(m_user)); + gf_sys_close(); +} +CGPAXPlugin::~CGPAXPlugin() +{ + UnloadTerm(); +#ifndef _WIN32_WCE + if (m_pBrowser) m_pBrowser->Release(); + m_pBrowser = NULL; +#endif +} +LRESULT CGPAXPlugin::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + UnloadTerm(); + return 0; +} + + +HRESULT CGPAXPlugin::OnDraw(ATL_DRAWINFO& di) +{ + if (m_term && m_bInitialDraw) { + m_bInitialDraw = GF_FALSE; + if (m_bAutoStart) Play(); + } + return S_OK; +} + +// Load is called before OnCreate, but it may not be called at +// all if there are no parameters. +STDMETHODIMP CGPAXPlugin::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog) +{ + char szOpt[1024]; + // examine the / tag arguments + + m_url[0] = 0; + ReadParamString(pPropBag,pErrorLog,L"src", m_url, MAXLEN_URL); + if (!m_url[0]) + ReadParamString(pPropBag,pErrorLog,L"data", m_url, MAXLEN_URL); + + if (ReadParamString(pPropBag,pErrorLog,L"autostart", szOpt, 1024)) + m_bAutoStart = (!stricmp(szOpt, "false") || !stricmp(szOpt, "no")) ? GF_FALSE : GF_TRUE; + + if (ReadParamString(pPropBag,pErrorLog,L"use3d", szOpt, 1024)) + m_bUse3D = (!stricmp(szOpt, "true") || !stricmp(szOpt, "yes")) ? GF_TRUE : GF_FALSE; + + if (ReadParamString(pPropBag,pErrorLog,L"aspectratio", szOpt, 1024)) { + if (!stricmp(szOpt, "keep")) m_AR = GF_ASPECT_RATIO_KEEP; + else if (!stricmp(szOpt, "16:9")) m_AR = GF_ASPECT_RATIO_16_9; + else if (!stricmp(szOpt, "4:3")) m_AR = GF_ASPECT_RATIO_4_3; + else if (!stricmp(szOpt, "fill")) m_AR = GF_ASPECT_RATIO_FILL_SCREEN; + } + + if (ReadParamString(pPropBag,pErrorLog,L"loop", szOpt, 1024)) + m_bLoop = !stricmp(szOpt, "true") ? GF_FALSE : GF_TRUE; + + if (ReadParamString(pPropBag,pErrorLog,L"gui", szOpt, 1024)) + m_bUseGUI = (!stricmp(szOpt, "true") || !stricmp(szOpt, "yes")) ? GF_TRUE : GF_FALSE; + + UpdateURL(); + +#ifndef _WIN32_WCE + /*get the top-level container*/ + if (!m_pBrowser) { + IServiceProvider *isp, *isp2 = NULL; + if ( SUCCEEDED(m_spClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast(&isp)) ) ) { + + if (SUCCEEDED(isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast(&isp2)) ) ) { + isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast(&m_pBrowser)); + isp2->Release(); + } + isp->Release(); + } + } + if (m_pBrowser) m_pBrowser->put_StatusText(L"GPAC Ready"); +#endif + + return IPersistPropertyBagImpl::Load(pPropBag, pErrorLog); +} + +void CGPAXPlugin::UpdateURL() +{ + /*get absolute URL*/ + if (!strlen(m_url)) return; + IMoniker* pMoniker = NULL; + LPOLESTR sDisplayName; + + if (SUCCEEDED(m_spClientSite->GetMoniker(OLEGETMONIKER_TEMPFORUSER, + OLEWHICHMK_CONTAINER, + &pMoniker) ) ) { + char parent_url[1024]; + pMoniker->GetDisplayName(NULL, NULL, &sDisplayName); + wcstombs(parent_url, sDisplayName, 300); + pMoniker->Release(); + + char *abs_url = gf_url_concatenate(parent_url, m_url); + if (abs_url) { + strcpy(m_url, abs_url); + gf_free(abs_url); + } + } +} + +STDMETHODIMP CGPAXPlugin::Save(LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties) +{ + u16 wurl[MAXLEN_URL]; + const char *sptr; + u16 len; + + VARIANT value; + if( pPropBag == NULL) return E_INVALIDARG; + + VariantInit(&value); + + V_VT(&value) = VT_BOOL; + V_BOOL(&value) = m_bAutoStart ? VARIANT_TRUE : VARIANT_FALSE; + pPropBag->Write(OLESTR("AutoStart"), &value); + VariantClear(&value); + + V_VT(&value) = VT_BSTR; + + sptr = (const char *)m_url; + len = (u16) gf_utf8_mbstowcs(wurl, MAXLEN_URL, &sptr); + V_BSTR(&value) = SysAllocStringLen(NULL, len+1); + memcpy(V_BSTR(&value) , wurl, len*sizeof(u16)); + V_BSTR(&value) [len] = 0; + + pPropBag->Write(OLESTR("src"), &value); + VariantClear(&value); + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::Play() +{ + if (m_term) { + if (!m_bIsConnected) { + if (strlen(m_url)) { + /*connect from 0 and pause if not autoplay*/ + const char *gui = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + if (gui && m_bUseGUI) { + gf_cfg_set_key(m_user.config, "Temp", "BrowserMode", "yes"); + gf_cfg_set_key(m_user.config, "Temp", "GUIStartupFile", m_url); + gf_term_connect(m_term, gui); + } else { + gf_term_connect(m_term, m_url); + } + gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, m_AR); + } + } else + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); //if target is connected, set it playing + } + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::Pause() +{ + if(m_term) { + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE) == GF_STATE_PAUSED) { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + } else { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + } + } + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::Stop() +{ + if(m_term) gf_term_disconnect(m_term); //set it stop + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::QualitySwitch(int switch_up) +{ + if (m_term) gf_term_switch_quality(m_term, switch_up ? GF_TRUE : GF_FALSE); + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::SetURL(BSTR _url) +{ + if (m_term) { + u16 *srcp; + u32 len; + char *url; + + srcp = (u16 *)_url; + len = (u32) gf_utf8_wcstombs(NULL, 0, (const u16 **)&srcp); + if (len) { + url = (char *) gf_malloc(sizeof(char) * (len+1)); + srcp = (u16 *)_url; + len = (u32) gf_utf8_wcstombs(url, len, (const u16 **)&srcp); + url[len] = 0; + strcpy(m_url, url); + gf_term_connect(m_term, url); + gf_free(url); + } + } + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::Update(BSTR _mtype, BSTR _updates) +{ + if (m_term) { + u16 *srcp; + u32 len; + char mtype[1024], *updates; + + srcp = (u16 *) _mtype; + len = (u32) gf_utf8_wcstombs(mtype, 1024, (const u16 **)&srcp); + mtype[len] = 0; + + srcp = (u16 *)_updates; + len = (u32) gf_utf8_wcstombs(NULL, 0, (const u16 **)&srcp); + if (len) { + updates = (char *) gf_malloc(sizeof(char) * (len+1)); + srcp = (u16 *)_updates; + len = (u32) gf_utf8_wcstombs(updates, len, (const u16 **)&srcp); + updates[len] = 0; + gf_term_scene_update(m_term, mtype, updates); + gf_free(updates); + } + } + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::get_src(BSTR *url) +{ + u16 wurl[MAXLEN_URL]; + const char *sptr; + u16 len; + if (url==NULL) return E_POINTER; + + sptr = (const char *)m_url; + len = (u32) gf_utf8_mbstowcs(wurl, MAXLEN_URL, &sptr); + *url = SysAllocStringLen(NULL, len+1); + memcpy(*url, wurl, len*sizeof(u16)); + *url[len] = 0; + return S_OK; +} +STDMETHODIMP CGPAXPlugin::put_src(BSTR url) +{ + const u16 *srcp = (const u16 *)url; + u32 len = (u32) gf_utf8_wcstombs(m_url, MAXLEN_URL, &srcp); + m_url[len] = 0; + UpdateURL(); + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::get_AutoStart(VARIANT_BOOL *as) +{ + if (as==NULL) return E_POINTER; + *as = m_bAutoStart ? VARIANT_TRUE: VARIANT_FALSE; + return S_OK; +} +STDMETHODIMP CGPAXPlugin::put_AutoStart(VARIANT_BOOL as) +{ + m_bAutoStart = (as !=VARIANT_FALSE) ? GF_TRUE : GF_FALSE; + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::get_DownloadProgress(INT *dp) +{ + if (dp==NULL) return E_POINTER; + *dp = m_iDownload_progress; + return S_OK; +} +STDMETHODIMP CGPAXPlugin::put_DownloadProgress(INT dp) +{ + return S_OK; +} + +STDMETHODIMP CGPAXPlugin::GetInterfaceSafetyOptions( + REFIID riid, + DWORD *pdwSupportedOptions, + DWORD *pdwEnabledOptions +) +{ + if( (NULL == pdwSupportedOptions) || (NULL == pdwEnabledOptions) ) + return E_POINTER; + + *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACESAFE_FOR_UNTRUSTED_CALLER; + + if ((IID_IDispatch == riid) || (IID_IGPAX == riid)) { + *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; + return NOERROR; + } + else if (IID_IPersistPropertyBag == riid) { + *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA; + return NOERROR; + } + *pdwEnabledOptions = 0; + return E_NOINTERFACE; +}; + +STDMETHODIMP CGPAXPlugin::SetInterfaceSafetyOptions( + REFIID riid, + DWORD dwOptionSetMask, + DWORD dwEnabledOptions +) +{ + if ((IID_IDispatch == riid) || (IID_IGPAX == riid) ) { + if( (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask) + && (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions) ) { + return NOERROR; + } + return E_FAIL; + } + else if (IID_IPersistPropertyBag == riid) { + if( (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwOptionSetMask) + && (INTERFACESAFE_FOR_UNTRUSTED_DATA == dwEnabledOptions) ) { + return NOERROR; + } + return E_FAIL; + } + return E_FAIL; +}; + diff --git a/applications/deprecated/old_arch/GPAX/GPAXPlugin.h b/applications/deprecated/old_arch/GPAX/GPAXPlugin.h new file mode 100644 index 0000000..651399c --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAXPlugin.h @@ -0,0 +1,269 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / ActiveX control + * + * 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 __GPAXPLUGIN_H_ +#define __GPAXPLUGIN_H_ + +#define MAXLEN_URL 300 + +#include "resource.h" // main symbols +#include +#include + + + +#include +#include +#include +#include +#include + +#if (_MSC_VER >= 1300) +using namespace ATL; +#endif + + +Bool GPAX_EventProc(void *ptr, GF_Event *evt); + +///////////////////////////////////////////////////////////////////////////// +// CGPAXPlugin +class ATL_NO_VTABLE CGPAXPlugin : + public CComObjectRootEx, + public IDispatchImpl, + public CComControl, + public CComCoClass, + public IOleControlImpl, + public IOleObjectImpl, + public IOleInPlaceActiveObjectImpl, + public IViewObjectExImpl, + public IOleInPlaceObjectWindowlessImpl, + public IProvideClassInfo2Impl<&CLSID_GPAX, &DIID_IGPAXEvents, &LIBID_GPAXLib>, + + public IPersistStreamInitImpl, + public ISupportErrorInfo, + public IConnectionPointContainerImpl, + public IPersistStorageImpl, + public ISpecifyPropertyPagesImpl, + public IQuickActivateImpl, + public IDataObjectImpl, + public IPropertyNotifySinkCP, + + public IPersistPropertyBagImpl, + public IObjectSafetyImpl + +{ +public: + CGPAXPlugin() { + m_term = NULL; + m_bAutoStart = GF_TRUE; + m_bInitialDraw = GF_TRUE; + m_bWindowOnly = GF_TRUE; //to declare that the control is a window control in order + //to inherit the member variable m_hWnd which contains the window handler + m_bIsConnected = GF_FALSE; + m_bUse3D = GF_FALSE; + m_bUseGUI = GF_FALSE; + m_iDownload_progress = 0; + m_AR = GF_ASPECT_RATIO_KEEP; + m_url[0] = 0; + m_pLogs = NULL; +#ifndef _WIN32_WCE + m_pBrowser = NULL; +#endif + memset(&m_user, 0, sizeof(m_user)); + + m_dwCurrentSafety = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; + } + + ~CGPAXPlugin(); + + Bool EventProc(GF_Event *evt); + + BOOL PreTranslateMessage(MSG* pMsg); + + DECLARE_REGISTRY_RESOURCEID(IDR_GPAXPLUGIN) + DECLARE_PROTECT_FINAL_CONSTRUCT() +#if (_MSC_VER >= 1300) + DECLARE_OLEMISC_STATUS(OLEMISC_ACTSLIKEBUTTON | OLEMISC_ACTIVATEWHENVISIBLE) +#endif + + static LPCTSTR GetWindowClassName() { + return TEXT("GPAC ActiveX"); + } + + BEGIN_COM_MAP(CGPAXPlugin) + COM_INTERFACE_ENTRY(IGPAX) + COM_INTERFACE_ENTRY(IDispatch) + COM_INTERFACE_ENTRY(IViewObjectEx) + COM_INTERFACE_ENTRY(IProvideClassInfo) + COM_INTERFACE_ENTRY(IOleControl) + COM_INTERFACE_ENTRY(IOleObject) + + COM_INTERFACE_ENTRY_IMPL(IViewObjectEx) + COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx) + COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx) + COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless) + COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless) + COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceActiveObject) + + COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject) + COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless) + +// COM_INTERFACE_ENTRY(IObjectSafety) + COM_INTERFACE_ENTRY_IID(IID_IObjectSafety, IObjectSafety) + COM_INTERFACE_ENTRY(IPersistPropertyBag) + COM_INTERFACE_ENTRY_IMPL_IID(IID_IPersist, IPersistPropertyBag) + + /* COM_INTERFACE_ENTRY(IViewObject) + COM_INTERFACE_ENTRY(IViewObject2) + COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless) + COM_INTERFACE_ENTRY(IOleInPlaceObject) + */ + + COM_INTERFACE_ENTRY(IProvideClassInfo2) + COM_INTERFACE_ENTRY(IPersistStreamInit) + COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit) + COM_INTERFACE_ENTRY(ISupportErrorInfo) + COM_INTERFACE_ENTRY(IConnectionPointContainer) + COM_INTERFACE_ENTRY(ISpecifyPropertyPages) + COM_INTERFACE_ENTRY(IQuickActivate) + COM_INTERFACE_ENTRY(IPersistStorage) + COM_INTERFACE_ENTRY(IDataObject) + + END_COM_MAP() + + BEGIN_PROP_MAP(CGPAXPlugin) + END_PROP_MAP() + + BEGIN_CONNECTION_POINT_MAP(CGPAXPlugin) + CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink) + END_CONNECTION_POINT_MAP() + + BEGIN_MSG_MAP(CGPAXPlugin) + CHAIN_MSG_MAP(CComControl) + DEFAULT_REFLECTION_HANDLER() + MESSAGE_HANDLER(WM_CREATE, OnCreate) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + + END_MSG_MAP() + // Handler prototypes: + // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled); + + + + // ISupportsErrorInfo + STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) + { + static const IID* arr[] = + { + &IID_IGPAX, + }; + for (int i=0; i + // + // + //the interface IPersistPropertyBag enable MSIE and ActiveX Control to communicate these + //properties included in tags + STDMETHODIMP Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog); + STDMETHODIMP Save(LPPROPERTYBAG, BOOL, BOOL); + + +private: + Bool ReadParamString(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog, WCHAR *name, char *buf, int bufsize); + void SetStatusText(char *msg); + void UpdateURL(); + void UnloadTerm(); + void LoadDATAUrl(); + + GF_Terminal *m_term; + GF_User m_user; + char m_url[MAXLEN_URL]; +#ifndef _WIN32_WCE + /*pointer to the parent browser if any*/ + IWebBrowser2 *m_pBrowser; +#endif + + u32 m_width, m_height, m_AR; + Bool m_bIsConnected, m_bInitialDraw, m_bAutoStart, m_bUse3D, m_bLoop, m_bUseGUI; + int m_iDownload_progress; + FILE *m_pLogs; + +}; + + + +#endif //__GPAXPLUGIN_H_ diff --git a/applications/deprecated/old_arch/GPAX/GPAX_i.c b/applications/deprecated/old_arch/GPAX/GPAX_i.c new file mode 100644 index 0000000..82d1beb --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX_i.c @@ -0,0 +1,178 @@ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + +/* File created by MIDL compiler version 5.03.0286 */ +/* at Thu Jul 20 19:14:15 2006 + */ +/* Compiler settings for \CVS\gpac\applications\GPAX\GPAX.idl: + Oicf (OptLev=i2), W1, Zp8, env=Win32 (32b run), ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#if !defined(_M_IA64) && !defined(_M_AXP64) + +#ifdef __cplusplus +extern "C" { +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_GPAXLib,0xE64FAC7F,0x0134,0x4A75,0xA7,0xDA,0x80,0xD5,0x3E,0xBC,0x56,0xA6); + + +MIDL_DEFINE_GUID(IID, IID_IGPAX,0xE2A9A937,0xBB35,0x47E0,0x89,0x42,0x96,0x48,0x06,0x29,0x9A,0xB4); + + +MIDL_DEFINE_GUID(IID, DIID_IGPAXEvents,0x1FDA32FC,0x4C9A,0x461F,0xB3,0x3B,0x07,0x15,0xB0,0x34,0x30,0x06); + + +MIDL_DEFINE_GUID(CLSID, CLSID_GPAX,0x181D18E6,0x4DC1,0x4B55,0xB7,0x2E,0xBE,0x2A,0x10,0x06,0x49,0x95); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + +#endif /* !defined(_M_IA64) && !defined(_M_AXP64)*/ + + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + +/* File created by MIDL compiler version 5.03.0286 */ +/* at Thu Jul 20 19:14:15 2006 + */ +/* Compiler settings for \CVS\gpac\applications\GPAX\GPAX.idl: + Oicf (OptLev=i2), W1, Zp8, env=Win64 (32b run,appending), ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#if defined(_M_IA64) || defined(_M_AXP64) + +#ifdef __cplusplus +extern "C" { +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_GPAXLib,0xE64FAC7F,0x0134,0x4A75,0xA7,0xDA,0x80,0xD5,0x3E,0xBC,0x56,0xA6); + + +MIDL_DEFINE_GUID(IID, IID_IGPAX,0xE2A9A937,0xBB35,0x47E0,0x89,0x42,0x96,0x48,0x06,0x29,0x9A,0xB4); + + +MIDL_DEFINE_GUID(IID, DIID_IGPAXEvents,0x1FDA32FC,0x4C9A,0x461F,0xB3,0x3B,0x07,0x15,0xB0,0x34,0x30,0x06); + + +MIDL_DEFINE_GUID(CLSID, CLSID_GPAX,0x181D18E6,0x4DC1,0x4B55,0xB7,0x2E,0xBE,0x2A,0x10,0x06,0x49,0x95); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + +#endif /* defined(_M_IA64) || defined(_M_AXP64)*/ + diff --git a/applications/deprecated/old_arch/GPAX/GPAX_p.c b/applications/deprecated/old_arch/GPAX/GPAX_p.c new file mode 100644 index 0000000..16cec2e --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAX_p.c @@ -0,0 +1,603 @@ +/* this ALWAYS GENERATED file contains the proxy stub code */ + + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Mon Jul 17 15:58:48 2006 + */ +/* Compiler settings for D:\CVS\gpac\applications\GPAX\GPAX.idl: + Oicf (OptLev=i2), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +//@@MIDL_FILE_HEADING( ) + +#define USE_STUBLESS_PROXY + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REDQ_RPCPROXY_H_VERSION__ +#define __REQUIRED_RPCPROXY_H_VERSION__ 440 +#endif + + +#include "rpcproxy.h" +#ifndef __RPCPROXY_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCPROXY_H_VERSION__ + + +#include "GPAX.h" + +#define TYPE_FORMAT_STRING_SIZE 59 +#define PROC_FORMAT_STRING_SIZE 213 + +typedef struct _MIDL_TYPE_FORMAT_STRING +{ + short Pad; + unsigned char Format[ TYPE_FORMAT_STRING_SIZE ]; +} MIDL_TYPE_FORMAT_STRING; + +typedef struct _MIDL_PROC_FORMAT_STRING +{ + short Pad; + unsigned char Format[ PROC_FORMAT_STRING_SIZE ]; +} MIDL_PROC_FORMAT_STRING; + + +extern const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString; +extern const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString; + + +/* Standard interface: __MIDL_itf_GPAX_0000, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} */ + + +/* Object interface: IUnknown, ver. 0.0, + GUID={0x00000000,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IDispatch, ver. 0.0, + GUID={0x00020400,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}} */ + + +/* Object interface: IGPAX, ver. 0.0, + GUID={0xE2A9A937,0xBB35,0x47E0,{0x89,0x42,0x96,0x48,0x06,0x29,0x9A,0xB4}} */ + + +extern const MIDL_STUB_DESC Object_StubDesc; + + +extern const MIDL_SERVER_INFO IGPAX_ServerInfo; + +#pragma code_seg(".orpc") +extern const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[1]; + +static const MIDL_STUB_DESC Object_StubDesc = +{ + 0, + NdrOleAllocate, + NdrOleFree, + 0, + 0, + 0, + 0, + 0, + __MIDL_TypeFormatString.Format, + 1, /* -error bounds_check flag */ + 0x20000, /* Ndr library version */ + 0, + 0x50100a4, /* MIDL Version 5.1.164 */ + 0, + UserMarshalRoutines, + 0, /* notify & notify_flag routine table */ + 1, /* Flags */ + 0, /* Reserved3 */ + 0, /* Reserved4 */ + 0 /* Reserved5 */ +}; + +static const unsigned short IGPAX_FormatStringOffsetTable[] = +{ + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + (unsigned short) -1, + 0, + 22, + 44, + 66, + 100, + 128, + 156, + 184 +}; + +static const MIDL_SERVER_INFO IGPAX_ServerInfo = +{ + &Object_StubDesc, + 0, + __MIDL_ProcFormatString.Format, + &IGPAX_FormatStringOffsetTable[-3], + 0, + 0, + 0, + 0 +}; + +static const MIDL_STUBLESS_PROXY_INFO IGPAX_ProxyInfo = +{ + &Object_StubDesc, + __MIDL_ProcFormatString.Format, + &IGPAX_FormatStringOffsetTable[-3], + 0, + 0, + 0 +}; + +CINTERFACE_PROXY_VTABLE(15) _IGPAXProxyVtbl = +{ + &IGPAX_ProxyInfo, + &IID_IGPAX, + IUnknown_QueryInterface_Proxy, + IUnknown_AddRef_Proxy, + IUnknown_Release_Proxy , + 0 /* (void *)-1 /* IDispatch::GetTypeInfoCount */ , + 0 /* (void *)-1 /* IDispatch::GetTypeInfo */ , + 0 /* (void *)-1 /* IDispatch::GetIDsOfNames */ , + 0 /* IDispatch_Invoke_Proxy */ , + (void *)-1 /* IGPAX::Play */ , + (void *)-1 /* IGPAX::Pause */ , + (void *)-1 /* IGPAX::Stop */ , + (void *)-1 /* IGPAX::Update */ , + (void *)-1 /* IGPAX::QualitySwitch */ , + (void *)-1 /* IGPAX::get_URL */ , + (void *)-1 /* IGPAX::put_URL */ , + (void *)-1 /* IGPAX::get_AutoStart */ , + (void *)-1 /* IGPAX::put_AutoStart */ +}; + + +static const PRPC_STUB_FUNCTION IGPAX_table[] = +{ + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + STUB_FORWARDING_FUNCTION, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2, + NdrStubCall2 +}; + +CInterfaceStubVtbl _IGPAXStubVtbl = +{ + &IID_IGPAX, + &IGPAX_ServerInfo, + 15, + &IGPAX_table[-3], + CStdStubBuffer_DELEGATING_METHODS +}; + +#pragma data_seg(".rdata") + +static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[1] = +{ + + { + BSTR_UserSize + ,BSTR_UserMarshal + ,BSTR_UserUnmarshal + ,BSTR_UserFree + } + +}; + + +#if !defined(__RPC_WIN32__) +#error Invalid build platform for this stub. +#endif + +#if !(TARGET_IS_NT40_OR_LATER) +#error You need a Windows NT 4.0 or later to run this stub because it uses these features: +#error -Oif or -Oicf, [wire_marshal] or [user_marshal] attribute, more than 32 methods in the interface. +#error However, your C/C++ compilation flags indicate you intend to run this app on earlier systems. +#error This app will die there with the RPC_X_WRONG_STUB_VERSION error. +#endif + + +static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString = +{ + 0, + { + + /* Procedure Play */ + + 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 2 */ NdrFcLong( 0x0 ), /* 0 */ + /* 6 */ NdrFcShort( 0x7 ), /* 7 */ +#ifndef _ALPHA_ + /* 8 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 10 */ NdrFcShort( 0x0 ), /* 0 */ + /* 12 */ NdrFcShort( 0x8 ), /* 8 */ + /* 14 */ 0x4, /* Oi2 Flags: has return, */ + 0x1, /* 1 */ + + /* Return value */ + + /* 16 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 18 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 20 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure Pause */ + + /* 22 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 24 */ NdrFcLong( 0x0 ), /* 0 */ + /* 28 */ NdrFcShort( 0x8 ), /* 8 */ +#ifndef _ALPHA_ + /* 30 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 32 */ NdrFcShort( 0x0 ), /* 0 */ + /* 34 */ NdrFcShort( 0x8 ), /* 8 */ + /* 36 */ 0x4, /* Oi2 Flags: has return, */ + 0x1, /* 1 */ + + /* Return value */ + + /* 38 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 40 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 42 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure Stop */ + + /* 44 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 46 */ NdrFcLong( 0x0 ), /* 0 */ + /* 50 */ NdrFcShort( 0x9 ), /* 9 */ +#ifndef _ALPHA_ + /* 52 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 54 */ NdrFcShort( 0x0 ), /* 0 */ + /* 56 */ NdrFcShort( 0x8 ), /* 8 */ + /* 58 */ 0x4, /* Oi2 Flags: has return, */ + 0x1, /* 1 */ + + /* Return value */ + + /* 60 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 62 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 64 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure Update */ + + /* 66 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 68 */ NdrFcLong( 0x0 ), /* 0 */ + /* 72 */ NdrFcShort( 0xa ), /* 10 */ +#ifndef _ALPHA_ + /* 74 */ NdrFcShort( 0x10 ), /* x86, MIPS, PPC Stack size/offset = 16 */ +#else + NdrFcShort( 0x20 ), /* Alpha Stack size/offset = 32 */ +#endif + /* 76 */ NdrFcShort( 0x0 ), /* 0 */ + /* 78 */ NdrFcShort( 0x8 ), /* 8 */ + /* 80 */ 0x6, /* Oi2 Flags: clt must size, has return, */ + 0x3, /* 3 */ + + /* Parameter mtype */ + + /* 82 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +#ifndef _ALPHA_ + /* 84 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 86 */ NdrFcShort( 0x1a ), /* Type Offset=26 */ + + /* Parameter updates */ + + /* 88 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +#ifndef _ALPHA_ + /* 90 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 92 */ NdrFcShort( 0x1a ), /* Type Offset=26 */ + + /* Return value */ + + /* 94 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 96 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif + /* 98 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure get_URL */ + + /* 100 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 102 */ NdrFcLong( 0x0 ), /* 0 */ + /* 106 */ NdrFcShort( 0xb ), /* 11 */ +#ifndef _ALPHA_ + /* 108 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif + /* 110 */ NdrFcShort( 0x0 ), /* 0 */ + /* 112 */ NdrFcShort( 0x8 ), /* 8 */ + /* 114 */ 0x5, /* Oi2 Flags: srv must size, has return, */ + 0x2, /* 2 */ + + /* Parameter mrl */ + + /* 116 */ NdrFcShort( 0x2113 ), /* Flags: must size, must free, out, simple ref, srv alloc size=8 */ +#ifndef _ALPHA_ + /* 118 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 120 */ NdrFcShort( 0x2c ), /* Type Offset=44 */ + + /* Return value */ + + /* 122 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 124 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 126 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure put_URL */ + + /* 128 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 130 */ NdrFcLong( 0x0 ), /* 0 */ + /* 134 */ NdrFcShort( 0xc ), /* 12 */ +#ifndef _ALPHA_ + /* 136 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif + /* 138 */ NdrFcShort( 0x0 ), /* 0 */ + /* 140 */ NdrFcShort( 0x8 ), /* 8 */ + /* 142 */ 0x6, /* Oi2 Flags: clt must size, has return, */ + 0x2, /* 2 */ + + /* Parameter mrl */ + + /* 144 */ NdrFcShort( 0x8b ), /* Flags: must size, must free, in, by val, */ +#ifndef _ALPHA_ + /* 146 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 148 */ NdrFcShort( 0x1a ), /* Type Offset=26 */ + + /* Return value */ + + /* 150 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 152 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 154 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure get_AutoStart */ + + /* 156 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 158 */ NdrFcLong( 0x0 ), /* 0 */ + /* 162 */ NdrFcShort( 0xd ), /* 13 */ +#ifndef _ALPHA_ + /* 164 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif + /* 166 */ NdrFcShort( 0x0 ), /* 0 */ + /* 168 */ NdrFcShort( 0xe ), /* 14 */ + /* 170 */ 0x4, /* Oi2 Flags: has return, */ + 0x2, /* 2 */ + + /* Parameter autoplay */ + + /* 172 */ NdrFcShort( 0x2150 ), /* Flags: out, base type, simple ref, srv alloc size=8 */ +#ifndef _ALPHA_ + /* 174 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 176 */ 0x6, /* FC_SHORT */ + 0x0, /* 0 */ + + /* Return value */ + + /* 178 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 180 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 182 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + /* Procedure put_AutoStart */ + + /* 184 */ 0x33, /* FC_AUTO_HANDLE */ + 0x6c, /* Old Flags: object, Oi2 */ + /* 186 */ NdrFcLong( 0x0 ), /* 0 */ + /* 190 */ NdrFcShort( 0xe ), /* 14 */ +#ifndef _ALPHA_ + /* 192 */ NdrFcShort( 0xc ), /* x86, MIPS, PPC Stack size/offset = 12 */ +#else + NdrFcShort( 0x18 ), /* Alpha Stack size/offset = 24 */ +#endif + /* 194 */ NdrFcShort( 0x6 ), /* 6 */ + /* 196 */ NdrFcShort( 0x8 ), /* 8 */ + /* 198 */ 0x4, /* Oi2 Flags: has return, */ + 0x2, /* 2 */ + + /* Parameter autoplay */ + + /* 200 */ NdrFcShort( 0x48 ), /* Flags: in, base type, */ +#ifndef _ALPHA_ + /* 202 */ NdrFcShort( 0x4 ), /* x86, MIPS, PPC Stack size/offset = 4 */ +#else + NdrFcShort( 0x8 ), /* Alpha Stack size/offset = 8 */ +#endif + /* 204 */ 0x6, /* FC_SHORT */ + 0x0, /* 0 */ + + /* Return value */ + + /* 206 */ NdrFcShort( 0x70 ), /* Flags: out, return, base type, */ +#ifndef _ALPHA_ + /* 208 */ NdrFcShort( 0x8 ), /* x86, MIPS, PPC Stack size/offset = 8 */ +#else + NdrFcShort( 0x10 ), /* Alpha Stack size/offset = 16 */ +#endif + /* 210 */ 0x8, /* FC_LONG */ + 0x0, /* 0 */ + + 0x0 + } +}; + +static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString = +{ + 0, + { + NdrFcShort( 0x0 ), /* 0 */ + /* 2 */ + 0x12, 0x0, /* FC_UP */ + /* 4 */ NdrFcShort( 0xc ), /* Offset= 12 (16) */ + /* 6 */ + 0x1b, /* FC_CARRAY */ + 0x1, /* 1 */ + /* 8 */ NdrFcShort( 0x2 ), /* 2 */ + /* 10 */ 0x9, /* Corr desc: FC_ULONG */ + 0x0, /* */ + /* 12 */ NdrFcShort( 0xfffc ), /* -4 */ + /* 14 */ 0x6, /* FC_SHORT */ + 0x5b, /* FC_END */ + /* 16 */ + 0x17, /* FC_CSTRUCT */ + 0x3, /* 3 */ + /* 18 */ NdrFcShort( 0x8 ), /* 8 */ + /* 20 */ NdrFcShort( 0xfffffff2 ), /* Offset= -14 (6) */ + /* 22 */ 0x8, /* FC_LONG */ + 0x8, /* FC_LONG */ + /* 24 */ 0x5c, /* FC_PAD */ + 0x5b, /* FC_END */ + /* 26 */ 0xb4, /* FC_USER_MARSHAL */ + 0x83, /* 131 */ + /* 28 */ NdrFcShort( 0x0 ), /* 0 */ + /* 30 */ NdrFcShort( 0x4 ), /* 4 */ + /* 32 */ NdrFcShort( 0x0 ), /* 0 */ + /* 34 */ NdrFcShort( 0xffffffe0 ), /* Offset= -32 (2) */ + /* 36 */ + 0x11, 0x4, /* FC_RP [alloced_on_stack] */ + /* 38 */ NdrFcShort( 0x6 ), /* Offset= 6 (44) */ + /* 40 */ + 0x13, 0x0, /* FC_OP */ + /* 42 */ NdrFcShort( 0xffffffe6 ), /* Offset= -26 (16) */ + /* 44 */ 0xb4, /* FC_USER_MARSHAL */ + 0x83, /* 131 */ + /* 46 */ NdrFcShort( 0x0 ), /* 0 */ + /* 48 */ NdrFcShort( 0x4 ), /* 4 */ + /* 50 */ NdrFcShort( 0x0 ), /* 0 */ + /* 52 */ NdrFcShort( 0xfffffff4 ), /* Offset= -12 (40) */ + /* 54 */ + 0x11, 0xc, /* FC_RP [alloced_on_stack] [simple_pointer] */ + /* 56 */ 0x6, /* FC_SHORT */ + 0x5c, /* FC_PAD */ + + 0x0 + } +}; + +const CInterfaceProxyVtbl * _GPAX_ProxyVtblList[] = +{ + ( CInterfaceProxyVtbl *) &_IGPAXProxyVtbl, + 0 +}; + +const CInterfaceStubVtbl * _GPAX_StubVtblList[] = +{ + ( CInterfaceStubVtbl *) &_IGPAXStubVtbl, + 0 +}; + +PCInterfaceName const _GPAX_InterfaceNamesList[] = +{ + "IGPAX", + 0 +}; + +const IID * _GPAX_BaseIIDList[] = +{ + &IID_IDispatch, + 0 +}; + + +#define _GPAX_CHECK_IID(n) IID_GENERIC_CHECK_IID( _GPAX, pIID, n) + +int __stdcall _GPAX_IID_Lookup( const IID * pIID, int * pIndex ) +{ + + if(!_GPAX_CHECK_IID(0)) + { + *pIndex = 0; + return 1; + } + + return 0; +} + +const ExtendedProxyFileInfo GPAX_ProxyFileInfo = +{ + (PCInterfaceProxyVtblList *) & _GPAX_ProxyVtblList, + (PCInterfaceStubVtblList *) & _GPAX_StubVtblList, + (const PCInterfaceName * ) & _GPAX_InterfaceNamesList, + (const IID ** ) & _GPAX_BaseIIDList, + & _GPAX_IID_Lookup, + 1, + 2, + 0, /* table of [async_uuid] interfaces */ + 0, /* Filler1 */ + 0, /* Filler2 */ + 0 /* Filler3 */ +}; diff --git a/applications/deprecated/old_arch/GPAX/GPAXps.def b/applications/deprecated/old_arch/GPAX/GPAXps.def new file mode 100644 index 0000000..c4ab3de --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAXps.def @@ -0,0 +1,11 @@ + +LIBRARY "GPAXPS" + +DESCRIPTION 'Proxy/Stub DLL' + +EXPORTS + DllGetClassObject @1 PRIVATE + DllCanUnloadNow @2 PRIVATE + GetProxyDllInfo @3 PRIVATE + DllRegisterServer @4 PRIVATE + DllUnregisterServer @5 PRIVATE diff --git a/applications/deprecated/old_arch/GPAX/GPAXps.mk b/applications/deprecated/old_arch/GPAX/GPAXps.mk new file mode 100644 index 0000000..70cf327 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/GPAXps.mk @@ -0,0 +1,16 @@ + +GPAXps.dll: dlldata.obj GPAX_p.obj GPAX_i.obj + link /dll /out:GPAXps.dll /def:GPAXps.def /entry:DllMain dlldata.obj GPAX_p.obj GPAX_i.obj \ + kernel32.lib rpcndr.lib rpcns4.lib rpcrt4.lib oleaut32.lib uuid.lib \ + +.c.obj: + cl /c /Ox /DWIN32 /D_WIN32_WINNT=0x0400 /DREGISTER_PROXY_DLL \ + $< + +clean: + @del GPAXps.dll + @del GPAXps.lib + @del GPAXps.exp + @del dlldata.obj + @del GPAX_p.obj + @del GPAX_i.obj diff --git a/applications/deprecated/old_arch/GPAX/StdAfx.cpp b/applications/deprecated/old_arch/GPAX/StdAfx.cpp new file mode 100644 index 0000000..a5eea17 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/StdAfx.cpp @@ -0,0 +1,12 @@ +// stdafx.cpp : source file that includes just the standard includes +// stdafx.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +#ifdef _ATL_STATIC_REGISTRY +#include +#include +#endif + +#include diff --git a/applications/deprecated/old_arch/GPAX/StdAfx.h b/applications/deprecated/old_arch/GPAX/StdAfx.h new file mode 100644 index 0000000..597b3ca --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/StdAfx.h @@ -0,0 +1,34 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#if !defined(AFX_STDAFX_H__2CD656F1_059C_4EC4_9EAA_8FECF66BB748__INCLUDED_) +#define AFX_STDAFX_H__2CD656F1_059C_4EC4_9EAA_8FECF66BB748__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define STRICT + +#ifndef _WIN32_WCE + +#ifndef _WIN32_WINNT +#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 +extern CComModule _Module; +#include +#include + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__2CD656F1_059C_4EC4_9EAA_8FECF66BB748__INCLUDED) diff --git a/applications/deprecated/old_arch/GPAX/dlldata.c b/applications/deprecated/old_arch/GPAX/dlldata.c new file mode 100644 index 0000000..837e022 --- /dev/null +++ b/applications/deprecated/old_arch/GPAX/dlldata.c @@ -0,0 +1,38 @@ +/********************************************************* + DllData file -- generated by MIDL compiler + + DO NOT ALTER THIS FILE + + This file is regenerated by MIDL on every IDL file compile. + + To completely reconstruct this file, delete it and rerun MIDL + on all the IDL files in this DLL, specifying this file for the + /dlldata command line option + +*********************************************************/ + +#define PROXY_DELEGATION + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +EXTERN_PROXY_FILE( GPAX ) + + +PROXYFILE_LIST_START +/* Start of list */ +REFERENCE_PROXY_FILE( GPAX ), + /* End of list */ + PROXYFILE_LIST_END + + + DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID ) + +#ifdef __cplusplus +} /*extern "C" */ +#endif + +/* end of generated dlldata file */ diff --git a/applications/deprecated/old_arch/GPAX/gpax.bmp b/applications/deprecated/old_arch/GPAX/gpax.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3ff99ff3a736c68624df2285444fa06e7fb7e705 GIT binary patch literal 246 zcmZuqF%H5o47^H6WrIw#Q&!%=&R@a;>XdAx6J&}y@s&KOSx7n=Cq+!yzB^w|kx%D0 z*1EDB8T&69Y-(UC|07OHXv`|iyds3aS^}yAqOvi#%Tw{cx(nB_$-NMhCK{eV.depend + +distclean: clean + rm -f Makefile.bak .depend + +-include .depend diff --git a/applications/dashcast/audio_data.c b/applications/deprecated/old_arch/dashcast/audio_data.c similarity index 100% rename from applications/dashcast/audio_data.c rename to applications/deprecated/old_arch/dashcast/audio_data.c diff --git a/applications/deprecated/old_arch/dashcast/audio_data.h b/applications/deprecated/old_arch/dashcast/audio_data.h new file mode 100644 index 0000000..de888a8 --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/audio_data.h @@ -0,0 +1,146 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 AUDIO_DATA_H_ +#define AUDIO_DATA_H_ + +#define AUDIO_CB_SIZE 3 + +#define LIVE_FRAME_SIZE 1024 +#define MAX_AUDIO_PACKET_SIZE (128 * 1024) + + +#include "../../modules/ffmpeg_in/ffmpeg_in.h" +#include "libavcodec/avcodec.h" +#include "libavutil/channel_layout.h" +#include "libavutil/mem.h" +#include "libav_compat.h" +#include "circular_buffer.h" + +#include + +//we force the number of channels between the decoder and the encoder: interleaved 16 bits stereo 44100Hz +#define DC_AUDIO_SAMPLE_RATE 44100 +#define DC_AUDIO_NUM_CHANNELS 2 +#define DC_AUDIO_CHANNEL_LAYOUT AV_CH_LAYOUT_STEREO +#define DC_AUDIO_SAMPLE_FORMAT AV_SAMPLE_FMT_S16 + +#define DC_AUDIO_MAX_CHUNCK_SIZE 192000 + + +/* + * AudioInputData is designed to keep the data of input audio in a circular buffer. + * The circular buffer has its own mechanism for synchronization. + */ +typedef struct { + /* The circular buffer of input audio. Input audio is the audio frames after decoding. */ + CircularBuffer circular_buf; + + /* The user of circular buffer has an index to it, which is in this variable. */ + Producer producer; + + AVFrame *aframe; + + int64_t next_pts; + + int channels; + int samplerate; +} AudioInputData; + +/* + * This structure corresponds to an entry of audio configuration in the configuration file + */ +typedef struct { + /* audio file name */ + char filename[GF_MAX_PATH]; + /* audio format */ + char format[GF_MAX_PATH]; + /* audio bitrate */ + int bitrate; + /* audio samplerate */ + int samplerate; + /* audio channel number */ + int channels; + /* audio codec */ + char codec[GF_MAX_PATH]; + /* custom parameter to be passed directly to the encoder - free it once you're done */ + char custom[GF_MAX_PATH]; + + /* used for source switching */ + char source_id[GF_MAX_PATH]; + time_t start_time; + time_t end_time; + + /* RFC6381 codec name, only valid when VIDEO_MUXER == GPAC_INIT_VIDEO_MUXER_AVC1 */ + char codec6381[RFC6381_CODEC_NAME_SIZE_MAX]; +} AudioDataConf; + +/* + * Each node in a circular buffer is a pointer. + * To use the circular buffer for audio frame we must + * define the node. AudioDataNode simply contains + * an AVFrame. + */ +typedef struct { + uint8_t *abuf; + int abuf_size; + uint64_t channel_layout; + int sample_rate; + int format; + int channels; +} AudioDataNode; + +void dc_audio_data_set_default(AudioDataConf *audio_data_conf); + +/* + * Initialize an AudioInputData. + * + * @param audio_input_data [out] is the structure to be initialize. + * @param num_consumers [in] contains information on the number of users of circular buffer; + * which means the number of audio encoders. + * @param live [in] indicates the system is live + * + * @return 0 on success, -1 on failure. + * + * @note Must use dc_audio_data_destroy to free memory. + */ +int dc_audio_input_data_init(AudioInputData *audio_input_data, int channels, int samplerate, int num_consumers, int mode); + +/* + * Destroy an AudioInputData + * + * @param audio_input_data [in] the structure to be destroyed. + */ +void dc_audio_input_data_destroy(AudioInputData *audio_input_data); + +/* + * Signal to all the users of the circular buffer in the AudioInputData + * which the current node is the last node to consume. + * + * @param audio_input_data [in] the structure to be signaled on. + */ +void dc_audio_inout_data_end_signal(AudioInputData *audio_input_data); + +#endif /* AUDIO_DATA_H_ */ diff --git a/applications/deprecated/old_arch/dashcast/audio_decoder.c b/applications/deprecated/old_arch/dashcast/audio_decoder.c new file mode 100644 index 0000000..01de12a --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/audio_decoder.c @@ -0,0 +1,446 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 "audio_decoder.h" + +int dc_audio_decoder_open(AudioInputFile *audio_input_file, AudioDataConf *audio_data_conf, int mode, int no_loop, int video_framerate) +{ + u32 i; + AVCodecContext *codec_ctx; + AVCodec *codec; + AVInputFormat *in_fmt = NULL; + + if (!audio_data_conf) return -1; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio Decoder enter setup at UTC "LLU"\n", gf_net_get_utc() )); + + if (strcmp(audio_data_conf->format,"") != 0) { + in_fmt = av_find_input_format(audio_data_conf->format); + if (in_fmt == NULL) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find the format %s.\n", audio_data_conf->format)); + return -1; + } + } + + /* + * Open audio (may already be opened when shared with the video input). + */ + if (!audio_input_file->av_fmt_ctx) { + s32 ret; + AVDictionary *options = NULL; + //we may need to set the framerate when the default one used by ffmpeg is not supported + if (video_framerate > 0) { + char vfr[16]; + snprintf(vfr, sizeof(vfr), "%d", video_framerate); + ret = av_dict_set(&options, "framerate", vfr, 0); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set video framerate %s.\n", vfr)); + return -1; + } + } + + ret = avformat_open_input(&audio_input_file->av_fmt_ctx, audio_data_conf->filename, in_fmt, options ? &options : NULL); + + if (ret != 0) { + if (options) { + av_dict_free(&options); + options = NULL; + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error %d opening input - retrying without options\n", ret)); + ret = avformat_open_input(&audio_input_file->av_fmt_ctx, audio_data_conf->filename, in_fmt, NULL); + } + + if (ret != 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open file: %s\n", audio_data_conf->filename)); + return -1; + } + } + + if (options) av_dict_free(&options); + + /* + * Retrieve stream information + */ + if (avformat_find_stream_info(audio_input_file->av_fmt_ctx, NULL) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find stream information\n")); + return -1; + } + + av_dump_format(audio_input_file->av_fmt_ctx, 0, audio_data_conf->filename, 0); + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio capture open at UTC "LLU"\n", gf_net_get_utc() )); + + /* + * Find the first audio stream + */ + audio_input_file->astream_idx = -1; + for (i=0; iav_fmt_ctx->nb_streams; i++) { + if (audio_input_file->av_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) { + audio_input_file->astream_idx = i; + break; + } + } + if (audio_input_file->astream_idx == -1) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find a audio stream\n")); + return -1; + } + + /* + * Get a pointer to the codec context for the audio stream + */ + codec_ctx = audio_input_file->av_fmt_ctx->streams[audio_input_file->astream_idx]->codec; + + /* + * Find the decoder for the audio stream + */ + codec = avcodec_find_decoder(codec_ctx->codec_id); + if (codec == NULL) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Input audio codec is not supported.\n")); + avformat_close_input(&audio_input_file->av_fmt_ctx); + return -1; + } + + /* + * Open codec + */ + if (avcodec_open2(codec_ctx, codec, NULL) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input audio codec.\n")); + avformat_close_input(&audio_input_file->av_fmt_ctx); + return -1; + } + +#ifdef DC_AUDIO_RESAMPLER + audio_input_file->aresampler = NULL; +#endif + audio_input_file->fifo = av_fifo_alloc(2 * MAX_AUDIO_PACKET_SIZE); + + audio_data_conf->channels = codec_ctx->channels; + audio_data_conf->samplerate = codec_ctx->sample_rate; + + audio_input_file->mode = mode; + audio_input_file->no_loop = no_loop; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio Decoder open at UTC "LLU"\n", gf_net_get_utc() )); + + return 0; +} + +#ifdef DC_AUDIO_RESAMPLER +static int ensure_resampler(AudioInputFile *audio_input_file, int sample_rate, int num_channels, u64 channel_layout, enum AVSampleFormat sample_format) +{ + if (!audio_input_file->aresampler) { + audio_input_file->aresampler = swr_alloc(); + if (!audio_input_file->aresampler) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate the audio resampler. Aborting.\n")); + return -1; + } + av_opt_set_channel_layout(audio_input_file->aresampler, "in_channel_layout", channel_layout, 0); + av_opt_set_channel_layout(audio_input_file->aresampler, "out_channel_layout", DC_AUDIO_CHANNEL_LAYOUT, 0); + av_opt_set_sample_fmt(audio_input_file->aresampler, "in_sample_fmt", sample_format, 0); + av_opt_set_sample_fmt(audio_input_file->aresampler, "out_sample_fmt", DC_AUDIO_SAMPLE_FORMAT, 0); + av_opt_set_int(audio_input_file->aresampler, "in_sample_rate", sample_rate, 0); + av_opt_set_int(audio_input_file->aresampler, "out_sample_rate", DC_AUDIO_SAMPLE_RATE, 0); + av_opt_set_int(audio_input_file->aresampler, "in_channels", num_channels, 0); + av_opt_set_int(audio_input_file->aresampler, "out_channels", DC_AUDIO_NUM_CHANNELS, 0); + + if (swr_init(audio_input_file->aresampler)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not open the audio resampler. Aborting.\n")); + return -1; + } + } + + return 0; +} + +//resample - see http://ffmpeg.org/pipermail/libav-user/2012-June/002164.html +static int resample_audio(AudioInputFile *audio_input_file, AudioInputData *audio_input_data, AVCodecContext *audio_codec_ctx, uint8_t ***output, int *num_planes_out, int num_channels, enum AVSampleFormat sample_format) +{ + int i; + *num_planes_out = av_sample_fmt_is_planar(DC_AUDIO_SAMPLE_FORMAT) ? DC_AUDIO_NUM_CHANNELS : 1; + *output = (uint8_t**)av_malloc(*num_planes_out*sizeof(uint8_t*)); + for (i=0; i<*num_planes_out; i++) { + (*output) [i] = (uint8_t*)av_malloc(DC_AUDIO_MAX_CHUNCK_SIZE); //FIXME: fix using size below av_samples_get_buffer_size() + } + + i = swr_convert(audio_input_file->aresampler, *output, audio_input_data->aframe->nb_samples, (const uint8_t **)audio_input_data->aframe->extended_data, audio_input_data->aframe->nb_samples); + if (i < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not resample audio frame. Aborting.\n")); + return -1; + } + + return i; +} +#endif + +int dc_audio_decoder_read(AudioInputFile *audio_input_file, AudioInputData *audio_input_data) +{ + int ret; + AVPacket packet; + int got_frame = 0; + AVCodecContext *codec_ctx; + AudioDataNode *audio_data_node; + + /* Get a pointer to the codec context for the audio stream */ + codec_ctx = audio_input_file->av_fmt_ctx->streams[audio_input_file->astream_idx]->codec; + + /* Read frames */ + while (1) { + if (audio_input_file->av_pkt_list) { + if (gf_list_count(audio_input_file->av_pkt_list)) { + AVPacket *packet_copy; + assert(audio_input_file->av_pkt_list); + gf_mx_p(audio_input_file->av_pkt_list_mutex); + packet_copy = (AVPacket*)gf_list_pop_front(audio_input_file->av_pkt_list); + gf_mx_v(audio_input_file->av_pkt_list_mutex); + + if (packet_copy == NULL) { + ret = AVERROR_EOF; + } else { + memcpy(&packet, packet_copy, sizeof(AVPacket)); + gf_free(packet_copy); + ret = 0; + } + } else { + gf_sleep(1); + continue; + } + } else { + ret = av_read_frame(audio_input_file->av_fmt_ctx, &packet); + } + if (ret == AVERROR_EOF) { + if (audio_input_file->mode == LIVE_MEDIA && audio_input_file->no_loop == 0) { + av_seek_frame(audio_input_file->av_fmt_ctx, audio_input_file->astream_idx, 0, 0); + continue; + } + + /* Flush decoder */ + packet.data = NULL; + packet.size = 0; + +#ifndef FF_API_AVFRAME_LAVC + avcodec_get_frame_defaults(audio_input_data->aframe); +#else + av_frame_unref(audio_input_data->aframe); +#endif + + avcodec_decode_audio4(codec_ctx, audio_input_data->aframe, &got_frame, &packet); + + if (got_frame) { + dc_producer_lock(&audio_input_data->producer, &audio_input_data->circular_buf); + dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); + audio_data_node = (AudioDataNode*)dc_producer_produce(&audio_input_data->producer, &audio_input_data->circular_buf); + + audio_data_node->abuf_size = audio_input_data->aframe->linesize[0]; + memcpy(audio_data_node->abuf, audio_input_data->aframe->data[0], audio_data_node->abuf_size); + + dc_producer_advance(&audio_input_data->producer, &audio_input_data->circular_buf); + return 0; + } + + dc_producer_end_signal(&audio_input_data->producer, &audio_input_data->circular_buf); + dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); + + return -2; + } + else if (ret < 0) + { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot read audio frame.\n")); + continue; + } + + /* Is this a packet from the audio stream? */ + if (packet.stream_index == audio_input_file->astream_idx) { + /* Set audio frame to default */ + +#ifndef FF_API_AVFRAME_LAVC + avcodec_get_frame_defaults(audio_input_data->aframe); +#else + av_frame_unref(audio_input_data->aframe); +#endif + + /* Decode audio frame */ + if (avcodec_decode_audio4(codec_ctx, audio_input_data->aframe, &got_frame, &packet) < 0) { + av_free_packet(&packet); + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while decoding audio.\n")); + dc_producer_end_signal(&audio_input_data->producer, &audio_input_data->circular_buf); + dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); + return -1; + } + + if (audio_input_data->aframe->pts != AV_NOPTS_VALUE) + audio_input_data->next_pts = audio_input_data->aframe->pts; + + audio_input_data->next_pts += ((int64_t)AV_TIME_BASE * audio_input_data->aframe->nb_samples) / codec_ctx->sample_rate; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Decode audio frame pts %d at UTC "LLU"\n", audio_input_data->next_pts, gf_net_get_utc() )); + + /* Did we get an audio frame? */ + if (got_frame) { + uint8_t **data; + int data_size; + enum AVSampleFormat sample_format; + Bool resample; +#ifdef DC_AUDIO_RESAMPLER + int num_planes_out=0; +#endif +#ifdef GPAC_USE_LIBAV + int sample_rate = codec_ctx->sample_rate; + int num_channels = codec_ctx->channels; + u64 channel_layout = codec_ctx->channel_layout; +#else + int sample_rate = audio_input_data->aframe->sample_rate; + int num_channels = audio_input_data->aframe->channels; + u64 channel_layout; + if (!audio_input_data->aframe->channel_layout) { + if (audio_input_data->aframe->channels == 2) { + audio_input_data->aframe->channel_layout = AV_CH_LAYOUT_STEREO; + } else if (audio_input_data->aframe->channels == 1) { + audio_input_data->aframe->channel_layout = AV_CH_LAYOUT_MONO; + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Unknown input channel layout for %d channels. Aborting.\n", audio_input_data->aframe->channels)); + exit(1); + } + } + channel_layout = audio_input_data->aframe->channel_layout; +#endif + sample_format = (enum AVSampleFormat)audio_input_data->aframe->format; + resample = (sample_rate != DC_AUDIO_SAMPLE_RATE + || num_channels != DC_AUDIO_NUM_CHANNELS + || channel_layout != DC_AUDIO_CHANNEL_LAYOUT + || sample_format != DC_AUDIO_SAMPLE_FORMAT); + + /* Resample if needed */ + if (resample) { +#ifndef DC_AUDIO_RESAMPLER + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Audio resampling is needed at the decoding stage, but not supported by your version of DashCast. Aborting.\n")); + exit(1); +#else + uint8_t **output; + int nb_samp; + if (ensure_resampler(audio_input_file, sample_rate, num_channels, channel_layout, sample_format)) { + return -1; + } + + nb_samp = resample_audio(audio_input_file, audio_input_data, codec_ctx, &output, &num_planes_out, num_channels, sample_format); + if (nb_samp<0) { + return -1; + } + + av_samples_get_buffer_size(&data_size, DC_AUDIO_NUM_CHANNELS, nb_samp, DC_AUDIO_SAMPLE_FORMAT, 0); + data = output; +#endif + } else { + /*no resampling needed: read data from the AVFrame*/ + data = audio_input_data->aframe->extended_data; + data_size = audio_input_data->aframe->linesize[0]; + } + + assert(!av_sample_fmt_is_planar(DC_AUDIO_SAMPLE_FORMAT)); + av_fifo_generic_write(audio_input_file->fifo, data[0], data_size, NULL); + + if (/*audio_input_file->circular_buf.mode == OFFLINE*/audio_input_file->mode == ON_DEMAND || audio_input_file->mode == LIVE_MEDIA) { + dc_producer_lock(&audio_input_data->producer, &audio_input_data->circular_buf); + + /* Unlock the previous node in the circular buffer. */ + dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); + + /* Get the pointer of the current node in circular buffer. */ + audio_data_node = (AudioDataNode *) dc_producer_produce(&audio_input_data->producer, &audio_input_data->circular_buf); + audio_data_node->channels = DC_AUDIO_NUM_CHANNELS; + audio_data_node->channel_layout = DC_AUDIO_CHANNEL_LAYOUT; + audio_data_node->sample_rate = DC_AUDIO_SAMPLE_RATE; + audio_data_node->format = DC_AUDIO_SAMPLE_FORMAT; + audio_data_node->abuf_size = data_size; + av_fifo_generic_read(audio_input_file->fifo, audio_data_node->abuf, audio_data_node->abuf_size, NULL); + + dc_producer_advance(&audio_input_data->producer, &audio_input_data->circular_buf); + } else { + while (av_fifo_size(audio_input_file->fifo) >= LIVE_FRAME_SIZE) { + /* Lock the current node in the circular buffer. */ + if (dc_producer_lock(&audio_input_data->producer, &audio_input_data->circular_buf) < 0) { + continue; + } + + /* Unlock the previous node in the circular buffer. */ + dc_producer_unlock_previous(&audio_input_data->producer, &audio_input_data->circular_buf); + + /* Get the pointer of the current node in circular buffer. */ + audio_data_node = (AudioDataNode *) dc_producer_produce(&audio_input_data->producer, &audio_input_data->circular_buf); + + audio_data_node->abuf_size = LIVE_FRAME_SIZE; + av_fifo_generic_read(audio_input_file->fifo, audio_data_node->abuf, audio_data_node->abuf_size, NULL); + + dc_producer_advance(&audio_input_data->producer, &audio_input_data->circular_buf); + } + } + +#ifdef DC_AUDIO_RESAMPLER + if (resample) { + int i; + for (i=0; iav_fmt_ctx); + + if (audio_input_file->av_pkt_list_mutex) { + gf_mx_p(audio_input_file->av_pkt_list_mutex); + while (gf_list_count(audio_input_file->av_pkt_list)) { + AVPacket *pkt = (AVPacket*)gf_list_last(audio_input_file->av_pkt_list); + av_free_packet(pkt); + gf_list_rem_last(audio_input_file->av_pkt_list); + } + gf_list_del(audio_input_file->av_pkt_list); + gf_mx_v(audio_input_file->av_pkt_list_mutex); + gf_mx_del(audio_input_file->av_pkt_list_mutex); + } + + av_fifo_free(audio_input_file->fifo); + +#ifdef DC_AUDIO_RESAMPLER + swr_free(&audio_input_file->aresampler); +#endif +} diff --git a/applications/deprecated/old_arch/dashcast/audio_decoder.h b/applications/deprecated/old_arch/dashcast/audio_decoder.h new file mode 100644 index 0000000..90b9839 --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/audio_decoder.h @@ -0,0 +1,100 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 AUDIO_DECODER_H_ +#define AUDIO_DECODER_H_ + +#include "audio_data.h" + +#include "libavformat/avformat.h" +#include "libavutil/fifo.h" +#ifdef DC_AUDIO_RESAMPLER +#include "libavutil/opt.h" +#include "libswresample/swresample.h" +#endif + + +/* + * The structure which keeps the data of + * input audio file. + */ +typedef struct { + /* Format context structure provided by avlib to open and read from a media file. */ + AVFormatContext *av_fmt_ctx; + + /* A list of AVPackets and return value to be processed: when this parameter is non-null, + * the video thread makes the demux and pushes the packets. */ + GF_List *av_pkt_list; + GF_Mutex *av_pkt_list_mutex; + + /* The index of the audio stream in the file. */ + int astream_idx; + + /* This is the output FIFO linking the decoder to the other encoder: only conveys + * stereo 44100 (and resample if needed) */ + AVFifoBuffer *fifo; +#ifdef DC_AUDIO_RESAMPLER + /* Optional audio resampling between the decoder and the encoder */ + SwrContext *aresampler; +#endif + + LockMode mode; + int no_loop; +} AudioInputFile; + +/* + * Open the input audio + * + * @param cmd_data [in] contains information about the file name + * and the audio format. + * + * @param audio_input_file [out] pointer to the structure which we want to + * open the file + * + * @return 0 on success -1 on failure. + */ +int dc_audio_decoder_open(AudioInputFile *audio_input_file, AudioDataConf *audio_data_conf, int mode, int no_loop, int video_framerate); + +/* + * Read and decode audio and put samples on circular buffer + * + * @param audio_input_file [in] contains info on input audio. This parameter + * must have been opened with open_audio_input + * + * @param audio_input_data [out] the samples will be saved on the circular buffer + * of this parameter. + * + * @return 0 on success, -1 on failure, -2 on EOF (end of the file) + */ +int dc_audio_decoder_read(AudioInputFile *audio_input_file, AudioInputData *audio_input_data); + +/* + * Close the input audio + * + * @param audio_input_file [in] the audio file to be closed + */ +void dc_audio_decoder_close(AudioInputFile *audio_input_file); + +#endif /* AUDIO_DECODER_H_ */ diff --git a/applications/deprecated/old_arch/dashcast/audio_encoder.c b/applications/deprecated/old_arch/dashcast/audio_encoder.c new file mode 100644 index 0000000..b957191 --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/audio_encoder.c @@ -0,0 +1,355 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 "audio_encoder.h" + + +extern void build_dict(void *priv_data, const char *options); + + +int dc_audio_encoder_open(AudioOutputFile *audio_output_file, AudioDataConf *audio_data_conf) +{ + AVDictionary *opts = NULL; + + audio_output_file->audio_data_conf = audio_data_conf; + audio_output_file->fifo = av_fifo_alloc(2 * MAX_AUDIO_PACKET_SIZE); + audio_output_file->aframe = FF_ALLOC_FRAME(); + audio_output_file->adata_buf = (uint8_t*) av_malloc(2 * MAX_AUDIO_PACKET_SIZE); +#ifndef GPAC_USE_LIBAV + audio_output_file->aframe->channels = -1; +#endif +#ifndef LIBAV_FRAME_OLD + audio_output_file->aframe->channel_layout = 0; + audio_output_file->aframe->sample_rate = -1; +#endif + audio_output_file->aframe->format = -1; + audio_output_file->codec = avcodec_find_encoder_by_name(audio_data_conf->codec); + if (audio_output_file->codec == NULL) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Output audio codec %s not found\n", audio_data_conf->codec)); + return -1; + } + + audio_output_file->codec_ctx = avcodec_alloc_context3(audio_output_file->codec); + audio_output_file->codec_ctx->codec_id = audio_output_file->codec->id; + audio_output_file->codec_ctx->codec_type = AVMEDIA_TYPE_AUDIO; + audio_output_file->codec_ctx->bit_rate = audio_data_conf->bitrate; + audio_output_file->codec_ctx->sample_rate = DC_AUDIO_SAMPLE_RATE /*audio_data_conf->samplerate*/; + + { + AVRational time_base; + time_base.num = 1; + time_base.den = audio_output_file->codec_ctx->sample_rate; + audio_output_file->codec_ctx->time_base = time_base; + } + audio_output_file->codec_ctx->channels = audio_data_conf->channels; + + /*FIXME: depends on channels -> http://ffmpeg.org/doxygen/trunk/channel__layout_8c_source.html#l00074*/ + if (audio_data_conf->channels == 1) { + audio_output_file->codec_ctx->channel_layout = AV_CH_LAYOUT_MONO; + } else { + audio_output_file->codec_ctx->channel_layout = AV_CH_LAYOUT_STEREO; + } + + audio_output_file->codec_ctx->sample_fmt = audio_output_file->codec->sample_fmts[0]; +#ifdef DC_AUDIO_RESAMPLER + audio_output_file->aresampler = NULL; +#endif + if (strcmp(audio_data_conf->custom, "")) { + build_dict(audio_output_file->codec_ctx->priv_data, audio_data_conf->custom); + } + audio_output_file->astream_idx = 0; + + /* open the audio codec */ + av_dict_set(&opts, "strict", "experimental", 0); + if (avcodec_open2(audio_output_file->codec_ctx, audio_output_file->codec, &opts) < 0) { + /*FIXME: if we enter here (set "mp2" as a codec and "200000" as a bitrate -> deadlock*/ + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output audio codec\n")); + av_dict_free(&opts); + return -1; + } + av_dict_free(&opts); + + audio_output_file->frame_bytes = audio_output_file->codec_ctx->frame_size * av_get_bytes_per_sample(DC_AUDIO_SAMPLE_FORMAT) * DC_AUDIO_NUM_CHANNELS; + +#ifndef FF_API_AVFRAME_LAVC + avcodec_get_frame_defaults(audio_output_file->aframe); +#else + av_frame_unref(audio_output_file->aframe); +#endif + + + audio_output_file->aframe->nb_samples = audio_output_file->codec_ctx->frame_size; + + if (avcodec_fill_audio_frame(audio_output_file->aframe, audio_output_file->codec_ctx->channels, audio_output_file->codec_ctx->sample_fmt, + audio_output_file->adata_buf, audio_output_file->codec_ctx->frame_size * av_get_bytes_per_sample(audio_output_file->codec_ctx->sample_fmt) * audio_output_file->codec_ctx->channels, 1) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Fill audio frame failed\n")); + return -1; + } + + //audio_output_file->acc_samples = 0; + + return 0; +} + +int dc_audio_encoder_read(AudioOutputFile *audio_output_file, AudioInputData *audio_input_data) +{ + int ret; + AudioDataNode *audio_data_node; + + ret = dc_consumer_lock(&audio_output_file->consumer, &audio_input_data->circular_buf); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Audio encoder got an end of buffer!\n")); + return -2; + } + + dc_consumer_unlock_previous(&audio_output_file->consumer, &audio_input_data->circular_buf); + + audio_data_node = (AudioDataNode *) dc_consumer_consume(&audio_output_file->consumer, &audio_input_data->circular_buf); +#ifndef GPAC_USE_LIBAV + audio_output_file->aframe->channels = audio_output_file->codec_ctx->channels; +#endif +#ifndef LIBAV_FRAME_OLD + audio_output_file->aframe->channel_layout = audio_output_file->codec_ctx->channel_layout; + audio_output_file->aframe->sample_rate = audio_output_file->codec_ctx->sample_rate; +#endif + audio_output_file->aframe->format = audio_output_file->codec_ctx->sample_fmt; + + /* Write audio sample on fifo */ + av_fifo_generic_write(audio_output_file->fifo, audio_data_node->abuf, audio_data_node->abuf_size, NULL); + + dc_consumer_advance(&audio_output_file->consumer); + + return 0; +} + +#if 0 +int dc_audio_encoder_flush(AudioOutputFile *audio_output_file, AudioInputData *audio_input_data) +{ + int got_pkt; + //AVStream *audio_stream = audio_output_file->av_fmt_ctx->streams[audio_output_file->astream_idx]; + //AVCodecContext *audio_codec_ctx = audio_stream->codec; + AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; + + av_init_packet(&audio_output_file->packet); + audio_output_file->packet.data = NULL; + audio_output_file->packet.size = 0; + + /* Set PTS (method 1) */ + audio_output_file->aframe->pts = audio_input_data->next_pts; + /* Encode audio */ +#ifdef DC_AUDIO_RESAMPLER +#error resampling is not done here +#endif + if (avcodec_encode_audio2(audio_codec_ctx, &audio_output_file->packet, NULL, &got_pkt) != 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while encoding audio.\n")); + return -1; + } + if (got_pkt) { + //audio_output_file->acc_samples += audio_output_file->aframe->nb_samples; + return 0; + } + av_free_packet(&audio_output_file->packet); + return 1; +} +#endif + +#ifdef DC_AUDIO_RESAMPLER +static int ensure_resampler(AudioOutputFile *audio_output_file, AVCodecContext *audio_codec_ctx) +{ + if (!audio_output_file->aresampler) { + audio_output_file->aresampler = swr_alloc(); + if (!audio_output_file->aresampler) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate the audio resampler. Aborting.\n")); + return -1; + } + av_opt_set_channel_layout(audio_output_file->aresampler, "in_channel_layout", DC_AUDIO_CHANNEL_LAYOUT, 0); + av_opt_set_channel_layout(audio_output_file->aresampler, "out_channel_layout", audio_codec_ctx->channel_layout, 0); + av_opt_set_sample_fmt(audio_output_file->aresampler, "in_sample_fmt", DC_AUDIO_SAMPLE_FORMAT, 0); + av_opt_set_sample_fmt(audio_output_file->aresampler, "out_sample_fmt", audio_codec_ctx->sample_fmt, 0); + av_opt_set_int(audio_output_file->aresampler, "in_sample_rate", DC_AUDIO_SAMPLE_RATE, 0); + av_opt_set_int(audio_output_file->aresampler, "out_sample_rate", audio_codec_ctx->sample_rate, 0); + av_opt_set_int(audio_output_file->aresampler, "in_channels", DC_AUDIO_NUM_CHANNELS, 0); + av_opt_set_int(audio_output_file->aresampler, "out_channels", audio_codec_ctx->channels, 0); + + if (swr_init(audio_output_file->aresampler)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not open the audio resampler. Aborting.\n")); + return -1; + } + } + + return 0; +} + +//resample - see http://ffmpeg.org/pipermail/libav-user/2012-June/002164.html +static int resample_audio(AudioOutputFile *audio_output_file, AVCodecContext *audio_codec_ctx, int *num_planes_out) +{ + int i, linesize; + uint8_t **output; + *num_planes_out = av_sample_fmt_is_planar(audio_output_file->codec->sample_fmts[0]) ? audio_output_file->codec_ctx->channels : 1; + linesize = audio_output_file->codec_ctx->frame_size * av_get_bytes_per_sample(audio_output_file->codec->sample_fmts[0]) * audio_output_file->codec_ctx->channels / *num_planes_out; + output = (uint8_t**)av_malloc(*num_planes_out*sizeof(uint8_t*)); + for (i=0; i<*num_planes_out; i++) { + output[i] = (uint8_t*)av_malloc(linesize); + } + + if (swr_convert(audio_output_file->aresampler, output, audio_output_file->aframe->nb_samples, (const uint8_t **)audio_output_file->aframe->extended_data, audio_output_file->aframe->nb_samples) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not resample audio frame. Aborting.\n")); + return -1; + } + + audio_output_file->aframe->extended_data = output; + for (i=0; i<*num_planes_out; i++) { + audio_output_file->aframe->linesize[i] = linesize; + } + audio_codec_ctx->channel_layout = audio_output_file->aframe->channel_layout; + audio_codec_ctx->sample_fmt = audio_output_file->aframe->format; + audio_codec_ctx->sample_rate = audio_output_file->aframe->sample_rate; +#ifndef GPAC_USE_LIBAV + audio_codec_ctx->channels = audio_output_file->aframe->channels; +#endif + + return 0; +} +#endif + +int dc_audio_encoder_encode(AudioOutputFile *audio_output_file, AudioInputData *audio_input_data) +{ + int got_pkt; + AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; + + while (av_fifo_size(audio_output_file->fifo) >= audio_output_file->frame_bytes) { +#ifdef DC_AUDIO_RESAMPLER + uint8_t **data = NULL; //mirror AVFrame::data + int num_planes_out = 0; +#endif + Bool resample; + + av_fifo_generic_read(audio_output_file->fifo, audio_output_file->adata_buf, audio_output_file->frame_bytes, NULL); + + audio_output_file->aframe->data[0] = audio_output_file->adata_buf; + audio_output_file->aframe->linesize[0] = audio_output_file->frame_bytes; + audio_output_file->aframe->linesize[1] = 0; + + av_init_packet(&audio_output_file->packet); + audio_output_file->packet.data = NULL; + audio_output_file->packet.size = 0; + + /* + * Set PTS (method 1) + */ + //audio_output_file->aframe->pts = audio_input_data->next_pts; + + /* + * Set PTS (method 2) + */ + //{ + // int64_t now = av_gettime(); + // AVRational avr; + // avr.num = 1; + // avr.den = AV_TIME_BASE; + // audio_output_file->aframe->pts = av_rescale_q(now, avr, audio_codec_ctx->time_base); + //} + + resample = (DC_AUDIO_SAMPLE_FORMAT != audio_codec_ctx->sample_fmt + || DC_AUDIO_SAMPLE_RATE != audio_codec_ctx->sample_rate + || DC_AUDIO_NUM_CHANNELS != audio_codec_ctx->channels + || DC_AUDIO_CHANNEL_LAYOUT != audio_codec_ctx->channel_layout); + /* Resample if needed */ + if (resample) { +#ifndef DC_AUDIO_RESAMPLER + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Audio resampling is needed at the encoding stage, but not supported by your version of DashCast. Aborting.\n")); + exit(1); +#else + if (ensure_resampler(audio_output_file, audio_codec_ctx)) { + return -1; + } + + data = audio_output_file->aframe->extended_data; + if (resample_audio(audio_output_file, audio_codec_ctx, &num_planes_out)) { + return -1; + } +#endif + } + + /* Encode audio */ + if (avcodec_encode_audio2(audio_codec_ctx, &audio_output_file->packet, audio_output_file->aframe, &got_pkt) != 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while encoding audio.\n")); +#ifdef DC_AUDIO_RESAMPLER + if (resample) { + int i; + for (i=0; iaframe->extended_data[i]); + } + av_free(audio_output_file->aframe->extended_data); + audio_output_file->aframe->extended_data = data; + } +#endif + return -1; + } + +#ifdef DC_AUDIO_RESAMPLER + if (resample) { + int i; + for (i=0; iaframe->extended_data[i]); + } + av_free(audio_output_file->aframe->extended_data); + audio_output_file->aframe->extended_data = data; + } +#endif + + if (got_pkt) { + //audio_output_file->acc_samples += audio_output_file->aframe->nb_samples; + return 0; + } + + av_free_packet(&audio_output_file->packet); + } + + return 1; +} + +void dc_audio_encoder_close(AudioOutputFile *audio_output_file) +{ +// int i; +// +// /* free the streams */ +// for (i = 0; i < audio_output_file->av_fmt_ctx->nb_streams; i++) { +// avcodec_close(audio_output_file->av_fmt_ctx->streams[i]->codec); +// av_freep(&audio_output_file->av_fmt_ctx->streams[i]->info); +// } + + av_fifo_free(audio_output_file->fifo); + + av_free(audio_output_file->adata_buf); + av_free(audio_output_file->aframe); + + avcodec_close(audio_output_file->codec_ctx); + av_free(audio_output_file->codec_ctx); + +#ifdef DC_AUDIO_RESAMPLER + swr_free(&audio_output_file->aresampler); +#endif +} diff --git a/applications/dashcast/audio_encoder.h b/applications/deprecated/old_arch/dashcast/audio_encoder.h similarity index 100% rename from applications/dashcast/audio_encoder.h rename to applications/deprecated/old_arch/dashcast/audio_encoder.h diff --git a/applications/deprecated/old_arch/dashcast/audio_muxer.c b/applications/deprecated/old_arch/dashcast/audio_muxer.c new file mode 100644 index 0000000..dd861dc --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/audio_muxer.c @@ -0,0 +1,466 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 "audio_muxer.h" +#include "libavformat/avio.h" + +#ifndef GPAC_DISABLE_ISOM + +int dc_gpac_audio_moov_create(AudioOutputFile *audio_output_file, char *filename) +{ + GF_Err ret; + u32 di, track; + u8 bpsample; + GF_ESD *esd; +#ifndef GPAC_DISABLE_AV_PARSERS + GF_M4ADecSpecInfo acfg; +#endif + AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; + + audio_output_file->isof = gf_isom_open(filename, GF_ISOM_OPEN_WRITE, NULL); + if (!audio_output_file->isof) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open iso file %s\n", filename)); + return -1; + } + + esd = gf_odf_desc_esd_new(2); + if (!esd) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create GF_ESD\n")); + return -1; + } + + esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); + esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); + esd->decoderConfig->streamType = GF_STREAM_AUDIO; + if (!strcmp(audio_output_file->codec_ctx->codec->name, "aac")) { //TODO: find an automatic table + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; + esd->decoderConfig->bufferSizeDB = 20; + esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; + esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + esd->ESID = 1; + +#ifndef GPAC_DISABLE_AV_PARSERS + memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); + acfg.base_object_type = GF_M4A_AAC_LC; + acfg.base_sr = audio_codec_ctx->sample_rate; + acfg.nb_chan = audio_codec_ctx->channels; + acfg.sbr_object_type = 0; + acfg.audioPL = gf_m4a_get_profile(&acfg); + + ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); + assert(ret == GF_OK); +#endif + } else { + if (strcmp(audio_output_file->codec_ctx->codec->name, "mp2")) { + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Unlisted codec, setting GPAC_OTI_AUDIO_MPEG1 descriptor.\n")); + } + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; + esd->decoderConfig->bufferSizeDB = 20; + esd->slConfig->timestampResolution = audio_codec_ctx->sample_rate; + esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + esd->ESID = 1; + +#ifndef GPAC_DISABLE_AV_PARSERS + memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo)); + acfg.base_object_type = GF_M4A_LAYER2; + acfg.base_sr = audio_codec_ctx->sample_rate; + acfg.nb_chan = audio_codec_ctx->channels; + acfg.sbr_object_type = 0; + acfg.audioPL = gf_m4a_get_profile(&acfg); + + ret = gf_m4a_write_config(&acfg, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); + assert(ret == GF_OK); +#endif + } + + //gf_isom_store_movie_config(video_output_file->isof, 0); + track = gf_isom_new_track(audio_output_file->isof, esd->ESID, GF_ISOM_MEDIA_AUDIO, audio_codec_ctx->sample_rate); + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("TimeScale: %d \n", audio_codec_ctx->time_base.den)); + if (!track) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create new track\n")); + return -1; + } + + ret = gf_isom_set_track_enabled(audio_output_file->isof, track, 1); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret))); + return -1; + } + +// if (!esd->ESID) esd->ESID = gf_isom_get_track_id(audio_output_file->isof, track); + + ret = gf_isom_new_mpeg4_description(audio_output_file->isof, track, esd, NULL, NULL, &di); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_new_mpeg4_description\n", gf_error_to_string(ret))); + return -1; + } + + gf_odf_desc_del((GF_Descriptor *) esd); + esd = NULL; + + bpsample = av_get_bytes_per_sample(audio_output_file->codec_ctx->sample_fmt) * 8; + + ret = gf_isom_set_audio_info(audio_output_file->isof, track, di, audio_codec_ctx->sample_rate, audio_output_file->codec_ctx->channels, bpsample, GF_IMPORT_AUDIO_SAMPLE_ENTRY_v0_BS); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_audio_info\n", gf_error_to_string(ret))); + return -1; + } + +#ifndef GPAC_DISABLE_AV_PARSERS + ret = gf_isom_set_pl_indication(audio_output_file->isof, GF_ISOM_PL_AUDIO, acfg.audioPL); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_pl_indication\n", gf_error_to_string(ret))); + return -1; + } +#endif + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("time scale: %d sample dur: %d \n", audio_codec_ctx->time_base.den, audio_output_file->codec_ctx->frame_size)); + + ret = gf_isom_setup_track_fragment(audio_output_file->isof, track, 1, audio_output_file->codec_ctx->frame_size, 0, 0, 0, 0, 0); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret))); + return -1; + } + + //gf_isom_add_track_to_root_od(video_output_file->isof,1); + + ret = gf_isom_finalize_for_fragment(audio_output_file->isof, 1); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); + return -1; + } + + ret = gf_media_get_rfc_6381_codec_name(audio_output_file->isof, track, audio_output_file->audio_data_conf->codec6381, GF_FALSE, GF_FALSE); + if (ret != GF_OK) return -1; + return 0; +} + +int dc_gpac_audio_isom_open_seg(AudioOutputFile *audio_output_file, char *filename) +{ + GF_Err ret; + ret = gf_isom_start_segment(audio_output_file->isof, filename, GF_TRUE); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_start_segment\n", gf_error_to_string(ret))); + return -1; + } + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio segment %s started at "LLU"\n", filename, gf_net_get_utc() )); + + audio_output_file->dts = 0; + + return 0; +} + +int dc_gpac_audio_isom_write(AudioOutputFile *audio_output_file) +{ + GF_Err ret; + audio_output_file->sample->data = (char *) audio_output_file->packet.data; + audio_output_file->sample->dataLength = audio_output_file->packet.size; + + audio_output_file->sample->DTS = audio_output_file->dts; //audio_output_file->aframe->pts; + audio_output_file->sample->IsRAP = RAP; //audio_output_file->aframe->key_frame;//audio_codec_ctx->coded_frame->key_frame; + + ret = gf_isom_fragment_add_sample(audio_output_file->isof, 1, audio_output_file->sample, 1, audio_output_file->codec_ctx->frame_size, 0, 0, 0); + audio_output_file->dts += audio_output_file->codec_ctx->frame_size; + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_fragment_add_sample\n", gf_error_to_string(ret))); + return -1; + } + return 0; +} + +int dc_gpac_audio_isom_close_seg(AudioOutputFile *audio_output_file) +{ + u64 seg_size; + GF_Err ret; + ret = gf_isom_close_segment(audio_output_file->isof, 0, 0, 0, 0, 0, 0, 0, GF_TRUE, GF_FALSE, audio_output_file->seg_marker, NULL, NULL, &seg_size); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close_segment\n", gf_error_to_string(ret))); + return -1; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio segment %s closed at "LLU" - size "LLU" bytes\n", gf_isom_get_segment_name(audio_output_file->isof), gf_net_get_utc(), seg_size )); + + //audio_output_file->acc_samples = 0; + + return 0; +} + +int dc_gpac_audio_isom_close(AudioOutputFile *audio_output_file) +{ + GF_Err ret; + ret = gf_isom_close(audio_output_file->isof); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close\n", gf_error_to_string(ret))); + return -1; + } + + //audio_output_file->acc_samples = 0; + + return 0; +} + +#endif + + + +int dc_ffmpeg_audio_muxer_open(AudioOutputFile *audio_output_file, char *filename) +{ + AVStream *audio_stream; + AVOutputFormat *output_fmt; + AVDictionary *opts = NULL; + + AVCodecContext *audio_codec_ctx = audio_output_file->codec_ctx; + audio_output_file->av_fmt_ctx = NULL; + +// strcpy(audio_output_file->filename, audio_data_conf->filename); +// audio_output_file->abr = audio_data_conf->bitrate; +// audio_output_file->asr = audio_data_conf->samplerate; +// audio_output_file->ach = audio_data_conf->channels; +// strcpy(audio_output_file->codec, audio_data_conf->codec); + + /* Find output format */ + output_fmt = av_guess_format(NULL, filename, NULL); + if (!output_fmt) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find suitable output format\n")); + return -1; + } + + audio_output_file->av_fmt_ctx = avformat_alloc_context(); + if (!audio_output_file->av_fmt_ctx) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate memory for pOutVideoFormatCtx\n")); + return -1; + } + + audio_output_file->av_fmt_ctx->oformat = output_fmt; + strcpy(audio_output_file->av_fmt_ctx->filename, filename); + + /* Open the output file */ + if (!(output_fmt->flags & AVFMT_NOFILE)) { + if (avio_open(&audio_output_file->av_fmt_ctx->pb, filename, URL_WRONLY) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot not open '%s'\n", filename)); + return -1; + } + } + + audio_stream = avformat_new_stream(audio_output_file->av_fmt_ctx, audio_output_file->codec); + if (!audio_stream) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create output video stream\n")); + return -1; + } + + audio_stream->codec->codec_id = audio_output_file->codec->id; + audio_stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; + audio_stream->codec->bit_rate = audio_codec_ctx->bit_rate;//audio_output_file->audio_data_conf->bitrate; + audio_stream->codec->sample_rate = audio_codec_ctx->sample_rate;//audio_output_file->audio_data_conf->samplerate; + audio_stream->codec->channels = audio_codec_ctx->channels;//audio_output_file->audio_data_conf->channels; + assert(audio_codec_ctx->codec->sample_fmts); + audio_stream->codec->sample_fmt = audio_codec_ctx->codec->sample_fmts[0]; + +// if (audio_output_file->av_fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) +// audio_output_file->codec_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; + + //video_stream->codec = video_output_file->codec_ctx; + + /* open the video codec */ + av_dict_set(&opts, "strict", "experimental", 0); + if (avcodec_open2(audio_stream->codec, audio_output_file->codec, &opts) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video codec\n")); + av_dict_free(&opts); + return -1; + } + av_dict_free(&opts); + + return avformat_write_header(audio_output_file->av_fmt_ctx, NULL); + +} + +int dc_ffmpeg_audio_muxer_write(AudioOutputFile *audio_output_file) +{ + AVStream *audio_stream = audio_output_file->av_fmt_ctx->streams[audio_output_file->astream_idx]; + AVCodecContext *audio_codec_ctx = audio_stream->codec; + + audio_output_file->packet.stream_index = audio_stream->index; + + if (audio_output_file->packet.pts != AV_NOPTS_VALUE) + audio_output_file->packet.pts = av_rescale_q(audio_output_file->packet.pts, audio_codec_ctx->time_base, audio_stream->time_base); + + if (audio_output_file->packet.duration > 0) + audio_output_file->packet.duration = (int)av_rescale_q(audio_output_file->packet.duration, audio_codec_ctx->time_base, audio_stream->time_base); + /* + * if (pkt.pts != AV_NOPTS_VALUE) + * pkt.pts = av_rescale_q(pkt.pts, audioEncCtx->time_base, audioStream->time_base); + */ + + audio_output_file->packet.flags |= AV_PKT_FLAG_KEY; + + if (av_interleaved_write_frame(audio_output_file->av_fmt_ctx, &audio_output_file->packet) != 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Writing frame is not successful\n")); + av_free_packet(&audio_output_file->packet); + return -1; + } + + av_free_packet(&audio_output_file->packet); + + return 0; +} + +int dc_ffmpeg_audio_muxer_close(AudioOutputFile *audio_output_file) +{ + u32 i; + + av_write_trailer(audio_output_file->av_fmt_ctx); + avio_close(audio_output_file->av_fmt_ctx->pb); + + // free the streams + for (i = 0; i < audio_output_file->av_fmt_ctx->nb_streams; i++) { + avcodec_close(audio_output_file->av_fmt_ctx->streams[i]->codec); + av_freep(&audio_output_file->av_fmt_ctx->streams[i]->info); + } + + //video_output_file->av_fmt_ctx->streams[video_output_file->vstream_idx]->codec = NULL; + avformat_free_context(audio_output_file->av_fmt_ctx); + + //audio_output_file->acc_samples = 0; + + return 0; + +} + +int dc_audio_muxer_init(AudioOutputFile *audio_output_file, AudioDataConf *audio_data_conf, AudioMuxerType muxer_type, int frame_per_seg, int frame_per_frag, u32 seg_marker) +{ + char name[GF_MAX_PATH]; + snprintf(name, sizeof(name), "audio encoder %s", audio_data_conf->filename); + dc_consumer_init(&audio_output_file->consumer, AUDIO_CB_SIZE, name); + +#ifndef GPAC_DISABLE_ISOM + audio_output_file->sample = gf_isom_sample_new(); + audio_output_file->isof = NULL; +#endif + + audio_output_file->muxer_type = muxer_type; + audio_output_file->frame_per_seg = frame_per_seg; + audio_output_file->frame_per_frag = frame_per_frag; + audio_output_file->seg_marker = seg_marker; + return 0; +} + +void dc_audio_muxer_free(AudioOutputFile *audio_output_file) +{ +#ifndef GPAC_DISABLE_ISOM + if (audio_output_file->isof != NULL) { + gf_isom_close(audio_output_file->isof); + } + //gf_isom_sample_del(&audio_output_file->sample); +#endif +} + +GF_Err dc_audio_muxer_open(AudioOutputFile *audio_output_file, char *directory, char *id_name, int seg) +{ + GF_Err ret = GF_NOT_SUPPORTED; + char name[GF_MAX_PATH]; + + switch (audio_output_file->muxer_type) { + case FFMPEG_AUDIO_MUXER: + snprintf(name, sizeof(name), "%s/%s_%d_ffmpeg.mp4", directory, id_name, seg); + return dc_ffmpeg_audio_muxer_open(audio_output_file, name); +#ifndef GPAC_DISABLE_ISOM + case GPAC_AUDIO_MUXER: + snprintf(name, sizeof(name), "%s/%s_%d_gpac.mp4", directory, id_name, seg); + dc_gpac_audio_moov_create(audio_output_file, name); + return dc_gpac_audio_isom_open_seg(audio_output_file, NULL); + case GPAC_INIT_AUDIO_MUXER: + if (seg == 1) { + snprintf(name, sizeof(name), "%s/%s_init_gpac.mp4", directory, id_name); + dc_gpac_audio_moov_create(audio_output_file, name); + audio_output_file->first_dts = 0; + } + snprintf(name, sizeof(name), "%s/%s_%d_gpac.m4s", directory, id_name, seg); + ret = dc_gpac_audio_isom_open_seg(audio_output_file, name); + return ret; +#endif + default: + ret = GF_BAD_PARAM; + break; + } + + return ret; +} + +int dc_audio_muxer_write(AudioOutputFile *audio_output_file, int frame_nb, Bool insert_ntp) +{ + switch (audio_output_file->muxer_type) { + case FFMPEG_AUDIO_MUXER: + return dc_ffmpeg_audio_muxer_write(audio_output_file); +#ifndef GPAC_DISABLE_ISOM + case GPAC_AUDIO_MUXER: + case GPAC_INIT_AUDIO_MUXER: + if (frame_nb % audio_output_file->frame_per_frag == 0) { + gf_isom_start_fragment(audio_output_file->isof, 1); + + if (insert_ntp) { + gf_isom_set_fragment_reference_time(audio_output_file->isof, 1, audio_output_file->frame_ntp, audio_output_file->first_dts * audio_output_file->codec_ctx->frame_size); + } + + gf_isom_set_traf_base_media_decode_time(audio_output_file->isof, 1, audio_output_file->first_dts * audio_output_file->codec_ctx->frame_size); + audio_output_file->first_dts += audio_output_file->frame_per_frag; + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio start fragment first DTS %u at "LLU"\n", audio_output_file->first_dts, gf_net_get_utc() )); + } + dc_gpac_audio_isom_write(audio_output_file); + if (frame_nb % audio_output_file->frame_per_frag == audio_output_file->frame_per_frag - 1) { + gf_isom_flush_fragments(audio_output_file->isof, 1); + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Audio flush fragment first DTS %u at "LLU"\n", audio_output_file->first_dts, gf_net_get_utc() )); + } + //TODO - do same as video, flush based on time in case of losses + if (frame_nb + 1 == audio_output_file->frame_per_seg) { + return 1; + } + + return 0; +#endif + + default: + return GF_BAD_PARAM; + } + return GF_BAD_PARAM; +} + +int dc_audio_muxer_close(AudioOutputFile *audio_output_file) +{ + switch (audio_output_file->muxer_type) { + case FFMPEG_AUDIO_MUXER: + return dc_ffmpeg_audio_muxer_close(audio_output_file); +#ifndef GPAC_DISABLE_ISOM + case GPAC_AUDIO_MUXER: + dc_gpac_audio_isom_close_seg(audio_output_file); + return dc_gpac_audio_isom_close(audio_output_file); + case GPAC_INIT_AUDIO_MUXER: + return dc_gpac_audio_isom_close_seg(audio_output_file); +#endif + default: + return GF_BAD_PARAM; + } + + return GF_BAD_PARAM; +} diff --git a/applications/deprecated/old_arch/dashcast/audio_muxer.h b/applications/deprecated/old_arch/dashcast/audio_muxer.h new file mode 100644 index 0000000..afc91ac --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/audio_muxer.h @@ -0,0 +1,132 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 AUDIO_MUXER_H_ +#define AUDIO_MUXER_H_ + +#include +#include "../../modules/ffmpeg_in/ffmpeg_in.h" +#include "libavutil/fifo.h" +#include "libavformat/avformat.h" +#include "libavdevice/avdevice.h" +#ifdef DC_AUDIO_RESAMPLER +#include "libswresample/swresample.h" +#endif +#include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include +#include +#include +#include "audio_data.h" + + +typedef enum { + FFMPEG_AUDIO_MUXER, + GPAC_AUDIO_MUXER, + GPAC_INIT_AUDIO_MUXER +} AudioMuxerType; + +/* + * AudioOutputFile structure has the data needed + * to encode audio samples and write them on the file. + * It reads the data from a circular buffer so it needs + * to keep the index to that circular buffer. This index is + * available in Consumer data structure. + * + */ +typedef struct { + AudioDataConf *audio_data_conf; + + /* File format context structure */ + AVFormatContext *av_fmt_ctx; + AVCodec *codec; + AVCodecContext *codec_ctx; + +#ifndef GPAC_DISABLE_ISOM + GF_ISOFile *isof; + GF_ISOSample *sample; +#endif + + int dts; + + /* The index to the audio stream in the file */ + int astream_idx; + + /* It keeps the index with which encoder access to the circular buffer (as a consumer) */ + Consumer consumer; + +#ifdef DC_AUDIO_RESAMPLER + /* Optional audio resampling between the decoder and the encoder */ + SwrContext *aresampler; +#endif + + /* Variables that encoder needs to encode data */ + AVFrame *aframe; + uint8_t *adata_buf; + int frame_bytes; + AVPacket packet; + + /* + * Audio samples stored in the AVFrame are not always + * complete. Which means more than 1 AVFrame is needed + * to complete an access unit. This fifo is provided + * to store audio samples in the fifo and once an access unit + * is complete we can encode it. + */ + AVFifoBuffer *fifo; + + AudioMuxerType muxer_type; + + /* Accumulated sample */ + //int acc_samples; + + int frame_per_seg; + int frame_per_frag; + int first_dts; + + u32 seg_marker; + u64 frame_ntp; +} AudioOutputFile; + +int dc_audio_muxer_init(AudioOutputFile *audio_output_file, AudioDataConf *audio_data_conf, AudioMuxerType muxer_type, int frame_per_seg, int frame_per_frag, u32 seg_marker); +void dc_audio_muxer_free(AudioOutputFile *audio_output_file); + +/* + * Open the output audio + * + * @param audio_output_file [out] open the audio output on this file + * + * @param audio_data_conf [in] the structure containing the + * configuration of the output file (bitrate, samplerate, name, channels) + * + * @return 0 on success, -1 on failure + */ +GF_Err dc_audio_muxer_open(AudioOutputFile *audio_output_file, char *directory, char *id_name, int seg); + +GF_Err dc_audio_muxer_write(AudioOutputFile *audio_output_file, int frame_nb, Bool insert_ntp); + +GF_Err dc_audio_muxer_close(AudioOutputFile *audio_output_file); + +#endif /* AUDIO_MUXER_H_ */ diff --git a/applications/dashcast/circular_buffer.c b/applications/deprecated/old_arch/dashcast/circular_buffer.c similarity index 100% rename from applications/dashcast/circular_buffer.c rename to applications/deprecated/old_arch/dashcast/circular_buffer.c diff --git a/applications/dashcast/circular_buffer.h b/applications/deprecated/old_arch/dashcast/circular_buffer.h similarity index 100% rename from applications/dashcast/circular_buffer.h rename to applications/deprecated/old_arch/dashcast/circular_buffer.h diff --git a/applications/dashcast/cmd_data.c b/applications/deprecated/old_arch/dashcast/cmd_data.c similarity index 100% rename from applications/dashcast/cmd_data.c rename to applications/deprecated/old_arch/dashcast/cmd_data.c diff --git a/applications/dashcast/cmd_data.h b/applications/deprecated/old_arch/dashcast/cmd_data.h similarity index 100% rename from applications/dashcast/cmd_data.h rename to applications/deprecated/old_arch/dashcast/cmd_data.h diff --git a/applications/deprecated/old_arch/dashcast/controler.c b/applications/deprecated/old_arch/dashcast/controler.c new file mode 100644 index 0000000..c4dbd2c --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/controler.c @@ -0,0 +1,1454 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 "controler.h" + + +#if (!defined(__DARWIN__) && !defined(__APPLE__)) +# include +#endif + +#include + +#if defined(__GNUC__) +# include +# include +#elif defined(WIN32) +# include +# include +# define suseconds_t long +#else +# error +#endif + +#include + +typedef struct { + int segnum; + u64 utc_time, ntpts; +} segtime; + + +//#define MAX_SOURCE_NUMBER 20 +#define FRAGMENTER 0 +//#define DEBUG 1 + +//#define VIDEO_MUXER FFMPEG_VIDEO_MUXER +//#define VIDEO_MUXER RAW_VIDEO_H264 +//#define VIDEO_MUXER GPAC_VIDEO_MUXER +#define VIDEO_MUXER GPAC_INIT_VIDEO_MUXER_AVC1 +//#define VIDEO_MUXER GPAC_INIT_VIDEO_MUXER_AVC3 + +//#define AUDIO_MUXER FFMPEG_AUDIO_MUXER +//#define AUDIO_MUXER GPAC_AUDIO_MUXER +#define AUDIO_MUXER GPAC_INIT_AUDIO_MUXER + +#define AUDIO_FRAME_SIZE 1024 + + +void optimize_seg_frag_dur(int *seg, int *frag) +{ + int min_rem; + int seg_nb = *seg; + int frag_nb = *frag; + if (!frag_nb) frag_nb = 1; + + min_rem = seg_nb % frag_nb; + + if (seg_nb % (frag_nb + 1) < min_rem) { + min_rem = seg_nb % (frag_nb + 1); + *seg = seg_nb; + *frag = frag_nb + 1; + } + + if ((seg_nb + 1) % frag_nb < min_rem) { + min_rem = (seg_nb + 1) % frag_nb; + *seg = seg_nb + 1; + *frag = frag_nb; + } + + if ((seg_nb + 1) % (frag_nb + 1) < min_rem) { + min_rem = (seg_nb + 1) % (frag_nb + 1); + *seg = seg_nb + 1; + *frag = frag_nb + 1; + } + + *seg -= min_rem; +} + +Bool change_source_thread(void *params) +{ + Bool ret = GF_FALSE; + return ret; +} + +u32 send_frag_event(void *params) +{ + int ret; + //int status; + char buff[GF_MAX_PATH]; + ThreadParam *th_param = (ThreadParam*)params; + CmdData *cmd_data = th_param->in_data; + MessageQueue *mq = th_param->mq; + + while (1) { + if (cmd_data->exit_signal) { + break; + } + + ret = dc_message_queue_get(mq, (void*) buff); + if (ret > 0) { + fprintf(stdout, "Message received: %s\n", buff); + } + } + + return 0; +} + +static void dc_write_mpd(CmdData *cmddata, const AudioDataConf *audio_data_conf, const VideoDataConf *video_data_conf, const char *presentation_duration, const char *availability_start_time, const char *time_shift, const int segnum, const int ast_offset) +{ + u32 i = 0, sec; + int audio_seg_dur = 0, video_seg_dur = 0, audio_frag_dur = 0, video_frag_dur = 0; + int audio_frame_size = AUDIO_FRAME_SIZE; + time_t gtime; + struct tm *t; + FILE *f; + + char name[GF_MAX_PATH]; + + snprintf(name, sizeof(name), "%s/%s", cmddata->out_dir, cmddata->mpd_filename); + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Write MPD at UTC "LLU" ms - %s : %s\n", gf_net_get_utc(), (cmddata->mode == ON_DEMAND) ? "mediaPresentationDuration" : "availabilityStartTime", (cmddata->mode == ON_DEMAND) ? presentation_duration : availability_start_time)); + + if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { + audio_data_conf = (const AudioDataConf*)gf_list_get(cmddata->audio_lst, 0); + if (audio_data_conf) { + audio_seg_dur = (int)((audio_data_conf->samplerate / (double) audio_frame_size) * (cmddata->seg_dur / 1000.0)); + audio_frag_dur = (int)((audio_data_conf->samplerate / (double) audio_frame_size) * (cmddata->frag_dur / 1000.0)); + optimize_seg_frag_dur(&audio_seg_dur, &audio_frag_dur); + } + } + + if (strcmp(cmddata->video_data_conf.filename, "") != 0) { + video_data_conf = (VideoDataConf*)gf_list_get(cmddata->video_lst, 0); + if (video_data_conf) { + video_seg_dur = (int)(video_data_conf->framerate * (cmddata->seg_dur / 1000.0)); + video_frag_dur = (int)(video_data_conf->framerate * (cmddata->frag_dur / 1000.0)); + optimize_seg_frag_dur(&video_seg_dur, &video_frag_dur); + } + } + + f = gf_fopen(name, "w"); + //TODO: if (!f) ... + + // time_t t = time(NULL); + // time_t t2 = t + 2; + // t += (2 * (cmddata->seg_dur / 1000.0)); + // tm = *gmtime(&t2); + // snprintf(availability_start_time, "%d-%d-%dT%d:%d:%dZ", tm.tm_year + 1900, + // tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + // fprintf(stdout, "%s \n", availability_start_time); + + fprintf(f, "\n"); + fprintf(f, "min_buffer_time); + + if (cmddata->mode == ON_DEMAND) { + fprintf(f, " type=\"static\" mediaPresentationDuration=\"%s\"", presentation_duration); + } else { + fprintf(f, " type=\"dynamic\" availabilityStartTime=\"%s\"", availability_start_time); + if (time_shift) fprintf(f, " timeShiftBufferDepth=\"%s\"", time_shift); + + if (cmddata->minimum_update_period > 0) + fprintf(f, " minimumUpdatePeriod=\"PT%dS\"", cmddata->minimum_update_period); + + gf_net_get_ntp(&sec, NULL); + gtime = sec - GF_NTP_SEC_1900_TO_1970; + t = gmtime(>ime); + fprintf(f, " publishTime=\"%d-%02d-%02dT%02d:%02d:%02dZ\"", 1900+t->tm_year, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); + + } + + fprintf(f, ">\n"); + + fprintf(f, + " \n" + " %s\n" + " \n", cmddata->mpd_filename); + + if (strcmp(cmddata->base_url, "") != 0) { + fprintf(f, " %s\n", cmddata->base_url); + } + + fprintf(f, " \n"); + + if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { + fprintf(f, " \n"); + + fprintf(f, + " \n"); + + fprintf(f, + " samplerate, audio_seg_dur * audio_frame_size, segnum); + + if (ast_offset<0) { + fprintf(f, " availabilityTimeOffset=\"%g\"", -ast_offset/1000.0); + } + fprintf(f, "/>\n"); + + + + for (i = 0; i < gf_list_count(cmddata->audio_lst); i++) { + audio_data_conf = (const AudioDataConf*)gf_list_get(cmddata->audio_lst, i); + fprintf(f, + " \n" + " \n", audio_data_conf->filename, audio_data_conf->codec6381, audio_data_conf->samplerate, audio_data_conf->bitrate); + } + + fprintf(f, " \n"); + } + + if (strcmp(cmddata->video_data_conf.filename, "") != 0) { + fprintf(f, " \n"); + + fprintf(f, + " framerate, video_seg_dur, segnum); + + + if (ast_offset<0) { + fprintf(f, " availabilityTimeOffset=\"%g\"", -ast_offset/1000.0); + } + fprintf(f, "/>\n"); + + for (i = 0; i < gf_list_count(cmddata->video_lst); i++) { + video_data_conf = (VideoDataConf*)gf_list_get(cmddata->video_lst, i); + fprintf(f, " \n" + " \n", video_data_conf->filename, + VIDEO_MUXER == GPAC_INIT_VIDEO_MUXER_AVC1 ? video_data_conf->codec6381 : "avc3", + video_data_conf->width, video_data_conf->height, video_data_conf->framerate, + video_data_conf->bitrate); + } + + fprintf(f, " \n"); + } + + fprintf(f, " \n"); + + fprintf(f, "\n"); + + gf_fclose(f); +} + +static u32 mpd_thread(void *params) +{ + ThreadParam *th_param = (ThreadParam*)params; + CmdData *cmddata = th_param->in_data; + MessageQueue *mq = th_param->mq; + char availability_start_time[GF_MAX_PATH]; + char presentation_duration[GF_MAX_PATH]; + char time_shift[GF_MAX_PATH] = ""; + AudioDataConf *audio_data_conf = NULL; + VideoDataConf *video_data_conf = NULL; + struct tm ast_time; + int dur = 0; + int h, m, s, ms; + segtime last_seg_time; + segtime main_seg_time; + Bool first = GF_TRUE; + main_seg_time.segnum = 0; + main_seg_time.utc_time = 0; + main_seg_time.ntpts = 0; + last_seg_time = main_seg_time; + + if (cmddata->mode == LIVE_CAMERA || cmddata->mode == LIVE_MEDIA) { + while (1) { + u32 msecs; + time_t t; + segtime seg_time; + seg_time.segnum = 0; + seg_time.utc_time = 0; + seg_time.ntpts = 0; + + if (cmddata->exit_signal) { + break; + } + + if (strcmp(cmddata->video_data_conf.filename, "") != 0) { + if (dc_message_queue_get(mq, &seg_time) < 0) { + continue; + } + } + + if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { + if (dc_message_queue_get(mq, &seg_time) < 0) { + continue; + } + } + assert(seg_time.ntpts); + + if (cmddata->use_dynamic_ast) { + main_seg_time = seg_time; + } else { + //get the last notification of AST + if (first) { + main_seg_time = seg_time; + first = GF_FALSE; + } + assert(main_seg_time.ntpts); + } + + last_seg_time = seg_time; + assert(main_seg_time.ntpts <= seg_time.ntpts); + + t = (seg_time.ntpts >> 32) - GF_NTP_SEC_1900_TO_1970; + msecs = (u32) ( (seg_time.ntpts & 0xFFFFFFFF) * (1000.0/0xFFFFFFFF) ); + ast_time = *gmtime(&t); + fprintf(stdout, "Generating MPD at %d-%02d-%02dT%02d:%02d:%02d.%03dZ\n", 1900 + ast_time.tm_year, ast_time.tm_mon+1, ast_time.tm_mday, ast_time.tm_hour, ast_time.tm_min, ast_time.tm_sec, msecs); + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Generating MPD at %d-%02d-%02dT%02d:%02d:%02d.%03dZ - UTC "LLU" ms - AST UTC "LLU" ms\n", 1900 + ast_time.tm_year, ast_time.tm_mon+1, ast_time.tm_mday, ast_time.tm_hour, ast_time.tm_min, ast_time.tm_sec, msecs, seg_time.utc_time, main_seg_time.utc_time)); + + t = (main_seg_time.ntpts >> 32) - GF_NTP_SEC_1900_TO_1970; + if (cmddata->ast_offset>0) { + t += cmddata->ast_offset/1000; + } + msecs = (u32) ( (main_seg_time.ntpts & 0xFFFFFFFF) * (1000.0/0xFFFFFFFF) ); + ast_time = *gmtime(&t); + assert(ast_time.tm_year); + + sprintf(availability_start_time, "%d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + ast_time.tm_year, ast_time.tm_mon+1, ast_time.tm_mday, ast_time.tm_hour, ast_time.tm_min, ast_time.tm_sec, msecs); + fprintf(stdout, "StartTime: %s - startNumber %d - last number %d\n", availability_start_time, main_seg_time.segnum+1, seg_time.segnum+1); + + if (cmddata->time_shift != -1) { + int ts, h, m, s; + ts = cmddata->time_shift; + h = ts / 3600; + ts = ts % 3600; + m = ts / 60; + s = ts % 60; + snprintf(time_shift, sizeof(time_shift), "PT%02dH%02dM%02dS", h, m, s); + } + + dc_write_mpd(cmddata, audio_data_conf, video_data_conf, presentation_duration, availability_start_time, time_shift, main_seg_time.segnum+1, cmddata->ast_offset); + } + + if (cmddata->no_mpd_rewrite) return 0; + + //finally rewrite the MPD to static + dur = cmddata->seg_dur * (last_seg_time.segnum - main_seg_time.segnum); + if (cmddata->time_shift) { + if (dur > cmddata->time_shift * 1000) { + u32 nb_seg = cmddata->time_shift*1000 / cmddata->seg_dur; + main_seg_time.segnum = last_seg_time.segnum - nb_seg; + //dur = cmddata->time_shift; + } + dur = cmddata->seg_dur * (last_seg_time.segnum - main_seg_time.segnum); + } + cmddata->mode = ON_DEMAND; + + } else { + int a_dur = 0; + int v_dur = 0; + + if (strcmp(cmddata->audio_data_conf.filename, "") != 0) { + dc_message_queue_get(mq, &a_dur); + } + + if (strcmp(cmddata->video_data_conf.filename, "") != 0) { + dc_message_queue_get(mq, &v_dur); + } + + dur = v_dur > a_dur ? v_dur : a_dur; + } + + + h = dur / 3600000; + dur = dur % 3600000; + m = dur / 60000; + dur = dur % 60000; + s = dur / 1000; + ms = dur % 1000; + snprintf(presentation_duration, sizeof(presentation_duration), "PT%02dH%02dM%02d.%03dS", h, m, s, ms); + fprintf(stdout, "Duration: %s\n", presentation_duration); + + + dc_write_mpd(cmddata, audio_data_conf, video_data_conf, presentation_duration, availability_start_time, 0, main_seg_time.segnum+1, 0); + + return 0; +} + +u32 delete_seg_thread(void *params) +{ + int ret; + ThreadParam *th_param = (ThreadParam*)params; + CmdData *cmd_data = th_param->in_data; + MessageQueue *mq = th_param->mq; + + char buff[GF_MAX_PATH]; + + while (1) { + ret = dc_message_queue_get(mq, (void*) buff); + if (ret > 0) { + int status; + status = unlink(buff); + if (status != 0) { + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("Unable to delete the file %s\n", buff)); + } + } + + if (cmd_data->exit_signal) { + break; + } + } + + return 0; +} + +Bool fragmenter_thread(void *params) +{ +// int ret; + ThreadParam *th_param = (ThreadParam*)params; + CmdData *cmd_data = th_param->in_data; + MessageQueue *mq = th_param->mq; + + char buff[GF_MAX_PATH]; + + while (1) { + /*ret = */dc_message_queue_get(mq, (void*) buff); + if (cmd_data->exit_signal) { + break; + } + } + + return GF_FALSE; +} + +static u32 keyboard_thread(void *params) +{ + + ThreadParam *th_param = (ThreadParam*)params; + CmdData *in_data = th_param->in_data; + char c; + + while (1) { + if (gf_prompt_has_input()) { + c = gf_prompt_get_char(); + if (c == 'q' || c == 'Q') { + in_data->exit_signal = 1; + break; + } + } + + if (in_data->exit_signal) { + break; + } + + gf_sleep(100); + } + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Keyboard thread exit\n")); + return 0; +} + +u32 video_decoder_thread(void *params) +{ +#ifdef DASHCAST_PRINT + int i = 0; +#endif + int ret; + int source_number = 0; + + //int first_time = 1; + struct timeval time_start, time_end, time_wait; + VideoThreadParam *thread_params = (VideoThreadParam *) params; + + CmdData *in_data = thread_params->in_data; + VideoInputData *video_input_data = thread_params->video_input_data; + VideoInputFile **video_input_file = thread_params->video_input_file; + + suseconds_t total_wait_time = (int) (1000000.0 / (double) in_data->video_data_conf.framerate); + suseconds_t pick_packet_delay, select_delay = 0, real_wait, other_delays = 2; + + Task t; + //fprintf(stdout, "wait time : %f\n", total_wait_time); + + if (!gf_list_count(in_data->video_lst)) + return 0; + + while (1) { + dc_task_get_current(&in_data->task_list, &t); + source_number = t.source_number; + + //fprintf(stdout, "sourcenumber: %d\n", source_number); + +// if (video_input_file[source_number]->mode == LIVE_MEDIA) { + gf_gettimeofday(&time_start, NULL); +// } + + ret = dc_video_decoder_read(video_input_file[source_number], video_input_data, source_number, in_data->use_source_timing, (in_data->mode == LIVE_CAMERA) ? 1 : 0, (const int *) &in_data->exit_signal); +#ifdef DASHCAST_PRINT + fprintf(stdout, "Read video frame %d\r", i++); + fflush(stdout); +#endif + if (ret == -2) { + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video reader has no more frame to read.\n")); + break; + } + if (ret == -1) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occurred while reading video frame.\n")); + break; + } + + if (in_data->exit_signal) { + dc_video_input_data_end_signal(video_input_data); + break; + } + + if (video_input_file[source_number]->mode == LIVE_MEDIA) { + gf_gettimeofday(&time_end, NULL); + pick_packet_delay = ((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec; + time_wait.tv_sec = 0; + real_wait = total_wait_time - pick_packet_delay - select_delay - other_delays; + time_wait.tv_usec = real_wait; + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("delay: %ld = %ld - %ld\n", time_wait.tv_usec, total_wait_time, pick_packet_delay)); + + gf_gettimeofday(&time_start, NULL); + select(0, NULL, NULL, NULL, &time_wait); + gf_gettimeofday(&time_end, NULL); + + select_delay = (((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec) - real_wait; + } + } + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Video decoder is exiting...\n")); + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("video decoder thread exit\n")); + return 0; +} + +u32 audio_decoder_thread(void *params) +{ + int ret; + struct timeval time_start, time_end, time_wait; + AudioThreadParam *thread_params = (AudioThreadParam*)params; + + CmdData *in_data = thread_params->in_data; + AudioInputData *audio_input_data = thread_params->audio_input_data; + AudioInputFile *audio_input_file = thread_params->audio_input_file; + + suseconds_t pick_packet_delay, select_delay = 0, real_wait, other_delays = 1; + suseconds_t total_wait_time; + if (in_data->audio_data_conf.samplerate < 1024) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error: invalid audio sample rate: %d\n", in_data->audio_data_conf.samplerate)); + dc_audio_inout_data_end_signal(audio_input_data); + //FIXME: deadlock on the mpd thread. Reproduce with big_buck_bunny.mp4. + return 1; + } + total_wait_time = (int) (1000000.0 / (in_data->audio_data_conf.samplerate / (double) AUDIO_FRAME_SIZE)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("wait time : %ld\n", total_wait_time)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("sample-rate : %ld\n", in_data->audio_data_conf.samplerate)); + + if (!gf_list_count(in_data->audio_lst)) + return 0; + + while (1) { +// if (audio_input_file->mode == LIVE_MEDIA) { + gf_gettimeofday(&time_start, NULL); +// } + + ret = dc_audio_decoder_read(audio_input_file, audio_input_data); + if (ret == -2) { + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio decoder has no more frame to read.\n")); + break; + } + if (ret == -1) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occurred while reading audio frame.\n")); + break; + } + + if (in_data->exit_signal) { + dc_audio_inout_data_end_signal(audio_input_data); + break; + } + + if (audio_input_file->mode == LIVE_MEDIA) { + gf_gettimeofday(&time_end, NULL); + pick_packet_delay = ((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec; + time_wait.tv_sec = 0; + real_wait = total_wait_time - pick_packet_delay - select_delay - other_delays; + time_wait.tv_usec = real_wait; + + gf_gettimeofday(&time_start, NULL); + select(0, NULL, NULL, NULL, &time_wait); + gf_gettimeofday(&time_end, NULL); + + select_delay = (((time_end.tv_sec - time_start.tv_sec) * 1000000) + time_end.tv_usec - time_start.tv_usec) - real_wait; + } + } + + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio decoder is exiting...\n")); + return 0; +} + +u32 video_scaler_thread(void *params) +{ + int ret; + VideoThreadParam *thread_params = (VideoThreadParam *) params; + CmdData *in_data = thread_params->in_data; + VideoInputData *video_input_data = thread_params->video_input_data; + VideoScaledData *video_scaled_data = thread_params->video_scaled_data; + + if (!gf_list_count(in_data->video_lst)) + return 0; + + while (1) { + ret = dc_video_scaler_scale(video_input_data, video_scaled_data); + if (ret == -2) { + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video scaler has no more frame to read.\n")); + break; + } + } + + dc_video_scaler_end_signal(video_scaled_data); + + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("video scaler thread exit\n")); + return 0; +} + +u32 video_encoder_thread(void *params) +{ + int ret, shift, frame_nb, seg_frame_max, frag_frame_max, seg_nb = 0, loss_state = 0, quit = 0, real_video_seg_dur; + char name_to_delete[GF_MAX_PATH], name_to_send[GF_MAX_PATH]; + u64 start_utc, seg_utc; + segtime time_at_segment_start; + VideoMuxerType muxer_type = VIDEO_MUXER; + VideoThreadParam *thread_params = (VideoThreadParam*)params; + u32 sec, frac; + Bool init_mpd = GF_FALSE; + CmdData *in_data = thread_params->in_data; + int video_conf_idx = thread_params->video_conf_idx; + VideoDataConf *video_data_conf = (VideoDataConf*)gf_list_get(in_data->video_lst, video_conf_idx); + + VideoScaledData *video_scaled_data = thread_params->video_scaled_data; + int video_cb_size = (in_data->mode == LIVE_MEDIA || in_data->mode == LIVE_CAMERA) ? 1 : VIDEO_CB_DEFAULT_SIZE; + VideoOutputFile out_file; + + MessageQueue *mq = thread_params->mq; + MessageQueue *delete_seg_mq = thread_params->delete_seg_mq; + MessageQueue *send_seg_mq = thread_params->send_seg_mq; + + if (!gf_list_count(in_data->video_lst)) + return 0; + + seg_frame_max = (int)(video_data_conf->framerate * (float) (in_data->seg_dur / 1000.0)); + frag_frame_max = (int)(video_data_conf->framerate * (float) (in_data->frag_dur / 1000.0)); + optimize_seg_frag_dur(&seg_frame_max, &frag_frame_max); + + real_video_seg_dur = (int) (seg_frame_max * 1000.0 / (float) video_data_conf->framerate); + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[video_encoder] seg_frame_max=%d, frag_frame_max=%d, real_video_seg_dur=%d ms\n", seg_frame_max, frag_frame_max, real_video_seg_dur)); + + + if (seg_frame_max <= 0) + seg_frame_max = -1; + + if (dc_video_muxer_init(&out_file, video_data_conf, muxer_type, seg_frame_max, frag_frame_max, in_data->seg_marker, in_data->gdr, in_data->seg_dur, in_data->frag_dur, (u32) video_scaled_data->vsprop->video_input_data->frame_duration, in_data->gop_size, video_cb_size) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot init output video file.\n")); + in_data->exit_signal = 1; + return -1; + } + + if (dc_video_encoder_open(&out_file, video_data_conf, in_data->use_source_timing, video_scaled_data->sar) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video stream.\n")); + in_data->exit_signal = 1; + return -1; + } + + if (in_data->mode == LIVE_MEDIA || in_data->mode == LIVE_CAMERA) { + init_mpd = GF_TRUE; + } + + + time_at_segment_start.ntpts = 0; + start_utc = gf_net_get_utc(); + + while (1) { + frame_nb = 0; + //log time at segment start, because segment availabilityStartTime is computed from AST anchor + segment duration + //logging at the end of the segment production will induce one segment delay + time_at_segment_start.segnum = seg_nb; + time_at_segment_start.utc_time = gf_net_get_utc(); + gf_net_get_ntp(&sec, &frac); + +#ifndef GPAC_DISABLE_LOG + if (gf_log_tool_level_on(GF_LOG_DASH, GF_LOG_INFO)) { + if (time_at_segment_start.ntpts) { + u32 ref_sec, ref_frac; + Double tr, t; + ref_sec = (time_at_segment_start.ntpts>>32) & 0xFFFFFFFFULL; + ref_frac = (u32) (time_at_segment_start.ntpts & 0xFFFFFFFFULL); + tr = ref_sec * 1000.0; + tr += ref_frac*1000.0 /0xFFFFFFFF; + t = sec * 1000.0; + t += frac*1000.0 /0xFFFFFFFF; + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] NTP diff since last segment start in msec is %f\n", t - tr)); + + } + } +#endif + + time_at_segment_start.ntpts = sec; + time_at_segment_start.ntpts <<= 32; + time_at_segment_start.ntpts |= frac; + + //force writing MPD before any encoding happens (eg don't wait for the end of the first segment) + if (init_mpd) { + init_mpd = GF_FALSE; + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Initial MPD publish at UTC "LLU" ms\n", time_at_segment_start.utc_time)); + dc_message_queue_put(mq, &time_at_segment_start, sizeof(time_at_segment_start)); + } + + assert(! out_file.segment_started); + + if (dc_video_muxer_open(&out_file, in_data->out_dir, video_data_conf->filename, seg_nb+1) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video file.\n")); + in_data->exit_signal = 1; + return -1; + } +// fprintf(stdout, "Header size: %d\n", ret); + while (1) { + //we have the RAP already encoded, skip coder + if (loss_state == 2) { + ret = 1; + loss_state = 0; + } else { + ret = dc_video_encoder_encode(&out_file, video_scaled_data); + } + + if (ret == -2) { + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video encoder has no more data to encode.\n")); + quit = 1; + break; + } + if (ret == -1) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occured while writing video frame.\n")); + quit = 1; + break; + } + + if (ret > 0) { + int r; + + /*resync at first RAP: flush current broken segment and restart next one on rap*/ + if ((loss_state==1) && out_file.codec_ctx->coded_frame->key_frame) { + loss_state = 2; + break; + } + + r = dc_video_muxer_write(&out_file, frame_nb, in_data->insert_utc ? GF_TRUE : GF_FALSE); + if (r < 0) { + quit = 1; + in_data->exit_signal = 1; + break; + } else if (r == 1) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("fragment is written!\n")); + if (in_data->send_message == 1) { + snprintf(name_to_send, sizeof(name_to_send), "%s/%s_%d_gpac.m4s", in_data->out_dir, video_data_conf->filename, seg_nb); + dc_message_queue_put(send_seg_mq, name_to_send, sizeof(name_to_send)); + } + + break; + } + + frame_nb++; + } + } + + dc_video_muxer_close(&out_file); + + // If system is live, + // Send the time that a segment is available to MPD generator thread. + if (in_data->mode == LIVE_MEDIA || in_data->mode == LIVE_CAMERA) { + //check we don't loose sync + int diff; + int seg_diff; + seg_utc = gf_net_get_utc(); + diff = (int) (seg_utc - start_utc); + + //if seg UTC is after next segment UTC (current ends at seg_nb+1, next at seg_nb+2), adjust numbers + if (diff > (seg_nb+2) * real_video_seg_dur) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff %d bigger than segment duration %d - some frame where probably lost. Adjusting\n", out_file.rep_id, diff, seg_nb)); + + while (diff > (seg_nb+2) * real_video_seg_dur) { + seg_nb++; + + //do a rough estimate of losses to adjust timing... + if (! in_data->use_source_timing) { + out_file.first_dts_in_fragment += out_file.codec_ctx->time_base.den; + } + } + //wait for RAP to cut next segment + loss_state = 1; + } else { +#define SYNC_SAFE 800 + + seg_diff = diff; + seg_diff -= (seg_nb+1) * real_video_seg_dur; + if (seg_diff > SYNC_SAFE) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff at segment close: %d is higher than cumulated segment duration %d (diff %d) - frame rate is probably not correct!\n", out_file.rep_id, diff, (seg_nb+1) * in_data->seg_dur, seg_diff)); + } + else if (seg_diff < -SYNC_SAFE) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff at segment close: %d is lower than cumulated segment duration %d (diff %d) - frame rate is probably not correct or frames were lost!\n", out_file.rep_id, diff, (seg_nb+1) * in_data->seg_dur, seg_diff)); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[video_encoder] Rep %s UTC diff at segment close: %d - cumulated segment duration %d (diff %d)\n", out_file.rep_id, diff, (seg_nb+1) * in_data->seg_dur, seg_diff)); + } + } + + //time_t t = time(NULL); + dc_message_queue_put(mq, &time_at_segment_start, sizeof(time_at_segment_start)); + } + + if ((in_data->time_shift != -1)) { + shift = 1000 * in_data->time_shift / in_data->seg_dur; + if (seg_nb > shift) { + snprintf(name_to_delete, sizeof(name_to_delete), "%s/%s_%d_gpac.m4s", in_data->out_dir, video_data_conf->filename, (seg_nb - shift)); + dc_message_queue_put(delete_seg_mq, name_to_delete, sizeof(name_to_delete)); + } + } + + seg_nb++; + + if (quit) + break; + } + + // If system is not live, + // Send the duration of the video + if (in_data->mode == ON_DEMAND) { + if (thread_params->video_conf_idx == 0) { + int dur = (seg_nb * seg_frame_max * 1000) / video_data_conf->framerate; + int dur_tot = (out_file.codec_ctx->frame_number * 1000) + / video_data_conf->framerate; + if (dur > dur_tot) + dur = dur_tot; + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Duration: %d \n", dur)); + dc_message_queue_put(mq, &dur, sizeof(dur)); + } + } + + /* Close output video file */ + dc_video_encoder_close(&out_file); + + dc_video_muxer_free(&out_file); + + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("video encoder thread exit\n")); + return 0; +} + +u32 audio_encoder_thread(void *params) +{ + int ret, exit_loop = 0, quit = 0, seg_nb = 0, frame_per_seg, frame_per_frag, frame_nb, shift, real_audio_seg_dur; + //int seg_frame_max; + //int frag_frame_max; + //int audio_frame_size = AUDIO_FRAME_SIZE; + char name_to_delete[GF_MAX_PATH]; + u64 start_utc, seg_utc; + segtime time_at_segment_start; + Bool check_first_seg_utc = GF_TRUE; + + AudioMuxerType muxer_type = AUDIO_MUXER; + AudioThreadParam *thread_params = (AudioThreadParam *) params; + + CmdData *in_data = thread_params->in_data; + int audio_conf_idx = thread_params->audio_conf_idx; + AudioDataConf *audio_data_conf = (AudioDataConf*)gf_list_get(in_data->audio_lst, audio_conf_idx); + + AudioInputData *audio_input_data = thread_params->audio_input_data; + AudioOutputFile audio_output_file; + + MessageQueue *mq = thread_params->mq; + MessageQueue *delete_seg_mq = thread_params->delete_seg_mq; + + if (!gf_list_count(in_data->audio_lst)) + return 0; + + //seg_frame_max = audio_data_conf->samplerate + // * (float) (in_data->seg_dur / 1000.0); + + //frag_frame_max = audio_data_conf->samplerate * (float) (in_data->frag_dur / 1000.0); + //if (seg_frame_max <= 0) + // seg_frame_max = -1; + + if (dc_audio_encoder_open(&audio_output_file, audio_data_conf) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output audio stream.\n")); + in_data->exit_signal = 1; + return -1; + } + + frame_per_seg = (int)((audio_data_conf->samplerate / (double) audio_output_file.codec_ctx->frame_size) * (in_data->seg_dur / 1000.0)); + frame_per_frag = (int)((audio_data_conf->samplerate / (double) audio_output_file.codec_ctx->frame_size) * (in_data->frag_dur / 1000.0)); + optimize_seg_frag_dur(&frame_per_seg, &frame_per_frag); + + real_audio_seg_dur = (int) (frame_per_seg * (double) audio_output_file.codec_ctx->frame_size * 1000.0 / (double) audio_data_conf->samplerate); + GF_LOG(GF_LOG_INFO, GF_LOG_DASH,("[audio_encoder] frame_per_seg=%d, frame_per_frag=%d, real_audio_seg_dur=%d ms\n", frame_per_seg, frame_per_frag, real_audio_seg_dur) ); + + if (dc_audio_muxer_init(&audio_output_file, audio_data_conf, muxer_type, frame_per_seg, frame_per_frag, in_data->seg_marker) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot init output audio.\n")); + in_data->exit_signal = 1; + return -1; + } + + start_utc = gf_net_get_utc(); + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[audio_encoder] start_utc="LLU"\n", start_utc)); + + while (1) { + //logging at the end of the segment production will induce one segment delay + time_at_segment_start.utc_time = gf_net_get_utc(); + time_at_segment_start.ntpts = gf_net_get_ntp_ts(); + + frame_nb = 0; + quit = 0; + + if (dc_audio_muxer_open(&audio_output_file, in_data->out_dir, audio_data_conf->filename, seg_nb+1) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output audio.\n")); + in_data->exit_signal = 1; + return -1; + } + + while (1) { + exit_loop = 0; +// if (frame_per_seg > 0) { +// if (frame_nb == frame_per_seg) { +// +// //if (dc_audio_encoder_flush(&audio_output_file, audio_input_data) == 0) { +// // dc_audio_muxer_write(&audio_output_file); +// // frame_nb++;//= audio_output_file.codec_ctx->frame_size; //audio_output_file.acc_samples; +// //} +// +// exit_loop = 1; +// break; +// } +// } + + audio_output_file.frame_ntp = gf_net_get_ntp_ts(); + ret = dc_audio_encoder_read(&audio_output_file, audio_input_data); + if (ret == -2) { + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio encoder has no more data to encode.\n")); + //if (dc_audio_encoder_flush(&audio_output_file, audio_input_data) == 0) { + // dc_audio_muxer_write(&audio_output_file); + // frame_nb++;//= audio_output_file.codec_ctx->frame_size; //audio_output_file.acc_samples; + //} + quit = 1; + break; + } + + while (1) { + ret = dc_audio_encoder_encode(&audio_output_file, audio_input_data); + if (ret == 1) { + break; + } + if (ret == -1) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occured while encoding audio frame.\n")); + quit = 1; + break; + } + + ret = dc_audio_muxer_write(&audio_output_file, frame_nb, in_data->insert_utc); + if (ret == -1) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("An error occured while writing audio frame.\n")); + quit = 1; + break; + } + + if (ret == 1) { + exit_loop = 1; + break; + } + + frame_nb++; //= audio_output_file.codec_ctx->frame_size; //audio_output_file.acc_samples; + } + + if (exit_loop || quit) + break; + } + + dc_audio_muxer_close(&audio_output_file); + + // Send the time that a segment is available to MPD generator thread. + if (in_data->mode == LIVE_CAMERA || in_data->mode == LIVE_MEDIA) { + int diff; + if (check_first_seg_utc) { + u64 now = gf_net_get_utc(); + check_first_seg_utc = GF_FALSE; + + diff = (int) (now - time_at_segment_start.utc_time); + if (diff < real_audio_seg_dur / 2) { + u32 sec, frac, ms; + s32 left, nb_s; + gf_net_get_ntp(&sec, &frac); + nb_s = real_audio_seg_dur/1000; + sec -= nb_s; + ms = (u32) ((u64) 1000 * frac / 0xFFFFFFFF); + left = ms; + left -= (s32) (real_audio_seg_dur - 1000*nb_s); + while (left<0) { + left += 1000; + sec-=1; + } + time_at_segment_start.ntpts = sec; + time_at_segment_start.ntpts <<= 32; + time_at_segment_start.ntpts |= (u32) ((0xFFFFFFFF*left)/1000); + + start_utc = time_at_segment_start.utc_time = now - real_audio_seg_dur; + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[audio_encoder] First segment produced faster (%d ms) than duration (%d ms) probably due to HW buffers - adjusting ast\n", diff, real_audio_seg_dur)); + } + } + if (thread_params->audio_conf_idx == 0) { + + //check we don't loose sync + seg_utc = gf_net_get_utc(); + diff = (int) (seg_utc - start_utc); + //if seg UTC is after next segment UTC (current ends at seg_nb+1, next at seg_nb+2), adjust numbers + if (diff > (seg_nb+2) * real_audio_seg_dur) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[audio_encoder] UTC dur %d bigger than segment duration %d - some frame where probably lost. Adjusting\n", diff, seg_nb)); + while (diff > (seg_nb+2) * real_audio_seg_dur) { + seg_nb++; + } + } + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[audio_encoder] UTC dur %d - cumulated segment duration %d (diff %d ms)\n", diff, (seg_nb+1) * real_audio_seg_dur, diff - (seg_nb+1) * real_audio_seg_dur)); + + + time_at_segment_start.segnum = seg_nb; + dc_message_queue_put(mq, &time_at_segment_start, sizeof(time_at_segment_start)); + } + } + + if (in_data->time_shift != -1) { + shift = 1000 * in_data->time_shift / in_data->seg_dur; + if (seg_nb > shift) { + snprintf(name_to_delete, sizeof(name_to_delete), "%s/%s_%d_gpac.m4s", in_data->out_dir, audio_data_conf->filename, (seg_nb - shift)); + dc_message_queue_put(delete_seg_mq, name_to_delete, sizeof(name_to_delete)); + } + } + + seg_nb++; + + if (quit) + break; + } + + // If system is not live, + // Send the duration of the video + if (in_data->mode == ON_DEMAND) { + if (thread_params->audio_conf_idx == 0) { + int dur = (seg_nb * audio_output_file.codec_ctx->frame_size * frame_per_seg * 1000) / audio_data_conf->samplerate; + int dur_tot = (audio_output_file.codec_ctx->frame_number * audio_output_file.codec_ctx->frame_size * 1000) / audio_data_conf->samplerate; + if (dur > dur_tot) + dur = dur_tot; + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Duration: %d \n", dur)); + dc_message_queue_put(mq, &dur, sizeof(dur)); + } + } + + dc_audio_muxer_free(&audio_output_file); + + /* Close output audio file */ + dc_audio_encoder_close(&audio_output_file); + + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Audio encoder is exiting...\n")); + return 0; +} + +int dc_run_controler(CmdData *in_data) +{ + int ret = 0; + u32 video_cb_size = VIDEO_CB_DEFAULT_SIZE; + u32 i, j; + + ThreadParam keyboard_th_params; + ThreadParam mpd_th_params; + ThreadParam delete_seg_th_params; + ThreadParam send_frag_th_params; + + //Video parameters + VideoThreadParam vdecoder_th_params; + VideoThreadParam *vencoder_th_params = (VideoThreadParam*)alloca(gf_list_count(in_data->video_lst) * sizeof(VideoThreadParam)); + VideoInputData video_input_data; + VideoInputFile *video_input_file[MAX_SOURCE_NUMBER]; + VideoScaledDataList video_scaled_data_list; + VideoThreadParam *vscaler_th_params = NULL; + + //Audio parameters + AudioThreadParam adecoder_th_params; + AudioThreadParam *aencoder_th_params = (AudioThreadParam*)alloca(gf_list_count(in_data->audio_lst) * sizeof(AudioThreadParam)); + AudioInputData audio_input_data; + AudioInputFile audio_input_file; + + MessageQueue mq; + MessageQueue delete_seg_mq; + MessageQueue send_frag_mq; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Controler init at UTC "LLU"\n", gf_net_get_utc() )); + dc_register_libav(); + + for (i = 0; i < MAX_SOURCE_NUMBER; i++) + video_input_file[i] = (VideoInputFile*)gf_malloc(sizeof(VideoInputFile)); + + dc_message_queue_init(&mq); + dc_message_queue_init(&delete_seg_mq); + dc_message_queue_init(&send_frag_mq); + + memset(&audio_input_data, 0, sizeof(AudioInputData)); + memset(&audio_input_file, 0, sizeof(AudioInputFile)); + memset(&video_input_data, 0, sizeof(VideoInputData)); + + + if (in_data->mode == LIVE_CAMERA || in_data->mode == LIVE_MEDIA) + video_cb_size = 1; + + if (strcmp(in_data->video_data_conf.filename, "") != 0) { + dc_video_scaler_list_init(&video_scaled_data_list, in_data->video_lst); + vscaler_th_params = (VideoThreadParam*)gf_malloc(video_scaled_data_list.size * sizeof(VideoThreadParam)); + + /* Open input video */ + if (dc_video_decoder_open(video_input_file[0], &in_data->video_data_conf, in_data->mode, in_data->no_loop, video_scaled_data_list.size) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input video.\n")); + ret = -1; + goto exit; + } + + if (dc_video_input_data_init(&video_input_data, /*video_input_file[0]->width, video_input_file[0]->height, + video_input_file[0]->pix_fmt,*/video_scaled_data_list.size, in_data->mode, MAX_SOURCE_NUMBER, video_cb_size) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot initialize audio data.\n")); + ret = -1; + goto exit; + } + + /* open other input videos for source switching */ + for (i = 0; i < gf_list_count(in_data->vsrc); i++) { + VideoDataConf *video_data_conf = (VideoDataConf*)gf_list_get(in_data->vsrc, i); + if (dc_video_decoder_open(video_input_file[i + 1], video_data_conf, LIVE_MEDIA, 1, video_scaled_data_list.size) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input video.\n")); + ret = -1; + goto exit; + } + } + + for (i=0; ivsrc) + 1; i++) { + dc_video_input_data_set_prop(&video_input_data, i, video_input_file[i]->width, video_input_file[i]->height, in_data->video_data_conf.crop_x, in_data->video_data_conf.crop_y, video_input_file[i]->pix_fmt, video_input_file[i]->sar); + } + + for (i=0; ivsrc) + 1; j++) { + dc_video_scaler_data_set_prop(&video_input_data, video_scaled_data_list.video_scaled_data[i], j); + } + } + + /* Initialize video decoder thread */ + vdecoder_th_params.thread = gf_th_new("video_decoder_thread"); + + for (i=0; ivideo_lst); i++) + vencoder_th_params[i].thread = gf_th_new("video_encoder_thread"); + } + + /* When video and audio share the same source, open it once. This allow to read from unicast streams */ + if (!strcmp(in_data->video_data_conf.filename, in_data->audio_data_conf.filename)) { + audio_input_file.av_fmt_ctx = video_input_file[0]->av_fmt_ctx; + video_input_file[0]->av_fmt_ctx_ref_cnt++; + audio_input_file.av_pkt_list = video_input_file[0]->av_pkt_list = gf_list_new(); + audio_input_file.av_pkt_list_mutex = video_input_file[0]->av_pkt_list_mutex = gf_mx_new("Demux AVPackets List"); + } + + if (strcmp(in_data->audio_data_conf.filename, "") != 0) { + /* Open input audio */ + if (dc_audio_decoder_open(&audio_input_file, &in_data->audio_data_conf, in_data->mode, in_data->no_loop, in_data->video_data_conf.framerate) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open input audio.\n")); + ret = -1; + goto exit; + } + + if (dc_audio_input_data_init(&audio_input_data, in_data->audio_data_conf.channels, in_data->audio_data_conf.samplerate, gf_list_count(in_data->audio_lst), in_data->mode) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot initialize audio data.\n")); + ret = -1; + goto exit; + } + + /* Initialize audio decoder thread */ + adecoder_th_params.thread = gf_th_new("audio_decoder_thread"); + + /* Initialize audio encoder threads */ + for (i = 0; i < gf_list_count(in_data->audio_lst); i++) + aencoder_th_params[i].thread = gf_th_new("video_encoder_thread"); + } + + /******** Keyboard controler Thread ********/ + + /* Initialize keyboard controller thread */ + keyboard_th_params.thread = gf_th_new("keyboard_thread"); + + /* Create keyboard controller thread */ + keyboard_th_params.in_data = in_data; + if (gf_th_run(keyboard_th_params.thread, keyboard_thread, (void *)&keyboard_th_params) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for keyboard_thread.\n")); + } + + /********************************************/ + + //Communication between decoder and audio encoder + for (i = 0; i < gf_list_count(in_data->audio_lst); i++) { + AudioDataConf *tmadata = (AudioDataConf*)gf_list_get(in_data->audio_lst, i); + tmadata->channels = in_data->audio_data_conf.channels; + tmadata->samplerate = in_data->audio_data_conf.samplerate; + } + + //Communication between decoder and video encoder + for (i = 0; i < gf_list_count(in_data->video_lst); i++) { + VideoDataConf *tmvdata = (VideoDataConf*)gf_list_get(in_data->video_lst, i); + tmvdata->framerate = in_data->video_data_conf.framerate; + if (in_data->use_source_timing) { + tmvdata->time_base = in_data->video_data_conf.time_base; + } + } + + /******** MPD Thread ********/ + + /* Initialize MPD generator thread */ + mpd_th_params.thread = gf_th_new("mpd_thread"); + + /* Create MPD generator thread */ + mpd_th_params.in_data = in_data; + mpd_th_params.mq = &mq; + if (gf_th_run(mpd_th_params.thread, mpd_thread, (void *)&mpd_th_params) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for mpd_thread.\n")); + } + + + if (strcmp(in_data->video_data_conf.filename, "") != 0) { + /* Create video decoder thread */ + vdecoder_th_params.in_data = in_data; + vdecoder_th_params.video_input_data = &video_input_data; + vdecoder_th_params.video_input_file = video_input_file; + if (gf_th_run(vdecoder_th_params.thread, video_decoder_thread, (void *) &vdecoder_th_params) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for video_decoder_thread.\n")); + } + + while ((in_data->mode == LIVE_CAMERA) && !video_input_data.frame_duration) { + gf_sleep(0); + } + } + + if (strcmp(in_data->audio_data_conf.filename, "") != 0) { + /* Create audio decoder thread */ + adecoder_th_params.in_data = in_data; + adecoder_th_params.audio_input_data = &audio_input_data; + adecoder_th_params.audio_input_file = &audio_input_file; + if (gf_th_run(adecoder_th_params.thread, audio_decoder_thread, (void *) &adecoder_th_params) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for audio_decoder_thread.\n")); + } + } + + /****************************/ + + if (strcmp(in_data->video_data_conf.filename, "") != 0) { + /* Create video encoder threads */ + for (i=0; ivideo_lst); i++) { + VideoDataConf * video_data_conf = (VideoDataConf*)gf_list_get(in_data->video_lst, i); + + vencoder_th_params[i].in_data = in_data; + vencoder_th_params[i].video_conf_idx = i; + vencoder_th_params[i].video_scaled_data = dc_video_scaler_get_data(&video_scaled_data_list, video_data_conf->width, video_data_conf->height); + + vencoder_th_params[i].mq = &mq; + vencoder_th_params[i].delete_seg_mq = &delete_seg_mq; + vencoder_th_params[i].send_seg_mq = &send_frag_mq; + + if (gf_th_run(vencoder_th_params[i].thread, video_encoder_thread, (void*)&vencoder_th_params[i]) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for video_encoder_thread.\n")); + } + } + + /* Create video scaler threads */ + for (i=0; iaudio_data_conf.filename, "") != 0) { + /* Create audio encoder threads */ + for (i = 0; i < gf_list_count(in_data->audio_lst); i++) { + aencoder_th_params[i].in_data = in_data; + aencoder_th_params[i].audio_conf_idx = i; + aencoder_th_params[i].audio_input_data = &audio_input_data; + + aencoder_th_params[i].mq = &mq; + aencoder_th_params[i].delete_seg_mq = &delete_seg_mq; + aencoder_th_params[i].send_seg_mq = &send_frag_mq; + + if (gf_th_run(aencoder_th_params[i].thread, audio_encoder_thread, (void *) &aencoder_th_params[i]) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for audio_encoder_thread.\n")); + } + } + } + + if (in_data->time_shift != -1) { + /* Initialize delete segment thread */ + delete_seg_th_params.thread = gf_th_new("delete_seg_thread"); + delete_seg_th_params.in_data = in_data; + delete_seg_th_params.mq = &delete_seg_mq; + if (gf_th_run(delete_seg_th_params.thread, delete_seg_thread, (void *) &delete_seg_th_params) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for delete_seg_thread.\n")); + } + } + + if (in_data->send_message == 1) { + /* Initialize delete segment thread */ + send_frag_th_params.thread = gf_th_new("send_frag_event_thread"); + send_frag_th_params.in_data = in_data; + send_frag_th_params.mq = &send_frag_mq; + if (gf_th_run(send_frag_th_params.thread, send_frag_event, (void *) &send_frag_th_params) != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while doing pthread_create for send_frag_event_thread.\n")); + } + } + + fprintf(stdout, "Press q or Q to exit...\n"); + + if (strcmp(in_data->audio_data_conf.filename, "") != 0) { + /* Wait for and destroy audio decoder threads */ + gf_th_stop(adecoder_th_params.thread); + gf_th_del(adecoder_th_params.thread); + } + + if (strcmp(in_data->video_data_conf.filename, "") != 0) { + /* Wait for and destroy video decoder threads */ + gf_th_stop(vdecoder_th_params.thread); + gf_th_del(vdecoder_th_params.thread); + } + + if (strcmp(in_data->audio_data_conf.filename, "") != 0) { + /* Wait for and destroy audio encoder threads */ + for (i = 0; i < gf_list_count(in_data->audio_lst); i++) { + gf_th_stop(aencoder_th_params[i].thread); + gf_th_del(aencoder_th_params[i].thread); + } + } + + if (strcmp(in_data->video_data_conf.filename, "") != 0) { + /* Wait for and destroy video encoder threads */ + for (i=0; ivideo_lst); i++) { + gf_th_stop(vencoder_th_params[i].thread); + gf_th_del(vencoder_th_params[i].thread); + } + + /* Wait for and destroy video scaler threads */ + for (i=0; iexit_signal = 1; + + /********** Keyboard thread ***********/ + + /* Wait for and destroy keyboard controler thread */ + gf_th_stop(keyboard_th_params.thread); + gf_th_del(keyboard_th_params.thread); + + /**************************************/ + + /********** MPD generator thread ***********/ + + /* Wait for and destroy MPD generator thread */ + gf_th_stop(mpd_th_params.thread); + gf_th_del(mpd_th_params.thread); + + /**************************************/ + + if (in_data->time_shift != -1) { + // dc_message_queue_flush(&delete_seg_mq); + /* Wait for and destroy delete segment thread */ + gf_th_stop(delete_seg_th_params.thread); + gf_th_del(delete_seg_th_params.thread); + } + + if (in_data->send_message == 1) { + /* Wait for and destroy delete segment thread */ + gf_th_stop(send_frag_th_params.thread); + gf_th_del(send_frag_th_params.thread); + } + +exit: + if (strcmp(in_data->audio_data_conf.filename, "") != 0) { + /* Destroy audio input data */ + dc_audio_input_data_destroy(&audio_input_data); + /* Close input audio */ + dc_audio_decoder_close(&audio_input_file); + } + + if (strcmp(in_data->video_data_conf.filename, "") != 0) { + /* Destroy video input data */ + dc_video_input_data_destroy(&video_input_data); + + for (i = 0; i < gf_list_count(in_data->vsrc); i++) { + /* Close input video */ + dc_video_decoder_close(video_input_file[i]); + } + + for (i=0; i + +//anything different is broken in dash cast (random frame inversions at encoding time ...) +#define VIDEO_CB_DEFAULT_SIZE 1 + + +/* + * This structure corresponds to an + * entry of video configuration in the + * configuration file. + */ +typedef struct { + /* video file name */ + char filename[GF_MAX_PATH]; + /* video format */ + char format[GF_MAX_PATH]; + /* video format */ + char pixel_format[GF_MAX_PATH]; + /* v4l2 format */ + char v4l2f[GF_MAX_PATH]; + /* left crop */ + int crop_x; + /* top crop */ + int crop_y; + /* video final width */ + int width; + /* video final height */ + int height; + /* video bitrate */ + int bitrate; + /* video frame rate */ + int framerate; + /* video codec */ + char codec[GF_MAX_PATH]; + /* RFC6381 codec name, only valid when VIDEO_MUXER == GPAC_INIT_VIDEO_MUXER_AVC1 */ + char codec6381[RFC6381_CODEC_NAME_SIZE_MAX]; + /* custom parameter to be passed directly to the encoder - free it once you're done */ + char custom[GF_MAX_PATH]; + /*low delay is used*/ + int low_delay; + /*demuxer buffer size or 0 if default FFmpeg one is used*/ + int demux_buffer_size; + + /* used for source switching */ + char source_id[GF_MAX_PATH]; + time_t start_time; + time_t end_time; + + //copy over from source file + AVRational time_base; + u64 frame_duration; +} VideoDataConf; + +typedef struct { + /* Width, height and pixel format of the input video. */ + int width; + int height; + int crop_x, crop_y; + int pix_fmt; + AVRational sar; +} VideoInputProp; + +/* + * VideoInputData is designed to keep the data + * of input video in a circular buffer. + * The circular buffer has its own mechanism for synchronization. + */ +typedef struct { + /* The circular buffer of the video frames after decoding. */ + CircularBuffer circular_buf; + /* The user of circular buffer has an index to it, which is in this variable. */ + Producer producer; + + VideoInputProp *vprop; + + /* Width, height and pixel format of the input video */ + //int width; + //int height; + //int pix_fmt; + u64 frame_duration; +} VideoInputData; + + +/* + * Each node in a circular buffer is a pointer. + * To use the circular buffer for video frame we must + * define the node. VideoDataNode simply contains + * an AVFrame. + */ +typedef struct { + AVFrame * vframe; + int source_number; + uint8_t nb_raw_frames_ref; + AVPacket raw_packet; + + u64 frame_ntp, frame_utc; +} VideoDataNode; + +void dc_video_data_set_default(VideoDataConf *video_data_conf); + +/* + * Initialize a VideoInputData. + * + * @param video_input_data [out] is the structure to be initialize. + * @param width [in] input video width + * @param height [in] input video height + * @param pixfmt [in] input video pixel format + * @param num_consumers [in] contains information on the number of users of circular buffer; + * which means the number of video encoders. + * @param live [in] indicates the system is live + * + * @return 0 on success, -1 on failure. + * + * @note Must use dc_video_data_destroy to free memory. + */ +int dc_video_input_data_init(VideoInputData *video_input_data,/* int width, int height, int pix_fmt,*/ int num_consumers, int mode, int num_producers, int video_cb_size); + +/* + * Set properties for a VideoInputData. + */ +void dc_video_input_data_set_prop(VideoInputData *video_input_data, int index, int width, int height, int crop_x, int crop_y, int pix_fmt, AVRational sar); + +/* + * Destroy a VideoInputData. + * + * @param video_input_data [in] the structure to be destroyed. + */ +void dc_video_input_data_destroy(VideoInputData *video_input_data); + +/* + * Signal to all the users of the circular buffer in the VideoInputData + * which the current node is the last node to consume. + * + * @param video_input_data [in] the structure to be signaled on. + */ +void dc_video_input_data_end_signal(VideoInputData *video_input_data); + +#endif /* VIDEO_DATA_H_ */ diff --git a/applications/deprecated/old_arch/dashcast/video_decoder.c b/applications/deprecated/old_arch/dashcast/video_decoder.c new file mode 100644 index 0000000..5fa80c7 --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/video_decoder.c @@ -0,0 +1,441 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 "video_decoder.h" +#include +#include + + +//#define DASHCAST_DEBUG_TIME_ + + +int dc_video_decoder_open(VideoInputFile *video_input_file, VideoDataConf *video_data_conf, int mode, int no_loop, int nb_consumers) +{ + s32 ret; + u32 i; + s32 open_res; + AVInputFormat *in_fmt = NULL; + AVDictionary *options = NULL; + AVCodecContext *codec_ctx; + AVCodec *codec; + + memset(video_input_file, 0, sizeof(VideoInputFile)); + + if (video_data_conf->width > 0 && video_data_conf->height > 0) { + char vres[16]; + snprintf(vres, sizeof(vres), "%dx%d", video_data_conf->width, video_data_conf->height); + ret = av_dict_set(&options, "video_size", vres, 0); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set video size %s.\n", vres)); + return -1; + } + } + + if (video_data_conf->framerate > 0) { + char vfr[16]; + snprintf(vfr, sizeof(vfr), "%d", video_data_conf->framerate); + ret = av_dict_set(&options, "framerate", vfr, 0); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set video framerate %s.\n", vfr)); + return -1; + } + } + + if (strlen(video_data_conf->pixel_format)) { + ret = av_dict_set(&options, "pixel_format", video_data_conf->pixel_format, 0); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set pixel format %s.\n", video_data_conf->pixel_format)); + return -1; + } + } + +#ifndef WIN32 + if (strcmp(video_data_conf->v4l2f, "") != 0) { + ret = av_dict_set(&options, "input_format", video_data_conf->v4l2f, 0); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set input format %s.\n", video_data_conf->v4l2f)); + return -1; + } + } +#endif + + if (strcmp(video_data_conf->format, "") != 0) { + in_fmt = av_find_input_format(video_data_conf->format); + if (in_fmt == NULL) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find the format %s.\n", video_data_conf->format)); + return -1; + } + } + + video_input_file->av_fmt_ctx = NULL; + + if (video_data_conf->demux_buffer_size) { + char szBufSize[100]; + sprintf(szBufSize, "%d", video_data_conf->demux_buffer_size); + ret = av_dict_set(&options, "buffer_size", szBufSize, 0); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Could not set demuxer's input buffer size.\n")); + return -1; + } + } + + /* Open video */ + open_res = avformat_open_input(&video_input_file->av_fmt_ctx, video_data_conf->filename, in_fmt, options ? &options : NULL); + if ( (open_res < 0) && !stricmp(video_data_conf->filename, "screen-capture-recorder") ) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Buggy screen capture input (open failed with code %d), retrying without specifying resolution\n", open_res)); + av_dict_set(&options, "video_size", NULL, 0); + open_res = avformat_open_input(&video_input_file->av_fmt_ctx, video_data_conf->filename, in_fmt, options ? &options : NULL); + } + + if ( (open_res < 0) && options) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error %d opening input - retrying without options\n", open_res)); + av_dict_free(&options); + open_res = avformat_open_input(&video_input_file->av_fmt_ctx, video_data_conf->filename, in_fmt, NULL); + } + + if (open_res < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open file %s\n", video_data_conf->filename)); + return -1; + } + + /* Retrieve stream information */ + if (avformat_find_stream_info(video_input_file->av_fmt_ctx, NULL) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find stream information\n")); + return -1; + } + + av_dump_format(video_input_file->av_fmt_ctx, 0, video_data_conf->filename, 0); + + /* Find the first video stream */ + video_input_file->vstream_idx = -1; + for (i = 0; i < video_input_file->av_fmt_ctx->nb_streams; i++) { + if (video_input_file->av_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + video_input_file->vstream_idx = i; + break; + } + } + if (video_input_file->vstream_idx == -1) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find a video stream\n")); + return -1; + } + + /* Get a pointer to the codec context for the video stream */ + codec_ctx = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->codec; + + /* Find the decoder for the video stream */ + codec = avcodec_find_decoder(codec_ctx->codec_id); + if (codec == NULL) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Codec is not supported.\n")); + if (!video_input_file->av_fmt_ctx_ref_cnt) + avformat_close_input(&video_input_file->av_fmt_ctx); + return -1; + } + + /* Open codec */ + if (avcodec_open2(codec_ctx, codec, NULL) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open codec.\n")); + if (!video_input_file->av_fmt_ctx_ref_cnt) + avformat_close_input(&video_input_file->av_fmt_ctx); + return -1; + } + + video_input_file->width = codec_ctx->width; + video_input_file->height = codec_ctx->height; + video_input_file->sar = codec_ctx->sample_aspect_ratio; + + video_input_file->pix_fmt = codec_ctx->pix_fmt; + if (codec_ctx->time_base.num==1) { + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("AVCTX give frame duration of %d/%d - keeping requested rate %d, but this may result in unexpected behaviour.\n", codec_ctx->time_base.num, codec_ctx->time_base.den, video_data_conf->framerate )); + + if (codec_ctx->time_base.den==1000000) { + codec_ctx->time_base.num = codec_ctx->time_base.den / video_data_conf->framerate; + } + } + else if (video_data_conf->framerate >= 0 && codec_ctx->time_base.num) { + video_data_conf->framerate = codec_ctx->time_base.den / codec_ctx->time_base.num; + } + if (video_data_conf->framerate <= 1 || video_data_conf->framerate > 1000) { + const int num = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->avg_frame_rate.num; + const int den = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->avg_frame_rate.den == 0 ? 1 : video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->avg_frame_rate.den; + video_data_conf->framerate = num / den; + if (video_data_conf->framerate / 1000 != 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Framerate %d was divided by 1000: %d\n", video_data_conf->framerate, video_data_conf->framerate/1000)); + video_data_conf->framerate = video_data_conf->framerate / 1000; + } + + if (video_data_conf->framerate <= 1 || video_data_conf->framerate > 1000) { + video_data_conf->framerate = num / den; + if (video_data_conf->framerate / 1000 != 0) { + video_data_conf->framerate = video_data_conf->framerate / 1000; + } + } + } + + if (video_data_conf->framerate <= 1 || video_data_conf->framerate > 1000) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Invalid input framerate %d (AVCTX timebase is %d/%d).\n", video_data_conf->framerate, codec_ctx->time_base.num, codec_ctx->time_base.den)); + return -1; + } + + video_data_conf->time_base = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->time_base; + video_input_file->mode = mode; + video_input_file->no_loop = no_loop; + video_input_file->nb_consumers = nb_consumers; + return 0; +} + +int dc_video_decoder_read(VideoInputFile *video_input_file, VideoInputData *video_input_data, int source_number, int use_source_timing, int is_live_capture, const int *exit_signal_addr) +{ +#ifdef DASHCAST_DEBUG_TIME_ + struct timeval start, end; + long elapsed_time; +#endif + AVPacket packet; + int ret, got_frame, already_locked = 0; + AVCodecContext *codec_ctx; + VideoDataNode *video_data_node; + + /* Get a pointer to the codec context for the video stream */ + codec_ctx = video_input_file->av_fmt_ctx->streams[video_input_file->vstream_idx]->codec; + + /* Read frames */ + while (1) { +#ifdef DASHCAST_DEBUG_TIME_ + gf_gettimeofday(&start, NULL); +#endif + memset(&packet, 0, sizeof(AVPacket)); + ret = av_read_frame(video_input_file->av_fmt_ctx, &packet); +#ifdef DASHCAST_DEBUG_TIME_ + gf_gettimeofday(&end, NULL); + elapsed_time = (end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec); + fprintf(stdout, "fps: %f\n", 1000000.0/elapsed_time); +#endif + + /* If we demux for the audio thread, send the packet to the audio */ + if (video_input_file->av_fmt_ctx_ref_cnt && ((packet.stream_index != video_input_file->vstream_idx) || (ret == AVERROR_EOF))) { + AVPacket *packet_copy = NULL; + if (ret != AVERROR_EOF) { + GF_SAFEALLOC(packet_copy, AVPacket); + if (packet_copy) + memcpy(packet_copy, &packet, sizeof(AVPacket)); + } + + assert(video_input_file->av_pkt_list); + gf_mx_p(video_input_file->av_pkt_list_mutex); + gf_list_add(video_input_file->av_pkt_list, packet_copy); + gf_mx_v(video_input_file->av_pkt_list_mutex); + + if (ret != AVERROR_EOF) { + continue; + } + } + + if (ret == AVERROR_EOF) { + if (video_input_file->mode == LIVE_MEDIA && video_input_file->no_loop == 0) { + av_seek_frame(video_input_file->av_fmt_ctx, video_input_file->vstream_idx, 0, 0); + av_free_packet(&packet); + continue; + } + + dc_producer_lock(&video_input_data->producer, &video_input_data->circular_buf); + dc_producer_unlock_previous(&video_input_data->producer, &video_input_data->circular_buf); + video_data_node = (VideoDataNode *) dc_producer_produce(&video_input_data->producer, &video_input_data->circular_buf); + video_data_node->source_number = source_number; + /* Flush decoder */ + memset(&packet, 0, sizeof(AVPacket)); +#ifndef FF_API_AVFRAME_LAVC + avcodec_get_frame_defaults(video_data_node->vframe); +#else + av_frame_unref(video_data_node->vframe); +#endif + + avcodec_decode_video2(codec_ctx, video_data_node->vframe, &got_frame, &packet); + if (got_frame) { + dc_producer_advance(&video_input_data->producer, &video_input_data->circular_buf); + return 0; + } + + dc_producer_end_signal(&video_input_data->producer, &video_input_data->circular_buf); + dc_producer_unlock(&video_input_data->producer, &video_input_data->circular_buf); + return -2; + } + else if (ret < 0) + { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot read video frame.\n")); + continue; + } + + /* Is this a packet from the video stream? */ + if (packet.stream_index == video_input_file->vstream_idx) { + u32 nb_retry = 10; + while (!already_locked) { + if (dc_producer_lock(&video_input_data->producer, &video_input_data->circular_buf) < 0) { + if (!nb_retry) break; + gf_sleep(10); + nb_retry--; + continue; + } + dc_producer_unlock_previous(&video_input_data->producer, &video_input_data->circular_buf); + already_locked = 1; + } + if (!already_locked) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[dashcast] Live system dropped a video frame\n")); + continue; + } + + video_data_node = (VideoDataNode *) dc_producer_produce(&video_input_data->producer, &video_input_data->circular_buf); + video_data_node->source_number = source_number; + + /* Set video frame to default */ +#ifndef FF_API_AVFRAME_LAVC + avcodec_get_frame_defaults(video_data_node->vframe); +#else + av_frame_unref(video_data_node->vframe); +#endif + + video_data_node->frame_ntp = gf_net_get_ntp_ts(); + video_data_node->frame_utc = gf_net_get_utc(); + + /* Decode video frame */ + if (avcodec_decode_video2(codec_ctx, video_data_node->vframe, &got_frame, &packet) < 0) { + av_free_packet(&packet); + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error while decoding video.\n")); + dc_producer_end_signal(&video_input_data->producer, &video_input_data->circular_buf); + dc_producer_unlock(&video_input_data->producer, &video_input_data->circular_buf); + return -1; + } + + /* Did we get a video frame? */ + if (got_frame) { + if (use_source_timing && is_live_capture) { + u64 pts; + if (video_input_file->pts_init == 0) { + video_input_file->pts_init = 1; + video_input_file->utc_at_init = gf_net_get_utc(); + video_input_file->first_pts = packet.pts; + video_input_file->prev_pts = 0; + video_input_data->frame_duration = 0; + } +#if 0 + if (video_input_file->pts_init && (video_input_file->pts_init!=3) ) { + if (packet.pts==AV_NOPTS_VALUE) { + video_input_file->pts_init=1; + } else if (video_input_file->pts_init==1) { + video_input_file->pts_init=2; + video_input_file->pts_dur_estimate = packet.pts; + } else if (video_input_file->pts_init==2) { + video_input_file->pts_init=3; + video_input_data->frame_duration = packet.pts - video_input_file->pts_dur_estimate; + video_input_file->sync_tolerance = 9*video_input_data->frame_duration/5; + //TODO - check with audio if sync is OK + } + } +#endif + + //move to 0-based PTS + if (packet.pts!=AV_NOPTS_VALUE) { + pts = packet.pts - video_input_file->first_pts; + } else { + pts = video_input_file->prev_pts + video_input_data->frame_duration; + } + + //check for drop frames +#ifndef GPAC_DISABLE_LOG + if (0 && gf_log_tool_level_on(GF_LOG_DASH, GF_LOG_WARNING)) { + if (pts - video_input_file->prev_pts > video_input_file->sync_tolerance) { + u32 nb_lost=0; + while (video_input_file->prev_pts + video_input_data->frame_duration + video_input_file->sync_tolerance < pts) { + video_input_file->prev_pts += video_input_data->frame_duration; + nb_lost++; + } + if (nb_lost) { + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DashCast] Capture lost %d video frames \n", nb_lost)); + } + } + } +#endif + + if ((pts != video_input_file->prev_pts) && (video_input_file->pts_init == 1)) { + video_input_file->pts_init = 2; + video_input_data->frame_duration = pts - video_input_file->prev_pts; + video_input_file->sync_tolerance = 9*video_input_data->frame_duration/5; + } + + video_input_file->prev_pts = pts; + video_data_node->vframe->pts = pts; + } + + if (video_data_node->vframe->pts==AV_NOPTS_VALUE) { + if (!use_source_timing) { + video_data_node->vframe->pts = video_input_file->frame_decoded; + } else { + video_data_node->vframe->pts = video_data_node->vframe->pkt_pts; + } + } + video_input_file->frame_decoded++; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Video Frame TS "LLU" decoded at UTC "LLU" ms (frame duration %d)\n", video_data_node->vframe->pts, gf_net_get_utc(), video_input_data->frame_duration)); + + // For a decode/encode process we must free this memory. + //But if the input is raw and there is no need to decode then + // the packet is directly passed for decoded frame. We must wait until rescale is done before freeing it + + if (codec_ctx->codec->id == CODEC_ID_RAWVIDEO) { + if (is_live_capture && !video_input_data->frame_duration) { + } else { + video_data_node->nb_raw_frames_ref = video_input_file->nb_consumers; + + video_data_node->raw_packet = packet; + + dc_producer_advance(&video_input_data->producer, &video_input_data->circular_buf); + while (video_data_node->nb_raw_frames_ref && ! *exit_signal_addr) { + gf_sleep(0); + } + } + } else { + dc_producer_advance(&video_input_data->producer, &video_input_data->circular_buf); + av_free_packet(&packet); + } + return 0; + + } + } + + /* Free the packet that was allocated by av_read_frame */ + av_free_packet(&packet); + } + + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Unknown error while reading video frame.\n")); + return -1; +} + +void dc_video_decoder_close(VideoInputFile *video_input_file) +{ + /* Close the video format context */ + if (!video_input_file->av_fmt_ctx_ref_cnt) + avformat_close_input(&video_input_file->av_fmt_ctx); + + video_input_file->av_pkt_list = NULL; + video_input_file->av_pkt_list_mutex = NULL; +} diff --git a/applications/dashcast/video_decoder.h b/applications/deprecated/old_arch/dashcast/video_decoder.h similarity index 100% rename from applications/dashcast/video_decoder.h rename to applications/deprecated/old_arch/dashcast/video_decoder.h diff --git a/applications/deprecated/old_arch/dashcast/video_encoder.c b/applications/deprecated/old_arch/dashcast/video_encoder.c new file mode 100644 index 0000000..030ddb6 --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/video_encoder.c @@ -0,0 +1,294 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 "video_encoder.h" +#include "libavutil/opt.h" +#include "libavdevice/avdevice.h" + + +#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) + +#define _TOSTR(_val) #_val +#define TOSTR(_val) _TOSTR(_val) + +#endif + + +//#define DEBUG 1 + + +/** + * A function which pushes argument to a libav codec using its private data. + * param priv_data + * param options a list of space separated and ':' affected options (e.g. "a:b c:d e:f"). @options be non NULL. + */ +void build_dict(void *priv_data, const char *options) { + char *opt = gf_strdup(options); + char *tok = strtok(opt, "="); + char *tokval = NULL; + while (tok && (tokval=strtok(NULL, " "))) { + if (av_opt_set(priv_data, tok, tokval, 0) < 0) + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Unknown custom option \"%s\" with value \"%s\" in %s\n", tok, tokval, options)); + tok = strtok(NULL, "="); + } + gf_free(opt); +} + +int dc_video_encoder_open(VideoOutputFile *video_output_file, VideoDataConf *video_data_conf, Bool use_source_timing, AVRational sar) +{ + video_output_file->vbuf_size = 9 * video_data_conf->width * video_data_conf->height + 10000; + video_output_file->vbuf = (uint8_t *) av_malloc(video_output_file->vbuf_size); + video_output_file->video_data_conf = video_data_conf; + + video_output_file->codec = avcodec_find_encoder_by_name(video_data_conf->codec); + if (video_output_file->codec == NULL) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Output video codec %s not found\n", video_data_conf->codec)); + return -1; + } + + video_output_file->codec_ctx = avcodec_alloc_context3(video_output_file->codec); + + video_output_file->codec_ctx->codec_id = video_output_file->codec->id; + video_output_file->codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; + video_output_file->codec_ctx->bit_rate = video_data_conf->bitrate; + video_output_file->codec_ctx->width = video_data_conf->width; + video_output_file->codec_ctx->height = video_data_conf->height; + video_output_file->codec_ctx->sample_aspect_ratio = sar; + + video_output_file->codec_ctx->time_base.num = 1; + video_output_file->codec_ctx->time_base.den = video_output_file->gop_size ? video_output_file->gop_size : video_data_conf->framerate; + + video_output_file->use_source_timing = use_source_timing; + if (use_source_timing) { + //for avcodec to do rate allocation, we need to have ctx->timebase == 1/framerate + video_output_file->codec_ctx->time_base.den = video_data_conf->time_base.den; + video_output_file->codec_ctx->time_base.num = video_data_conf->time_base.num * video_data_conf->time_base.den / video_data_conf->framerate; + } + video_output_file->codec_ctx->pix_fmt = PIX_FMT_YUV420P; + video_output_file->codec_ctx->gop_size = video_data_conf->framerate; + +// video_output_file->codec_ctx->codec_id = video_codec->id; +// video_output_file->codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; +// video_output_file->codec_ctx->bit_rate = video_data_conf->bitrate; +// video_output_file->codec_ctx->width = video_data_conf->width; +// video_output_file->codec_ctx->height = video_data_conf->height; +// video_output_file->codec_ctx->time_base = (AVRational) {1 , +// video_output_file->video_data_conf->framerate}; +// video_output_file->codec_ctx->codec->pix_fmt = PIX_FMT_YUV420P; + video_output_file->codec_ctx->gop_size = video_data_conf->framerate; +// +// av_opt_set(video_output_file->codec_ctx->priv_data, "preset", "ultrafast", 0); +// av_opt_set(video_output_file->codec_ctx->priv_data, "tune", "zerolatency", 0); + + /* + video_output_file->codec_ctx->max_b_frames = 0; + video_output_file->codec_ctx->thread_count = 1; + video_output_file->codec_ctx->delay = 0; + video_output_file->codec_ctx->rc_lookahead = 0; + */ + + /* + * video_stream->codec->gosize = video_output_file->vfr; + * videoStream->codec->gosize = 1; + * video_stream->codec->rc_lookahead = 0; + * videoStream->time_base = (AVRational) {1 , 1000000}; + * videoStream->r_frame_rate = (AVRational) {outVideoCtx->video_framerate, 1}; + * av_opt_set(videoStream->codec->priv_data, "preset", "slow", 0); + * videoStream->codec->me_range = 16; + * videoStream->codec->max_qdiff = 4; + * videoStream->codec->qmin = 10; + * videoStream->codec->qmax = 51; + * videoStream->codec->qcompress = 0.6; + * videoStream->codec->profile = FF_PROFILE_H264_BASELINE; + * videoStream->codec->level = 10; + * + */ + + if ( strlen(video_data_conf->custom) ) { + build_dict(video_output_file->codec_ctx->priv_data, video_data_conf->custom); + } else if (video_data_conf->low_delay) { + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("Video Encoder: applying default options (preset=ultrafast tune=zerolatency)\n")); + av_opt_set(video_output_file->codec_ctx->priv_data, "vprofile", "baseline", 0); + av_opt_set(video_output_file->codec_ctx->priv_data, "preset", "ultrafast", 0); + av_opt_set(video_output_file->codec_ctx->priv_data, "tune", "zerolatency", 0); + if (strstr(video_data_conf->codec, "264")) { + av_opt_set(video_output_file->codec_ctx->priv_data, "x264opts", "no-mbtree:sliced-threads:sync-lookahead=0", 0); + } + } + + if (video_output_file->gdr) { + av_opt_set_int(video_output_file->codec_ctx->priv_data, "intra-refresh", 1, 0); + av_opt_set_int(video_output_file->codec_ctx->priv_data, "key-int", video_output_file->gdr, 0); + } + +#ifdef AV_CODEC_FLAG_GLOBAL_HEADER + //the global header gives access to the extradata (SPS/PPS) + video_output_file->codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; +#endif + + video_output_file->vstream_idx = 0;//video_stream->index; + + /* open the video codec - options are passed thru video_output_file->codec_ctx->priv_data */ + if (avcodec_open2(video_output_file->codec_ctx, video_output_file->codec, NULL) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video codec\n")); + return -1; + } + + video_output_file->rep_id = video_data_conf->filename; + return 0; +} + +int dc_video_encoder_encode(VideoOutputFile *video_output_file, VideoScaledData *video_scaled_data) +{ + VideoScaledDataNode *video_data_node; + int ret; + u64 time_spent; + int got_packet = 0; + AVPacket pkt; + + AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; + + //FIXME: deadlock when pressing 'q' with BigBuckBunny_640x360.m4v + ret = dc_consumer_lock(&video_output_file->consumer, &video_scaled_data->circular_buf); + if (ret < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Video encoder got an end of buffer!\n")); + return -2; + } + + if (video_scaled_data->circular_buf.size > 1) + dc_consumer_unlock_previous(&video_output_file->consumer, &video_scaled_data->circular_buf); + + video_data_node = (VideoScaledDataNode*)dc_consumer_consume(&video_output_file->consumer, &video_scaled_data->circular_buf); + + /* + * Set PTS (method 1) + */ + if (!video_output_file->use_source_timing) { + video_data_node->vframe->pts = video_codec_ctx->frame_number; + } + + time_spent = gf_sys_clock_high_res(); + /* Encoding video */ + av_init_packet(&pkt); + pkt.data = video_output_file->vbuf; + pkt.size = video_output_file->vbuf_size; + pkt.pts = pkt.dts = video_data_node->vframe->pkt_dts = video_data_node->vframe->pkt_pts = video_data_node->vframe->pts; + video_data_node->vframe->pict_type = 0; + video_data_node->vframe->width = video_codec_ctx->width; + video_data_node->vframe->height = video_codec_ctx->height; + video_data_node->vframe->format = video_codec_ctx->pix_fmt; + + +#ifdef LIBAV_ENCODE_OLD + if (!video_output_file->segment_started) + video_data_node->vframe->pict_type = FF_I_TYPE; + + video_output_file->encoded_frame_size = avcodec_encode_video(video_codec_ctx, video_output_file->vbuf, video_output_file->vbuf_size, video_data_node->vframe); + got_packet = video_output_file->encoded_frame_size>=0 ? 1 : 0; +#else + //this is correct but unfortunately doesn't work with some versions of FFMPEG (output is just grey video ...) + if (!video_output_file->segment_started) + video_data_node->vframe->pict_type = AV_PICTURE_TYPE_I; + + video_output_file->encoded_frame_size = avcodec_encode_video2(video_codec_ctx, &pkt, video_data_node->vframe, &got_packet); +#endif + + time_spent = gf_sys_clock_high_res() - time_spent; + //this is not true with libav ! +#ifndef GPAC_USE_LIBAV + if (video_output_file->encoded_frame_size >= 0) + video_output_file->encoded_frame_size = pkt.size; +#else + if (got_packet) + video_output_file->encoded_frame_size = pkt.size; +#endif + if (video_output_file->encoded_frame_size >= 0) { + if (got_packet) { + video_codec_ctx->coded_frame->pts = video_codec_ctx->coded_frame->pkt_pts = pkt.pts; + video_codec_ctx->coded_frame->pkt_dts = pkt.dts; + video_codec_ctx->coded_frame->key_frame = (pkt.flags & AV_PKT_FLAG_KEY) ? 1 : 0; + video_output_file->frame_ntp = video_data_node->frame_ntp; + video_output_file->frame_utc = video_data_node->frame_utc; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] Video %s Frame TS "LLU" encoded at UTC "LLU" ms in "LLU" us size %d bytes\n", video_output_file->rep_id, pkt.pts, gf_net_get_utc(), time_spent, video_output_file->encoded_frame_size )); + } + } + + dc_consumer_advance(&video_output_file->consumer); + + if (video_scaled_data->circular_buf.size == 1) + dc_consumer_unlock_previous(&video_output_file->consumer, &video_scaled_data->circular_buf); + + if (video_output_file->encoded_frame_size < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Error occured while encoding video frame.\n")); + return -1; + } + + /* if zero size, it means the image was buffered */ +// if (out_size > 0) { +// av_init_packet(&pkt); +// pkt.data = NULL; +// pkt.size = 0; +// +// if (video_codec_ctx->coded_frame->pts != AV_NOPTS_VALUE) { +// pkt.pts = av_rescale_q(video_codec_ctx->coded_frame->pts, +// video_codec_ctx->time_base, video_stream->time_base); +// } +// +// +// if (video_codec_ctx->coded_frame->key_frame) +// pkt.flags |= AV_PKT_FLAG_KEY; +// +// pkt.stream_index = video_stream->index; +// pkt.data = video_output_file->vbuf; +// pkt.size = out_size; +// +// // write the compressed frame in the media file +// if (av_interleaved_write_frame(video_output_file->av_fmt_ctx, &pkt) +// != 0) { +// GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Writing frame is not successful\n")); +// return -1; +// } +// +// av_free_packet(&pkt); +// +// } + + return video_output_file->encoded_frame_size; +} + +void dc_video_encoder_close(VideoOutputFile *video_output_file) +{ +// int i; +// +// // free the streams +// for (i = 0; i < video_output_file->av_fmt_ctx->nb_streams; i++) { +// avcodec_close(video_output_file->av_fmt_ctx->streams[i]->codec); +// av_freep(&video_output_file->av_fmt_ctx->streams[i]->info); +// } + av_free(video_output_file->vbuf); + avcodec_close(video_output_file->codec_ctx); + av_free(video_output_file->codec_ctx); +} diff --git a/applications/dashcast/video_encoder.h b/applications/deprecated/old_arch/dashcast/video_encoder.h similarity index 100% rename from applications/dashcast/video_encoder.h rename to applications/deprecated/old_arch/dashcast/video_encoder.h diff --git a/applications/deprecated/old_arch/dashcast/video_muxer.c b/applications/deprecated/old_arch/dashcast/video_muxer.c new file mode 100644 index 0000000..b1c36da --- /dev/null +++ b/applications/deprecated/old_arch/dashcast/video_muxer.c @@ -0,0 +1,979 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Arash Shafiei + * Copyright (c) Telecom ParisTech 2000-2013 + * All rights reserved + * + * This file is part of GPAC / dashcast + * + * 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 "video_muxer.h" +#include "libavutil/opt.h" +#include + + +/** + * A function which takes FFmpeg H264 extradata (SPS/PPS) and bring them ready to be pushed to the MP4 muxer. + * @param extradata + * @param extradata_size + * @param dstcfg + * @returns GF_OK is the extradata was parsed and is valid, other values otherwise. + */ +static GF_Err avc_import_ffextradata(const u8 *extradata, const u64 extradata_size, GF_AVCConfig *dstcfg) +{ +#ifdef GPAC_DISABLE_AV_PARSERS + return GF_OK; +#else + u8 nal_size; + AVCState avc; + GF_BitStream *bs; + if (!extradata || (extradata_size < sizeof(u32))) + return GF_BAD_PARAM; + bs = gf_bs_new((const char *) extradata, extradata_size, GF_BITSTREAM_READ); + if (!bs) + return GF_BAD_PARAM; + if (gf_bs_read_u32(bs) != 0x00000001) { + gf_bs_del(bs); + return GF_BAD_PARAM; + } + + //SPS + { + s32 idx; + char *buffer = NULL; + const u64 nal_start = 4; + nal_size = gf_media_nalu_next_start_code_bs(bs); + if (nal_start + nal_size > extradata_size) { + gf_bs_del(bs); + return GF_BAD_PARAM; + } + buffer = (char*)gf_malloc(nal_size); + gf_bs_read_data(bs, buffer, nal_size); + gf_bs_seek(bs, nal_start); + if ((gf_bs_read_u8(bs) & 0x1F) != GF_AVC_NALU_SEQ_PARAM) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + idx = gf_media_avc_read_sps(buffer, nal_size, &avc, 0, NULL); + if (idx < 0) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + 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; + dstcfg->chroma_format = avc.sps[idx].chroma_format; + dstcfg->luma_bit_depth = 8 + avc.sps[idx].luma_bit_depth_m8; + dstcfg->chroma_bit_depth = 8 + avc.sps[idx].chroma_bit_depth_m8; + + { + GF_AVCConfigSlot *slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); + slc->size = nal_size; + slc->id = idx; + slc->data = buffer; + gf_list_add(dstcfg->sequenceParameterSets, slc); + } + } + + //PPS + { + s32 idx; + char *buffer = NULL; + const u64 nal_start = 4 + nal_size + 4; + gf_bs_seek(bs, nal_start); + nal_size = gf_media_nalu_next_start_code_bs(bs); + if (nal_start + nal_size > extradata_size) { + gf_bs_del(bs); + return GF_BAD_PARAM; + } + buffer = (char*)gf_malloc(nal_size); + gf_bs_read_data(bs, buffer, nal_size); + gf_bs_seek(bs, nal_start); + if ((gf_bs_read_u8(bs) & 0x1F) != GF_AVC_NALU_PIC_PARAM) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + idx = gf_media_avc_read_pps(buffer, nal_size, &avc); + if (idx < 0) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + { + GF_AVCConfigSlot *slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); + slc->size = nal_size; + slc->id = idx; + slc->data = buffer; + gf_list_add(dstcfg->pictureParameterSets, slc); + } + } + + gf_bs_del(bs); + return GF_OK; +#endif +} + +/** + * A function which takes FFmpeg H265 extradata (SPS/PPS) and bring them ready to be pushed to the MP4 muxer. + * @param extradata + * @param extradata_size + * @param dstcfg + * @returns GF_OK is the extradata was parsed and is valid, other values otherwise. + */ +static GF_Err hevc_import_ffextradata(const u8 *extradata, const u64 extradata_size, GF_HEVCConfig *dst_cfg) +{ +#ifdef GPAC_DISABLE_AV_PARSERS + return GF_OK; +#else + HEVCState hevc; + GF_HEVCParamArray *vpss = NULL, *spss = NULL, *ppss = NULL, *seis = NULL; + GF_BitStream *bs; + char *buffer = NULL; + u32 buffer_size = 0; + if (!extradata || (extradata_size < sizeof(u32))) + return GF_BAD_PARAM; + bs = gf_bs_new((const char *) extradata, extradata_size, GF_BITSTREAM_READ); + if (!bs) + return GF_BAD_PARAM; + + memset(&hevc, 0, sizeof(HEVCState)); + hevc.sps_active_idx = -1; + + while (gf_bs_available(bs)) { + s32 idx; + GF_AVCConfigSlot *slc; + u8 nal_unit_type, temporal_id, layer_id; + u64 nal_start, start_code; + u32 nal_size; + + start_code = gf_bs_read_u32(bs); + if (start_code>>8 == 0x000001) { + nal_start = gf_bs_get_position(bs) - 1; + gf_bs_seek(bs, nal_start); + start_code = 1; + } + if (start_code != 0x00000001) { + gf_bs_del(bs); + if (buffer) gf_free(buffer); + if (vpss && spss && ppss) return GF_OK; + return GF_BAD_PARAM; + } + nal_start = gf_bs_get_position(bs); + nal_size = gf_media_nalu_next_start_code_bs(bs); + if (nal_start + nal_size > extradata_size) { + gf_bs_del(bs); + return GF_BAD_PARAM; + } + + if (nal_size > buffer_size) { + buffer = (char*)gf_realloc(buffer, nal_size); + buffer_size = nal_size; + } + gf_bs_read_data(bs, buffer, nal_size); + + gf_media_hevc_parse_nalu(buffer, nal_size, &hevc, &nal_unit_type, &temporal_id, &layer_id); + if (layer_id) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + switch (nal_unit_type) { + case GF_HEVC_NALU_VID_PARAM: + idx = gf_media_hevc_read_vps(buffer, nal_size , &hevc); + if (idx < 0) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + assert(hevc.vps[idx].state == 1); //we don't expect multiple VPS + if (hevc.vps[idx].state == 1) { + hevc.vps[idx].state = 2; + hevc.vps[idx].crc = gf_crc_32(buffer, nal_size); + + dst_cfg->avgFrameRate = hevc.vps[idx].rates[0].avg_pic_rate; + dst_cfg->constantFrameRate = hevc.vps[idx].rates[0].constand_pic_rate_idc; + dst_cfg->numTemporalLayers = hevc.vps[idx].max_sub_layers; + dst_cfg->temporalIdNested = hevc.vps[idx].temporal_id_nesting; + + if (!vpss) { + GF_SAFEALLOC(vpss, GF_HEVCParamArray); + if (vpss) { + vpss->nalus = gf_list_new(); + gf_list_add(dst_cfg->param_array, vpss); + vpss->array_completeness = 1; + vpss->type = GF_HEVC_NALU_VID_PARAM; + } + } + + slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); + if (slc) { + slc->size = nal_size; + slc->id = idx; + slc->data = (char*)gf_malloc(sizeof(char)*slc->size); + if (slc->data) + memcpy(slc->data, buffer, sizeof(char)*slc->size); + + if (vpss) + gf_list_add(vpss->nalus, slc); + } + } + break; + case GF_HEVC_NALU_SEQ_PARAM: + idx = gf_media_hevc_read_sps(buffer, nal_size, &hevc); + if (idx < 0) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + assert(!(hevc.sps[idx].state & AVC_SPS_DECLARED)); //we don't expect multiple SPS + if ((hevc.sps[idx].state & AVC_SPS_PARSED) && !(hevc.sps[idx].state & AVC_SPS_DECLARED)) { + hevc.sps[idx].state |= AVC_SPS_DECLARED; + hevc.sps[idx].crc = gf_crc_32(buffer, nal_size); + } + + dst_cfg->configurationVersion = 1; + dst_cfg->profile_space = hevc.sps[idx].ptl.profile_space; + dst_cfg->tier_flag = hevc.sps[idx].ptl.tier_flag; + dst_cfg->profile_idc = hevc.sps[idx].ptl.profile_idc; + dst_cfg->general_profile_compatibility_flags = hevc.sps[idx].ptl.profile_compatibility_flag; + dst_cfg->progressive_source_flag = hevc.sps[idx].ptl.general_progressive_source_flag; + dst_cfg->interlaced_source_flag = hevc.sps[idx].ptl.general_interlaced_source_flag; + dst_cfg->non_packed_constraint_flag = hevc.sps[idx].ptl.general_non_packed_constraint_flag; + dst_cfg->frame_only_constraint_flag = hevc.sps[idx].ptl.general_frame_only_constraint_flag; + + dst_cfg->constraint_indicator_flags = hevc.sps[idx].ptl.general_reserved_44bits; + dst_cfg->level_idc = hevc.sps[idx].ptl.level_idc; + + dst_cfg->chromaFormat = hevc.sps[idx].chroma_format_idc; + dst_cfg->luma_bit_depth = hevc.sps[idx].bit_depth_luma; + dst_cfg->chroma_bit_depth = hevc.sps[idx].bit_depth_chroma; + + if (!spss) { + GF_SAFEALLOC(spss, GF_HEVCParamArray); + if (spss) { + spss->nalus = gf_list_new(); + gf_list_add(dst_cfg->param_array, spss); + spss->array_completeness = 1; + spss->type = GF_HEVC_NALU_SEQ_PARAM; + } + } + + slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); + if (slc) { + slc->size = nal_size; + slc->id = idx; + slc->data = (char*)gf_malloc(sizeof(char)*slc->size); + if (slc->data) + memcpy(slc->data, buffer, sizeof(char)*slc->size); + if (spss) + gf_list_add(spss->nalus, slc); + } + break; + case GF_HEVC_NALU_PIC_PARAM: + idx = gf_media_hevc_read_pps(buffer, nal_size, &hevc); + if (idx < 0) { + gf_bs_del(bs); + gf_free(buffer); + return GF_BAD_PARAM; + } + + assert(hevc.pps[idx].state == 1); //we don't expect multiple PPS + if (hevc.pps[idx].state == 1) { + hevc.pps[idx].state = 2; + hevc.pps[idx].crc = gf_crc_32(buffer, nal_size); + + if (!ppss) { + GF_SAFEALLOC(ppss, GF_HEVCParamArray); + if (ppss) { + ppss->nalus = gf_list_new(); + gf_list_add(dst_cfg->param_array, ppss); + ppss->array_completeness = 1; + ppss->type = GF_HEVC_NALU_PIC_PARAM; + } + } + + slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); + if (slc) { + slc->size = nal_size; + slc->id = idx; + slc->data = (char*)gf_malloc(sizeof(char)*slc->size); + if (slc->data) + memcpy(slc->data, buffer, sizeof(char)*slc->size); + + if (ppss) + gf_list_add(ppss->nalus, slc); + } + } + break; + case GF_HEVC_NALU_SEI_PREFIX: + if (!seis) { + GF_SAFEALLOC(seis, GF_HEVCParamArray); + if (seis) { + seis->nalus = gf_list_new(); + seis->array_completeness = 0; + seis->type = GF_HEVC_NALU_SEI_PREFIX; + } + } + slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); + if (slc) { + slc->size = nal_size; + slc->data = (char*)gf_malloc(sizeof(char)*slc->size); + if (slc->data) + memcpy(slc->data, buffer, sizeof(char)*slc->size); + if (seis) + gf_list_add(seis->nalus, slc); + } + break; + default: + break; + } + } + + gf_bs_del(bs); + if (buffer) gf_free(buffer); + + return GF_OK; +#endif +} + +#ifndef GPAC_DISABLE_ISOM + +static GF_Err dc_gpac_video_write_config(VideoOutputFile *video_output_file, u32 *di, u32 track) { + GF_Err ret; + if (video_output_file->codec_ctx->codec_id == CODEC_ID_H264) { + GF_AVCConfig *avccfg; + avccfg = gf_odf_avc_cfg_new(); + if (!avccfg) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create AVCConfig\n")); + return GF_OUT_OF_MEM; + } + + ret = avc_import_ffextradata(video_output_file->codec_ctx->extradata, video_output_file->codec_ctx->extradata_size, avccfg); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot parse AVC/H264 SPS/PPS\n")); + gf_odf_avc_cfg_del(avccfg); + return ret; + } + + ret = gf_isom_avc_config_new(video_output_file->isof, track, avccfg, NULL, NULL, di); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_avc_config_new\n", gf_error_to_string(ret))); + return ret; + } + + gf_odf_avc_cfg_del(avccfg); + + //inband SPS/PPS + if (video_output_file->muxer_type == GPAC_INIT_VIDEO_MUXER_AVC3) { + ret = gf_isom_avc_set_inband_config(video_output_file->isof, track, 1); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_avc_set_inband_config\n", gf_error_to_string(ret))); + return ret; + } + } + } else if (!strcmp(video_output_file->codec_ctx->codec->name, "libx265")) { //FIXME CODEC_ID_HEVC would break on old releases + GF_HEVCConfig *hevccfg = gf_odf_hevc_cfg_new(); + if (!hevccfg) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create HEVCConfig\n")); + return GF_OUT_OF_MEM; + } + + ret = hevc_import_ffextradata(video_output_file->codec_ctx->extradata, video_output_file->codec_ctx->extradata_size, hevccfg); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot parse HEVC/H265 SPS/PPS\n")); + gf_odf_hevc_cfg_del(hevccfg); + return ret; + } + + ret = gf_isom_hevc_config_new(video_output_file->isof, track, hevccfg, NULL, NULL, di); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_hevc_config_new\n", gf_error_to_string(ret))); + return ret; + } + + gf_odf_hevc_cfg_del(hevccfg); + + //inband SPS/PPS + if (video_output_file->muxer_type == GPAC_INIT_VIDEO_MUXER_AVC3) { + ret = gf_isom_hevc_set_inband_config(video_output_file->isof, track, 1); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_hevc_set_inband_config\n", gf_error_to_string(ret))); + return ret; + } + } + } + + return GF_OK; +} + +int dc_gpac_video_moov_create(VideoOutputFile *video_output_file, char *filename) +{ + GF_Err ret; + AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; + u32 di=1, track; + + //TODO: For the moment it is fixed + //u32 sample_dur = video_output_file->codec_ctx->time_base.den; + + //int64_t profile = 0; + //av_opt_get_int(video_output_file->codec_ctx->priv_data, "level", AV_OPT_SEARCH_CHILDREN, &profile); + + video_output_file->isof = gf_isom_open(filename, GF_ISOM_OPEN_WRITE, NULL); + if (!video_output_file->isof) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open iso file %s\n", filename)); + return -1; + } + //gf_isom_store_movie_config(video_output_file->isof, 0); + track = gf_isom_new_track(video_output_file->isof, 0, GF_ISOM_MEDIA_VISUAL, video_codec_ctx->time_base.den); + video_output_file->trackID = gf_isom_get_track_id(video_output_file->isof, track); + + video_output_file->timescale = video_codec_ctx->time_base.den; + if (!video_output_file->frame_dur) + video_output_file->frame_dur = video_codec_ctx->time_base.num; + + if (!track) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create new track\n")); + return -1; + } + + ret = gf_isom_set_track_enabled(video_output_file->isof, track, 1); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_set_track_enabled\n", gf_error_to_string(ret))); + return -1; + } + + ret = dc_gpac_video_write_config(video_output_file, &di, track); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: dc_gpac_video_write_config\n", gf_error_to_string(ret))); + return -1; + } + + gf_isom_set_visual_info(video_output_file->isof, track, di, video_codec_ctx->width, video_codec_ctx->height); + gf_isom_set_sync_table(video_output_file->isof, track); + + ret = gf_isom_setup_track_fragment(video_output_file->isof, track, 1, video_output_file->use_source_timing ? (u32) video_output_file->frame_dur : 1, 0, 0, 0, 0, 0); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_setup_track_fragment\n", gf_error_to_string(ret))); + return -1; + } + + ret = gf_isom_finalize_for_fragment(video_output_file->isof, track); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); + return -1; + } + + ret = gf_media_get_rfc_6381_codec_name(video_output_file->isof, track, video_output_file->video_data_conf->codec6381, GF_FALSE, GF_FALSE); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_finalize_for_fragment\n", gf_error_to_string(ret))); + return -1; + } + + return 0; +} + +int dc_gpac_video_isom_open_seg(VideoOutputFile *video_output_file, char *filename) +{ + GF_Err ret; + ret = gf_isom_start_segment(video_output_file->isof, filename, 1); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_start_segment\n", gf_error_to_string(ret))); + return -1; + } + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Opening new segment %s at UTC "LLU" ms\n", filename, gf_net_get_utc() )); + return 0; +} + +int dc_gpac_video_isom_write(VideoOutputFile *video_output_file) +{ + GF_Err ret; + AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; + + u32 sc_size = 0; + u32 nalu_size = 0; + + u32 buf_len = video_output_file->encoded_frame_size; + u8 *buf_ptr = video_output_file->vbuf; + + GF_BitStream *out_bs = gf_bs_new(NULL, 2 * buf_len, GF_BITSTREAM_WRITE); + nalu_size = gf_media_nalu_next_start_code(buf_ptr, buf_len, &sc_size); + if (nalu_size != 0) { + gf_bs_write_u32(out_bs, nalu_size); + gf_bs_write_data(out_bs, (const char*) buf_ptr, nalu_size); + } + if (sc_size) { + buf_ptr += (nalu_size + sc_size); + buf_len -= (nalu_size + sc_size); + } + + while (buf_len) { + nalu_size = gf_media_nalu_next_start_code(buf_ptr, buf_len, &sc_size); + if (nalu_size != 0) { + gf_bs_write_u32(out_bs, nalu_size); + gf_bs_write_data(out_bs, (const char*) buf_ptr, nalu_size); + } + + buf_ptr += nalu_size; + + if (!sc_size || (buf_len < nalu_size + sc_size)) + break; + buf_len -= nalu_size + sc_size; + buf_ptr += sc_size; + } + + gf_bs_get_content(out_bs, &video_output_file->sample->data, &video_output_file->sample->dataLength); + //video_output_file->sample->data = //(char *) (video_output_file->vbuf + nalu_size + sc_size); + //video_output_file->sample->dataLength = //video_output_file->encoded_frame_size - (sc_size + nalu_size); + + video_output_file->sample->DTS = video_codec_ctx->coded_frame->pkt_dts; + video_output_file->sample->CTS_Offset = (s32) (video_codec_ctx->coded_frame->pts - video_output_file->sample->DTS); + video_output_file->sample->IsRAP = video_codec_ctx->coded_frame->key_frame; + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Isom Write: RAP %d , DTS "LLD" CTS offset %d \n", video_output_file->sample->IsRAP, video_output_file->sample->DTS, video_output_file->sample->CTS_Offset)); + + ret = gf_isom_fragment_add_sample(video_output_file->isof, video_output_file->trackID, video_output_file->sample, 1, video_output_file->use_source_timing ? (u32) video_output_file->frame_dur : 1, 0, 0, 0); + if (ret != GF_OK) { + gf_bs_del(out_bs); + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_fragment_add_sample\n", gf_error_to_string(ret))); + return -1; + } + + //free data but keep sample structure alive + gf_free(video_output_file->sample->data); + video_output_file->sample->data = NULL; + video_output_file->sample->dataLength = 0; + + gf_bs_del(out_bs); + return 0; +} + +int dc_gpac_video_isom_close_seg(VideoOutputFile *video_output_file) +{ + u64 seg_size; + GF_Err ret = gf_isom_close_segment(video_output_file->isof, 0, 0, 0, 0, 0, 0, 0, GF_TRUE, GF_FALSE, video_output_file->seg_marker, NULL, NULL, &seg_size); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close_segment\n", gf_error_to_string(ret))); + return -1; + } + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Rep %s Closing segment %s at UTC "LLU" ms - size "LLU" bytes\n", video_output_file->rep_id, gf_isom_get_segment_name(video_output_file->isof), gf_net_get_utc(), seg_size )); + + return 0; +} + +int dc_gpac_video_isom_close(VideoOutputFile *video_output_file) +{ + GF_Err ret; + ret = gf_isom_close(video_output_file->isof); + if (ret != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_close\n", gf_error_to_string(ret))); + return -1; + } + + return 0; +} + +#endif + + +int dc_raw_h264_open(VideoOutputFile *video_output_file, char *filename) +{ + video_output_file->file = gf_fopen(filename, "w"); + return 0; +} + +int dc_raw_h264_write(VideoOutputFile *video_output_file) +{ + fwrite(video_output_file->vbuf, video_output_file->encoded_frame_size, 1, video_output_file->file); + return 0; +} + +int dc_raw_h264_close(VideoOutputFile *video_output_file) +{ + gf_fclose(video_output_file->file); + return 0; +} + +int dc_ffmpeg_video_muxer_open(VideoOutputFile *video_output_file, char *filename) +{ + AVStream *video_stream; + AVOutputFormat *output_fmt; + int ret; + + AVCodecContext *video_codec_ctx = video_output_file->codec_ctx; + video_output_file->av_fmt_ctx = NULL; + +// video_output_file->vbr = video_data_conf->bitrate; +// video_output_file->vfr = video_data_conf->framerate; +// video_output_file->width = video_data_conf->width; +// video_output_file->height = video_data_conf->height; +// strcpy(video_output_file->filename, video_data_conf->filename); +// strcpy(video_output_file->codec, video_data_conf->codec); + + /* Find output format */ + output_fmt = av_guess_format(NULL, filename, NULL); + if (!output_fmt) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot find suitable output format\n")); + return -1; + } + + video_output_file->av_fmt_ctx = avformat_alloc_context(); + if (!video_output_file->av_fmt_ctx) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot allocate memory for pOutVideoFormatCtx\n")); + return -1; + } + + video_output_file->av_fmt_ctx->oformat = output_fmt; + strcpy(video_output_file->av_fmt_ctx->filename, filename); + + /* Open the output file */ + if (!(output_fmt->flags & AVFMT_NOFILE)) { + if (avio_open(&video_output_file->av_fmt_ctx->pb, filename, URL_WRONLY) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot not open '%s'\n", filename)); + return -1; + } + } + + video_stream = avformat_new_stream(video_output_file->av_fmt_ctx, + video_output_file->codec); + if (!video_stream) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot create output video stream\n")); + return -1; + } + + //video_stream->codec = video_output_file->codec_ctx; + + video_stream->codec->codec_id = video_output_file->codec->id; + video_stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; + video_stream->codec->bit_rate = video_codec_ctx->bit_rate; //video_output_file->video_data_conf->bitrate; + video_stream->codec->width = video_codec_ctx->width; //video_output_file->video_data_conf->width; + video_stream->codec->height = video_codec_ctx->height; //video_output_file->video_data_conf->height; + + video_stream->codec->time_base = video_codec_ctx->time_base; + + video_stream->codec->pix_fmt = PIX_FMT_YUV420P; + video_stream->codec->gop_size = video_codec_ctx->time_base.den; //video_output_file->video_data_conf->framerate; + + av_opt_set(video_stream->codec->priv_data, "preset", "ultrafast", 0); + av_opt_set(video_stream->codec->priv_data, "tune", "zerolatency", 0); + + /* open the video codec */ + if (avcodec_open2(video_stream->codec, video_output_file->codec, NULL) < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Cannot open output video codec\n")); + return -1; + } + + ret = avformat_write_header(video_output_file->av_fmt_ctx, NULL); + + if (!ret) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("avformat_write_header returned %d\n", ret)); + return ret; + } + + video_output_file->timescale = video_codec_ctx->time_base.den; + return 0; +} + +int dc_ffmpeg_video_muxer_write(VideoOutputFile *video_output_file) +{ + AVPacket pkt; + AVStream *video_stream = video_output_file->av_fmt_ctx->streams[video_output_file->vstream_idx]; + AVCodecContext *video_codec_ctx = video_stream->codec; + + av_init_packet(&pkt); + pkt.data = NULL; + pkt.size = 0; + + if (video_codec_ctx->coded_frame->pts != AV_NOPTS_VALUE) { + pkt.pts = av_rescale_q(video_codec_ctx->coded_frame->pts, video_codec_ctx->time_base, video_stream->time_base); + } + + if (video_codec_ctx->coded_frame->key_frame) + pkt.flags |= AV_PKT_FLAG_KEY; + + pkt.stream_index = video_stream->index; + pkt.data = video_output_file->vbuf; + pkt.size = video_output_file->encoded_frame_size; + + // write the compressed frame in the media file + if (av_interleaved_write_frame(video_output_file->av_fmt_ctx, &pkt) != 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Writing frame is not successful\n")); + return -1; + } + + av_free_packet(&pkt); + + return 0; +} + +int dc_ffmpeg_video_muxer_close(VideoOutputFile *video_output_file) +{ + u32 i; + + av_write_trailer(video_output_file->av_fmt_ctx); + + avio_close(video_output_file->av_fmt_ctx->pb); + + // free the streams + for (i = 0; i < video_output_file->av_fmt_ctx->nb_streams; i++) { + avcodec_close(video_output_file->av_fmt_ctx->streams[i]->codec); + av_freep(&video_output_file->av_fmt_ctx->streams[i]->info); + } + + //video_output_file->av_fmt_ctx->streams[video_output_file->vstream_idx]->codec = NULL; + avformat_free_context(video_output_file->av_fmt_ctx); + + return 0; +} + +int dc_video_muxer_init(VideoOutputFile *video_output_file, VideoDataConf *video_data_conf, VideoMuxerType muxer_type, int frame_per_segment, int frame_per_fragment, u32 seg_marker, int gdr, int seg_dur, int frag_dur, int frame_dur, int gop_size, int video_cb_size) +{ + char name[GF_MAX_PATH]; + memset(video_output_file, 0, sizeof(VideoOutputFile)); + snprintf(name, sizeof(name), "video encoder %s", video_data_conf->filename); + dc_consumer_init(&video_output_file->consumer, video_cb_size, name); + +#ifndef GPAC_DISABLE_ISOM + video_output_file->sample = gf_isom_sample_new(); + video_output_file->isof = NULL; +#endif + + video_output_file->muxer_type = muxer_type; + + video_output_file->frame_per_segment = frame_per_segment; + video_output_file->frame_per_fragment = frame_per_fragment; + + video_output_file->seg_dur = seg_dur; + video_output_file->frag_dur = frag_dur; + + video_output_file->seg_marker = seg_marker; + video_output_file->gdr = gdr; + video_output_file->gop_size = gop_size; + video_output_file->frame_dur = frame_dur; + + return 0; +} + +int dc_video_muxer_free(VideoOutputFile *video_output_file) +{ +#ifndef GPAC_DISABLE_ISOM + if (video_output_file->isof != NULL) { + gf_isom_close(video_output_file->isof); + } + + gf_isom_sample_del(&video_output_file->sample); +#endif + return 0; +} + +GF_Err dc_video_muxer_open(VideoOutputFile *video_output_file, char *directory, char *id_name, int seg) +{ + char name[GF_MAX_PATH]; + + switch (video_output_file->muxer_type) { + case FFMPEG_VIDEO_MUXER: + snprintf(name, sizeof(name), "%s/%s_%d_ffmpeg.mp4", directory, id_name, seg); + return dc_ffmpeg_video_muxer_open(video_output_file, name); + case RAW_VIDEO_H264: + snprintf(name, sizeof(name), "%s/%s_%d.264", directory, id_name, seg); + return dc_raw_h264_open(video_output_file, name); +#ifndef GPAC_DISABLE_ISOM + case GPAC_VIDEO_MUXER: + snprintf(name, sizeof(name), "%s/%s_%d_gpac.mp4", directory, id_name, seg); + dc_gpac_video_moov_create(video_output_file, name); + return dc_gpac_video_isom_open_seg(video_output_file, NULL); + case GPAC_INIT_VIDEO_MUXER_AVC1: + if (seg == 1) { + snprintf(name, sizeof(name), "%s/%s_init_gpac.mp4", directory, id_name); + dc_gpac_video_moov_create(video_output_file, name); + video_output_file->first_dts_in_fragment = 0; + } + snprintf(name, sizeof(name), "%s/%s_%d_gpac.m4s", directory, id_name, seg); + return dc_gpac_video_isom_open_seg(video_output_file, name); + case GPAC_INIT_VIDEO_MUXER_AVC3: + if (seg == 0) { + snprintf(name, sizeof(name), "%s/%s_init_gpac.mp4", directory, id_name); + dc_gpac_video_moov_create(video_output_file, name); + video_output_file->first_dts_in_fragment = 0; + } + snprintf(name, sizeof(name), "%s/%s_%d_gpac.m4s", directory, id_name, seg); + return dc_gpac_video_isom_open_seg(video_output_file, name); +#endif + default: + return GF_BAD_PARAM; + }; + + return -2; +} + +int dc_video_muxer_write(VideoOutputFile *video_output_file, int frame_nb, Bool insert_ntp) +{ + Bool segment_close = GF_FALSE; + Bool fragment_close = GF_FALSE; + switch (video_output_file->muxer_type) { + case FFMPEG_VIDEO_MUXER: + return dc_ffmpeg_video_muxer_write(video_output_file); + case RAW_VIDEO_H264: + return dc_raw_h264_write(video_output_file); +#ifndef GPAC_DISABLE_ISOM + case GPAC_VIDEO_MUXER: + case GPAC_INIT_VIDEO_MUXER_AVC1: + case GPAC_INIT_VIDEO_MUXER_AVC3: + if (video_output_file->use_source_timing) { + GF_Err ret; + if (!video_output_file->fragment_started) { + video_output_file->fragment_started = 1; + ret = gf_isom_start_fragment(video_output_file->isof, 1); + if (ret < 0) + return -1; + + + //insert UTC for each fragment + if (insert_ntp) { + gf_isom_set_fragment_reference_time(video_output_file->isof, video_output_file->trackID, video_output_file->frame_ntp, video_output_file->codec_ctx->coded_frame->pts); + } + + video_output_file->first_dts_in_fragment = video_output_file->codec_ctx->coded_frame->pkt_dts; + if (!video_output_file->segment_started) { + video_output_file->pts_at_segment_start = video_output_file->codec_ctx->coded_frame->pts; + video_output_file->segment_started = 1; + if (!video_output_file->nb_segments) { + video_output_file->pts_at_first_segment = video_output_file->pts_at_segment_start; + } + +#ifndef GPAC_DISABLE_LOG + if (insert_ntp && gf_log_tool_level_on(GF_LOG_DASH, GF_LOG_INFO)) { + if (!video_output_file->ntp_at_first_dts) { + video_output_file->ntp_at_first_dts = video_output_file->frame_ntp; + } else { + s32 ntp_diff = gf_net_get_ntp_diff_ms(video_output_file->ntp_at_first_dts); + s32 ts_diff = (s32) ( 1000 * (video_output_file->codec_ctx->coded_frame->pts - video_output_file->pts_at_first_segment) / video_output_file->timescale ); + + s32 diff_ms = ts_diff - ntp_diff; + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Video Segment start NTP diff: %d ms TS diff: %d ms drift: %d ms\n", ntp_diff, ts_diff, diff_ms)); + } + } +#endif + } + gf_isom_set_traf_base_media_decode_time(video_output_file->isof, video_output_file->trackID, video_output_file->first_dts_in_fragment); + } + + if (dc_gpac_video_isom_write(video_output_file) < 0) { + return -1; + } + video_output_file->last_pts = video_output_file->codec_ctx->coded_frame->pts; + video_output_file->last_dts = video_output_file->codec_ctx->coded_frame->pkt_dts; + GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[DashCast] PTS: "LLU", DTS: "LLU", first DTS in frag: "LLU", timescale: %d, frag dur: %d\n", video_output_file->last_pts, video_output_file->last_dts, video_output_file->first_dts_in_fragment, video_output_file->timescale, video_output_file->frag_dur)); + + //we may have rounding errors on the input PTS :( add half frame dur safety + //flush segments based on the cumultated duration , to avoid drift + /* Check why segment tests work on PTS while fragment tests work on DTS ? */ + /* Check why fragment closing is not tested based on accumulation of fragment duration to avoid drifts */ + segment_close = ((video_output_file->last_pts - video_output_file->pts_at_first_segment + video_output_file->frame_dur) * 1000 >= + (video_output_file->nb_segments+1)*video_output_file->seg_dur * (u64)video_output_file->timescale); +#if 0 + segment_close = ((video_output_file->last_pts - video_output_file->pts_at_segment_start + 3*video_output_file->frame_dur/2) * 1000 >= + (video_output_file->seg_dur * (u64)video_output_file->timescale); +#endif + //flush fragment if adding next frame will exceed target duration by half the frame duration + fragment_close = ((video_output_file->last_dts - video_output_file->first_dts_in_fragment + 3 * video_output_file->frame_dur / 2) * 1000 >= + (video_output_file->frag_dur * (u64)video_output_file->timescale)); + + if (segment_close || fragment_close) { + gf_isom_flush_fragments(video_output_file->isof, 1); + video_output_file->fragment_started = 0; + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Flushed fragment at UTC "LLU" ms - First DTS "LLU" last PTS "LLU" - First Segment PTS "LLU" timescale %d\n", gf_net_get_utc(), video_output_file->first_dts_in_fragment, video_output_file->codec_ctx->coded_frame->pts, video_output_file->pts_at_segment_start, video_output_file->timescale)); + } + + if (segment_close) { + return 1; + } + return 0; + } + + if (frame_nb % video_output_file->frame_per_fragment == 0) { + gf_isom_start_fragment(video_output_file->isof, 1); + + if (!video_output_file->segment_started) { + video_output_file->pts_at_segment_start = video_output_file->codec_ctx->coded_frame->pts; + video_output_file->segment_started = 1; + + if (insert_ntp) { + gf_isom_set_fragment_reference_time(video_output_file->isof, video_output_file->trackID, video_output_file->frame_ntp, video_output_file->pts_at_segment_start); + } + } + + + gf_isom_set_traf_base_media_decode_time(video_output_file->isof, video_output_file->trackID, video_output_file->first_dts_in_fragment); + video_output_file->first_dts_in_fragment += video_output_file->frame_per_fragment; + } + + dc_gpac_video_isom_write(video_output_file); + + if (frame_nb % video_output_file->frame_per_fragment == video_output_file->frame_per_fragment - 1) { + gf_isom_flush_fragments(video_output_file->isof, 1); + GF_LOG(GF_LOG_INFO, GF_LOG_DASH, ("[DashCast] Flushed fragment to disk at UTC "LLU" ms - last coded frame PTS "LLU"\n", gf_net_get_utc(), video_output_file->codec_ctx->coded_frame->pts)); + } + + if (frame_nb + 1 == video_output_file->frame_per_segment) + return 1; + + return 0; +#endif + + default: + return -2; + } + + return -2; +} + +int dc_video_muxer_close(VideoOutputFile *video_output_file) +{ + video_output_file->fragment_started = video_output_file->segment_started = 0; + video_output_file->nb_segments++; + + switch (video_output_file->muxer_type) { + case FFMPEG_VIDEO_MUXER: + return dc_ffmpeg_video_muxer_close(video_output_file); + case RAW_VIDEO_H264: + return dc_raw_h264_close(video_output_file); +#ifndef GPAC_DISABLE_ISOM + case GPAC_VIDEO_MUXER: + dc_gpac_video_isom_close_seg(video_output_file); + return dc_gpac_video_isom_close(video_output_file); + case GPAC_INIT_VIDEO_MUXER_AVC1: + case GPAC_INIT_VIDEO_MUXER_AVC3: + return dc_gpac_video_isom_close_seg(video_output_file); +#endif + default: + return -2; + } + + return -2; +} diff --git a/applications/dashcast/video_muxer.h b/applications/deprecated/old_arch/dashcast/video_muxer.h similarity index 100% rename from applications/dashcast/video_muxer.h rename to applications/deprecated/old_arch/dashcast/video_muxer.h diff --git a/applications/dashcast/video_scaler.c b/applications/deprecated/old_arch/dashcast/video_scaler.c similarity index 100% rename from applications/dashcast/video_scaler.c rename to applications/deprecated/old_arch/dashcast/video_scaler.c diff --git a/applications/dashcast/video_scaler.h b/applications/deprecated/old_arch/dashcast/video_scaler.h similarity index 100% rename from applications/dashcast/video_scaler.h rename to applications/deprecated/old_arch/dashcast/video_scaler.h diff --git a/applications/deprecated/old_arch/mp42avi/Makefile b/applications/deprecated/old_arch/mp42avi/Makefile new file mode 100644 index 0000000..065cd0c --- /dev/null +++ b/applications/deprecated/old_arch/mp42avi/Makefile @@ -0,0 +1,48 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/applications/mp42avi + +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 + + +ifeq ($(CONFIG_WIN32),yes) +EXE=.exe +PROG=MP42Avi$(EXE) +else +EXT= +PROG=MP42Avi +endif + +SRCS := $(OBJS:.o=.c) + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/$(TARGET_BIN_DIR) -lgpac -lz $(LDFLAGS) + +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 .depend diff --git a/applications/deprecated/old_arch/mp42avi/main.c b/applications/deprecated/old_arch/mp42avi/main.c new file mode 100644 index 0000000..262bee1 --- /dev/null +++ b/applications/deprecated/old_arch/mp42avi/main.c @@ -0,0 +1,768 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / command-line mp4 toolbox + * + * 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 +#include + +#ifdef WIN32 +#include +#define GPAC_CFG_FILE "GPAC.cfg" +#else +#include +typedef struct tagBITMAPFILEHEADER +{ + u16 bfType; + u32 bfSize; + u16 bfReserved1; + u16 bfReserved2; + u32 bfOffBits; +} BITMAPFILEHEADER; + +typedef struct tagBITMAPINFOHEADER { + u32 biSize; + s32 biWidth; + s32 biHeight; + u16 biPlanes; + u16 biBitCount; + u32 biCompression; + u32 biSizeImage; + s32 biXPelsPerMeter; + s32 biYPelsPerMeter; + u32 biClrUsed; + u32 biClrImportant; +} BITMAPINFOHEADER; + +#define BI_RGB 0L + +#define GPAC_CFG_FILE ".gpacrc" +#endif + +#include +#include + +void PrintVersion() +{ + printf ("MP42AVI - GPAC version %s\n", GPAC_FULL_VERSION); +} + +void PrintUsage() +{ + printf ("MP42AVI [option] input\n" + "Dumps BIFS media frames as AVI, BMP or raw\n\n" + "Options\n" + "-fps Framerate: specifies extraction framerate - if not set computed from track length\n" + "-size WxH: forces output BIFS to the given resolution\n" + "-raw [frame]: uses raw format for output - only dumps one frame if specified\n" + "-bmp [frame]: uses BMP format for output - only dumps one frame if specified\n" + "-outpath path: specifies where to dump frames/movie\n" + "\n" + "Note: when dumping a frame, either the frame number can be specified or the frame time\n" + "in the format hh:mm:ss:xFz where hh, mm, ss are hours, minutes, seconds, x the number\n" + "of the frame in the seconds and z the frame rate used to express the time\n" + "\n" + "-cfg: specifies path to GPAC config file (GPAC.cfg)\n" + "-v: prints version\n" + "-h: prints this message\n" + "\nWritten by Jean Le Feuvre - (c) 2000-2005\n"); +} + + +typedef struct +{ + GF_Compositor *sr; + GF_SceneGraph *sg; + GF_BifsDecoder *bifs; + GF_ISOFile *file; + + u32 track; + u64 duration, cts; +} BIFSVID; + +void node_init(void *cbk, GF_Node *node) +{ + BIFSVID *b2v = cbk; + switch (gf_node_get_tag(node)) { + case TAG_MPEG4_Conditional: + case TAG_MPEG4_QuantizationParameter: + break; + default: + if (b2v->sr) gf_sc_on_node_init(b2v->sr, node); + break; + } +} + +void node_modif(void *cbk, GF_Node *node) +{ + BIFSVID *b2v = cbk; + if (b2v->sr) gf_sc_invalidate(b2v->sr, node); +} + +Double get_scene_time(void *cbk) +{ + Double res; + BIFSVID *b2v = cbk; + res = (Double) (s64) b2v->cts; + res /= (Double) (s64) b2v->duration; + return res; +} + +void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num) +{ + char str[GF_MAX_PATH]; + BITMAPFILEHEADER fh; + BITMAPINFOHEADER fi; + FILE *fout; + u32 j, i; + char *ptr; + + if (img_num<10) { + sprintf(str, "%s_00%d.bmp", rad_name, img_num); + } else if (img_num<100) { + sprintf(str, "%s_0%d.bmp", rad_name, img_num); + } else { + sprintf(str, "%s_%d.bmp", rad_name, img_num); + } + + fout = gf_fopen(str, "wb"); + if (!fout) return; + + memset(&fh, 0, sizeof(fh)); + fh.bfType = 19778; + fh.bfOffBits = 14 + 40; + + memset(&fi, 0, sizeof(char)*40); + fi.biSize = sizeof(char)*40; + fi.biWidth = fb->width; + fi.biHeight = fb->height; + fi.biPlanes = 1; + fi.biBitCount = 24; + fi.biCompression = BI_RGB; + fi.biSizeImage = fb->pitch * fb->height; + + /*NOT ALIGNED!!*/ + gf_fwrite(&fh.bfType, 2, 1, fout); + gf_fwrite(&fh.bfSize, 4, 1, fout); + gf_fwrite(&fh.bfReserved1, 2, 1, fout); + gf_fwrite(&fh.bfReserved2, 2, 1, fout); + gf_fwrite(&fh.bfOffBits, 4, 1, fout); + + gf_fwrite(&fi, 1, 40, fout); + + for (j=fb->height; j>0; j--) { + ptr = fb->video_buffer + (j-1)*fb->pitch; + //gf_fwrite(ptr, 1, fb->width * 3, fout); + for (i=0; iwidth; i++) { + fputc(ptr[2], fout); + fputc(ptr[1], fout); + fputc(ptr[0], fout); + ptr+=3; + } + } + + gf_fclose(fout); +} + + +void write_raw(GF_VideoSurface *fb, char *rad_name, u32 img_num) +{ + char str[GF_MAX_PATH]; + FILE *fout; + if (img_num<10) { + sprintf(str, "%s_00%d.raw", rad_name, img_num); + } else if (img_num<100) { + sprintf(str, "%s_0%d.raw", rad_name, img_num); + } else { + sprintf(str, "%s_%d.raw", rad_name, img_num); + } + + fout = gf_fopen(str, "wb"); + if (!fout) return; + gf_fwrite(fb->video_buffer , fb->height*fb->pitch, 1, fout); + gf_fclose(fout); +} + +void dump_frame(BIFSVID b2v, char *conv_buf, char *out_path, u32 dump_type, avi_t *avi_out, u32 frameNum) +{ + u32 k; + GF_VideoSurface fb; + + /*lock it*/ + gf_sc_get_screen_buffer(b2v.sr, &fb); + /*export frame*/ + switch (dump_type) { + case 0: + /*reverse frame*/ + for (k=0; kdependsOnESID && (esd->decoderConfig->streamType == GF_STREAM_SCENE)) break; + gf_odf_desc_del((GF_Descriptor *) esd); + esd = NULL; + } + if (!esd) { + printf("no bifs track found\n"); + goto err_exit; + } + + es_id = (u16) gf_isom_get_track_id(file, track_number+1); + e = gf_bifs_decoder_configure_stream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication); + if (e) { + printf("BIFS init error %s\n", gf_error_to_string(e)); + gf_odf_desc_del((GF_Descriptor *) esd); + esd = NULL; + goto err_exit; + } + + { + GF_ISOSample *samp = gf_isom_get_sample(file, track_number+1, 1, &di); + b2v.cts = samp->DTS + samp->CTS_Offset; + /*apply command*/ + gf_bifs_decode_au(b2v.bifs, es_id, samp->data, samp->dataLength, ((Double)(s64)b2v.cts)/1000.0); + gf_isom_sample_del(&samp); + } + + b2v.duration = gf_isom_get_media_duration(file, track_number+1); + + gf_odf_desc_del((GF_Descriptor *) esd); + + } + gf_sc_set_scene(b2v.sr, b2v.sg); + + if (!width || !height) { + gf_sg_get_scene_size_info(b2v.sg, &width, &height); + } + /*we work in RGB24, and we must make sure the pitch is %4*/ + if ((width*3)%4) { + printf("Adjusting width (%d) to have a stride multiple of 4\n", width); + while ((width*3)%4) width--; + } + gf_sc_set_size(b2v.sr, width, height); + gf_sc_get_screen_buffer(b2v.sr, &fb); + width = fb.width; + height = fb.height; + gf_sc_release_screen_buffer(b2v.sr, &fb); + + GF_SAFEALLOC(rendered_frames, nb_viewpoints*sizeof(char *)); + for (viewpoint_index = 1; viewpoint_index <= nb_viewpoints; viewpoint_index++) { + GF_SAFEALLOC(rendered_frames[viewpoint_index-1], fb.width*fb.height*3); + gf_sc_set_viewpoint(b2v.sr, viewpoint_index, NULL); + gf_sc_draw_frame(b2v.sr, 0, NULL); + /*needed for background2D !!*/ + gf_sc_draw_frame(b2v.sr, 0, NULL); + strcpy(out_path, ""); + if (out_dir) { + strcat(out_path, out_dir); + if (out_path[strlen(out_path)-1] != '\\') strcat(out_path, "\\"); + } + strcat(out_path, rad_name); + strcat(out_path, "_view"); + gf_sc_get_screen_buffer(b2v.sr, &fb); + write_bmp(&fb, out_path, viewpoint_index); + memcpy(rendered_frames[viewpoint_index-1], fb.video_buffer, fb.width*fb.height*3); + gf_sc_release_screen_buffer(b2v.sr, &fb); + } + + if (width != 800 || height != 480) { + printf("Wrong scene dimension, cannot produce output\n"); + goto err_exit; + } else { + u32 x, y; + GF_VideoSurface out_fb; + u32 bpp = 3; + out_fb.width = 800; + out_fb.height = 480; + out_fb.pitch = 800*bpp; + out_fb.pixel_format = GF_PIXEL_RGB_24; + out_fb.is_hardware_memory = 0; + GF_SAFEALLOC(out_fb.video_buffer, out_fb.pitch*out_fb.height) +#if 1 + for (y=0; ydependsOnESID && (esd->decoderConfig->streamType == GF_STREAM_SCENE)) break; + gf_odf_desc_del((GF_Descriptor *) esd); + esd = NULL; + } + if (!esd) { + printf("no bifs track found\n"); + goto err_exit; + } + + b2v.duration = gf_isom_get_media_duration(file, i+1); + timescale = gf_isom_get_media_timescale(file, i+1); + es_id = (u16) gf_isom_get_track_id(file, i+1); + e = gf_bifs_decoder_configure_stream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication); + if (e) { + printf("BIFS init error %s\n", gf_error_to_string(e)); + gf_odf_desc_del((GF_Descriptor *) esd); + esd = NULL; + goto err_exit; + } + if (dump_time>=0) dump_time = dump_time *1000 / timescale; + + gf_sc_set_scene(b2v.sr, b2v.sg); + count = gf_isom_get_sample_count(file, i+1); + + reset_fps = 0; + if (!fps) { + fps = (Float) (count * timescale); + fps /= (Double) (s64) b2v.duration; + printf("Estimated BIFS FrameRate %g\n", fps); + reset_fps = 1; + } + + if (!width || !height) { + gf_sg_get_scene_size_info(b2v.sg, &width, &height); + } + /*we work in RGB24, and we must make sure the pitch is %4*/ + if ((width*3)%4) { + printf("Adjusting width (%d) to have a stride multiple of 4\n", width); + while ((width*3)%4) width--; + } + + gf_sc_set_size(b2v.sr, width, height); + gf_sc_draw_frame(b2v.sr, 0, NULL); + + gf_sc_get_screen_buffer(b2v.sr, &fb); + width = fb.width; + height = fb.height; + if (avi_out) { + AVI_set_video(avi_out, width, height, fps, comp); + 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); + + cur_time = 0; + + duration = (u32)(timescale / fps); + if (reset_fps) fps = 0; + + frameNum = 1; + first_dump = 1; + for (j=0; jDTS + samp->CTS_Offset; + /*apply command*/ + gf_bifs_decode_au(b2v.bifs, es_id, samp->data, samp->dataLength, ((Double)(s64)b2v.cts)/1000.0); + gf_isom_sample_del(&samp); + + if ((frameID>=0) && (j<(u32)frameID)) continue; + if ((dump_time>=0) && ((u32) dump_time>b2v.cts)) continue; + /*render frame*/ + gf_sc_draw_frame(b2v.sr, 0, NULL); + /*needed for background2D !!*/ + if (first_dump) { + gf_sc_draw_frame(b2v.sr, 0, NULL); + first_dump = 0; + } + + if (fps) { + if (cur_time > b2v.cts) continue; + + while (1) { + printf("dumped frame time %f (frame %d - sample %d)\r", ((Float)cur_time)/timescale, frameNum, j+1); + dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, frameNum); + frameNum++; + cur_time += duration; + if (cur_time > b2v.cts) break; + } + } else { + dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, (frameID>=0) ? frameID : frameNum); + if (frameID>=0 || dump_time>=0) break; + frameNum++; + printf("dumped frame %d / %d\r", j+1, count); + } + + } + gf_odf_desc_del((GF_Descriptor *) esd); + + /*destroy everything*/ + gf_bifs_decoder_del(b2v.bifs); + gf_sg_del(b2v.sg); + gf_sc_set_scene(b2v.sr, NULL); + gf_sc_del(b2v.sr); + +err_exit: + if (avi_out) AVI_close(avi_out); + if (conv_buf) gf_free(conv_buf); + if (user.modules) gf_modules_del(user.modules); + if (needs_raw) gf_cfg_set_key(user.config, "core", "video-output", old_driv); + gf_cfg_del(user.config); +} + +int main (int argc, char **argv) +{ + Double fps_dump; + u32 i; + char rad[500]; + s32 frameID, h, m, s, f; + Float fps; + u32 dump_type; + s32 dump_time; + u32 dump_w, dump_h; + Bool copy; + char szConfigFile[4096]; + char *dump_out; + char *inName, *arg; + GF_ISOFile *file; + + if (argc < 2) { + PrintUsage(); + return 0; + } + + dump_type = 0; + fps_dump = 0.0f; + dump_w = dump_h = 0; + dump_out = NULL; + inName = NULL; + frameID = -1; + dump_time = -1; + szConfigFile[0] = 0; + + for (i = 1; i < (u32) argc ; i++) { + arg = argv[i]; + if (arg[0] != '-') { + inName = arg; + break; + } + if (!stricmp(arg, "-h")) { + PrintUsage(); + return 0; + } else if (!stricmp(arg, "-version")) { + PrintVersion(); + return 0; + } else if (!stricmp(arg, "-size")) { + sscanf(argv[i+1], "%dx%d", &dump_w, &dump_h); + i++; + } else if (!stricmp(arg, "-raw")) { + dump_type = 2; + if ((i+1<(u32)argc) && (argv[i+1][0]!='-')) { + if (strstr(argv[i+1], "T")) { + if (strstr(argv[i+1], "F")) { + sscanf(argv[i+1], "T%d:%d:%d:%dF%f", &h, &m, &s, &f, &fps); + dump_time = (s32) ((3600*h + 60*m + s)*1000 + 1000*f/fps); + } else { + sscanf(argv[i+1], "T%d:%d:%d", &h, &m, &s); + dump_time = (s32) ((3600*h + 60*m + s)*1000); + } + } else { + frameID = atoi(argv[i+1]); + } + i++; + } + } else if (!stricmp(arg, "-bmp")) { + dump_type = 1; + if ((i+1<(u32)argc) && (argv[i+1][0]!='-')) { + if (strstr(argv[i+1], "T")) { + if (strstr(argv[i+1], "F")) { + sscanf(argv[i+1], "T%d:%d:%d:%dF%f", &h, &m, &s, &f, &fps); + dump_time = (s32) ((3600*h + 60*m + s)*1000 + 1000*f/fps); + } else { + sscanf(argv[i+1], "T%d:%d:%d", &h, &m, &s); + dump_time = (s32) ((3600*h + 60*m + s)*1000); + } + } else { + frameID = atoi(argv[i+1]); + } + i++; + } + } else if (!stricmp(arg, "-3d")) { + dump_type = 3; + } else if (!stricmp(arg, "-outpath")) { + dump_out = argv[i+1]; + i++; + } else if (!stricmp(arg, "-fps")) { + fps_dump = atof(argv[i+1]); + i++; + } else if (!stricmp(arg, "-copy")) { + copy = 1; + } else if (!stricmp(arg, "-cfg")) { + strcpy(szConfigFile, argv[i+1]); + i += 1; + } else { + PrintUsage(); + return (0); + } + } + if (!inName) { + PrintUsage(); + return 0; + } + gf_sys_init(GF_MemTrackerNone); + + file = gf_isom_open(inName, GF_ISOM_OPEN_READ, NULL); + if (!file) { + printf("Error opening file: %s\n", gf_error_to_string(gf_isom_last_error(NULL))); + return 0; + } + + if (dump_out) { + arg = strrchr(inName, GF_PATH_SEPARATOR); + if (arg) { + strcpy(rad, arg + 1); + } else { + strcpy(rad, inName); + } + } else { + strcpy(rad, inName); + } + while (rad[strlen(rad)-1] != '.') rad[strlen(rad)-1] = 0; + rad[strlen(rad)-1] = 0; + if (dump_type == 3) { + bifs3d_viewpoints_merger(file, szConfigFile, dump_w, dump_h, rad, dump_type, dump_out, fps_dump, frameID, dump_time); + } + else bifs_to_vid(file, szConfigFile, dump_w, dump_h, rad, dump_type, dump_out, fps_dump, frameID, dump_time); + printf("\ndone\n"); + gf_isom_delete(file); + return 0; + +} + diff --git a/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_icon.bmp b/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f811efdbfea2e72282c35a6cd9662f39814d5b01 GIT binary patch literal 5862 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 literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_icon_mask.bmp b/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_icon_mask.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cff9766729ff720fff5aed99d283b0aaf8a8f720 GIT binary patch literal 414 zcmY+=J&MCH5Cz~T3~^)d1;V;bvBj2KC6GRM$PxAiGNkY=au%5sdky6V3TX@xo_#a2 z7b1{8^fUI%98XsV8+)!h&d+5!l#4SNKgzU+%OdMYfJpG7X4GbaGb7;jyax^{V>>!; z(6lr+*wl3TMpdala2J{)+(;wiBfZn4hT@I#EmnV*{XjF%he*HPbhc++=7h>*zUGWp z<8Fe^zAI6RFLRWq*#G5WM&92ObMZkm&vXc0^PaliYaO}m_gdFnW2<$pb^rH)d0Kzg OK4rAFmmozpmvMj6lcPug literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_menu.bmp b/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_menu.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f44d9b1afae601d554d0dabd8dd2d03bcd587ae1 GIT binary patch literal 3766 zcmc&$drXs86#s5j=-N_iX$32fsi26;qrv(B2?Fwn3fdYUxD}LOn=+inSTxZ{mbgC_ z6aGOH6U}1W7&--fp%YvL)V6lj#YB+0Mpqb=hbx6n8fn>nwyrB$YhizQ^L=0Lckeyt zcV73LlfJ%zO*w}M-x$2Hc*F4$DimLes=$6rgzI%K;PdxK9h1WE?>C=6uPH0LoSFH( zPM2DTDXP=?VDc1;Jl|1R12`00G#rlfFImKYyqNqpCtu`L-yW_`i z*zNWYO5q>A&GxFe_&Omi6!iy#@u09!BaxH~1mSc#{S)WFBq}OaD*a~T#yeA|YH^H4 zyDgLbFfuaYTLeGw?RLk`oi_=&PssDsRIOV5drnRcgTa_SeR^sTL_~b* z9O2>Nvu4eL6cC}JqQYc)nUc~15*n?!s;cpS;CFNk1O;6tq$@X9YqQyFYipr7bOv&C zbaZTN>>}rgiHVsvZ{Ff&-Q7z|zS6X8SpOQlT|rRVc? zU0v3(v9avz>=`p=KwAJNBqS_dx^&sHWg?MCC=@PUyf`W<3Pyn=%FD|Es8;s{1gJnR zm)B1Uzq8ZAVqGP~`1RNAU@$y992y!L5)uN<6B83xu3VXxmX@BLzIyfQl#~?60#m>n zFadrcEJ%uq?&FSfxplq0FT9H2Q~#4E9})6^!FXsg{RQgY-d=bZMuw^YU$bV-+O=!* z^77WLTbGrUwQAKWSOKEVoH=vJk|nOor`7h+XgWf4)z$YWj$crKEB!1rRpTNZ92|t_ zVSHE~Is~(n$=qmSu^LR$(=WMKJSRTw z9~M>*(j!OS=nuN8sw%h__Rq-3faVH?V$YsEa=9FH;3EX)&Yg<@ZE0z7gA^Ad9d*XX zPXb>cc#VJP&^e@>YKCc3)1j(2yl z;uBx5e?h0?3K$O_{Mjotq=5e+h1Xpy?%u5fIiG*sV)0%Gec~g9<>lQ#0_AX;pFHu> zQm9m_`1p8Sd!y0I?&HS;Or{3p`}e=O!S9Oc6CcNQIuo6K3H2vAxo&7^oNrOvQ4Wys z5CxtW-UTu|Y!iu4g}XvRuJ`neBlMKwL-;s*`0zbK?x2{iUw^@Dwz#Q}9Xo~)3=0dx z7iFiRp~1anHowfxZFbh*JJr?RJ?}c~2focVnxB7-5Oe|0laelKwe4_wM@I*05y}A? z0c0fPoVd6+i^YO1ovt%6u@Q&SvM7}rXB~1&_V&aNe2`eJuOyNNbRlT0==5f(^kQ;y zPC!5adI2;X7-+(#O$*q*{Y$CzW?&#{F8Z%lrBa3b|2E?IfB*17Gdk)xdQ`(=)&1Ll zBC8!Iq>M)Uj7IyMki8UjilQDO)!;x#$kpmpq*r@edc*4O_wIB4?* R^WL>d;lG#L#5X=Z{y!0U=#~Hg literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_menu_mask.bmp b/applications/deprecated/old_arch/osmo4_sym/aif/osmo4_menu_mask.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4f02c6757c8b1e4ff3a55180707705cd6b2eb08f GIT binary patch literal 294 zcmYMvF%H5o3 + +RESOURCE AIF_DATA + { + + app_uid = 0x1000AC00; + num_icons = 2; + embeddability = KAppNotEmbeddable; + newfile = KAppDoesNotSupportNewFile; + } + +// End of File diff --git a/applications/deprecated/old_arch/osmo4_sym/osmo4.cpp b/applications/deprecated/old_arch/osmo4_sym/osmo4.cpp new file mode 100644 index 0000000..c817e2c --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/osmo4.cpp @@ -0,0 +1,82 @@ +#include "osmo4.h" +#include "osmo4_ui.h" + + +EXPORT_C CApaApplication* NewApplication() +{ + return new COsmo4Application; +} + + +#ifdef EKA2 + +#include + +GLDEF_C TInt E32Main() +{ + return EikStart::RunApplication( NewApplication ); +} + +#else + + +GLDEF_C TInt E32Dll( TDllReason /*aReason*/ ) +{ + return KErrNone; +} + +#endif + + +#if defined(__SERIES60_3X__) +const TUid KUidOsmo4App = { 0xf01f9075 }; +#else +const TUid KUidOsmo4App = { 0x1000AC00 }; +#endif + + +CApaDocument* COsmo4Application::CreateDocumentL() +{ + return (static_cast ( COsmo4Document::NewL( *this ) ) ); +} + +TUid COsmo4Application::AppDllUid() const +{ + return KUidOsmo4App; +} + + +COsmo4Document* COsmo4Document::NewL( CEikApplication& aApp ) +{ + COsmo4Document* self = NewLC( aApp ); + CleanupStack::Pop( self ); + return self; +} + +COsmo4Document* COsmo4Document::NewLC( CEikApplication& aApp ) +{ + COsmo4Document* self = + new ( ELeave ) COsmo4Document( aApp ); + + CleanupStack::PushL( self ); + self->ConstructL(); + return self; +} +void COsmo4Document::ConstructL() +{ +} + +COsmo4Document::COsmo4Document( CEikApplication& aApp ) + : CAknDocument( aApp ) +{ +} + +COsmo4Document::~COsmo4Document() +{ +} + +CEikAppUi* COsmo4Document::CreateAppUiL() +{ + return ( static_cast ( new ( ELeave ) COsmo4AppUi ) ); +} + diff --git a/applications/deprecated/old_arch/osmo4_sym/osmo4.h b/applications/deprecated/old_arch/osmo4_sym/osmo4.h new file mode 100644 index 0000000..cc83636 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/osmo4.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2004, Nokia. All rights reserved */ + + +#ifndef __OSMO4_H__ +#define __OSMO4_H__ + +// INCLUDES +#include +#include + +class COsmo4Application : public CAknApplication +{ +public: + TUid AppDllUid() const; + +protected: + CApaDocument* CreateDocumentL(); +}; + + +class COsmo4Document : public CAknDocument +{ +public: + static COsmo4Document* NewL( CEikApplication& aApp ); + static COsmo4Document* NewLC( CEikApplication& aApp ); + virtual ~COsmo4Document(); + +public: + CEikAppUi* CreateAppUiL(); + +private: + void ConstructL(); + COsmo4Document( CEikApplication& aApp ); + +}; + +#endif // __OSMO4_H__ + diff --git a/applications/deprecated/old_arch/osmo4_sym/osmo4_ui.cpp b/applications/deprecated/old_arch/osmo4_sym/osmo4_ui.cpp new file mode 100644 index 0000000..55191e4 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/osmo4_ui.cpp @@ -0,0 +1,605 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / Symbian GUI player + * + * 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 FILES +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include "osmo4_ui.h" +#include "osmo4_view.h" +#include "playlist.h" + +#include +#include + + + +// ============================ MEMBER FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// Cosmo4AppUi::ConstructL() +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void COsmo4AppUi::ConstructL() +{ + // Initialise app UI with standard value. + BaseConstructL(CAknAppUi::EAknEnableSkin); + + /*Create display*/ + iAppView = COsmo4AppView::NewL( ClientRect() ); + AddToStackL(iAppView); + + /*create playlist*/ +#ifndef GPAC_GUI_ONLY + iPlaylist = CPlaylist::NewL( ClientRect(), iAppView->GetUser() ); + + iPlaylist->MakeVisible(EFalse); +#endif + + iAppView->MakeVisible(ETrue); + view_mode = 0; + + m_title = NULL; + + //StatusPane ()->SwitchLayoutL ( R_AVKON_STATUS_PANE_LAYOUT_SMALL ); + + nb_keys = 0; + CaptureKeys(1); + + + + CCommandLineArguments *args = CCommandLineArguments::NewL(); +#ifndef GPAC_GUI_ONLY + if (args->Count() > 1) { + TPtrC url = args->Arg(1); +#if defined(_UNICODE) + char szURL[1024]; + u16 szURLUTF16[1024]; + size_t len; + len = url.Size(); + memcpy(szURLUTF16, url.Ptr(), sizeof(u8)*len); + szURLUTF16[len/2] = 0; + const u16 *sptr = szURLUTF16; + len = gf_utf8_wcstombs(szURL, 512, &sptr); + if (len != (size_t) -1) { + szURL[len] = 0; + iAppView->Connect((const char *)szURL); + } +#else + iAppView->Connect((const char *)url.Ptr()); +#endif + } +#endif + delete args; +} + +// ----------------------------------------------------------------------------- +// COsmo4AppUi::COsmo4AppUi() +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +COsmo4AppUi::COsmo4AppUi() +{ + // No implementation required +} + +// ----------------------------------------------------------------------------- +// COsmo4AppUi::~COsmo4AppUi() +// Destructor. +// ----------------------------------------------------------------------------- +// +COsmo4AppUi::~COsmo4AppUi() +{ + CaptureKeys(0); + + switch (view_mode) { + case 0: + if (iAppView) RemoveFromStack(iAppView); + break; + case 1: + if (iPlaylist) RemoveFromStack(iPlaylist); + break; + } + if (iAppView) delete iAppView; + if (iPlaylist) delete iPlaylist; + if (m_title) gf_free(m_title); + m_title = NULL; +} + + +void COsmo4AppUi::CaptureKey(TInt32 code, TInt32 scancode) +{ + RWindowGroup iWG = CCoeEnv::Static()->RootWin(); + if (nb_keys>=MAX_KEY_CAP) return; + keys[nb_keys].key_cap = iWG.CaptureKey(code, 0, 0); + keys[nb_keys].key_cap_ud = iWG.CaptureKeyUpAndDowns(scancode, 0, 0); + nb_keys++; +} +/* +possible meaning for key codes: +EStdKeyYes -Call +EStdKeyNo -End +EStdKeyApplication0 -Apps key +EStdKeyDevice0 -Left softkey +EStdKeyDevice1 -Right softkey +EStdKeyDevice2 -Power +EStdKeyDevice3 -Button press +EStdKeyDevice4 -Flip - Open +EStdKeyDevice5 -Flip - Close +EStdKeyDevice6 -Side key + +EStdKeyDeviceD -Jog Dial forward +EStdKeyDeviceE -Jog Dial back +*/ +void COsmo4AppUi::CaptureKeys(int do_capture) +{ + if (do_capture) { + CaptureKey(EKeyIncVolume, EStdKeyIncVolume); + CaptureKey(EKeyDecVolume, EStdKeyDecVolume); + } else { + RWindowGroup iWG = CCoeEnv::Static()->RootWin(); + for (int i=0; iShutdown(); + Exit(); + break; + /*PLAYLIST commands*/ + case EOsmo4PlayListAdd: + iPlaylist->PlaylistAct(Osmo4PLAdd); + break; + case EOsmo4PlayListRem: + iPlaylist->PlaylistAct(Osmo4PLRem); + break; + case EOsmo4PlayListMoveUp: + iPlaylist->PlaylistAct(Osmo4PLMoveUp); + break; + case EOsmo4PlayListMoveDown: + iPlaylist->PlaylistAct(Osmo4PLMoveDown); + break; + case EOsmo4PlayListClear: + iPlaylist->PlaylistAct(Osmo4PLClear); + break; + case EOsmo4PlayListMode: + iPlaylist->PlaylistAct(Osmo4PLToggleMode); + break; + case EOsmo4PlayListAllFiles: + iPlaylist->PlaylistAct(Osmo4PLToggleAllFiles); + break; + + /*FILE menu command*/ + case EOsmo4PlayListView: + TogglePlaylist(); + break; + case EOsmo4OpenURL: + break; + case EOsmo4Fullscreen: + break; + case EOsmo4ViewMaxSize: + { + CEikStatusPane* statusPane = StatusPane(); + if (statusPane->IsVisible()) statusPane->MakeVisible(EFalse); + else statusPane->MakeVisible(ETrue); + } + break; + case EOsmo4AROriginal: + gf_term_set_option(iAppView->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); + break; + case EOsmo4ARFillScreen: + gf_term_set_option(iAppView->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); + break; + case EOsmo4AR4_3: + gf_term_set_option(iAppView->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); + break; + case EOsmo4AR16_9: + gf_term_set_option(iAppView->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); + break; + + case EOsmo4NavReset: + gf_term_set_option(iAppView->m_term, GF_OPT_NAVIGATION_TYPE, 0); + break; + case EOsmo4NavNone: + gf_term_set_option(iAppView->m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE); + break; + case EOsmo4NavSlide: + e = gf_term_set_option(iAppView->m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("Cannot set navigation: %s", gf_error_to_string(e) )); + } + break; + case EOsmo4NavWalk: + gf_term_set_option(iAppView->m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_WALK); + break; + case EOsmo4NavFly: + gf_term_set_option(iAppView->m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_FLY); + break; + case EOsmo4NavExamine: + gf_term_set_option(iAppView->m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE); + break; + case EOsmo4NavHeadlight: + gf_term_set_option(iAppView->m_term, GF_OPT_HEADLIGHT, !gf_term_get_option(iAppView->m_term, GF_OPT_HEADLIGHT) ); + break; + case EOsmo4CollideNone: + gf_term_set_option(iAppView->m_term, GF_OPT_COLLISION, GF_COLLISION_NONE); + break; + case EOsmo4CollideSimple: + gf_term_set_option(iAppView->m_term, GF_OPT_COLLISION, GF_COLLISION_NORMAL); + break; + case EOsmo4CollideDisp: + gf_term_set_option(iAppView->m_term, GF_OPT_COLLISION, GF_COLLISION_DISPLACEMENT); + break; + case EOsmo4NavGravity: + gf_term_set_option(iAppView->m_term, GF_OPT_GRAVITY, !gf_term_get_option(iAppView->m_term, GF_OPT_GRAVITY)); + break; + case EOsmo4ViewRTI: + iAppView->show_rti = !iAppView->show_rti; + break; + + case EOsmo4OptEnableLogs: + { + const char *opt = gf_cfg_get_key(iAppView->m_user.config, "General", "Logs"); + if (opt && !stricmp(opt, "@debug")) { + gf_cfg_set_key(iAppView->m_user.config, "General", "Logs", "all@error"); + } else { + gf_cfg_set_key(iAppView->m_user.config, "General", "Logs", "all@debug"); + } + iAppView->SetupLogs(); + } + break; + case EOsmo4OptOpenGL: + { + const char *opt = gf_cfg_get_key(iAppView->m_user.config, "Compositor", "ForceOpenGL"); + Bool use_gl = (opt && !strcmp(opt, "yes")) ? 1 : 0; + gf_cfg_set_key(iAppView->m_user.config, "Compositor", "ForceOpenGL", use_gl ? "no" : "yes"); + gf_term_set_option(iAppView->m_term, GF_OPT_USE_OPENGL, !use_gl); + } + break; + case EOsmo4OptDirectDraw: + { + const char *opt = gf_cfg_get_key(iAppView->m_user.config, "Compositor", "DirectDraw"); + Bool use_dd = (opt && !strcmp(opt, "yes")) ? 1 : 0; + gf_cfg_set_key(iAppView->m_user.config, "Compositor", "DirectDraw", use_dd ? "no" : "yes"); + gf_term_set_option(iAppView->m_term, GF_OPT_DIRECT_DRAW, !use_dd); + } + break; + case EOsmo4OptXMLProgressive: + { + const char *opt = gf_cfg_get_key(iAppView->m_user.config, "SAXLoader", "Progressive"); + Bool use_prog = (opt && !strcmp(opt, "yes")) ? 1 : 0; + gf_cfg_set_key(iAppView->m_user.config, "SAXLoader", "Progressive", use_prog ? "no" : "yes"); + gf_cfg_set_key(iAppView->m_user.config, "SAXLoader", "MaxDuration", "100"); + } + break; + + default: + if ((aCommand>=EOsmo4OpenRecentFirst) && (aCommand<=EOsmo4OpenRecentLast)) { + const char *sOpt = gf_cfg_get_key_name(iAppView->m_user.config, "RecentFiles", aCommand - EOsmo4OpenRecentFirst); + if (sOpt) iAppView->Connect(sOpt); + } else { + iAppView->MessageBox("Unandled command - panic", "Osmo4"); + Panic( EOsmo4Ui ); + } + break; + } +#endif +} + + +// ----------------------------------------------------------------------------- +// Called by the framework when the application status pane +// size is changed. Passes the new client rectangle to the +// AppView +// ----------------------------------------------------------------------------- +// +void COsmo4AppUi::HandleStatusPaneSizeChange() +{ + iAppView->SetRect( ClientRect() ); +#ifndef GPAC_GUI_ONLY + iPlaylist->SetRect( ClientRect() ); +#endif +} + +void COsmo4AppUi::TogglePlaylist() +{ + CEikButtonGroupContainer* cba= CEikButtonGroupContainer::Current(); + +#ifndef GPAC_GUI_ONLY + switch (view_mode) { + case 0: + RemoveFromStack(iAppView); + iAppView->ShowHide(0); + AddToStackL(iPlaylist); + if (cba) { + cba->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_BACK); + cba->DrawDeferred(); + } + view_was_max = StatusPane()->IsVisible() ? 0 : 1; + if (view_was_max) StatusPane()->MakeVisible(ETrue); + iPlaylist->ShowHide(1); + view_mode = 1; + break; + case 1: + RemoveFromStack(iPlaylist); + iPlaylist->ShowHide(0); + AddToStackL(iAppView); + if (cba) { + cba->SetCommandSetL(R_AVKON_SOFTKEYS_OPTIONS_EXIT); + cba->DrawDeferred(); + } + iAppView->ShowHide(1); + if (view_was_max) StatusPane()->MakeVisible(EFalse); + view_was_max = 0; + view_mode = 0; + break; + } +#endif +} + +void COsmo4AppUi::PlayURL(const char *url) +{ + if (view_mode) { + TogglePlaylist(); + } + if (url) { + char *sep; + iAppView->Connect(url); + sep = strrchr(url, '\\'); + SetTitle(sep ? sep+1 : url); + } +} + +void COsmo4AppUi::SetTitleInfo(const char *title) +{ +#if 1 + CEikStatusPane* statusPane = StatusPane(); + CAknTitlePane *iTitlePane = (CAknTitlePane*) statusPane->ControlL(TUid::Uid(EEikStatusPaneUidTitle)); + + if (!title) title = "Osmo4"; + + HBufC *htitle = HBufC::NewL( strlen(title)+1); + htitle->Des().Copy( TPtrC8(( TText8* ) title) ); + iTitlePane->SetText(htitle); +#endif +} + +void COsmo4AppUi::SetTitle(const char *title, int store_it) +{ + if (store_it) { + if (m_title) gf_free(m_title); + m_title = NULL; + if (title) m_title = gf_strdup(title); + } + SetTitleInfo(title ? title : m_title); +} + +void COsmo4AppUi::SetInfo(const char *info) +{ + if (view_mode) return; + if (info) { + char szTitle[200]; + sprintf(szTitle, "%s\n%s", info, m_title ? m_title : "Osmo4"); + SetTitleInfo(szTitle); + } else { + SetTitleInfo(m_title); + } +} + + +#define DECLARE_MENU_ITEM(__text, __com, __check, __res, has_sep) \ + item.iText = __text; \ + item.iCommandId = __com; \ + item.iFlags = has_sep ? EEikMenuItemSeparatorAfter : 0; \ + if (__check) item.iFlags |= EEikMenuItemCheckBox | EEikMenuItemSymbolOn; \ + item.iCascadeId = __res; \ + aMenuPane->AddMenuItemL(item); + + +void COsmo4AppUi::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane) +{ + CEikMenuPaneItem::SData item; + + if (aResourceId==R_OSMO4_MENU) { + + aMenuPane->Reset(); + + if (view_mode==1) { +#ifndef GPAC_GUI_ONLY + Bool is_file = iPlaylist->SelectionIsFile(); + Bool in_pl = (is_file && iPlaylist->IsInPlaylist()) ? 1 : 0; + + if (iPlaylist->PlaylistMode()) { + DECLARE_MENU_ITEM(_L("Up"), EOsmo4PlayListMoveUp, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Down"), EOsmo4PlayListMoveDown, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Remove"), EOsmo4PlayListRem, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Clear"), EOsmo4PlayListClear, 0, 0, 1); + } else if (!in_pl) { + DECLARE_MENU_ITEM(_L("Add to PlayList"), EOsmo4PlayListAdd, 0, 0, 1); + } else if (is_file) { + DECLARE_MENU_ITEM(_L("Remove from Playlist"), EOsmo4PlayListRem, 0, 0, 1); + } + + if (! iPlaylist->PlaylistMode()) { + DECLARE_MENU_ITEM(iPlaylist->ViewAllFiles() ? _L("View known files") : _L("View all files"), EOsmo4PlayListAllFiles, 0, 0, 1); + } else { + DECLARE_MENU_ITEM(_L("Sort"), 0, 0, R_OSMO4_SM1, 1); + } + DECLARE_MENU_ITEM(iPlaylist->PlaylistMode() ? _L("Browse") : _L("Playlist"), EOsmo4PlayListMode, 0, 0, 0); +#endif + } else { + /*open*/ + DECLARE_MENU_ITEM(_L("File"), 0, 0, R_OSMO4_SM1, 0); + DECLARE_MENU_ITEM(_L("View"), 0, 0, R_OSMO4_SM2, 0); + DECLARE_MENU_ITEM(_L("Options"), 0, 0, R_OSMO4_SM3, 0); + //DECLARE_MENU_ITEM(_L("Exit"), EEikCmdExit, 0, 0, 0); + } + smenu_id = 0; + return; + } + else if (aResourceId==R_OSMO4_SM1) { + aMenuPane->Reset(); + /*sort menu*/ + if (view_mode==1) { + } + /*file menu*/ + else { + DECLARE_MENU_ITEM(_L("Open local"), EOsmo4PlayListView, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Open URL"), EOsmo4OpenURL, 0, 0, 1); +#ifndef GPAC_GUI_ONLY + if (gf_cfg_get_key_name(iAppView->m_user.config, "RecentFiles", 0) != NULL) { + DECLARE_MENU_ITEM(_L("Recent"), 0, 0, R_OSMO4_SSM1, 0); + } +#endif + } + smenu_id = 1; + return; + } + /*not used*/ + if (view_mode==1) return; + + /*View menu*/ + if (aResourceId==R_OSMO4_SM2) { + aMenuPane->Reset(); +#ifndef GPAC_GUI_ONLY + /*content view menu*/ + if (gf_term_get_option(iAppView->m_term, GF_OPT_NAVIGATION_TYPE) != GF_NAVIGATE_TYPE_NONE) { + DECLARE_MENU_ITEM(_L("Navigate"), 0, 0, R_OSMO4_SSM1, 1); + } +#endif + DECLARE_MENU_ITEM(_L("Fullscreen"), EOsmo4Fullscreen, 0, 0, 0); + /*don't allow content AR modification by user*/ + //DECLARE_MENU_ITEM(_L("Aspect Ratio"), 0, 0, R_OSMO4_SSM2, 1); + DECLARE_MENU_ITEM(_L("Maximize size"), EOsmo4ViewMaxSize, (StatusPane()->IsVisible() ? 0 : 1), 0, 1); + DECLARE_MENU_ITEM(_L("CPU Usage"), EOsmo4ViewRTI, iAppView->show_rti, 0, 0); + smenu_id = 2; + return; + } + /*Option menu*/ + if (aResourceId==R_OSMO4_SM3) { +#ifndef GPAC_GUI_ONLY + const char *opt = gf_cfg_get_key(iAppView->m_user.config, "Compositor", "ForceOpenGL"); + DECLARE_MENU_ITEM(_L("Use 2D OpenGL"), EOsmo4OptOpenGL, (opt && !strcmp(opt, "yes")) ? 1 : 0, 0, 0); + opt = gf_cfg_get_key(iAppView->m_user.config, "Compositor", "DirectDraw"); + DECLARE_MENU_ITEM(_L("Direct Draw"), EOsmo4OptDirectDraw, (opt && !strcmp(opt, "yes")) ? 1 : 0, 0, 0); + opt = gf_cfg_get_key(iAppView->m_user.config, "SAXLoader", "Progressive"); + DECLARE_MENU_ITEM(_L("Progressive XML"), EOsmo4OptXMLProgressive, (opt && !strcmp(opt, "yes")) ? 1 : 0, 0, 0); + +#endif + + DECLARE_MENU_ITEM(_L("Enable Logs"), EOsmo4OptEnableLogs, iAppView->do_log, 0, 0); + return; + } + + if (aResourceId==R_OSMO4_SSM1) { + aMenuPane->Reset(); + if (smenu_id == 1) { + u32 i = 0; +#ifndef GPAC_GUI_ONLY + while (1) { + const char *opt = gf_cfg_get_key_name(iAppView->m_user.config, "RecentFiles", i); + if (!opt) break; + const char *sep = strrchr(opt, '\\'); + if (!sep) sep = strrchr(opt, '/'); + if (!sep) sep = opt; + else sep += 1; + item.iText.Copy( TPtrC8(( TText8* ) sep) ); + item.iCommandId = EOsmo4OpenRecentFirst + i; + item.iFlags = 0; + item.iCascadeId = 0; + aMenuPane->AddMenuItemL(item); + i++; + if (i>=10) break; + } + if (!i) { + DECLARE_MENU_ITEM(_L("_"), 0, 0, 0, 0); + } +#endif + } else if (smenu_id == 2) { + DECLARE_MENU_ITEM(_L("Reset"), EOsmo4NavReset, 0, 0, 1); + DECLARE_MENU_ITEM(_L("None"), EOsmo4NavNone, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Slide"), EOsmo4NavSlide, 0, 0, 0); + +#ifndef GPAC_GUI_ONLY + if (gf_term_get_option(iAppView->m_term, GF_OPT_NAVIGATION_TYPE) == GF_NAVIGATE_TYPE_3D) { + DECLARE_MENU_ITEM(_L("Walk"), EOsmo4NavWalk, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Fly"), EOsmo4NavFly, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Examine"), EOsmo4NavExamine, 0, 0, 1); + DECLARE_MENU_ITEM(_L("Headlight"), EOsmo4NavHeadlight, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Gravity"), EOsmo4NavGravity, 0, 0, 0); + } +#endif + } + return; + } + + if (aResourceId==R_OSMO4_SSM2) { + aMenuPane->Reset(); + DECLARE_MENU_ITEM(_L("Keep Original"), EOsmo4AROriginal, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Fill Screen"), EOsmo4ARFillScreen, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Ratio 4-3"), EOsmo4AR4_3, 0, 0, 0); + DECLARE_MENU_ITEM(_L("Ratio 16-9"), EOsmo4AR16_9, 0, 0, 0); + return; + } +} + diff --git a/applications/deprecated/old_arch/osmo4_sym/osmo4_ui.h b/applications/deprecated/old_arch/osmo4_sym/osmo4_ui.h new file mode 100644 index 0000000..8179353 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/osmo4_ui.h @@ -0,0 +1,181 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / Symbian GUI player + * + * 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 __OSMO4_UI_H__ +#define __OSMO4_UI_H__ + +// INCLUDES +#include + + +// FORWARD DECLARATIONS +class COsmo4AppView; +class CPlaylist; + + +// osmo4 enumerate command codes +enum TOsmo4Ids +{ + /*Playlist commands*/ + EOsmo4PlayListView = 0x6001, + EOsmo4PlayListAdd, + EOsmo4PlayListRem, + EOsmo4PlayListMode, + EOsmo4PlayListMoveUp, + EOsmo4PlayListMoveDown, + EOsmo4PlayListClear, + EOsmo4PlayListAllFiles, + /*file commands*/ + EOsmo4OpenURL, + EOsmo4OpenRecentFirst, + EOsmo4OpenRecentLast = EOsmo4OpenRecentFirst + 10, + /*view commands*/ + EOsmo4Fullscreen, + EOsmo4ViewMaxSize, + EOsmo4AROriginal, + EOsmo4ARFillScreen, + EOsmo4AR4_3, + EOsmo4AR16_9, + EOsmo4NavReset, + EOsmo4NavNone, + EOsmo4NavSlide, + EOsmo4NavWalk, + EOsmo4NavFly, + EOsmo4NavExamine, + EOsmo4NavHeadlight, + EOsmo4NavGravity, + EOsmo4CollideNone, + EOsmo4CollideSimple, + EOsmo4CollideDisp, + EOsmo4ViewRTI, + + /*option commands*/ + EOsmo4OptEnableLogs, + EOsmo4OptOpenGL, + EOsmo4OptDirectDraw, + EOsmo4OptXMLProgressive, + + +}; + + +/** osmo4 application panic codes */ +enum TOsmo4Panics +{ + EOsmo4Ui = 1 + // add further panics here +}; + +inline void Panic(TOsmo4Panics aReason) +{ + _LIT(applicationName,"Osmo4"); + User::Panic(applicationName, aReason); +} + + +#define MAX_KEY_CAP 10 +typedef struct +{ + TInt32 key_cap; + TInt32 key_cap_ud; +} KeyCapInfo; + +// CLASS DECLARATION +/** +* COsmo4AppUi application UI class. +* Interacts with the user through the UI and request message processing +* from the handler class +*/ +class COsmo4AppUi : public CAknAppUi +{ +public: // Constructors and destructor + + /** + * ConstructL. + * 2nd phase constructor. + */ + void ConstructL(); + + /** + * COsmo4AppUi. + * C++ default constructor. This needs to be public due to + * the way the framework constructs the AppUi + */ + COsmo4AppUi(); + + /** + * ~COsmo4AppUi. + * Virtual Destructor. + */ + virtual ~COsmo4AppUi(); + +private: // Functions from base classes + + /** + * From CEikAppUi, HandleCommandL. + * Takes care of command handling. + * @param aCommand Command to be handled. + */ + void HandleCommandL( TInt aCommand ); + + + /** + * HandleStatusPaneSizeChange. + * Called by the framework when the application status pane + * size is changed. + */ + + void HandleStatusPaneSizeChange(); + virtual void DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane); + +public: + void PlayURL(const char *); + void SetTitle(const char *title, TBool store_it = ETrue); + void SetInfo(const char *); + +private: + void TogglePlaylist(); + void SetTitleInfo(const char *); + void HandleForegroundEventL(TBool aForeground); + void CaptureKeys(int do_capture); + void CaptureKey(TInt32 code, TInt32 scancode); + +private: + COsmo4AppView* iAppView; + CPlaylist *iPlaylist; + int view_was_max; + int smenu_id; + char *m_title; + /*current view mode*/ + int view_mode; + + KeyCapInfo keys[MAX_KEY_CAP]; + int nb_keys; +}; + +#endif // __OSMO4_UI_H__ + +// End of File + diff --git a/applications/deprecated/old_arch/osmo4_sym/osmo4_view.cpp b/applications/deprecated/old_arch/osmo4_sym/osmo4_view.cpp new file mode 100644 index 0000000..fed8f86 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/osmo4_view.cpp @@ -0,0 +1,587 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / Symbian GUI player + * + * 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 FILES +#include +#include + +#include "osmo4_view.h" +#include "osmo4_ui.h" + +#include +/*for initial setup*/ +#include + + +#if defined(__SERIES60_3X__) +#define GPAC_CFG_DIR "\\private\\F01F9075\\" +#define GPAC_MODULES_DIR "\\sys\\bin\\" +#else +#define GPAC_CFG_DIR "\\system\\apps\\Osmo4\\" +#define GPAC_MODULES_DIR GPAC_CFG_DIR +#endif + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// Cosmo4AppView::NewL() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +COsmo4AppView* COsmo4AppView::NewL( const TRect& aRect ) +{ + COsmo4AppView* self = COsmo4AppView::NewLC( aRect ); + CleanupStack::Pop( self ); + return self; +} + +// ----------------------------------------------------------------------------- +// COsmo4AppView::NewLC() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +COsmo4AppView* COsmo4AppView::NewLC( const TRect& aRect ) +{ + COsmo4AppView* self = new ( ELeave ) COsmo4AppView; + CleanupStack::PushL( self ); + self->ConstructL( aRect ); + return self; +} + + + +// ----------------------------------------------------------------------------- +// COsmo4AppView::COsmo4AppView() +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +COsmo4AppView::COsmo4AppView() +{ + // No implementation required + m_pTimer = NULL; +#ifndef GPAC_GUI_ONLY + memset(&m_user, 0, sizeof(GF_User)); + m_term = NULL; + m_mx = NULL; + memset(&m_rti, 0, sizeof(GF_SystemRTInfo)); +#endif + last_title_update = 0; + show_rti = 0; +#if defined(__SERIES60_3X__) + selector = NULL; + target = NULL; +#endif +} + + + +// ----------------------------------------------------------------------------- +// COsmo4AppView::~COsmo4AppView() +// Destructor. +// ----------------------------------------------------------------------------- +// +COsmo4AppView::~COsmo4AppView() +{ + Shutdown(); +#ifndef GPAC_GUI_ONLY + if (m_mx) gf_mx_del(m_mx); +#endif + +#if defined(__SERIES60_3X__) + if (selector) delete selector; + //if (target) delete target; +#endif +} + +void COsmo4AppView::Shutdown() +{ +// MessageBox("Osmo4 shutdown request", ""); + if (m_pTimer) { + m_pTimer->Cancel(); + delete m_pTimer; + m_pTimer = NULL; + } +#ifndef GPAC_GUI_ONLY + if (m_term) { + GF_Terminal *t = m_term; + m_term = NULL; + gf_term_del(t); + } + if (m_Logs) { + gf_fclose(m_Logs); + m_Logs = NULL; + } + if (m_user.config) { + gf_cfg_del(m_user.config); + m_user.config = NULL; + } + if (m_user.modules) { + gf_modules_del(m_user.modules); + m_user.modules = NULL; + } +#endif +// MessageBox("Osmo4 shutdown OK", ""); +} + +void COsmo4AppView::MessageBox(const char *text, const char *title) +{ + HBufC *msg1, *msg2; + TInt length = User::StringLength( ( TUint8* ) text) + 1; + msg1 = HBufC::NewL( length ); + msg1->Des().Copy( TPtrC8(( TText8* ) text) ); + + length = User::StringLength( ( TUint8* ) title) + 1; + msg2 = HBufC::NewL( length ); + msg2->Des().Copy( TPtrC8(( TText8* ) title) ); + + CEikonEnv::Static()->InfoWinL(*msg2, *msg1); + delete msg1; + delete msg2; +} + +TInt myTick(TAny* aObject) +{ + return ((COsmo4AppView*)aObject)->OnTick(); +} + +TInt COsmo4AppView::OnTick() +{ +#ifndef GPAC_GUI_ONLY + if (m_term) gf_term_process_step(m_term); + + /*check RTI display*/ + if (show_rti && gf_sys_get_rti(500, &m_rti, 0)) DisplayRTI(); +#endif + /*never stop...*/ + return 1; +} + +void COsmo4AppView::DisplayRTI() +{ +#ifndef GPAC_GUI_ONLY + COsmo4AppUi *app = (COsmo4AppUi *) CEikonEnv::Static()->AppUi(); + char szInfo[20]; + sprintf(szInfo, "CPU %02d FPS %02.2f", m_rti.process_cpu_usage, gf_term_get_framerate(m_term, 0)); + app->SetInfo(szInfo); +#endif +} + + +//GPAC log function +static void on_gpac_log(void *cbk, GF_LOG_Level ll, GF_LOG_Tool lm, const char *fmt, va_list list) +{ + char szMsg[2048]; + COsmo4AppView *app = (COsmo4AppView *)cbk; + +#ifndef GPAC_GUI_ONLY + gf_mx_p(app->m_mx); + if (app->m_Logs) { + vfprintf(app->m_Logs, fmt, list); + } else { + vsnprintf(szMsg, 2048, fmt, list); + app->MessageBox(szMsg, "Error:"); + } + gf_mx_v(app->m_mx); +#endif +} + +static Bool GPAC_EventProc(void *ptr, GF_Event *evt) +{ + COsmo4AppView *app = (COsmo4AppView *)ptr; + return app->EventProc(evt); +} + +Bool COsmo4AppView::EventProc(GF_Event *evt) +{ + TRect r; + +#ifndef GPAC_GUI_ONLY + switch (evt->type) { + case GF_EVENT_MESSAGE: + if (!evt->message.message) return 0; + if (evt->message.error) { + char err[1024]; + sprintf(err, "Error: %s", gf_error_to_string(evt->message.error)); + MessageBox(evt->message.message, err); + } else { + MessageBox(evt->message.message, "Info"); + } + break; + case GF_EVENT_SCENE_SIZE: + r = Rect(); + gf_term_set_size(m_term, r.Width(), r.Height()); + break; + } +#endif + return 0; +} + +void COsmo4AppView::SetupLogs() +{ + const char *opt; + +#ifndef GPAC_GUI_ONLY + gf_mx_p(m_mx); + if (do_log) { + gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_NONE); + do_log = 0; + } + /*setup GPAC logs: log all errors*/ + opt = gf_cfg_get_key(m_user.config, "General", "Logs"); + if (opt && !strstr(opt, "none")) { + const char *filename = gf_cfg_get_key(m_user.config, "General", "LogFile"); + if (!filename) { + gf_cfg_set_key(m_user.config, "General", "LogFile", "\\data\\gpac_logs.txt"); + filename = "\\data\\gpac_logs.txt"; + } + m_Logs = gf_fopen(filename, "wt"); + if (!m_Logs) { + MessageBox("Cannot open log file - disabling logs", "Warning !"); + } else { + MessageBox("Debug logs enabled!", filename); + do_log = 1; + gf_log_set_tools_levels( opt ); + } + } + if (!do_log) { + gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR); + if (m_Logs) gf_fclose(m_Logs); + } + + gf_log_set_callback(this, on_gpac_log); + gf_mx_v(m_mx); + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Osmo4 logs initialized\n")); +#endif +} + + +static void Osmo4_progress_cbk(void *usr, char *title, u32 done, u32 total) +{ +#ifndef GPAC_GUI_ONLY + COsmo4AppView *view = (COsmo4AppView *) usr; + COsmo4AppUi *app = (COsmo4AppUi *) CEikonEnv::Static()->AppUi(); + + if (done==total) { + app->SetInfo(NULL); + } else if (view->last_title_update + 500 < gf_sys_clock()) { + char szName[1024]; + view->last_title_update = gf_sys_clock(); + sprintf(szName, "%s %02d %%", title, (done*100 / total) ); + app->SetInfo(szName); + } +#endif +} + +// ----------------------------------------------------------------------------- +// COsmo4AppView::ConstructL() +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void COsmo4AppView::ConstructL( const TRect& aRect ) +{ + const char *opt; + Bool first_launch = 0; + +#if defined(__SERIES60_3X__) + selector = CRemConInterfaceSelector::NewL(); + target = CRemConCoreApiTarget::NewL(*selector, *this); + selector->OpenTargetL(); +#endif + + // Create a window for this application view + CreateWindowL(); + // Set the windows size + SetRect( aRect ); + //draw + ActivateL(); + +#ifndef GPAC_GUI_ONLY + m_window = Window(); + m_session = CEikonEnv::Static()->WsSession(); + + m_mx = gf_mx_new("Osmo4"); + + //load config file + m_user.config = gf_cfg_init(NULL, &first_launch); + if (!m_user.config) { + MessageBox("Cannot create GPAC Config file", "Fatal Error"); + User::Leave(KErrGeneral); + } + if (first_launch) { + MessageBox("Osmo4", "Thank you for Installing"); + } + + /*load modules*/ + opt = gf_cfg_get_key(m_user.config, "Core", "ModulesDirectory"); + m_user.modules = gf_modules_new(opt, m_user.config); + if (!m_user.modules || !gf_modules_get_count(m_user.modules)) { + MessageBox(m_user.modules ? "No modules available" : "Cannot create module manager", "Fatal Error"); + if (m_user.modules) gf_modules_del(m_user.modules); + gf_cfg_del(m_user.config); + User::Leave(KErrGeneral); + } + + if (first_launch) { + /*first launch, register all files ext*/ + for (u32 i=0; iCanHandleURL(ifce, "test.test"); + gf_modules_close_interface((GF_BaseInterface *)ifce); + } + } + } + + /*we don't thread the terminal, ie appart from the audio renderer, media decoding and visual rendering is + handled by the app process*/ + m_user.init_flags = GF_TERM_NO_REGULATION; + m_user.EventProc = GPAC_EventProc; + m_user.opaque = this; + m_user.os_window_handler = (void *) &m_window; + m_user.os_display = (void *) &m_session; + + m_term = gf_term_new(&m_user); + if (!m_term) { + MessageBox("Cannot load GPAC terminal", "Fatal Error"); + gf_modules_del(m_user.modules); + gf_cfg_del(m_user.config); + User::Leave(KErrGeneral); + } + //MessageBox("GPAC terminal loaded", "Success !"); + + /*ok set output size*/ + TSize s = m_window.Size(); + gf_term_set_size(m_term, s.iWidth, s.iHeight); + + + /*start our callback (every ms)*/ + const TInt KTickInterval = 33000; + m_pTimer = CPeriodic::NewL(CActive::EPriorityStandard); + m_pTimer->Start(KTickInterval, KTickInterval, TCallBack(myTick, this)); + + opt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + if (opt) gf_term_connect(m_term, opt); + +#endif + +} + + +// ----------------------------------------------------------------------------- +// COsmo4AppView::Draw() +// Draws the display. +// ----------------------------------------------------------------------------- +// +void COsmo4AppView::Draw( const TRect& /*aRect*/ ) const +{ +#ifndef GPAC_GUI_ONLY + if (!m_term) { + CWindowGc& gc = SystemGc(); + TRgb black(0,0,0); + gc.SetBrushColor(black); + gc.Clear(); + } else { + /*FIXME - this is just to force a screen flush, needs rework*/ + gf_term_set_option(m_term, GF_OPT_FREEZE_DISPLAY, 0); + } +#else + CWindowGc& gc = SystemGc(); + TRgb black(0,0,0); + TRect rect = Rect(); + gc.SetBrushColor(black); + gc.Clear(rect); +#endif +} + +void COsmo4AppView::ShowHide(Bool show) +{ +#ifndef GPAC_GUI_ONLY + if (show) { + MakeVisible(ETrue); + if (m_term) { + gf_term_set_option(m_term, GF_OPT_VISIBLE, 1); + DrawDeferred(); + } + } else { + MakeVisible(EFalse); + if (m_term) gf_term_set_option(m_term, GF_OPT_VISIBLE, 0); + } +#else + MakeVisible(ETrue); +#endif +} + +// ----------------------------------------------------------------------------- +// COsmo4AppView::SizeChanged() +// Called by framework when the view size is changed. +// ----------------------------------------------------------------------------- +// +void COsmo4AppView::SizeChanged() +{ +#ifndef GPAC_GUI_ONLY + if (m_term) { + TSize s = m_window.Size(); + gf_term_set_size(m_term, s.iWidth, s.iHeight); + } +#endif + DrawNow(); +} + +void COsmo4AppView::Connect(const char *url) +{ +#ifndef GPAC_GUI_ONLY + char the_url[1024]; + /*copy before removing from recent files*/ + strcpy(the_url, url); + gf_cfg_set_key(m_user.config, "RecentFiles", the_url, NULL); + gf_cfg_insert_key(m_user.config, "RecentFiles", the_url, "", 0); + u32 count = gf_cfg_get_key_count(m_user.config, "RecentFiles"); + if (count > 10) gf_cfg_set_key(m_user.config, "RecentFiles", gf_cfg_get_key_name(m_user.config, "RecentFiles", count-1), NULL); + + if (m_term) gf_term_connect(m_term, the_url); +#endif +} + + +TKeyResponse COsmo4AppView::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) +{ + GF_Event evt; + u32 ret; + + evt.key.hw_code = aKeyEvent.iScanCode; + evt.key.flags = 0; + switch (aType) { + case EEventKeyUp: + evt.type = GF_EVENT_KEYUP; + break; + case EEventKeyDown: + case EEventKey: + evt.type = GF_EVENT_KEYDOWN; + break; + default: + return EKeyWasNotConsumed; + } + + switch (aKeyEvent.iCode) { + case EKeyLeftArrow: + evt.key.key_code = GF_KEY_LEFT; + break; + case EKeyRightArrow: + evt.key.key_code = GF_KEY_RIGHT; + break; + case EKeyUpArrow: + evt.key.key_code = GF_KEY_UP; + break; + case EKeyDownArrow: + evt.key.key_code = GF_KEY_DOWN; + break; + case EKeyIncVolume: + evt.key.key_code = GF_KEY_VOLUMEUP; + break; + case EKeyDecVolume: + evt.key.key_code = GF_KEY_VOLUMEDOWN; + break; + default: + switch (aKeyEvent.iScanCode) { + case EStdKeyIncVolume: + evt.key.key_code = GF_KEY_VOLUMEUP; + break; + case EStdKeyDecVolume: + evt.key.key_code = GF_KEY_VOLUMEDOWN; + break; + default: + return EKeyWasNotConsumed; + } + } +#ifndef GPAC_GUI_ONLY + ret = gf_term_user_event(m_term, &evt); + /*generate a key up*/ + if (aType==EEventKey) { + evt.type = GF_EVENT_KEYUP; + ret += gf_term_user_event(m_term, &evt); + } +#else + ret = 0; +#endif + return ret ? EKeyWasConsumed : EKeyWasNotConsumed; +} + +#if defined(__SERIES60_3X__) +void COsmo4AppView::MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct) +{ + GF_Event e; + switch (aOperationId) { + /* + TRequestStatus status; + case ERemConCoreApiPausePlayFunction: + case ERemConCoreApiStop: + case ERemConCoreApiRewind: + case ERemConCoreApiForward: + case ERemConCoreApiFastForward: + case ERemConCoreApiBackward: + switch (aButtonAct) { + case ERemConCoreApiButtonPress: + break; + case ERemConCoreApiButtonRelease: + break; + case ERemConCoreApiButtonClick: + break; + default: + break; + } + */ + case ERemConCoreApiVolumeUp: + case ERemConCoreApiVolumeDown: +#ifndef GPAC_GUI_ONLY + e.key.hw_code = 0; + e.key.flags = 0; + e.key.key_code = (aOperationId==ERemConCoreApiVolumeUp) ? GF_KEY_VOLUMEUP : GF_KEY_VOLUMEDOWN; + switch (aButtonAct) { + case ERemConCoreApiButtonPress: + e.type = GF_EVENT_KEYDOWN; + gf_term_user_event(m_term, &e); + break; + case ERemConCoreApiButtonRelease: + e.type = GF_EVENT_KEYUP; + gf_term_user_event(m_term, &e); + break; + default: + e.type = GF_EVENT_KEYDOWN; + gf_term_user_event(m_term, &e); + e.type = GF_EVENT_KEYUP; + gf_term_user_event(m_term, &e); + break; + } +#endif + break; + default: + break; + } +} + +#endif diff --git a/applications/deprecated/old_arch/osmo4_sym/osmo4_view.h b/applications/deprecated/old_arch/osmo4_sym/osmo4_view.h new file mode 100644 index 0000000..c98e4a5 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/osmo4_view.h @@ -0,0 +1,171 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / Symbian GUI player + * + * 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 __OSMO4_VIEW_H__ +#define __OSMO4_VIEW_H__ + +// INCLUDES +#include + +#if defined(__SERIES60_3X__) +#include +#include +#include +#endif + + +#include +#include + + +// CLASS DECLARATION +class COsmo4AppView : public CCoeControl +#if defined(__SERIES60_3X__) + ,MRemConCoreApiTargetObserver +#endif + +{ +public: // New methods + + /** + * NewL. + * Two-phased constructor. + * Create a COsmo4AppView object, which will draw itself to aRect. + * @param aRect The rectangle this view will be drawn to. + * @return a pointer to the created instance of COsmo4AppView. + */ + static COsmo4AppView* NewL( const TRect& aRect ); + + /** + * NewLC. + * Two-phased constructor. + * Create a COsmo4AppView object, which will draw itself + * to aRect. + * @param aRect Rectangle this view will be drawn to. + * @return A pointer to the created instance of COsmo4AppView. + */ + static COsmo4AppView* NewLC( const TRect& aRect ); + + /** + * ~COsmo4AppView + * Virtual Destructor. + */ + virtual ~COsmo4AppView(); + +public: // Functions from base classes + + /** + * From CCoeControl, Draw + * Draw this COsmo4AppView to the screen. + * @param aRect the rectangle of this view that needs updating + */ + void Draw( const TRect& aRect ) const; + + /** + * From CoeControl, SizeChanged. + * Called by framework when the view size is changed. + */ + virtual void SizeChanged(); + +#ifndef GPAC_GUI_ONLY + GF_User *GetUser() { + return &m_user; + } +#else + GF_User *GetUser() { + return NULL; + } +#endif + void SetupLogs(); + void MessageBox(const char *text, const char *title); + + virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType); + +#if defined(__SERIES60_3X__) + void MrccatoCommand(TRemConCoreApiOperationId aOperationId, TRemConCoreApiButtonAction aButtonAct); +#endif + + TInt OnTick(); + + void Shutdown(); + + void Connect(const char *url); + void ShowHide(Bool show); + Bool EventProc(GF_Event *evt); + +#ifndef GPAC_GUI_ONLY + GF_Terminal *m_term; +#endif + +private: // Constructors + + /** + * ConstructL + * 2nd phase constructor. + * Perform the second phase construction of a + * COsmo4AppView object. + * @param aRect The rectangle this view will be drawn to. + */ + void ConstructL(const TRect& aRect); + + void DisplayRTI(); + + /** + * COsmo4AppView. + * C++ default constructor. + */ + COsmo4AppView(); + + CPeriodic *m_pTimer; + + RWindow m_window; + RWsSession m_session; +#ifndef GPAC_GUI_ONLY + GF_SystemRTInfo m_rti; +#endif + +#if defined(__SERIES60_3X__) + CRemConInterfaceSelector *selector; + CRemConCoreApiTarget *target; +#endif + + +public: + u32 last_title_update; + FILE *m_Logs; + Bool do_log; + Bool show_rti; +#ifndef GPAC_GUI_ONLY + GF_Mutex *m_mx; + GF_User m_user; +#endif +}; + + +#endif // __OSMO4_VIEW_H__ + +// End of File + diff --git a/applications/deprecated/old_arch/osmo4_sym/playlist.cpp b/applications/deprecated/old_arch/osmo4_sym/playlist.cpp new file mode 100644 index 0000000..cca94d2 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/playlist.cpp @@ -0,0 +1,529 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / Symbian GUI player + * + * 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 FILES +#include "osmo4_ui.h" +#include "playlist.h" + +#ifdef USE_SKIN +#include +#include +#include // skin +#include //skin +#endif + + +CPlaylist::CPlaylist() +{ + playlist_mode = 0; + view_all_files = 0; +} +CPlaylist::~CPlaylist() +{ + delete iListBox; + delete iBackGround; +} + +CPlaylist* CPlaylist::NewL( const TRect& aRect, GF_User *user) +{ + CPlaylist* self = CPlaylist::NewLC( aRect, user); + CleanupStack::Pop( self ); + return self; +} +CPlaylist* CPlaylist::NewLC( const TRect& aRect, GF_User *user) +{ + CPlaylist* self = new ( ELeave ) CPlaylist; + CleanupStack::PushL( self ); + self->ConstructL( aRect, user); + return self; +} + +void CPlaylist::ConstructL(const TRect& aRect, GF_User *user) +{ + CreateWindowL(); + +#ifdef USE_SKIN + iListBox = new (ELeave) CAknSingleStyleListBox(); +#else + iListBox = new (ELeave) CEikTextListBox(); +#endif + iListBox->ConstructL(this); + iListBox->SetContainerWindowL(*this); + iListBox->SetListBoxObserver(this); + + CDesCArray* textArray = new (ELeave) CDesCArrayFlat(16); + iListBox->Model()->SetItemTextArray( textArray ); + iListBox->Model()->SetOwnershipType( ELbmOwnsItemArray ); + + // Creates scrollbar. + iListBox->CreateScrollBarFrameL( ETrue ); + iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EAuto, CEikScrollBarFrame::EAuto); + //iListBox->ActivateL(); + + iListBox->SetFocus(ETrue); + + SetRect(aRect); + ActivateL(); + MakeVisible(EFalse); + + strcpy(szCurrentDir, ""); + +#ifndef GPAC_GUI_ONLY + m_user = user; + + strcpy(ext_list, ""); + u32 count = gf_cfg_get_key_count(user->config, "MimeTypes"); + for (u32 i=0; iconfig, "MimeTypes", i); + const char *opt = gf_cfg_get_key(user->config, "MimeTypes", sMime); + strcpy(szKeyList, opt+1); + sKey = strrchr(szKeyList, '\"'); + if (!sKey) continue; + sKey[0] = 0; + strcat(ext_list, szKeyList); + strcat(ext_list, " "); + } + + const char *opt = gf_cfg_get_key(m_user->config, "General", "LastWorkingDir"); + if (opt) strcpy(szCurrentDir, opt); +#endif + +} + +void CPlaylist::SizeChanged() +{ + iListBox->SetRect( Rect() ); +} + +void CPlaylist::Draw(const TRect& aRect) const +{ +#ifdef USE_SKIN + CWindowGc& gc = SystemGc(); + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); + AknsDrawUtils::Background( skin, cc, this, gc, aRect ); +#endif + +} + +#ifdef USE_SKIN +TTypeUid::Ptr CPlaylist::MopSupplyObject(TTypeUid aId) +{ + if(aId.iUid == MAknsControlContext::ETypeId && iBackGround) { + return MAknsControlContext::SupplyMopObject( aId, iBackGround); + } + return CCoeControl::MopSupplyObject( aId ); +} +#endif + + +TInt CPlaylist::CountComponentControls() const +{ + return 1; +} +CCoeControl* CPlaylist::ComponentControl(TInt aIndex) const +{ + switch (aIndex) { + case 0: + return iListBox; + default: + return NULL; + } +} + +TKeyResponse CPlaylist::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) +{ + if (aType != EEventKey) return iListBox->OfferKeyEventL(aKeyEvent, aType); + + switch (aKeyEvent.iScanCode) { + case EStdKeyEnter: + HandleSelection(); + return EKeyWasConsumed; + default: + return iListBox->OfferKeyEventL(aKeyEvent, aType); + } +} +void CPlaylist::HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aEventType ) +{ + if (aEventType == MEikListBoxObserver::EEventItemClicked || + aEventType == MEikListBoxObserver::EEventEnterKeyPressed) + + HandleSelection(); +} + +void CPlaylist::ShowHide(Bool show) +{ + if (show) { + RefreshPlaylist(); + MakeVisible(ETrue); + DrawNow(); + } else { + /*cleanup*/ + ResetView(); + MakeVisible(EFalse); + ((COsmo4AppUi *) CEikonEnv::Static()->AppUi())->SetTitle(NULL, 0); + } +} + + +void CPlaylist::FlushItemList() +{ + iListBox->HandleItemAdditionL(); + iListBox->SetCurrentItemIndexAndDraw(0); +} + +void CPlaylist::ResetView() +{ + CDesCArray* array = static_cast(iListBox->Model()->ItemTextArray()); + array->Reset(); + iListBox->Reset(); +} + +void CPlaylist::AddItem(const char *name, int is_directory) +{ + TBuf<100> tmp; + char szName[100]; + CDesCArray* array = static_cast(iListBox->Model()->ItemTextArray()); + + if (is_directory) { +#ifdef USE_SKIN + sprintf(szName, "\t+ %s\t\t", name); +#else + sprintf(szName, "+ %s", name); +#endif + } else { +#ifdef USE_SKIN + sprintf(szName, "\t%s\t\t", name); +#else + strcpy(szName, name); +#endif + } + tmp.SetLength(strlen(szName)+1); + tmp.Copy( TPtrC8(( TText8* ) szName) ); + tmp.ZeroTerminate(); + array->AppendL(tmp); +} + +static Bool enum_dirs(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info) +{ + CPlaylist *of = (CPlaylist *)cbk; + of->AddItem(name, 1); + return 0; +} + +static Bool enum_files(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info) +{ + CPlaylist *of = (CPlaylist *)cbk; + of->AddItem(name, 0); + return 0; +} + + +void CPlaylist::ScanDirectory(const char *dir) +{ + ResetView(); + + if (!dir || !strlen(dir)) { + RFs iFs; + TDriveList aList; + iFs.Connect(); + iFs.DriveList(aList); + for (TInt i=0; iAppUi())->SetTitle(szCurrentDir, 0); + +} + +void CPlaylist::GetSelectionName(char *szName) +{ + CDesCArray* array = static_cast(iListBox->Model()->ItemTextArray()); + TInt idx = iListBox->CurrentItemIndex(); + +#ifndef GPAC_GUI_ONLY + +#if defined(_UNICODE) + size_t len; + /*handle terminating zero !!*/ + u16 szNameUTF16[100]; + len = (*array)[idx].Size(); + memcpy(szNameUTF16, (*array)[idx].Ptr(), sizeof(u8)*len); + szNameUTF16[len/2] = 0; + const u16 *sptr = szNameUTF16; + + /*skip initial '\t'*/ +#ifdef USE_SKIN + sptr += 1; +#endif + + len = gf_utf8_wcstombs(szName, 512, &sptr); + szName[len] = 0; + + +#else + + char *src = (*array)[idx]).Ptr(); + /*skip initial '\t'*/ +#ifdef USE_SKIN + src += 1; +#endif + strcpy(szName, (const char *) src) ; +#endif + + /*remove trailing "\t\t"*/ +#ifdef USE_SKIN + len = strlen(szName); + szName[len-2] = 0; +#endif + +#else + szName[0] = 0; +#endif + +} + +void CPlaylist::HandleSelection() +{ + char szName[100]; + GetSelectionName(szName); + + /*sub-directory*/ + if ((szName[0] == '+') && (szName[1] == ' ')) { + /*browse up*/ + if ((szName[2] == '.') && (szName[3] == '.')) { + char *prev = strrchr(szCurrentDir, '\\'); + if (prev) { + prev[0] = 0; + ScanDirectory(szCurrentDir); + } else { + ScanDirectory(NULL); + } + } else { + strcat(szCurrentDir, "\\"); + strcat(szCurrentDir, szName+2); + ScanDirectory(szCurrentDir); + } + } else if (szName[1] == ':') { + ScanDirectory(szName); + } else { + char szURL[1024]; + COsmo4AppUi *app = (COsmo4AppUi *) CEikonEnv::Static()->AppUi(); + if (playlist_mode) { + TInt idx = iListBox->CurrentItemIndex(); +#ifndef GPAC_GUI_ONLY + const char *url = gf_cfg_get_key_name(m_user->config, "Playlist", idx); + if (url) app->PlayURL(url); +#endif + } else { + gf_cfg_set_key(m_user->config, "General", "LastWorkingDir", (const char *) szCurrentDir); + sprintf(szURL, "%s\\%s", szCurrentDir, szName); + app->PlayURL(szURL); + } + } +} + +Bool CPlaylist::SelectionIsFile() +{ + char szName[100]; + GetSelectionName(szName); + if ((szName[0] == '+') && (szName[1] == ' ')) return 0; + else if (szName[1] == ':') return 0; + return 1; +} + +Bool CPlaylist::IsInPlaylist() +{ + char szURL[1024]; + char szName[100]; + GetSelectionName(szName); + if ((szName[0] == '+') && (szName[1] == ' ')) return 0; + else if (szName[1] == ':') return 0; + + /*remove from playlist*/ + sprintf(szURL, "%s\\%s", szCurrentDir, szName); +#ifndef GPAC_GUI_ONLY + const char *opt = gf_cfg_get_key(m_user->config, "Playlist", szURL); + if (opt) return 1; +#endif + return 0; +} + +static Bool dir_add_files(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info) +{ + CPlaylist *pl = (CPlaylist *)cbk; + +#if 0 + if (!bViewUnknownTypes && extension_list) { + char *ext = strrchr(name, '.'); + if (!ext || !strstr(extension_list, ext+1)) return 0; + } +#endif + +#ifndef GPAC_GUI_ONLY + gf_cfg_set_key(pl->m_user->config, "Playlist", path, ""); +#endif + + return 0; +} + + +void CPlaylist::RefreshPlaylist() +{ + if (playlist_mode) { +#ifndef GPAC_GUI_ONLY + u32 count = gf_cfg_get_key_count(m_user->config, "Playlist"); + ResetView(); + for (u32 i=0; iconfig, "Playlist", i); + const char *sep = strrchr(opt, '\\'); + if (!sep) sep = strrchr(opt, '/'); + AddItem(sep ? (sep+1) : opt, 0); + } + if (!count) AddItem("[empty]", 0); +#endif + FlushItemList(); + + ((COsmo4AppUi *) CEikonEnv::Static()->AppUi())->SetTitle("Playlist", 0); + } else { + ScanDirectory(szCurrentDir); + } +} + + +void CPlaylist::PlaylistAct(Osmo4_PLActions act) +{ + char szURL[1024]; + char szName[100]; + CDesCArray*array; + TInt idx; + TInt count; + + if (act==Osmo4PLClear) { + while (1) { +#ifndef GPAC_GUI_ONLY + const char *opt = gf_cfg_get_key_name(m_user->config, "Playlist", 0); + if (!opt) break; + gf_cfg_set_key(m_user->config, "Playlist", opt, NULL); +#endif + } + RefreshPlaylist(); + return; + } else if (act == Osmo4PLToggleMode) { + playlist_mode = !playlist_mode; + RefreshPlaylist(); + return; + } else if (act == Osmo4PLToggleAllFiles) { + view_all_files = !view_all_files; + RefreshPlaylist(); + return; + } else if (act == Osmo4PLAdd) { +#ifndef GPAC_GUI_ONLY + GetSelectionName(szName); + if ((szName[0] == '+') && (szName[1] == ' ')) { + if ((szName[2] != '.') && (szName[3] != '.')) { + sprintf(szURL, "%s\\%s", szCurrentDir, szName+2); + gf_enum_directory(szURL, 0, dir_add_files, this, view_all_files ? NULL : ext_list); + } + } else if (szName[1] == ':') { + gf_enum_directory(szName, 0, dir_add_files, this, view_all_files ? NULL : ext_list); + } else { + sprintf(szURL, "%s\\%s", szCurrentDir, szName); + gf_cfg_set_key(m_user->config, "Playlist", szURL, ""); + } +#endif + return; + } + + GetSelectionName(szName); + if ((szName[0] == '+') && (szName[1] == ' ')) return; + else if (szName[1] == ':') return; + + switch (act) { + /*remove from playlist*/ + case Osmo4PLRem: +#ifndef GPAC_GUI_ONLY + sprintf(szURL, "%s\\%s", szCurrentDir, szName); + gf_cfg_set_key(m_user->config, "Playlist", szURL, NULL); +#endif + RefreshPlaylist(); + break; + /*move up*/ + case Osmo4PLMoveUp: + array = static_cast(iListBox->Model()->ItemTextArray()); + count = array->Count(); + idx = iListBox->CurrentItemIndex(); + sprintf(szURL, "%s\\%s", szCurrentDir, szName); +#ifndef GPAC_GUI_ONLY + gf_cfg_set_key(m_user->config, "Playlist", szURL, NULL); + gf_cfg_insert_key(m_user->config, "Playlist", szURL, "", idx-1); +#endif + RefreshPlaylist(); + if (idx>1) iListBox->SetCurrentItemIndexAndDraw(idx-1); + break; + /*move down*/ + case Osmo4PLMoveDown: + array = static_cast(iListBox->Model()->ItemTextArray()); + count = array->Count(); + idx = iListBox->CurrentItemIndex(); + sprintf(szURL, "%s\\%s", szCurrentDir, szName); +#ifndef GPAC_GUI_ONLY + gf_cfg_set_key(m_user->config, "Playlist", szURL, NULL); + gf_cfg_insert_key(m_user->config, "Playlist", szURL, "", idx+1); +#endif + RefreshPlaylist(); + if (idxSetCurrentItemIndexAndDraw(idx+1); + break; + default: + break; + } +} + diff --git a/applications/deprecated/old_arch/osmo4_sym/playlist.h b/applications/deprecated/old_arch/osmo4_sym/playlist.h new file mode 100644 index 0000000..c8186c8 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/playlist.h @@ -0,0 +1,114 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2006-2012 + * All rights reserved + * + * This file is part of GPAC / Symbian GUI player + * + * 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 __osmo4playlist_H__ +#define __osmo4playlist_H__ + +#include +#include +#include + +#define USE_SKIN + +#ifdef USE_SKIN +class MAknsControlContext; // for skins support +#endif + + +#include + +class CEikTextListBox; //For list box + +enum Osmo4_PLActions +{ + Osmo4PLAdd = 0, + Osmo4PLRem, + Osmo4PLClear, + Osmo4PLMoveUp, + Osmo4PLMoveDown, + Osmo4PLToggleMode, + Osmo4PLToggleAllFiles, +}; + +class CPlaylist : public CCoeControl,MEikListBoxObserver +{ +public: + static CPlaylist* NewL( const TRect& aRect, GF_User *user); + static CPlaylist* NewLC( const TRect& aRect, GF_User *user); + virtual ~CPlaylist(); + void SizeChanged(); + + virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType); + + void HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aEventType ); + + void AddItem(const char *name, int is_directory); + TInt CountComponentControls() const; + CCoeControl* ComponentControl(TInt aIndex) const; + void Draw(const TRect& aRect) const; + + void ShowHide(Bool show); + Bool SelectionIsFile(); + Bool IsInPlaylist(); + Bool PlaylistMode() { + return playlist_mode; + } + Bool ViewAllFiles() { + return view_all_files; + } + + void PlaylistAct(Osmo4_PLActions act); + +#ifndef GPAC_GUI_ONLY + GF_User *m_user; +#endif + +private: + void ConstructL(const TRect& aRect, GF_User *user); + CPlaylist(); + + +#ifdef USE_SKIN + TTypeUid::Ptr MopSupplyObject(TTypeUid aId); + MAknsControlContext* iBackGround; +#endif + + + void ResetView(); + void FlushItemList(); + void ScanDirectory(const char *dir); + void HandleSelection(); + void GetSelectionName(char *name); + void RefreshPlaylist(); + + char szCurrentDir[1024]; + CEikTextListBox* iListBox; + Bool playlist_mode; + Bool view_all_files; + char ext_list[4096]; +}; + +#endif //__osmo4playlist_H__ + diff --git a/applications/deprecated/old_arch/osmo4_sym/res/osmo4.rss b/applications/deprecated/old_arch/osmo4_sym/res/osmo4.rss new file mode 100644 index 0000000..b73da36 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/res/osmo4.rss @@ -0,0 +1,19 @@ +#include +#include "osmo4_gen.rss" + +rls_string STRING_osmo_caption_string "Osmo4" + +RESOURCE LOCALISABLE_APP_INFO r_osmo4_localisable_app_info + { + short_caption = STRING_osmo_caption_string; + caption_and_icon = + CAPTION_AND_ICON_INFO + { + caption = STRING_osmo_caption_string; + + number_of_icons = 1; + icon_file = "\\resource\\apps\\osmo4_aif.mif"; + }; + } + +// End of File diff --git a/applications/deprecated/old_arch/osmo4_sym/res/osmo4.svg b/applications/deprecated/old_arch/osmo4_sym/res/osmo4.svg new file mode 100644 index 0000000..a8fa8b0 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/res/osmo4.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/deprecated/old_arch/osmo4_sym/res/osmo4_caption.rss b/applications/deprecated/old_arch/osmo4_sym/res/osmo4_caption.rss new file mode 100644 index 0000000..6a6a0a0 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/res/osmo4_caption.rss @@ -0,0 +1,21 @@ +/* Copyright (c) 2004, Nokia. All rights reserved */ + + +// INCLUDES +#include + + +// RESOURCE DEFINITIONS +// ----------------------------------------------------------------------------- +// +// Caption data for Osmo4 +// +// ----------------------------------------------------------------------------- +// +RESOURCE CAPTION_DATA + { + caption="Osmo4"; + shortcaption= "Osmo4"; + } + +// End of File diff --git a/applications/deprecated/old_arch/osmo4_sym/res/osmo4_gen.rss b/applications/deprecated/old_arch/osmo4_sym/res/osmo4_gen.rss new file mode 100644 index 0000000..a1cb490 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/res/osmo4_gen.rss @@ -0,0 +1,59 @@ +/* Copyright (c) 2004, Nokia. All rights reserved */ + +// RESOURCE IDENTIFIER +NAME OSMO // 4 letter ID + + +// INCLUDES +#include +#include +#include + +RESOURCE RSS_SIGNATURE + { + } + +RESOURCE TBUF r_default_document_name + { + buf="OSMO"; + } + +RESOURCE EIK_APP_INFO + { + menubar = r_Osmo4_menubar; + cba = R_AVKON_SOFTKEYS_OPTIONS_EXIT; + } + + +RESOURCE MENU_BAR r_Osmo4_menubar + { + titles = + { + MENU_TITLE { menu_pane = r_Osmo4_menu; } + }; + } + + +RESOURCE MENU_PANE r_Osmo4_menu + { + } + +RESOURCE MENU_PANE r_osmo4_sm1 + { + } + +RESOURCE MENU_PANE r_osmo4_sm2 + { + } + +RESOURCE MENU_PANE r_osmo4_sm3 + { + } + +RESOURCE MENU_PANE r_osmo4_ssm1 + { + } +RESOURCE MENU_PANE r_osmo4_ssm2 + { + } + diff --git a/applications/deprecated/old_arch/osmo4_sym/res/osmo4_reg.rss b/applications/deprecated/old_arch/osmo4_sym/res/osmo4_reg.rss new file mode 100644 index 0000000..eba4e8a --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_sym/res/osmo4_reg.rss @@ -0,0 +1,31 @@ +/* +* ============================================================================== +* Name : osmo4_reg.rss +* Part of : osmo4 +* Interface : +* Description : +* Version : +* +* Copyright (c) 2005-2006 Nokia Corporation. +* This material, including documentation and any related +* computer programs, is protected by copyright controlled by +* Nokia Corporation. +* ============================================================================== +*/ + +#include +#include + +UID2 KUidAppRegistrationResourceFile +UID3 0xF01F9075 + +RESOURCE APP_REGISTRATION_INFO + { + app_file="Osmo4"; + localisable_resource_file = "\\resource\\apps\\Osmo4"; + localisable_resource_id = R_OSMO4_LOCALISABLE_APP_INFO; + + embeddability=KAppNotEmbeddable; + newfile=KAppDoesNotSupportNewFile; + } + diff --git a/applications/deprecated/old_arch/osmo4_w32/AddressBar.cpp b/applications/deprecated/old_arch/osmo4_w32/AddressBar.cpp new file mode 100644 index 0000000..21d6049 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/AddressBar.cpp @@ -0,0 +1,182 @@ +// AddressBar.cpp : implementation file +// + +#include "stdafx.h" +#include "osmo4.h" +#include "MainFrm.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// AddressBar dialog + +IMPLEMENT_DYNAMIC(CInitDialogBar, CDialogBar) + +BEGIN_MESSAGE_MAP(CInitDialogBar, CDialogBar) +END_MESSAGE_MAP() + + +CInitDialogBar::CInitDialogBar() +{ +} + +CInitDialogBar::~CInitDialogBar() +{ +} + +BOOL CInitDialogBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID) +{ + if(!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID)) + return FALSE; + + if (!OnInitDialog()) return FALSE; + + return TRUE; +} + +BOOL CInitDialogBar::Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID) +{ + if(!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID)) return FALSE; + + if(!OnInitDialog()) return FALSE; + return TRUE; +} + + +BOOL CInitDialogBar::OnInitDialog() +{ + UpdateData(FALSE); + return TRUE; +} + +void CInitDialogBar::DoDataExchange(CDataExchange* pDX) +{ + CDialogBar::DoDataExchange(pDX); +} + + + +IMPLEMENT_DYNAMIC(AddressBar, CInitDialogBar) + + +BEGIN_MESSAGE_MAP(AddressBar, CInitDialogBar) + //{{AFX_MSG_MAP(AddressBar) + ON_WM_SIZE() + ON_WM_CLOSE() + ON_CBN_SELENDOK(IDC_ADDRESS, OnSelendOK) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +AddressBar::AddressBar () : CInitDialogBar() +{ +} + +BOOL AddressBar::OnInitDialog() +{ + CInitDialogBar::OnInitDialog(); + + return TRUE; +} + + +void AddressBar::DoDataExchange(CDataExchange* pDX) +{ + CInitDialogBar::DoDataExchange(pDX); + //{{AFX_DATA_MAP(AddressBar) + DDX_Control(pDX, IDC_DUMTXT, m_Title); + DDX_Control(pDX, IDC_ADDRESS, m_Address); + //}}AFX_DATA_MAP +} + + +///////////////////////////////////////////////////////////////////////////// +// AddressBar message handlers + +void AddressBar::OnSize(UINT nType, int cx, int cy) +{ + u32 w; + POINT pt; + //CDialog::OnSize(nType, cx, cy); + + if (!m_Address.m_hWnd) return; + RECT rc; + m_Title.GetClientRect(&rc); + w = rc.right - rc.left; + m_Address.GetWindowRect(&rc); + pt.x = rc.left; + pt.y = rc.top; + ScreenToClient(&pt); + rc.right = cx - pt.x; + m_Address.SetWindowPos(this, 0, 0, rc.right, rc.bottom, SWP_NOZORDER | SWP_NOMOVE); + +} + +void AddressBar::OnClose() +{ +} + +void AddressBar::ReloadURLs() +{ + Osmo4 *gpac = GetApp(); + u32 i=0; + + while (m_Address.GetCount()) m_Address.DeleteString(0); + while (1) { + const char *sOpt = gf_cfg_get_key_name(gpac->m_user.config, "RecentFiles", i); + if (!sOpt) return; + m_Address.AddString(sOpt); + i++; + } +} + +void AddressBar::SelectionReady() +{ + void UpdateLastFiles(GF_Config *cfg, const char *URL); + + CString URL; + int sel = m_Address.GetCurSel(); + if (sel == CB_ERR) { + m_Address.GetWindowText(URL); + } else { + m_Address.GetLBText(sel, URL); + } + if (!URL.GetLength()) return; + Osmo4 *gpac = GetApp(); + Playlist *pl = ((CMainFrame*)gpac->m_pMainWnd)->m_pPlayList; + /*don't store local files*/ + if (URL.Find("://", 0)>0) { + UpdateLastFiles(gpac->m_user.config, URL); + ReloadURLs(); + } + pl->Truncate(); + pl->QueueURL(URL); + pl->RefreshList(); + pl->PlayNext(); +} + +void AddressBar::OnSelendOK() +{ + SelectionReady(); +} + +BOOL AddressBar::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message == WM_KEYDOWN) { + switch (pMsg->wParam) { + case VK_RETURN: + ::TranslateMessage(pMsg); + ::DispatchMessage(pMsg); + SelectionReady(); + return TRUE; + default: + break; + } + } + return CInitDialogBar::PreTranslateMessage(pMsg); +} + diff --git a/applications/deprecated/old_arch/osmo4_w32/AddressBar.h b/applications/deprecated/old_arch/osmo4_w32/AddressBar.h new file mode 100644 index 0000000..7509d36 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/AddressBar.h @@ -0,0 +1,90 @@ +#if !defined(AFX_ADDRESSBAR_H__B0764C99_5CC2_4412_8B1F_22E71BAD70F0__INCLUDED_) +#define AFX_ADDRESSBAR_H__B0764C99_5CC2_4412_8B1F_22E71BAD70F0__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// AddressBar.h : header file +// + + +///////////////////////////////////////////////////////////////////////////// +// AddressBar dialog + +class CInitDialogBar : public CDialogBar +{ + DECLARE_DYNAMIC(CInitDialogBar) + +// Construction +public: + CInitDialogBar(); + virtual ~CInitDialogBar(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CInitDialogBar) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +public: + virtual BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID); + virtual BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID); + +protected: + virtual BOOL OnInitDialog(); + +protected: + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// AddressBar dialog + +class AddressBar : public CInitDialogBar +{ + + DECLARE_DYNAMIC(AddressBar) + + // Construction +public: + AddressBar(); + +// Dialog Data + //{{AFX_DATA(AddressBar) + enum { IDD = IDD_NAVBAR }; + CStatic m_Title; + CComboBox m_Address; + //}}AFX_DATA + + void ReloadURLs(); + void SelectionReady(); + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(AddressBar) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL PreTranslateMessage(MSG* pMsg); + //virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(AddressBar) + virtual BOOL OnInitDialog(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnClose(); + afx_msg void OnSelendOK(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_ADDRESSBAR_H__B0764C99_5CC2_4412_8B1F_22E71BAD70F0__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/FileProps.cpp b/applications/deprecated/old_arch/osmo4_w32/FileProps.cpp new file mode 100644 index 0000000..dc23abb --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/FileProps.cpp @@ -0,0 +1,622 @@ +// FileProps.cpp : implementation file +// + +#include "stdafx.h" +#include "osmo4.h" +#include "FileProps.h" +#include "MainFrm.h" + +/*ISO 639 languages*/ +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CFileProps dialog + + +CFileProps::CFileProps(CWnd* pParent /*=NULL*/) + : CDialog(CFileProps::IDD, pParent) +{ + //{{AFX_DATA_INIT(CFileProps) + //}}AFX_DATA_INIT +} + + +void CFileProps::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CFileProps) + DDX_Control(pDX, IDC_VIEWSEL, m_ViewSel); + DDX_Control(pDX, IDC_ODINFO, m_ODInfo); + DDX_Control(pDX, IDC_ODTREE, m_ODTree); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CFileProps, CDialog) + //{{AFX_MSG_MAP(CFileProps) + ON_NOTIFY(TVN_SELCHANGED, IDC_ODTREE, OnSelchangedOdtree) + ON_BN_CLICKED(IDC_WORLD, OnWorld) + ON_BN_CLICKED(IDC_VIEWSG, OnViewsg) + ON_WM_TIMER() + ON_WM_CLOSE() + ON_WM_DESTROY() + ON_NOTIFY(TCN_SELCHANGE, IDC_VIEWSEL, OnSelchangeViewsel) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CFileProps message handlers + + +#define FP_TIMER_ID 20 + +BOOL CFileProps::OnInitDialog() +{ + CDialog::OnInitDialog(); + + char sText[5000]; + sprintf(sText, "%s Properties", ((CMainFrame*)GetApp()->m_pMainWnd)->m_pPlayList->GetDisplayName()); + + SetWindowText(sText); + current_odm = NULL; + + m_ViewSel.InsertItem(0, "General"); + m_ViewSel.InsertItem(1, "Streams"); + m_ViewSel.InsertItem(2, "Playback"); + m_ViewSel.InsertItem(3, "Network"); + + m_ODTree.SetIndent(0); + RewriteODTree(); + SetTimer(FP_TIMER_ID, 500, NULL); + + return TRUE; +} + + +void CFileProps::WriteInlineTree(GF_ObjectManager *root_od, HTREEITEM parent) +{ + Osmo4 *gpac = GetApp(); + + /*browse all ODs*/ + u32 count = gf_term_get_object_count(gpac->m_term, root_od); + + for (u32 i=0; im_term, root_od, i); + if (!odm) return; + HTREEITEM item = m_ODTree.InsertItem("Object Descriptor", 0, 0, parent); + m_ODTree.SetItemData(item, (DWORD) odm); + /*if inline propagate*/ + switch (gf_term_object_subscene_type(gpac->m_term, odm)) { + case 1: + m_ODTree.SetItemText(item, "Root Scene"); + WriteInlineTree(odm, item); + break; + case 2: + m_ODTree.SetItemText(item, "Inline Scene"); + WriteInlineTree(odm, item); + break; + case 3: + m_ODTree.SetItemText(item, "Extern Proto Lib"); + WriteInlineTree(odm, item); + break; + default: + break; + } + } +} + +void CFileProps::RewriteODTree() +{ + Osmo4 *gpac = GetApp(); + + m_ODTree.DeleteAllItems(); + + GF_ObjectManager *root_odm = gf_term_get_root_object(gpac->m_term); + if (!root_odm) return; + + HTREEITEM root = m_ODTree.InsertItem("Root OD", 0, 0); + m_ODTree.SetItemData(root, (DWORD) root_odm); + + m_ODTree.SetItemText(root, "Root Scene"); + WriteInlineTree(root_odm, root); +} + +void CFileProps::OnSelchangedOdtree(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; + *pResult = 0; + + HTREEITEM item = m_ODTree.GetSelectedItem(); + GF_ObjectManager *odm = (GF_ObjectManager *) m_ODTree.GetItemData(item); + if (!odm) return; + + SetInfo(odm); +} + + +void CFileProps::OnClose() +{ + KillTimer(FP_TIMER_ID); + DestroyWindow(); +} + +void CFileProps::OnDestroy() +{ + CDialog::OnDestroy(); + delete this; + ((CMainFrame *)GetApp()->m_pMainWnd)->m_pProps = NULL; +} + +void CFileProps::OnSelchangeViewsel(NMHDR* pNMHDR, LRESULT* pResult) +{ + SetInfo(current_odm); + *pResult = 0; +} + +void CFileProps::SetInfo(GF_ObjectManager *odm) +{ + current_odm = odm; + switch (m_ViewSel.GetCurSel()) { + case 3: + SetNetworkInfo(); + break; + case 2: + SetDecoderInfo(); + break; + case 1: + SetStreamsInfo(); + break; + default: + SetGeneralInfo(); + break; + } +} + +void CFileProps::OnTimer(UINT_PTR nIDEvent) +{ + if (nIDEvent == FP_TIMER_ID) { + switch (m_ViewSel.GetCurSel()) { + case 3: + SetNetworkInfo(); + break; + case 2: + SetDecoderInfo(); + break; + } + } + + CDialog::OnTimer(nIDEvent); +} + +void CFileProps::SetGeneralInfo() +{ + char info[10000]; + char buf[1000]; + GF_MediaInfo odi; + GF_ObjectManager *odm; + u32 h, m, s, i, j; + + Osmo4 *gpac = GetApp(); + odm = current_odm; + + strcpy(info, ""); + if (!odm || gf_term_get_object_info(gpac->m_term, odm, &odi) != GF_OK) return; + + if (!odi.od) { + strcat(info, odi.service_url); + m_ODInfo.SetWindowText(info); + return; + } + sprintf(buf, "%sObject Descriptor ID %d\r\n", (odi.has_profiles) ? "Initial " : "", odi.od->objectDescriptorID); + strcat(info, buf); + if (odi.duration) { + h = (u32) (odi.duration / 3600); + m = (u32) (odi.duration / 60) - h*60; + s = (u32) (odi.duration) - h*3600 - m*60; + sprintf(buf, "Duration %02d:%02d:%02d\r\n", h, m, s); + strcat(info, buf); + } else { + strcat(info, "Unknown duration\r\n"); + } + if (odi.owns_service) { + strcat(info, "Service Handler: "); + strcat(info, odi.service_handler); + strcat(info, "\r\n"); + strcat(info, "Service URL: "); + strcat(info, odi.service_url); + strcat(info, "\r\n"); + } + + if (odi.od->URLString) { + strcat(info, "Remote OD - URL: "); + strcat(info, odi.od->URLString); + strcat(info, "\r\n"); + } + /*get OD content info*/ + if (odi.codec_name) { + switch (odi.od_type) { + case GF_STREAM_VISUAL: + sprintf(buf, "Video Object: Width %d - Height %d\r\n", odi.width, odi.height); + strcat(info, buf); + strcat(info, "Media Codec "); + strcat(info, odi.codec_name); + strcat(info, "\r\n"); + if (odi.par) { + sprintf(buf, "Pixel Aspect Ratio: %d:%d\r\n", (odi.par>>16)&0xFF, (odi.par)&0xFF); + strcat(info, buf); + } + break; + case GF_STREAM_AUDIO: + sprintf(buf, "Audio Object: Sample Rate %d - %d channels\r\n", odi.sample_rate, odi.num_channels); + strcat(info, buf); + strcat(info, "Media Codec "); + strcat(info, odi.codec_name); + strcat(info, "\r\n"); + break; + case GF_STREAM_PRIVATE_SCENE: + case GF_STREAM_SCENE: + if (odi.width && odi.height) { + sprintf(buf, "Scene Description: Width %d - Height %d\r\n", odi.width, odi.height); + } else { + sprintf(buf, "Scene Description: No size specified\r\n"); + } + strcat(info, buf); + strcat(info, "Scene Codec "); + strcat(info, odi.codec_name); + strcat(info, "\r\n"); + break; + case GF_STREAM_TEXT: + if (odi.width && odi.height) { + sprintf(buf, "Text Object: Width %d - Height %d\r\n", odi.width, odi.height); + } else { + sprintf(buf, "Text Object: No size specified\r\n"); + } + strcat(info, buf); + strcat(info, "Text Codec "); + strcat(info, odi.codec_name); + strcat(info, "\r\n"); + break; + } + } + if (odi.protection) { + strcat(info, "Encrypted Media"); + if (odi.protection==2) strcat(info, " NOT UNLOCKED"); + strcat(info, "\r\n"); + } + + if (!gf_list_count(odi.od->OCIDescriptors)) { + m_ODInfo.SetWindowText(info); + return; + } + + strcat(info, "\r\nObject Content Information:\r\n"); + + /*check OCI (not everything interests us) - FIXME: support for unicode*/ + for (i=0; iOCIDescriptors); i++) { + GF_Descriptor *desc = (GF_Descriptor *) gf_list_get(odi.od->OCIDescriptors, i); + switch (desc->tag) { + case GF_ODF_SEGMENT_TAG: + { + GF_Segment *sd = (GF_Segment *) desc; + strcat(info, "\r\nSegment Descriptor:\r\n"); + sprintf(buf, "Name: %s - start time %g sec - duration %g sec\r\n", sd->SegmentName, sd->startTime, sd->Duration); + strcat(info, buf); + } + break; + case GF_ODF_CC_NAME_TAG: + { + GF_CC_Name *ccn = (GF_CC_Name *)desc; + strcat(info, "\r\nContent Creators:\r\n"); + for (j=0; jContentCreators); j++) { + GF_ContentCreatorInfo *ci = (GF_ContentCreatorInfo *) gf_list_get(ccn->ContentCreators, j); + if (!ci->isUTF8) continue; + strcat(info, "\t"); + strcat(info, ci->contentCreatorName); + strcat(info, "\r\n"); + } + } + break; + + case GF_ODF_SHORT_TEXT_TAG: + { + GF_ShortTextual *std = (GF_ShortTextual *)desc; + strcat(info, "\r\n"); + strcat(info, std->eventName); + strcat(info, ": "); + strcat(info, std->eventText); + strcat(info, "\r\n"); + } + break; + /*todo*/ + case GF_ODF_CC_DATE_TAG: + break; + default: + break; + } + + } + + m_ODInfo.SetWindowText(info); +} + +void CFileProps::OnWorld() +{ + CString wit; + const char *str; + GF_List *descs; + Osmo4 *gpac = GetApp(); + + descs = gf_list_new(); + str = gf_term_get_world_info(gpac->m_term, current_odm, descs); + if (!str) { + MessageBox("No World Info available", "Sorry!"); + return; + } + + wit = ""; + for (u32 i=0; iszUserPath); + if ( szOutRadname[strlen(szOutRadname)-1] != '\\' + && szOutRadname[strlen(szOutRadname)-1] != '/') + strcat(szOutRadname, "\\"); + strcat(szOutRadname, "scene_dump"); + + GF_Err e = gf_term_dump_scene(gpac->m_term, (char *) szOutRadname, &pFilename, gpac->m_ViewXMTA, GF_FALSE, current_odm); + + if (e) { + MessageBox(gf_error_to_string(e), "Error while dumping"); + } else { + ShellExecute(NULL, "open", pFilename, NULL, NULL, SW_SHOWNORMAL); + } + if (pFilename) gf_free(pFilename); +} + +void CFileProps::SetDecoderInfo() +{ + GF_MediaInfo odi; + char buf[1000], info[2000]; + u32 h, m, s; + Osmo4 *gpac = GetApp(); + + sprintf(info, ""); + m_ODInfo.SetWindowText(""); + + if (!current_odm || gf_term_get_object_info(gpac->m_term, current_odm, &odi)) return; + if (!odi.od) return; + + strcat(info, "Status: "); + switch (odi.status) { + case 0: + case 1: + case 2: + h = (u32) (odi.current_time / 3600); + m = (u32) (odi.current_time / 60) - h*60; + s = (u32) (odi.current_time) - h*3600 - m*60; + sprintf(buf, "%s\r\nObject Time: %02d:%02d:%02d\r\n", (odi.status==0) ? "Stopped" : (odi.status==1) ? "Playing" : "Paused", h, m, s); + strcat(info, buf); + break; + case 3: + strcat(info, "Not Setup"); + m_ODInfo.SetWindowText(info); + return; + default: + strcat(info, "Setup Failed"); + m_ODInfo.SetWindowText(info); + return; + } + /*get clock drift*/ + sprintf(buf, "Clock drift: %d ms\r\n", odi.clock_drift); + strcat(info, buf); + /*get buffering*/ + if (odi.buffer>=0) { + sprintf(buf, "Buffering Time: %d ms\r\n", odi.buffer); + strcat(info, buf); + } else if (odi.buffer==-1) { + strcat(info, "Not buffering\r\n"); + } else { + strcat(info, "Not Playing\r\n"); + } + /*get DB occupation*/ + if (odi.buffer>=0) { + sprintf(buf, "Decoding Buffer: %d Access Units\r\n", odi.db_unit_count); + strcat(info, buf); + } + /*get CB occupation*/ + if (odi.cb_max_count) { + sprintf(buf, "Composition Memory: %d/%d Units\r\n", odi.cb_unit_count, odi.cb_max_count); + strcat(info, buf); + } + + Float avg_dec_time = 0; + if (odi.nb_dec_frames) { + avg_dec_time = (Float) odi.total_dec_time; + avg_dec_time /= odi.nb_dec_frames; + } + sprintf(buf, "Bitrate over last second: %d kbps\r\nMax bitrate over one second: %d kbps\r\nAverage Decoding Time %.2f ms (%d max)\r\nTotal decoded frames %d - %d dropped\r\n", + (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time, odi.nb_dec_frames, odi.nb_dropped); + strcat(info, buf); + + m_ODInfo.SetWindowText(info); +} + + +void CFileProps::SetStreamsInfo() +{ + u32 i, count; + char info[10000]; + char buf[1000]; + GF_MediaInfo odi; + GF_ObjectManager *odm; + Bool is_media; + + Osmo4 *gpac = GetApp(); + odm = current_odm; + + strcpy(info, ""); + m_ODInfo.SetWindowText(""); + + if (!odm || gf_term_get_object_info(gpac->m_term, odm, &odi) != GF_OK) return; + if (!odi.od) return; + + + if (odi.has_profiles) { + strcat(info, "MPEG-4 Profiles and Levels:\r\n"); + sprintf(buf, "\tOD Profile@Level %d\r\n", odi.OD_pl); + strcat(info, buf); + sprintf(buf, "\tScene Profile@Level %d\r\n", odi.scene_pl); + strcat(info, buf); + sprintf(buf, "\tGraphics Profile@Level %d\r\n", odi.graphics_pl); + strcat(info, buf); + sprintf(buf, "\tAudio Profile@Level %d\r\n", odi.audio_pl); + strcat(info, buf); + sprintf(buf, "\tVisual Profile@Level %d\r\n", odi.visual_pl); + strcat(info, buf); + sprintf(buf, "\tInline Content Profiled %s\r\n", odi.inline_pl ? "yes" : "no"); + strcat(info, buf); + strcat(info, "\r\n"); + } + is_media = GF_FALSE; + count = gf_list_count(odi.od->ESDescriptors); + + for (i=0; iESDescriptors, i); + + sprintf(buf, "\t** Stream ID %d - Clock ID %d **\r\n", esd->ESID, esd->OCRESID); + strcat(info, buf); + if (esd->dependsOnESID) { + sprintf(buf, "Depends on Stream ID %d for decoding\r\n", esd->dependsOnESID); + strcat(info, buf); + } + sprintf(buf, "%s\r\n", gf_esd_get_textual_description(esd)); + strcat(info, buf); + + sprintf(buf, "Buffer Size %d\r\nAverage Bitrate %d bps\r\nMaximum Bitrate %d bps\r\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate); + strcat(info, buf); + if (esd->slConfig->predefined==SLPredef_SkipSL) { + sprintf(buf, "Not using MPEG-4 Synchronization Layer\r\n"); + } else { + sprintf(buf, "Stream Clock Resolution %d\r\n", esd->slConfig->timestampResolution); + } + strcat(info, buf); + if (esd->URLString) { + sprintf(buf, "Stream Location: %s\r\n", esd->URLString); + strcat(info, buf); + } + + /*check language*/ + if (esd->langDesc) { + s32 lang_idx; + char lan[4]; + lan[0] = esd->langDesc->langCode>>16; + lan[1] = (esd->langDesc->langCode>>8)&0xFF; + lan[2] = (esd->langDesc->langCode)&0xFF; + lan[3] = 0; + + lang_idx = gf_lang_find(lan); + if (lang_idx>=0) { + sprintf(buf, "Stream Language: %s\r\n", gf_lang_get_name(lang_idx) ); + strcat(info, buf); + } + } + strcat(info, "\r\n"); + } + + m_ODInfo.SetWindowText(info); +} + +void CFileProps::SetNetworkInfo() +{ + char info[10000]; + char buf[10000]; + u32 id; + NetStatCommand com; + GF_MediaInfo odi; + u32 d_enum, nb_streams; + GF_Err e; + GF_ObjectManager *odm; + Osmo4 *gpac = GetApp(); + odm = current_odm; + + strcpy(info, ""); + m_ODInfo.SetWindowText(""); + + if (!odm || gf_term_get_object_info(gpac->m_term, odm, &odi) != GF_OK) return; + if (!odi.od) return; + + if (odi.owns_service) { + const char *url, *path; + u32 done, total, bps; + strcpy(info, "Current Downloads in service:\r\n"); + d_enum = 0; + while (gf_term_get_download_info(gpac->m_term, odm, &d_enum, &url, &path, &done, &total, &bps)) { + if (total && done) { + sprintf(buf, "%s %s: %d / %d bytes (%.2f %%) - %.2f kBps\r\n", url, path, done, total, (100.0f*done)/total, ((Float)bps)/1024); + } else { + sprintf(buf, "%s %s: %.2f kbps\r\n", url, path, ((Float)bps*8)/1024); + } + strcat(info, buf); + } + if (!d_enum) strcpy(info, "No Downloads in service\r\n"); + strcat(info, "\r\n"); + } + + d_enum = 0; + nb_streams = 0; + while (gf_term_get_channel_net_info(gpac->m_term, odm, &d_enum, &id, &com, &e)) { + if (e) continue; + if (!com.bw_down && !com.bw_up) continue; + nb_streams ++; + + sprintf(buf, "Stream ID %d statistics:\r\n", id); + strcat(info, buf); + if (com.multiplex_port) { + sprintf(buf, "\tMultiplex Port %d - multiplex ID %d\r\n", com.multiplex_port, com.port); + } else { + sprintf(buf, "\tPort %d\r\n", com.port); + } + strcat(info, buf); + sprintf(buf, "\tPacket Loss Percentage: %.4f\r\n", com.pck_loss_percentage); + strcat(info, buf); + sprintf(buf, "\tDown Bandwidth: %.3f kbps\r\n", ((Float)com.bw_down) / 1024); + strcat(info, buf); + if (com.bw_up) { + sprintf(buf, "\tUp Bandwidth: %d bps\r\n", com.bw_up); + strcat(info, buf); + } + if (com.ctrl_port) { + if (com.multiplex_port) { + sprintf(buf, "\tControl Multiplex Port: %d - Control Multiplex ID %d\r\n", com.multiplex_port, com.ctrl_port); + } else { + sprintf(buf, "\tControl Port: %d\r\n", com.ctrl_port); + } + strcat(info, buf); + sprintf(buf, "\tControl Down Bandwidth: %d bps\r\n", com.ctrl_bw_down); + strcat(info, buf); + sprintf(buf, "\tControl Up Bandwidth: %d bps\r\n", com.ctrl_bw_up); + strcat(info, buf); + } + strcat(info, "\r\n"); + } + if (!nb_streams) strcat(info, "No network streams in this object\r\n"); + + m_ODInfo.SetWindowText(info); +} diff --git a/applications/deprecated/old_arch/osmo4_w32/FileProps.h b/applications/deprecated/old_arch/osmo4_w32/FileProps.h new file mode 100644 index 0000000..4d8c5c8 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/FileProps.h @@ -0,0 +1,70 @@ +#if !defined(AFX_FILEPROPS_H__CA4484B4_0301_4BE1_8736_551250121C3F__INCLUDED_) +#define AFX_FILEPROPS_H__CA4484B4_0301_4BE1_8736_551250121C3F__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// FileProps.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// CFileProps dialog + +class CFileProps : public CDialog +{ +// Construction +public: + CFileProps(CWnd* pParent = NULL); // standard constructor + BOOL Create(CWnd * pParent) + { + return CDialog::Create( CFileProps::IDD, pParent); + } + +// Dialog Data + //{{AFX_DATA(CFileProps) + enum { IDD = IDD_PROPERTIES }; + CTabCtrl m_ViewSel; + CEdit m_ODInfo; + CTreeCtrl m_ODTree; + //}}AFX_DATA + + + void RewriteODTree(); + void WriteInlineTree(GF_ObjectManager *root_od, HTREEITEM parent); + void SetInfo(GF_ObjectManager *odm); + +private: + GF_ObjectManager *current_odm; + void SetGeneralInfo(); + void SetStreamsInfo(); + void SetDecoderInfo(); + void SetNetworkInfo(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CFileProps) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(CFileProps) + virtual BOOL OnInitDialog(); + afx_msg void OnSelchangedOdtree(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnWorld(); + afx_msg void OnViewsg(); + afx_msg void OnTimer(UINT_PTR nIDEvent); + afx_msg void OnClose(); + afx_msg void OnDestroy(); + afx_msg void OnSelchangeViewsel(NMHDR* pNMHDR, LRESULT* pResult); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_FILEPROPS_H__CA4484B4_0301_4BE1_8736_551250121C3F__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/MainFrm.cpp b/applications/deprecated/old_arch/osmo4_w32/MainFrm.cpp new file mode 100644 index 0000000..07bff79 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/MainFrm.cpp @@ -0,0 +1,1588 @@ +// MainFrm.cpp : implementation of the CMainFrame class +// + +#include "stdafx.h" +#include "Osmo4.h" + +#include "MainFrm.h" +#include "resource.h" + +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CChildView + +CChildView::CChildView() +{ +} + +CChildView::~CChildView() +{ + /*since the wndproc is overwritten by the terminal, we detach the handle otherwise we get a nice assertion + failure from windows*/ + HWND hWnd = Detach(); + ::PostMessage(hWnd, WM_QUIT, 0, 0); +} + + +BEGIN_MESSAGE_MAP(CChildView,CWnd ) + //{{AFX_MSG_MAP(CChildView) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CChildView message handlers + +BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) +{ + cs.dwExStyle = 0; + cs.style &= ~WS_BORDER; + + cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, + ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); + + return TRUE; +} + + + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_SETFOCUS() + ON_WM_INITMENUPOPUP() + ON_WM_SIZE() + ON_WM_MOVE() + ON_MESSAGE(WM_SETSIZE,OnSetSize) + ON_MESSAGE(WM_NAVIGATE,OnNavigate) + ON_MESSAGE(WM_OPENURL, Open) + ON_MESSAGE(WM_NEWINSTANCE, NewInstanceOpened) + + ON_WM_LBUTTONDOWN() + ON_WM_LBUTTONDBLCLK() + ON_WM_LBUTTONUP() + ON_WM_CHAR() + ON_WM_SYSKEYDOWN() + ON_WM_SYSKEYUP() + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_WM_DROPFILES() + ON_MESSAGE(WM_CONSOLEMSG, OnConsoleMessage) + ON_COMMAND(ID_VIEW_ORIGINAL, OnViewOriginal) + ON_COMMAND(ID_VIEW_FULLSCREEN, OnViewFullscreen) + ON_COMMAND(ID_AR_KEEP, OnArKeep) + ON_COMMAND(ID_AR_FILL, OnArFill) + ON_COMMAND(ID_AR_43, OnAr43) + ON_COMMAND(ID_AR_169, OnAr169) + ON_UPDATE_COMMAND_UI(ID_AR_169, OnUpdateAr169) + ON_UPDATE_COMMAND_UI(ID_AR_43, OnUpdateAr43) + ON_UPDATE_COMMAND_UI(ID_AR_FILL, OnUpdateArFill) + ON_UPDATE_COMMAND_UI(ID_AR_KEEP, OnUpdateArKeep) + ON_COMMAND(ID_NAVIGATE_NONE, OnNavigateNone) + ON_COMMAND(ID_NAVIGATE_WALK, OnNavigateWalk) + ON_COMMAND(ID_NAVIGATE_FLY, OnNavigateFly) + ON_COMMAND(ID_NAVIGATE_EXAM, OnNavigateExam) + ON_COMMAND(ID_NAVIGATE_SLIDE, OnNavigateSlide) + ON_COMMAND(ID_NAVIGATE_PAN, OnNavigatePan) + ON_COMMAND(ID_NAVIGATE_ORBIT, OnNavigateOrbit) + ON_COMMAND(ID_NAVIGATE_GAME, OnNavigateGame) + ON_COMMAND(ID_NAVIGATE_VR, OnNavigateVR) + ON_COMMAND(ID_NAV_RESET, OnNavigateReset) + ON_COMMAND(ID_SHORTCUTS, OnShortcuts) + ON_COMMAND(IDD_CONFIGURE, OnConfigure) + ON_COMMAND(ID_FILE_PROP, OnFileProp) + ON_COMMAND(ID_VIEW_PL, OnViewPlaylist) + ON_UPDATE_COMMAND_UI(ID_FILE_PROP, OnUpdateFileProp) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_NONE, OnUpdateNavigate) + ON_COMMAND(ID_REC_ENABLE, OnCacheEnable) + ON_UPDATE_COMMAND_UI(ID_REC_ENABLE, OnUpdateCacheEnable) + ON_COMMAND(ID_REC_STOP, OnCacheStop) + ON_COMMAND(ID_REC_ABORT, OnCacheAbort) + ON_UPDATE_COMMAND_UI(ID_REC_STOP, OnUpdateCacheStop) + ON_COMMAND(ID_COLLIDE_DISP, OnCollideDisp) + ON_UPDATE_COMMAND_UI(ID_COLLIDE_DISP, OnUpdateCollideDisp) + ON_COMMAND(ID_COLLIDE_NONE, OnCollideNone) + ON_UPDATE_COMMAND_UI(ID_COLLIDE_NONE, OnUpdateCollideNone) + ON_COMMAND(ID_COLLIDE_REG, OnCollideReg) + ON_UPDATE_COMMAND_UI(ID_COLLIDE_REG, OnUpdateCollideReg) + ON_COMMAND(ID_HEADLIGHT, OnHeadlight) + ON_UPDATE_COMMAND_UI(ID_HEADLIGHT, OnUpdateHeadlight) + ON_COMMAND(ID_GRAVITY, OnGravity) + ON_UPDATE_COMMAND_UI(ID_GRAVITY, OnUpdateGravity) + ON_COMMAND(ID_NAV_INFO, OnNavInfo) + ON_COMMAND(ID_NAV_NEXT, OnNavNext) + ON_COMMAND(ID_NAV_PREV, OnNavPrev) + ON_UPDATE_COMMAND_UI(ID_NAV_NEXT, OnUpdateNavNext) + ON_UPDATE_COMMAND_UI(ID_NAV_PREV, OnUpdateNavPrev) + ON_COMMAND(ID_CLEAR_NAV, OnClearNav) + ON_UPDATE_COMMAND_UI(ID_VIEW_PL, OnUpdateViewPlaylist) + ON_COMMAND(ID_PLAYLIST_LOOP, OnPlaylistLoop) + ON_UPDATE_COMMAND_UI(ID_PLAYLIST_LOOP, OnUpdatePlaylistLoop) + ON_COMMAND(ID_ADD_SUBTITLE, OnAddSubtitle) + ON_UPDATE_COMMAND_UI(ID_REC_ABORT, OnUpdateCacheStop) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_WALK, OnUpdateNavigate) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_FLY, OnUpdateNavigate) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_EXAM, OnUpdateNavigate) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_PAN, OnUpdateNavigate) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_SLIDE, OnUpdateNavigate) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_ORBIT, OnUpdateNavigate) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_VR, OnUpdateNavigate) + ON_UPDATE_COMMAND_UI(ID_NAVIGATE_GAME, OnUpdateNavigate) + ON_COMMAND(ID_FILE_EXIT, OnFileExit) + ON_COMMAND(ID_VIEW_CPU, OnViewCPU) + ON_UPDATE_COMMAND_UI(ID_VIEW_CPU, OnUpdateViewCPU) + + ON_COMMAND(ID_FILE_COPY, OnFileCopy) + ON_UPDATE_COMMAND_UI(ID_FILE_COPY, OnUpdateFileCopy) + ON_COMMAND(ID_FILE_PASTE, OnFilePaste) + ON_UPDATE_COMMAND_UI(ID_FILE_PASTE, OnUpdateFilePaste) + + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + m_icoerror = AfxGetApp()->LoadIcon(IDI_ERR); + m_icomessage = AfxGetApp()->LoadIcon(IDI_MESSAGE); + m_bFullScreen = GF_FALSE; + m_RestoreFS = 0; + m_aspect_ratio = GF_ASPECT_RATIO_KEEP; + m_pProps = NULL; + m_pOpt = NULL; + m_pPlayList = NULL; + m_pWndView = new CChildView(); + m_bInitShow = GF_TRUE; + m_bStartupFile = GF_TRUE; + m_num_chapters = 0; + m_chapters_start = NULL; + m_last_prog = -1; + m_timer_on = 0; + m_show_rti = GF_FALSE; + nb_viewpoints = 0; +} + +CMainFrame::~CMainFrame() +{ + 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; + delete m_pWndView; +} + +#define RTI_TIMER 22 +#define RTI_REFRESH_MS 250 + +void CALLBACK EXPORT RTInfoTimer(HWND , UINT , UINT_PTR nID , DWORD ) +{ + char szMsg[100]; + GF_SystemRTInfo rti; + if (nID != RTI_TIMER) return; + Osmo4 *app = GetApp(); + CMainFrame *pFrame = (CMainFrame *) app->m_pMainWnd; + /*shutdown*/ + if (!pFrame) return; + + if (pFrame->m_show_rti && !pFrame->m_timer_on) { + if (!gf_sys_get_rti(RTI_REFRESH_MS, &rti, 0)) return; + if (!rti.gpac_memory) rti.gpac_memory = rti.process_memory ? rti.process_memory : rti.physical_memory; + + if (pFrame->m_show_rti && !pFrame->m_timer_on) { + sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB", + gf_term_get_framerate(app->m_term, GF_FALSE), rti.total_cpu_usage, rti.process_cpu_usage, rti.gpac_memory/1024); + pFrame->m_wndStatusBar.SetPaneText(1, szMsg); + } + } + + if (! gf_term_get_option(app->m_term, GF_OPT_IS_FINISHED)) { + u32 ms = gf_term_get_time_in_ms(app->m_term); + u32 h = ms / 1000 / 3600; + u32 m = ms / 1000 / 60 - h*60; + u32 s = ms / 1000 - h*3600 - m*60; + + sprintf(szMsg, "%02d:%02d.%02d", h, m, s); + pFrame->m_wndStatusBar.SetPaneText(0, szMsg); + } +} + +static UINT status_indics[] = +{ + ID_TIMER, + ID_SEPARATOR, // status line indicator +}; + + + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + UINT buttonArray[50]; + TBBUTTONINFO bi; + u32 *ba; + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + // create a view to occupy the client area of the frame + if (!m_pWndView->CreateEx(0, NULL, NULL, WS_CHILD, 0, 0, 300, 200, m_hWnd, NULL, NULL)) + { + TRACE0("Failed to create view window\n"); + return -1; + } + m_pPlayList = new Playlist(); + m_pPlayList->Create(); + m_pPlayList->ShowWindow(SW_HIDE); + + + if (!m_wndToolBar.CreateEx(this, WS_CHILD | CBRS_TOP | CBRS_FLYBY) || + !m_wndToolBar.LoadBitmap(IDR_MAINTOOLS)) + { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + ba = &buttonArray[0]; + *ba = ID_OPEN_FILE; + ba++; + *ba = ID_SEPARATOR; + ba++; + *ba = ID_NAV_PREV; + ba++; + *ba = ID_NAV_NEXT; + ba++; + *ba = ID_SEPARATOR; + ba++; + *ba = ID_FILE_PLAY; + ba++; + *ba = ID_FILE_STEP; + ba++; + *ba = ID_FILE_STOP; + ba++; + *ba = ID_SEPARATOR; + ba++; + *ba = ID_FILE_PROP; + ba++; + *ba = ID_SEPARATOR; + ba++; + *ba = ID_FILE_PROP; + ba++; + *ba = ID_SWITCH_RENDER; + m_wndToolBar.SetButtons(buttonArray, 13); + m_wndToolBar.SetButtonInfo(0, ID_OPEN_FILE, TBBS_BUTTON, 0); + m_wndToolBar.SetButtonInfo(1, ID_SEPARATOR, TBBS_SEPARATOR, 0); + m_wndToolBar.SetButtonInfo(2, ID_NAV_PREV, TBBS_DROPDOWN, 1); + m_wndToolBar.SetButtonInfo(3, ID_NAV_NEXT, TBBS_DROPDOWN, 2); + m_wndToolBar.SetButtonInfo(4, ID_SEPARATOR, TBBS_SEPARATOR, 0); + m_wndToolBar.SetButtonInfo(5, ID_FILE_PLAY, TBBS_BUTTON, 3); + m_wndToolBar.SetButtonInfo(6, ID_FILE_STEP, TBBS_BUTTON, 5); + m_wndToolBar.SetButtonInfo(7, ID_FILE_STOP, TBBS_BUTTON, 6); + m_wndToolBar.SetButtonInfo(8, ID_SEPARATOR, TBBS_SEPARATOR, 0); + m_wndToolBar.SetButtonInfo(9, ID_FILE_PROP, TBBS_BUTTON, 7); + m_wndToolBar.SetButtonInfo(10, ID_SEPARATOR, TBBS_SEPARATOR, 0); + m_wndToolBar.SetButtonInfo(11, IDD_CONFIGURE, TBBS_BUTTON, 8); + m_wndToolBar.SetButtonInfo(12, ID_SWITCH_RENDER, TBBS_BUTTON, 9); + + CToolBarCtrl &ctrl = m_wndToolBar.GetToolBarCtrl(); + ctrl.SetStyle(TBSTYLE_FLAT | TBSTYLE_DROPDOWN); + ctrl.SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS); + + memset(&bi, 0, sizeof(bi)); + bi.cbSize = sizeof(bi); + ctrl.GetButtonInfo(2, &bi); + bi.fsStyle |= TBSTYLE_DROPDOWN; + ctrl.SetButtonInfo(ID_NAV_PREV, &bi); + + memset(&bi, 0, sizeof(bi)); + bi.cbSize = sizeof(bi); + ctrl.GetButtonInfo(3, &bi); + bi.fsStyle |= TBSTYLE_DROPDOWN; + ctrl.SetButtonInfo(ID_NAV_NEXT, &bi); + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(status_indics, + sizeof(status_indics)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + if (!m_Address.Create(this, IDD_NAVBAR, WS_CHILD | CBRS_TOP | CBRS_FLYBY | CBRS_SIZE_DYNAMIC, IDD_NAVBAR) ) { + return -1; // fail to create + } + + if (!m_Sliders.Create(IDD_SLIDERS, this) ) { + return -1; // fail to create + } + + m_wndStatusBar.SetPaneInfo(0, ID_TIMER, SBPS_NORMAL, 60); + m_wndStatusBar.SetPaneInfo(1, ID_SEPARATOR, SBPS_STRETCH, 0); + SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE); + SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE); + + SetTimer(RTI_TIMER, RTI_REFRESH_MS, RTInfoTimer); + return 0; +} + + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + // TODO: Modify the Window class or styles here by modifying + // the CREATESTRUCT cs + + cs.dwExStyle &= ~WS_EX_CLIENTEDGE; + cs.lpszClass = AfxRegisterWndClass(0); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers +void CMainFrame::OnSetFocus(CWnd* pOldWnd) +{ + m_pWndView->SetFocus(); + if (m_RestoreFS==1) { + m_RestoreFS=2; + } + else if (m_RestoreFS==2) { + m_RestoreFS = 0; + SetFullscreen(); + } +} + +BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + // let the view have first crack at the command + if (m_pWndView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) + return TRUE; + + // otherwise, do default handling + return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); +} + + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + RECT rc2; + u32 tool_h, slide_h, add_h, stat_h; + + if (m_bInitShow) { + CFrameWnd::OnSize(nType, cx, cy); + return; + } + m_wndToolBar.GetClientRect(&rc2); + tool_h = rc2.bottom - rc2.top; + m_Address.GetClientRect(&rc2); + add_h = rc2.bottom - rc2.top; + m_Sliders.GetClientRect(&rc2); + slide_h = rc2.bottom - rc2.top; + m_wndStatusBar.GetClientRect(&rc2); + stat_h = rc2.bottom - rc2.top; + if ((u32) cy <= tool_h+add_h+slide_h+stat_h) { + OnSetSize(cx, 1); + return; + } + + CFrameWnd::OnSize(nType, cx, cy); + cy -= tool_h + add_h + slide_h + stat_h; + + m_Address.SetWindowPos(this, 0, 0, cx, add_h, SWP_SHOWWINDOW | SWP_NOMOVE); + + m_pWndView->ShowWindow(SW_SHOW); + m_pWndView->SetWindowPos(this, 0, add_h + tool_h, cx, cy, SWP_NOZORDER); + + m_Sliders.SetWindowPos(this, 0, add_h + tool_h + cy, cx, slide_h, SWP_NOZORDER|SWP_SHOWWINDOW); + /*and resize term*/ + gf_term_set_size(GetApp()->m_term, cx, cy); +} + + +LRESULT CMainFrame::OnSetSize(WPARAM wParam, LPARAM lParam) +{ + UINT width, height; + width = (UINT) wParam; + height = (UINT) lParam; + if (m_bInitShow) { + m_wndToolBar.UpdateWindow(); + m_wndToolBar.ShowWindow(SW_SHOW); + m_Address.UpdateWindow(); + m_Address.ShowWindow(SW_SHOW); + m_Sliders.UpdateWindow(); + m_Sliders.ShowWindow(SW_SHOW); + m_Sliders.m_PosSlider.EnableWindow(FALSE); + m_pWndView->ShowWindow(SW_SHOW); + ShowWindow(SW_SHOW); + m_bInitShow = GF_FALSE; + } + + RECT winRect; + winRect.left = 0; + winRect.right = width; + winRect.top = 0; + winRect.bottom = height; + AdjustWindowRectEx(&winRect, GetStyle(), TRUE, GetExStyle()); + winRect.bottom -= winRect.top; + winRect.right -= winRect.left; + winRect.left = winRect.top = 0; + + RECT rc2; + m_Address.GetClientRect(&rc2); + winRect.bottom += rc2.bottom; + m_wndToolBar.GetClientRect(&rc2); + winRect.bottom += rc2.bottom; + m_Sliders.GetClientRect(&rc2); + winRect.bottom += rc2.bottom; + m_wndStatusBar.GetClientRect(&rc2); + winRect.bottom += rc2.bottom; + + GetWindowRect(&rc2); + rc2.bottom -= rc2.top; + rc2.right -= rc2.left; + if ((rc2.right != winRect.right) || (rc2.bottom != winRect.bottom)) { + 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); + SetWindowPos(NULL, 0, 0, winRect.right, winRect.bottom, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW); + } + return 0; +} + +void CMainFrame::OnMove(int x, int y) +{ + CFrameWnd::OnMove(x, y); + RECT rc; + + m_wndToolBar.GetClientRect(&rc); + m_wndToolBar.SetWindowPos(this, x, y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + y += rc.bottom - rc.top; + m_Address.SetWindowPos(this, x, y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); + m_Address.GetClientRect(&rc); + y += rc.bottom - rc.top; + m_pWndView->SetWindowPos(this, x, y, 0, 0, SWP_NOSIZE); + m_pWndView->GetClientRect(&rc); + y += rc.bottom; + m_Sliders.SetWindowPos(this, x, y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); +} + + +#define PROGRESS_TIMER 20 +#define PROGRESS_REFRESH_MS 100 + +void CALLBACK EXPORT ProgressTimer(HWND , UINT , UINT_PTR nID , DWORD ) +{ + u32 now; + if (nID != PROGRESS_TIMER) return; + Osmo4 *app = GetApp(); + CMainFrame *pFrame = (CMainFrame *) app->m_pMainWnd; + /*shutdown*/ + if (!pFrame) return; + + now = gf_term_get_time_in_ms(app->m_term); + if (!now) return; + + if (app->can_seek && !pFrame->m_Sliders.m_grabbed) { + if (now >= app->max_duration + 100) { + if (gf_term_get_option(app->m_term, GF_OPT_IS_FINISHED)) { + pFrame->m_pPlayList->PlayNext(); + } + /*if no IsOver go on forever*/ + } else { + if (!app->m_reset) + pFrame->m_Sliders.m_PosSlider.SetPos(now); + } + } +} + +void CMainFrame::SetProgTimer(Bool bOn) +{ + if (bOn) + SetTimer(PROGRESS_TIMER, PROGRESS_REFRESH_MS, ProgressTimer); + else + KillTimer(PROGRESS_TIMER); +} + + +LRESULT CMainFrame::Open(WPARAM wParam, LPARAM lParam) +{ + Bool do_pause; + Osmo4 *app = GetApp(); + CString txt, url; + m_bStartupFile = GF_FALSE; + txt = "Osmo4 - "; + txt += m_pPlayList->GetDisplayName(); + + url = m_pPlayList->GetURL(); + m_Address.m_Address.SetWindowText(url); + SetWindowText(txt); + if (app->start_mode==1) do_pause = GF_TRUE; + else if (app->start_mode==2) do_pause = GF_FALSE; + else do_pause = /*!app->m_AutoPlay*/GF_FALSE; + gf_term_connect_from_time(app->m_term, (LPCSTR) url, app->m_reconnect_time, do_pause); + app->m_reconnect_time = 0; + app->start_mode = 0; + app->UpdatePlayButton(); + nb_viewpoints = 0; + return 1; +} + +LRESULT CMainFrame::NewInstanceOpened(WPARAM wParam, LPARAM lParam) +{ + Bool queue_only = GF_FALSE; + char *url = (char *) static_gpac_get_url(); + if (!strnicmp(url, "-queue ", 7)) { + queue_only = GF_TRUE; + url += 7; + } + m_pPlayList->QueueURL(url); + m_pPlayList->RefreshList(); + if (!queue_only) m_pPlayList->PlayNext(); + return 1; +} + + +void CMainFrame::ForwardMessage() +{ + const MSG *msg = GetCurrentMessage(); + m_pWndView->SendMessage(msg->message, msg->wParam, msg->lParam); +} +void CMainFrame::OnSysKeyUp(UINT , UINT , UINT ) { + ForwardMessage(); +} +void CMainFrame::OnSysKeyDown(UINT , UINT , UINT ) { + ForwardMessage(); +} +void CMainFrame::OnChar(UINT , UINT , UINT ) { + ForwardMessage(); +} +void CMainFrame::OnKeyDown(UINT , UINT , UINT ) { + ForwardMessage(); +} +void CMainFrame::OnKeyUp(UINT , UINT , UINT ) { + ForwardMessage(); +} +void CMainFrame::OnLButtonDown(UINT , CPoint ) { + ForwardMessage(); +} +void CMainFrame::OnLButtonDblClk(UINT , CPoint ) { + ForwardMessage(); +} +void CMainFrame::OnLButtonUp(UINT , CPoint ) { + ForwardMessage(); +} + +void CMainFrame::OnDropFiles(HDROP hDropInfo) +{ + u32 i, count; + Osmo4 *app = GetApp(); + char fileName[MAX_PATH]; + + count = ::DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0); + if (!count) return; + + /*if playing and sub d&d, open sub in current presentation*/ + if (app->m_isopen && (count==1)) { + ::DragQueryFile(hDropInfo, 0, fileName, MAX_PATH); + char *ext = strrchr(fileName, '.'); + if (ext && ( !stricmp(ext, ".srt") || !stricmp(ext, ".sub") || !stricmp(ext, ".ttxt") || !stricmp(ext, ".xml") ) ) { + AddSubtitle(fileName, GF_TRUE); + return; + } + } + + /* if (count==1) + m_pPlayList->Truncate(); + else + */ m_pPlayList->Clear(); + + for (i=0; iQueueURL(fileName); + } + m_pPlayList->RefreshList(); + m_pPlayList->PlayNext(); +} + +void CALLBACK EXPORT ConsoleTimer(HWND , UINT , UINT_PTR , DWORD ) +{ + CMainFrame *pFrame = (CMainFrame *) GetApp()->m_pMainWnd; + + pFrame->m_wndStatusBar.GetStatusBarCtrl().SetIcon(2, NULL); + pFrame->KillTimer(pFrame->m_timer_on); + pFrame->m_timer_on = 0; + pFrame->m_wndStatusBar.SetPaneText(1, "Ready"); +} + +#define CONSOLE_DISPLAY_TIME 1000 + +LRESULT CMainFrame::OnConsoleMessage(WPARAM wParam, LPARAM lParam) +{ + if (m_timer_on) KillTimer(m_timer_on); + + if (console_err>=0) { + m_wndStatusBar.GetStatusBarCtrl().SetIcon(2, m_icomessage); + m_wndStatusBar.SetPaneText(1, console_message); + } else { + char msg[5000]; + m_wndStatusBar.GetStatusBarCtrl().SetIcon(2, m_icoerror); + sprintf(msg, "%s (%s)", console_message, console_service); + m_wndStatusBar.SetPaneText(1, msg); + } + m_timer_on = SetTimer(10, wParam ? (UINT) wParam : CONSOLE_DISPLAY_TIME, ConsoleTimer); + return 0; +} + +BOOL CMainFrame::DestroyWindow() +{ + if (GetApp()->m_isopen) KillTimer(PROGRESS_TIMER); + /*signal close to prevent callbacks but don't close, this is done in ExitInstance (otherwise there's a + deadlock happening not sure why yet)*/ +// GetApp()->m_open = 0; + return CFrameWnd::DestroyWindow(); +} + + +void CMainFrame::OnViewOriginal() +{ + Osmo4 *gpac = GetApp(); + gf_term_set_option(gpac->m_term, GF_OPT_ORIGINAL_VIEW, 1); + OnSetSize(gpac->orig_width, gpac->orig_height); +} + +void CMainFrame::SetFullscreen() +{ + Osmo4 *gpac = GetApp(); + if (!m_bFullScreen) { + GetWindowRect(&backup_wnd_rc); + if (gf_term_set_option(gpac->m_term, GF_OPT_FULLSCREEN, 1) == GF_OK) + m_bFullScreen = GF_TRUE; + } else { + if (gf_term_set_option(gpac->m_term, GF_OPT_FULLSCREEN, 0) == GF_OK) + m_bFullScreen = GF_FALSE; + SetWindowPos(NULL, backup_wnd_rc.left, backup_wnd_rc.top, backup_wnd_rc.right-backup_wnd_rc.left, backup_wnd_rc.bottom-backup_wnd_rc.top, SWP_NOZORDER); + } +} + +void CMainFrame::OnViewFullscreen() +{ + SetFullscreen(); +} + +void CMainFrame::OnArKeep() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); + m_aspect_ratio = GF_ASPECT_RATIO_KEEP; +} + +void CMainFrame::OnArFill() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); + m_aspect_ratio = GF_ASPECT_RATIO_FILL_SCREEN; +} + +void CMainFrame::OnAr43() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); + m_aspect_ratio = GF_ASPECT_RATIO_4_3; +} + +void CMainFrame::OnAr169() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); + m_aspect_ratio = GF_ASPECT_RATIO_16_9; +} + +void CMainFrame::OnUpdateAr169(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_aspect_ratio == GF_ASPECT_RATIO_16_9); +} + +void CMainFrame::OnUpdateAr43(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_aspect_ratio == GF_ASPECT_RATIO_4_3); +} + +void CMainFrame::OnUpdateArFill(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_aspect_ratio == GF_ASPECT_RATIO_FILL_SCREEN); +} + +void CMainFrame::OnUpdateArKeep(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_aspect_ratio == GF_ASPECT_RATIO_KEEP); +} + +void CMainFrame::OnUpdateNavigate(CCmdUI* pCmdUI) +{ + BOOL enable; + Osmo4 *app = GetApp(); + pCmdUI->Enable(FALSE); + if (!app->m_isopen) return; + + u32 type = gf_term_get_option(app->m_term, GF_OPT_NAVIGATION_TYPE); + enable = type ? TRUE : FALSE; + + if (pCmdUI->m_nID==ID_NAV_RESET) { + pCmdUI->Enable(TRUE); + return; + } + + u32 mode = gf_term_get_option(app->m_term, GF_OPT_NAVIGATION); + /*common 2D/3D modes*/ + if (pCmdUI->m_nID==ID_NAVIGATE_NONE) { + pCmdUI->Enable(enable); + pCmdUI->SetCheck(mode ? 0 : 1); + } + else if (pCmdUI->m_nID==ID_NAVIGATE_EXAM) { + pCmdUI->Enable(enable); + pCmdUI->SetCheck((mode==GF_NAVIGATE_EXAMINE) ? 1 : 0); + } + else if (pCmdUI->m_nID==ID_NAVIGATE_SLIDE) { + pCmdUI->Enable(enable); + pCmdUI->SetCheck((mode==GF_NAVIGATE_SLIDE) ? 1 : 0); + } + + if (type==GF_NAVIGATE_TYPE_2D) return; + pCmdUI->Enable(enable); + if (pCmdUI->m_nID==ID_NAVIGATE_WALK) pCmdUI->SetCheck((mode==GF_NAVIGATE_WALK) ? 1 : 0); + else if (pCmdUI->m_nID==ID_NAVIGATE_FLY) pCmdUI->SetCheck((mode==GF_NAVIGATE_FLY) ? 1 : 0); + else if (pCmdUI->m_nID==ID_NAVIGATE_PAN) pCmdUI->SetCheck((mode==GF_NAVIGATE_PAN) ? 1 : 0); + else if (pCmdUI->m_nID==ID_NAVIGATE_VR) pCmdUI->SetCheck((mode==GF_NAVIGATE_VR) ? 1 : 0); + else if (pCmdUI->m_nID==ID_NAVIGATE_GAME) pCmdUI->SetCheck((mode==GF_NAVIGATE_GAME) ? 1 : 0); +} + + +void CMainFrame::SetNavigate(u32 mode) +{ + Osmo4 *app = GetApp(); + gf_term_set_option(app->m_term, GF_OPT_NAVIGATION, mode); +} +void CMainFrame::OnNavigateNone() { + SetNavigate(GF_NAVIGATE_NONE); +} +void CMainFrame::OnNavigateWalk() { + SetNavigate(GF_NAVIGATE_WALK); +} +void CMainFrame::OnNavigateFly() { + SetNavigate(GF_NAVIGATE_FLY); +} +void CMainFrame::OnNavigateExam() { + SetNavigate(GF_NAVIGATE_EXAMINE); +} +void CMainFrame::OnNavigateSlide() { + SetNavigate(GF_NAVIGATE_SLIDE); +} +void CMainFrame::OnNavigatePan() { + SetNavigate(GF_NAVIGATE_PAN); +} +void CMainFrame::OnNavigateOrbit() { + SetNavigate(GF_NAVIGATE_ORBIT); +} +void CMainFrame::OnNavigateVR() { + SetNavigate(GF_NAVIGATE_VR); +} +void CMainFrame::OnNavigateGame() { + SetNavigate(GF_NAVIGATE_GAME); +} + +void CMainFrame::OnNavigateReset() +{ + Osmo4 *app = GetApp(); + gf_term_set_option(app->m_term, GF_OPT_NAVIGATION_TYPE, 0); +} + + +LRESULT CMainFrame::OnNavigate(WPARAM /*wParam*/, LPARAM /*lParam*/) +{ + Osmo4 *gpac = GetApp(); + + /*this is a migrate instruction, just disconnect the player*/ + if (gpac->m_navigate_url.IsEmpty() ) { + gf_term_disconnect(gpac->m_term); + return 0; + } + + if (gf_term_is_supported_url(gpac->m_term, gpac->m_navigate_url, GF_TRUE, gpac->m_NoMimeFetch)) { + char *str = gf_url_concatenate(m_pPlayList->GetURL(), gpac->m_navigate_url); + if (str) { + m_pPlayList->Truncate(); + m_pPlayList->QueueURL(str); + gf_free(str); + m_pPlayList->RefreshList(); + m_pPlayList->PlayNext(); + return 0; + } + } + + if (m_bFullScreen) { + SetFullscreen(); + m_RestoreFS = 1; + } + + console_message = gpac->m_navigate_url; + console_err = GF_OK; + PostMessage(WM_CONSOLEMSG); + ShellExecute(NULL, "open", (LPCSTR) gpac->m_navigate_url, NULL, NULL, SW_SHOWNORMAL); + + return 0; +} + +void CMainFrame::OnFileProp() +{ + if (!m_pProps) { + m_pProps = new CFileProps(this); + m_pProps->Create(this); + } + m_pProps->ShowWindow(SW_SHOW); +} + +void CMainFrame::OnUpdateFileProp(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(GetApp()->m_isopen); +} + +void CMainFrame::OnConfigure() +{ + if (!m_pOpt) { + m_pOpt = new COptions(this); + m_pOpt->Create(this); + } + m_pOpt->ShowWindow(SW_SHOW); +} + +void CMainFrame::OnShortcuts() +{ + MessageBox( + "Open File: Ctrl + O\n" + "Open URL: Ctrl + U\n" + "Reload File: F5\n" + "Pause/Resume File: Ctrl + P\n" + "Step by Step: Ctrl + S\n" + "Seek +5%: Alt + left arrow\n" + "Seek -5%: Alt + right arrow\n" + "Switch quality up: Ctrl + H\n" + "Switch quality down: Ctrl + L\n" + "Fullscreen On/Off: Double-click or Escape\n" + "\n" + "Show Properties: Ctrl + I\n" + "Show Playlist: F3\n" + "Next Playlist Item: Ctrl + right arrow\n" + "Previous Playlist Item: Ctrl + left arrow\n" + "\n" + "Aspect Ratio Normal: Ctrl + 1\n" + "Aspect Ratio Fill: Ctrl + 2\n" + "Aspect Ratio 4/3: Ctrl + 3\n" + "Aspect Ratio 16/9: Ctrl + 4\n" + + + , "Shortcuts Available on Osmo4", MB_OK); +} + +void CMainFrame::OnNavInfo() +{ + MessageBox( + "* Walk & Fly modes:\n" + "\tH move: H pan - V move: Z-translate - V move+CTRL or Wheel: V pan - Right Click (Walk only): Jump\n" + "\tleft/right: H pan - left/right+CTRL: H translate - up/down: Z-translate - up/down+CTRL: V pan\n" + "* Pan mode:\n" + "\tH move: H pan - V move: V pan - V move+CTRL or Wheel: Z-translate\n" + "\tleft/right: H pan - left/right+CTRL: H translate - up/down: V pan - up/down+CTRL: Z-translate\n" + "* Slide mode:\n" + "\tH move: H translate - V move: V translate - V move+CTRL or Wheel: Z-translate\n" + "\tleft/right: H translate - left/right+CTRL: H pan - up/down: V translate - up/down+CTRL: Z-translate\n" + "* Examine & Orbit mode:\n" + "\tH move: Y-Axis rotate - H move+CTRL: Z-Axis rotate - V move: X-Axis rotate - V move+CTRL or Wheel: Z-translate\n" + "\tleft/right: Y-Axis rotate - left/right+CTRL: H translate - up/down: X-Axis rotate - up/down+CTRL: Y-translate\n" + "* VR mode:\n" + "\tH move: H pan - V move: V pan - V move+CTRL or Wheel: Camera Zoom\n" + "\tleft/right: H pan - up/down: V pan - up/down+CTRL: Camera Zoom\n" + "* Game mode (press END to escape):\n" + "\tH move: H pan - V move: V pan\n" + "\tleft/right: H translate - up/down: Z-translate\n" + "\n" + "* All 3D modes: CTRL+PGUP/PGDOWN will zoom in/out camera (field of view) \n" + + "\n" + "*Slide Mode in 2D:\n" + "\tH move: H translate - V move: V translate - V move+CTRL: zoom\n" + "\tleft/right: H translate - up/down: V translate - up/down+CTRL: zoom\n" + "*Examine Mode in 2D (3D renderer only):\n" + "\tH move: Y-Axis rotate - V move: X-Axis rotate\n" + "\tleft/right: Y-Axis rotate - up/down: X-Axis rotate\n" + + "\n" + "HOME: reset navigation to last viewpoint (2D or 3D navigation)\n" + "SHIFT key in all modes: fast movement\n" + + , "3D navigation keys (\'H\'orizontal and \'V\'ertical) used in GPAC", MB_OK); +} + + + +void CMainFrame::BuildViewList() +{ + Osmo4 *app = GetApp(); + if (!app->m_isopen) return; + + /*THIS IS HARCODED FROM THE MENU LAYOUT */ + CMenu *pMenu = GetMenu()->GetSubMenu(1)->GetSubMenu(0); + while (pMenu->GetMenuItemCount()) pMenu->DeleteMenu(0, MF_BYPOSITION); + + s32 id = ID_VP_0; + nb_viewpoints = 0; + while (1) { + const char *szName = NULL; + Bool bound; + GF_Err e = gf_term_get_viewpoint(app->m_term, nb_viewpoints+1, &szName, &bound); + if (e) break; + if (szName) { + pMenu->AppendMenu(MF_ENABLED, id+nb_viewpoints, szName); + } else { + char szLabel[1024]; + sprintf(szLabel, "Viewpoint #%d", nb_viewpoints+1); + pMenu->AppendMenu(MF_ENABLED, id+nb_viewpoints, szLabel); + } + nb_viewpoints++; + if (nb_viewpoints==ID_VP_19-ID_VP_0) break; + } +} + + +void CMainFrame::BuildStreamList(Bool reset_only) +{ + u32 nb_subs; + CMenu *pSelect; + Osmo4 *app = GetApp(); + + pSelect = GetMenu()->GetSubMenu(2)->GetSubMenu(0); + /*THIS IS HARCODED FROM THE MENU LAYOUT */ + CMenu *pMenu = pSelect->GetSubMenu(0); + while (pMenu->GetMenuItemCount()) pMenu->DeleteMenu(0, MF_BYPOSITION); + pMenu = pSelect->GetSubMenu(1); + while (pMenu->GetMenuItemCount()) pMenu->DeleteMenu(0, MF_BYPOSITION); + pMenu = pSelect->GetSubMenu(2); + while (pMenu->GetMenuItemCount()) pMenu->DeleteMenu(0, MF_BYPOSITION); + + if (reset_only) { + m_bFirstStreamQuery = GF_TRUE; + return; + } + if (!app->m_isopen || !gf_term_get_option(app->m_term, GF_OPT_CAN_SELECT_STREAMS)) return; + + GF_ObjectManager *root_od = gf_term_get_root_object(app->m_term); + if (!root_od) return; + u32 count = gf_term_get_object_count(app->m_term, root_od); + nb_subs = 0; + + for (u32 i=0; im_term, root_od, i); + if (!odm) return; + + if (gf_term_get_object_info(app->m_term, odm, &info) != GF_OK) break; + if (info.owns_service) { + char *szName = (char *)strrchr(info.service_url, '\\'); + if (!szName) szName = (char *)strrchr(info.service_url, '/'); + if (!szName) szName = (char *) info.service_url; + else szName += 1; + strcpy(szLabel, szName); + szName = strrchr(szLabel, '.'); + if (szName) szName[0] = 0; + } + + switch (info.od_type) { + case GF_STREAM_AUDIO: + pMenu = pSelect->GetSubMenu(0); + if (!info.owns_service) { + if (info.lang) { + sprintf(szLabel, "Language %s (ID %d)", gf_4cc_to_str(info.lang), info.od->objectDescriptorID); + } else { + sprintf(szLabel, "ID %d", info.od->objectDescriptorID); + } + } + pMenu->AppendMenu(MF_ENABLED, ID_SELOBJ_0 + i, szLabel); + break; + case GF_STREAM_VISUAL: + pMenu = pSelect->GetSubMenu(1); + if (!info.owns_service) sprintf(szLabel, "ID %d", info.od->objectDescriptorID); + pMenu->AppendMenu(MF_ENABLED, ID_SELOBJ_0 + i, szLabel); + break; + case GF_STREAM_TEXT: + nb_subs ++; + pMenu = pSelect->GetSubMenu(2); + if (!info.owns_service) { + if (info.lang) { + sprintf(szLabel, "Language %s (ID %d)", gf_4cc_to_str(info.lang), info.od->objectDescriptorID); + } else { + sprintf(szLabel, "ID %d", info.od->objectDescriptorID); + } + } + pMenu->AppendMenu(MF_ENABLED, ID_SELOBJ_0 + i, szLabel); + break; + } + } + if (m_bFirstStreamQuery) { + m_bFirstStreamQuery = GF_FALSE; + if (!nb_subs && app->m_LookForSubtitles) LookForSubtitles(); + } + +} + +BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) +{ + int ID = LOWORD(wParam); + Osmo4 *app = GetApp(); + + if ( (ID>=ID_VP_0) && (ID<=ID_VP_0+nb_viewpoints)) { + ID -= ID_VP_0; + gf_term_set_viewpoint(app->m_term, ID+1, NULL); + return TRUE; + } + if ( (ID>=ID_NAV_PREV_0) && (ID<=ID_NAV_PREV_9)) { + ID -= ID_NAV_PREV_0; + s32 prev = m_pPlayList->m_cur_entry - ID; + if (prev>=0) { + m_pPlayList->m_cur_entry = prev; + m_pPlayList->PlayPrev(); + } + return TRUE; + } + if ( (ID>=ID_NAV_NEXT_0) && (ID<=ID_NAV_NEXT_9)) { + ID -= ID_NAV_NEXT_0; + u32 next = m_pPlayList->m_cur_entry + ID; + if (next < gf_list_count(m_pPlayList->m_entries) ) { + m_pPlayList->m_cur_entry = next; + m_pPlayList->PlayNext(); + } + return TRUE; + } + if ( (ID>=ID_SELOBJ_0) && (ID<=ID_SELOBJ_29)) { + ID -= ID_SELOBJ_0; + GF_ObjectManager *root_od = gf_term_get_root_object(app->m_term); + if (!root_od) return TRUE; + GF_ObjectManager *odm = gf_term_get_object(app->m_term, root_od, ID); + gf_term_select_object(app->m_term, odm); + return TRUE; + } + if ( (ID>=ID_SETCHAP_FIRST) && (ID<=ID_SETCHAP_LAST)) { + ID -= ID_SETCHAP_FIRST; + gf_term_play_from_time(app->m_term, (u32) (1000*m_chapters_start[ID]), 0); + return TRUE; + } + return CFrameWnd::OnCommand(wParam, lParam); +} + +void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT ID, BOOL bSys) +{ + Osmo4 *app = GetApp(); + /*viewport list*/ + if (pPopupMenu->GetMenuItemID(0)==ID_VP_0) { + for (int i=0; im_term, i+1, &szName, &bound); + pPopupMenu->EnableMenuItem(i, MF_BYPOSITION); + if (bound) pPopupMenu->CheckMenuItem(i, MF_BYPOSITION | MF_CHECKED); + } + return; + } + /*navigation*/ + if ((pPopupMenu->GetMenuItemID(0)==ID_NAV_PREV_0) || (pPopupMenu->GetMenuItemID(0)==ID_NAV_NEXT_0)) { + int count = pPopupMenu->GetMenuItemCount(); + for (int i=0; iEnableMenuItem(i, MF_BYPOSITION); + } + return; + } + /*stream selection*/ + if (pPopupMenu->m_hMenu == GetMenu()->GetSubMenu(2)->m_hMenu) { + if (!app->m_isopen || !gf_term_get_option(app->m_term, GF_OPT_CAN_SELECT_STREAMS)) { + pPopupMenu->EnableMenuItem(0, MF_BYPOSITION | MF_DISABLED | MF_GRAYED); + } else { + pPopupMenu->EnableMenuItem(0, MF_BYPOSITION | MF_ENABLED); + } + } + if ((pPopupMenu->GetMenuItemID(0)>=ID_SELOBJ_0) && (pPopupMenu->GetMenuItemID(0)<=ID_SELOBJ_29)) { + GF_ObjectManager *root_od = gf_term_get_root_object(app->m_term); + if (!root_od) return; + + int count = pPopupMenu->GetMenuItemCount(); + for (int i=0; iGetMenuItemID(i) - ID_SELOBJ_0; + GF_ObjectManager *odm = gf_term_get_object(app->m_term, root_od, id); + if (!odm) { + pPopupMenu->EnableMenuItem(i, MF_DISABLED | MF_BYPOSITION); + } else { + GF_MediaInfo info; + + gf_term_get_object_info(app->m_term, odm, &info); + pPopupMenu->EnableMenuItem(i, MF_BYPOSITION); + pPopupMenu->CheckMenuItem(i, MF_BYPOSITION | (info.status ? MF_CHECKED : MF_UNCHECKED) ); + } + } + return; + } + /*chapters*/ + if (pPopupMenu->m_hMenu == GetMenu()->GetSubMenu(2)->m_hMenu) { + if (!app->m_isopen || !m_num_chapters) { + pPopupMenu->EnableMenuItem(1, MF_BYPOSITION | MF_DISABLED | MF_GRAYED); + } else { + pPopupMenu->EnableMenuItem(1, MF_BYPOSITION | MF_ENABLED); + } + } + if ((pPopupMenu->GetMenuItemID(0)>=ID_SETCHAP_FIRST) && (pPopupMenu->GetMenuItemID(0)<=ID_SETCHAP_LAST)) { + Double now = gf_term_get_time_in_ms(app->m_term); + now /= 1000; + + int count = pPopupMenu->GetMenuItemCount(); + for (int i=0; iGetMenuItemID(i) - ID_SETCHAP_FIRST; + pPopupMenu->EnableMenuItem(i, MF_BYPOSITION); + + Bool is_current = GF_FALSE; + if (m_chapters_start[id]<=now) { + if (id+1now) is_current = GF_TRUE; + } else { + is_current = GF_TRUE; + } + } + pPopupMenu->CheckMenuItem(i, MF_BYPOSITION | (is_current ? MF_CHECKED : MF_UNCHECKED)); + } + return; + } + /*default*/ + CFrameWnd::OnInitMenuPopup(pPopupMenu, ID, bSys); +} + +void CMainFrame::OnCollideDisp() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_COLLISION, GF_COLLISION_DISPLACEMENT); +} + +void CMainFrame::OnUpdateCollideDisp(CCmdUI* pCmdUI) +{ + Osmo4 *gpac = GetApp(); + pCmdUI->Enable(gpac->m_isopen); + pCmdUI->SetCheck( (gf_term_get_option(gpac->m_term, GF_OPT_COLLISION) == GF_COLLISION_DISPLACEMENT) ? 1 : 0); +} + +void CMainFrame::OnCollideNone() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_COLLISION, GF_COLLISION_NONE); +} + +void CMainFrame::OnUpdateCollideNone(CCmdUI* pCmdUI) +{ + Osmo4 *gpac = GetApp(); + pCmdUI->Enable(gpac->m_isopen); + pCmdUI->SetCheck( (gf_term_get_option(gpac->m_term, GF_OPT_COLLISION) == GF_COLLISION_NONE) ? 1 : 0); +} + +void CMainFrame::OnCollideReg() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_COLLISION, GF_COLLISION_NORMAL); +} + +void CMainFrame::OnUpdateCollideReg(CCmdUI* pCmdUI) +{ + Osmo4 *gpac = GetApp(); + pCmdUI->Enable(gpac->m_isopen); + pCmdUI->SetCheck( (gf_term_get_option(gpac->m_term, GF_OPT_COLLISION) == GF_COLLISION_NORMAL) ? 1 : 0); +} + +void CMainFrame::OnHeadlight() +{ + Osmo4 *app = GetApp(); + Bool val = gf_term_get_option(app->m_term, GF_OPT_HEADLIGHT) ? GF_FALSE : GF_TRUE; + gf_term_set_option(app->m_term, GF_OPT_HEADLIGHT, val); +} + +void CMainFrame::OnUpdateHeadlight(CCmdUI* pCmdUI) +{ + Osmo4 *app = GetApp(); + pCmdUI->Enable(FALSE); + if (!app->m_isopen) return; + u32 type = gf_term_get_option(app->m_term, GF_OPT_NAVIGATION_TYPE); + if (type!=GF_NAVIGATE_TYPE_3D) return; + + pCmdUI->Enable(TRUE); + pCmdUI->SetCheck(gf_term_get_option(app->m_term, GF_OPT_HEADLIGHT) ? 1 : 0); +} + +void CMainFrame::OnGravity() +{ + Osmo4 *app = GetApp(); + Bool val = gf_term_get_option(app->m_term, GF_OPT_GRAVITY) ? GF_FALSE : GF_TRUE; + gf_term_set_option(app->m_term, GF_OPT_GRAVITY, val); +} + +void CMainFrame::OnUpdateGravity(CCmdUI* pCmdUI) +{ + Osmo4 *app = GetApp(); + pCmdUI->Enable(FALSE); + if (!app->m_isopen) return; + u32 type = gf_term_get_option(app->m_term, GF_OPT_NAVIGATION_TYPE); + if (type!=GF_NAVIGATE_TYPE_3D) return; + type = gf_term_get_option(app->m_term, GF_OPT_NAVIGATION); + if (type != GF_NAVIGATE_WALK) return; + pCmdUI->Enable(TRUE); + pCmdUI->SetCheck(gf_term_get_option(app->m_term, GF_OPT_GRAVITY) ? 1 : 0); +} + + +BOOL CMainFrame::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) +{ + + if (((LPNMHDR)lParam)->code == TBN_DROPDOWN) { + RECT rc; + s32 i, count, start; + POINT pt; + CMenu *pPopup = new CMenu(); + pPopup->CreatePopupMenu(); + + m_wndToolBar.GetWindowRect(&rc); + pt.y = rc.bottom; + pt.x = rc.left; + m_wndToolBar.GetToolBarCtrl().GetItemRect(0, &rc); + pt.x += (rc.right - rc.left); + m_wndToolBar.GetToolBarCtrl().GetItemRect(1, &rc); + pt.x += (rc.right - rc.left); + + count = gf_list_count(m_pPlayList->m_entries); + if ( ((LPNMTOOLBAR)lParam)->iItem == ID_NAV_PREV) { + start = m_pPlayList->m_cur_entry - 1; + for (i=0; i<10; i++) { + if (start - i < 0) break; + if (start - i >= count) break; + PLEntry *ple = (PLEntry *) gf_list_get(m_pPlayList->m_entries, start - i); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_NAV_PREV_0 + i, ple->m_disp_name); + } + } else { + start = m_pPlayList->m_cur_entry + 1; + for (i=0; i<10; i++) { + if (start + i >= count) break; + PLEntry *ple = (PLEntry *) gf_list_get(m_pPlayList->m_entries, start + i); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_NAV_NEXT_0 + i, ple->m_disp_name); + } + m_wndToolBar.GetToolBarCtrl().GetItemRect(2, &rc); + pt.x += (rc.right - rc.left); + } + pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this); + delete pPopup; + + return FALSE; + } + return CFrameWnd::OnNotify(wParam, lParam, pResult); +} + +void CMainFrame::OnNavNext() +{ + Osmo4 *app = GetApp(); + /*don't play if last could trigger playlist loop*/ + if ((m_pPlayList->m_cur_entry<0) || (gf_list_count(m_pPlayList->m_entries) == 1 + (u32) m_pPlayList->m_cur_entry)) return; + m_pPlayList->PlayNext(); +} + +void CMainFrame::OnUpdateNavNext(CCmdUI* pCmdUI) +{ + if (m_pPlayList->m_cur_entry<0) pCmdUI->Enable(FALSE); + else if ((u32) m_pPlayList->m_cur_entry + 1 == gf_list_count(m_pPlayList->m_entries) ) pCmdUI->Enable(FALSE); + else pCmdUI->Enable(TRUE); +} + +void CMainFrame::OnNavPrev() +{ + Osmo4 *app = GetApp(); + if (m_pPlayList->m_cur_entry<=0) return; + m_pPlayList->PlayPrev(); +} + +void CMainFrame::OnUpdateNavPrev(CCmdUI* pCmdUI) +{ + if (m_pPlayList->m_cur_entry<=0) pCmdUI->Enable(FALSE); + else pCmdUI->Enable(TRUE); +} + + +void CMainFrame::OnClearNav() +{ + m_pPlayList->ClearButPlaying(); +} + +void CMainFrame::OnViewPlaylist() +{ + m_pPlayList->ShowWindow(m_pPlayList->IsWindowVisible() ? SW_HIDE : SW_SHOW); +} + +void CMainFrame::OnUpdateViewPlaylist(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_pPlayList->IsWindowVisible() ? 1 : 0); +} +void CMainFrame::OnPlaylistLoop() +{ + GetApp()->m_Loop = GetApp()->m_Loop ? GF_FALSE : GF_TRUE; + gf_cfg_set_key(GetApp()->m_user.config, "General", "PlaylistLoop", GetApp()->m_Loop ? "yes" : "no"); +} + +void CMainFrame::OnUpdatePlaylistLoop(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(GetApp()->m_Loop ? GF_TRUE : GF_FALSE); +} + +void CMainFrame::OnAddSubtitle() +{ + CFileDialog fd(TRUE,NULL,NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "All Subtitles|*.srt;*.sub;*.ttxt;*.xml|SRT Subtitles|*.srt|SUB Subtitles|*.sub|3GPP TimedText|*.ttxt|QuckTime TeXML|*.xml|"); + if (fd.DoModal() != IDOK) return; + + AddSubtitle(fd.GetPathName(), GF_TRUE); +} + +void CMainFrame::AddSubtitle(const char *fileName, Bool auto_play) +{ + gf_term_add_object(GetApp()->m_term, fileName, auto_play); +} + +static Bool subs_enum_dir_item(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) +{ + CMainFrame *_this = (CMainFrame *)cbck; + _this->AddSubtitle(item_path, GF_FALSE); + return GF_FALSE; +} + +void CMainFrame::LookForSubtitles() +{ + char dir[GF_MAX_PATH]; + CString url = m_pPlayList->GetURL(); + strcpy(dir, url); + char *sep = strrchr(dir, '\\'); + if (!sep) ::GetCurrentDirectory(GF_MAX_PATH, dir); + else sep[0] = 0; + + gf_enum_directory(dir, GF_FALSE, subs_enum_dir_item, this, "ttxt;srt"); +} + +void CMainFrame::OnCacheEnable() +{ + Osmo4 *app = GetApp(); + u32 state = gf_term_get_option(app->m_term, GF_OPT_MEDIA_CACHE); + if (state==GF_MEDIA_CACHE_DISABLED) { + gf_term_set_option(app->m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_ENABLED); + } else if (state==GF_MEDIA_CACHE_DISABLED) { + gf_term_set_option(app->m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); + } +} + +void CMainFrame::OnUpdateCacheEnable(CCmdUI* pCmdUI) +{ + Osmo4 *app = GetApp(); + u32 state = gf_term_get_option(app->m_term, GF_OPT_MEDIA_CACHE); + switch (state) { + case GF_MEDIA_CACHE_ENABLED: + pCmdUI->SetText("Enabled"); + pCmdUI->Enable(TRUE); + break; + case GF_MEDIA_CACHE_RUNNING: + pCmdUI->SetText("Running"); + pCmdUI->Enable(FALSE); + break; + case GF_MEDIA_CACHE_DISABLED: + pCmdUI->SetText("Disabled"); + break; + } +} + +void CMainFrame::OnUpdateCacheStop(CCmdUI* pCmdUI) +{ + Osmo4 *app = GetApp(); + u32 state = gf_term_get_option(app->m_term, GF_OPT_MEDIA_CACHE); + pCmdUI->Enable( (state==GF_MEDIA_CACHE_RUNNING) ? TRUE : FALSE); +} + +void CMainFrame::OnCacheStop() +{ + Osmo4 *app = GetApp(); + gf_term_set_option(app->m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); +} +void CMainFrame::OnCacheAbort() +{ + Osmo4 *app = GetApp(); + gf_term_set_option(app->m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISCARD); +} + +void CMainFrame::OnFileExit() +{ + DestroyWindow(); +} + + +void CMainFrame::BuildChapterList(Bool reset_only) +{ + CMenu *pChaps; + GF_MediaInfo odi; + NetInfoCommand com; + Osmo4 *app = GetApp(); + + /*THIS IS HARCODED FROM THE MENU LAYOUT */ + pChaps = GetMenu()->GetSubMenu(2)->GetSubMenu(1); + while (pChaps->GetMenuItemCount()) pChaps->DeleteMenu(0, MF_BYPOSITION); + + if (m_chapters_start) gf_free(m_chapters_start); + m_chapters_start = NULL; + m_num_chapters = 0; + if (reset_only) return; + + GF_ObjectManager *root_od = gf_term_get_root_object(app->m_term); + if (!root_od) return; + if (gf_term_get_object_info(app->m_term, root_od, &odi) != GF_OK) return; + + u32 count = gf_list_count(odi.od->OCIDescriptors); + m_num_chapters = 0; + for (u32 i=0; iOCIDescriptors, i); + if (seg->tag != GF_ODF_SEGMENT_TAG) continue; + + if (seg->SegmentName && strlen((const char *)seg->SegmentName)) { + strcpy(szLabel, (const char *) seg->SegmentName); + } else { + sprintf(szLabel, "Chapter #%02d", m_num_chapters+1); + } + pChaps->AppendMenu(MF_ENABLED, ID_SETCHAP_FIRST + m_num_chapters, szLabel); + + 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++; + } + + /*get any service info*/ + if (!m_bStartupFile && gf_term_get_service_info(app->m_term, root_od, &com) == GF_OK) { + CString title(""); + if (com.track_info) { + title.Format("%02d ", (u32) (com.track_info>>16) ); + } + if (com.artist) { + title += com.artist; + title += " "; + } + if (com.name) { + title += com.name; + title += " "; + } + if (com.album) { + title += "("; + title += com.album; + title += ")"; + } + + if (title.GetLength()) SetWindowText(title); + } +} + +void CMainFrame::OnViewCPU() +{ + m_show_rti = m_show_rti ? GF_FALSE : GF_TRUE; +} + +void CMainFrame::OnUpdateViewCPU(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(TRUE); + pCmdUI->SetCheck(m_show_rti); +} + + +void CMainFrame::OnFileCopy() +{ + size_t len; + const char *text = gf_term_get_text_selection(GetApp()->m_term, GF_FALSE); + if (!text) return; + + if (!IsClipboardFormatAvailable(CF_TEXT)) return; + if (!OpenClipboard()) return; + EmptyClipboard(); + + len = strlen(text); + if (!len) return; + + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(char)); + LPTSTR lptstrCopy = (char *) GlobalLock(hglbCopy); + memcpy(lptstrCopy, text, len * sizeof(char)); + lptstrCopy[len] = 0; + GlobalUnlock(hglbCopy); + SetClipboardData(CF_TEXT, hglbCopy); + CloseClipboard(); +} + +void CMainFrame::OnUpdateFileCopy(CCmdUI* pCmdUI) +{ + Osmo4 *app = GetApp(); + if (IsClipboardFormatAvailable(CF_TEXT) + && app->m_term + && (gf_term_get_text_selection(app->m_term, GF_TRUE)!=NULL) + ) { + pCmdUI->Enable(TRUE); + } else { + pCmdUI->Enable(FALSE); + } +} + + +void CMainFrame::OnFilePaste() +{ + if (!IsClipboardFormatAvailable(CF_TEXT)) return; + if (!OpenClipboard()) return; + + HGLOBAL hglbCopy = GetClipboardData(CF_TEXT); + if (hglbCopy) { + LPTSTR lptstrCopy = (char *) GlobalLock(hglbCopy); + gf_term_paste_text(GetApp()->m_term, lptstrCopy, GF_FALSE); + GlobalUnlock(hglbCopy); + } + CloseClipboard(); +} + +void CMainFrame::OnUpdateFilePaste(CCmdUI* pCmdUI) +{ + Osmo4 *app = GetApp(); + if (IsClipboardFormatAvailable(CF_TEXT) + && app->m_term + && (gf_term_paste_text(app->m_term, NULL, GF_TRUE)==GF_OK) + ) { + pCmdUI->Enable(TRUE); + } else { + pCmdUI->Enable(FALSE); + } +} + + diff --git a/applications/deprecated/old_arch/osmo4_w32/MainFrm.h b/applications/deprecated/old_arch/osmo4_w32/MainFrm.h new file mode 100644 index 0000000..14d0e31 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/MainFrm.h @@ -0,0 +1,224 @@ +// MainFrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__3666B63B_D886_4F0B_9953_A2AF09E3C15A__INCLUDED_) +#define AFX_MAINFRM_H__3666B63B_D886_4F0B_9953_A2AF09E3C15A__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include +#include +#include +#include + +#include "FileProps.h" +#include "Options.h" +#include "AddressBar.h" +#include "Sliders.h" +#include "Playlist.h" + + +class CChildView : public CWnd +{ +// Construction +public: + CChildView(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CChildView) +protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CChildView(); + + // Generated message map functions +protected: + //{{AFX_MSG(CChildView) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +class CMainFrame : public CFrameWnd +{ + +public: + CMainFrame(); +protected: + DECLARE_DYNAMIC(CMainFrame) + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) +public: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + virtual BOOL DestroyWindow(); +protected: + virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +public: + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + Sliders m_Sliders; + AddressBar m_Address; + CFileProps *m_pProps; + COptions *m_pOpt; + Playlist *m_pPlayList; + CChildView *m_pWndView; + Bool m_bFullScreen; + u32 m_RestoreFS; + UINT_PTR m_timer_on; + CString console_message; + CString console_service; + GF_Err console_err; + u32 m_aspect_ratio; + RECT backup_wnd_rc; + Bool m_bFirstStreamQuery; + /*filter progress events to avoid killing importers with status bar text display...*/ + s32 m_last_prog; + Bool m_show_rti; + Bool m_bStartupFile; + +public: + void SetFullscreen(); + void BuildViewList(); + void BuildStreamList(Bool reset_ony); + void BuildChapterList(Bool reset_ony); + void SetProgTimer(Bool bOn); + void AddSubtitle(const char *fileName, Bool auto_play); + +private: + void ForwardMessage(); + HICON m_icoerror, m_icomessage; + s32 nb_viewpoints; + Bool m_bInitShow; + + void SetNavigate(u32 mode); + void LookForSubtitles(); + + Double *m_chapters_start; + u32 m_num_chapters; + + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSetFocus(CWnd *pOldWnd); + afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); + afx_msg BOOL OnCommand(WPARAM wParam, LPARAM lParam); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnMove(int x, int y); + afx_msg LRESULT OnSetSize(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnNavigate(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT Open(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT NewInstanceOpened(WPARAM wParam, LPARAM lParam); + + afx_msg void OnLButtonDown(UINT nFlags, CPoint point); + afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); + afx_msg void OnLButtonUp(UINT nFlags, CPoint point); + afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ); + afx_msg void OnSysKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ); + afx_msg void OnSysKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags ); + afx_msg void OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ); + afx_msg void OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags ); + afx_msg void OnDropFiles(HDROP hDropInfo); + afx_msg LRESULT OnConsoleMessage(WPARAM wParam, LPARAM lParam); + afx_msg void OnViewOriginal(); + afx_msg void OnViewFullscreen(); + afx_msg void OnArKeep(); + afx_msg void OnArFill(); + afx_msg void OnAr43(); + afx_msg void OnAr169(); + afx_msg void OnUpdateAr169(CCmdUI* pCmdUI); + afx_msg void OnUpdateAr43(CCmdUI* pCmdUI); + afx_msg void OnUpdateArFill(CCmdUI* pCmdUI); + afx_msg void OnUpdateArKeep(CCmdUI* pCmdUI); + afx_msg void OnNavigateNone(); + afx_msg void OnNavigateWalk(); + afx_msg void OnNavigateFly(); + afx_msg void OnNavigateExam(); + afx_msg void OnNavigateSlide(); + afx_msg void OnNavigatePan(); + afx_msg void OnNavigateOrbit(); + afx_msg void OnNavigateGame(); + afx_msg void OnNavigateVR(); + afx_msg void OnNavigateReset(); + afx_msg void OnShortcuts(); + afx_msg void OnConfigure(); + afx_msg void OnFileProp(); + afx_msg void OnViewPlaylist(); + afx_msg void OnUpdateFileProp(CCmdUI* pCmdUI); + afx_msg void OnUpdateNavigate(CCmdUI* pCmdUI); + afx_msg void OnCacheEnable(); + afx_msg void OnUpdateCacheEnable(CCmdUI* pCmdUI); + afx_msg void OnCacheStop(); + afx_msg void OnCacheAbort(); + afx_msg void OnUpdateCacheStop(CCmdUI* pCmdUI); + afx_msg void OnCollideDisp(); + afx_msg void OnUpdateCollideDisp(CCmdUI* pCmdUI); + afx_msg void OnCollideNone(); + afx_msg void OnUpdateCollideNone(CCmdUI* pCmdUI); + afx_msg void OnCollideReg(); + afx_msg void OnUpdateCollideReg(CCmdUI* pCmdUI); + afx_msg void OnHeadlight(); + afx_msg void OnUpdateHeadlight(CCmdUI* pCmdUI); + afx_msg void OnGravity(); + afx_msg void OnUpdateGravity(CCmdUI* pCmdUI); + afx_msg void OnNavInfo(); + afx_msg void OnNavNext(); + afx_msg void OnNavPrev(); + afx_msg void OnUpdateNavNext(CCmdUI* pCmdUI); + afx_msg void OnUpdateNavPrev(CCmdUI* pCmdUI); + afx_msg void OnClearNav(); + afx_msg void OnUpdateViewPlaylist(CCmdUI* pCmdUI); + afx_msg void OnPlaylistLoop(); + afx_msg void OnUpdatePlaylistLoop(CCmdUI* pCmdUI); + afx_msg void OnAddSubtitle(); + afx_msg void OnFileExit(); + afx_msg void OnViewCPU(); + afx_msg void OnUpdateViewCPU(CCmdUI* pCmdUI); + afx_msg void OnFileCopy(); + afx_msg void OnUpdateFileCopy(CCmdUI* pCmdUI); + afx_msg void OnFilePaste(); + afx_msg void OnUpdateFilePaste(CCmdUI* pCmdUI); + + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__3666B63B_D886_4F0B_9953_A2AF09E3C15A__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/OpenUrl.cpp b/applications/deprecated/old_arch/osmo4_w32/OpenUrl.cpp new file mode 100644 index 0000000..a0b1076 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/OpenUrl.cpp @@ -0,0 +1,98 @@ +// OpenUrl.cpp : implementation file +// + +#include "stdafx.h" +#include "Osmo4.h" +#include "OpenUrl.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// COpenUrl dialog + + +COpenUrl::COpenUrl(CWnd* pParent /*=NULL*/) + : CDialog(COpenUrl::IDD, pParent) +{ + //{{AFX_DATA_INIT(COpenUrl) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void COpenUrl::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COpenUrl) + DDX_Control(pDX, IDC_COMBOURL, m_URLs); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COpenUrl, CDialog) + //{{AFX_MSG_MAP(COpenUrl) + ON_BN_CLICKED(IDC_BUTGO, OnButgo) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + + + +#define MAX_LAST_FILES 20 +void UpdateLastFiles(GF_Config *cfg, const char *URL) +{ + u32 nb_entries; + gf_cfg_set_key(cfg, "RecentFiles", URL, NULL); + gf_cfg_insert_key(cfg, "RecentFiles", URL, "", 0); + /*remove last entry if needed*/ + nb_entries = gf_cfg_get_key_count(cfg, "RecentFiles"); + if (nb_entries>MAX_LAST_FILES) { + gf_cfg_set_key(cfg, "RecentFiles", gf_cfg_get_key_name(cfg, "RecentFiles", nb_entries-1), NULL); + } +} + + +///////////////////////////////////////////////////////////////////////////// +// COpenUrl message handlers + +void COpenUrl::OnButgo() +{ + CString URL; + int sel = m_URLs.GetCurSel(); + if (sel == CB_ERR) { + m_URLs.GetWindowText(URL); + } else { + m_URLs.GetLBText(sel, URL); + } + if (!URL.GetLength()) { + EndDialog(IDCANCEL); + return; + } + + Osmo4 *gpac = GetApp(); + + m_url = URL; + UpdateLastFiles(gpac->m_user.config, (const char *) URL); + EndDialog(IDOK); +} + +BOOL COpenUrl::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + u32 i=0; + + while (m_URLs.GetCount()) m_URLs.DeleteString(0); + while (1) { + const char *sOpt = gf_cfg_get_key_name(gpac->m_user.config, "RecentFiles", i); + if (!sOpt) break; + m_URLs.AddString(sOpt); + i++; + } + return TRUE; +} diff --git a/applications/deprecated/old_arch/osmo4_w32/OpenUrl.h b/applications/deprecated/old_arch/osmo4_w32/OpenUrl.h new file mode 100644 index 0000000..ecd9a43 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/OpenUrl.h @@ -0,0 +1,49 @@ +#if !defined(AFX_OPENURL_H__ADB51A74_305E_4183_8D44_03EEB83D2BFA__INCLUDED_) +#define AFX_OPENURL_H__ADB51A74_305E_4183_8D44_03EEB83D2BFA__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// OpenUrl.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// COpenUrl dialog + +class COpenUrl : public CDialog +{ +// Construction +public: + COpenUrl(CWnd* pParent = NULL); // standard constructor + CString m_url; + +// Dialog Data + //{{AFX_DATA(COpenUrl) + enum { IDD = IDD_OPENFILE }; + CComboBox m_URLs; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COpenUrl) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COpenUrl) + afx_msg void OnBrowse(); + afx_msg void OnButgo(); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OPENURL_H__ADB51A74_305E_4183_8D44_03EEB83D2BFA__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/Options.cpp b/applications/deprecated/old_arch/osmo4_w32/Options.cpp new file mode 100644 index 0000000..3fb3e05 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Options.cpp @@ -0,0 +1,2080 @@ +// Options.cpp : implementation file +// + +#include "stdafx.h" +#include "Osmo4.h" +#include "MainFrm.h" + +#include +#include +#include +#include +#include + +#include +#include "Options.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// COptions dialog + + +COptions::COptions(CWnd* pParent /*=NULL*/) + : CDialog(COptions::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptions) + //}}AFX_DATA_INIT +} + + +void COptions::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptions) + DDX_Control(pDX, IDC_SELECT, m_Selector); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptions, CDialog) + //{{AFX_MSG_MAP(COptions) + ON_BN_CLICKED(IDC_SAVEOPT, OnSaveopt) + ON_WM_CLOSE() + ON_WM_DESTROY() + ON_CBN_SELCHANGE(IDC_SELECT, OnSelchangeSelect) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +BOOL COptions::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_general.Create(IDD_OPT_GEN, this); + m_systems.Create(IDD_OPT_SYSTEMS, this); + m_render.Create(IDD_OPT_RENDER, this); + m_render2d.Create(IDD_OPT_RENDER2D, this); + m_render3d.Create(IDD_OPT_RENDER3D, this); + m_decoder.Create(IDD_OPT_DECODER, this); + m_audio.Create(IDD_OPT_AUDIO, this); + m_video.Create(IDD_OPT_VIDEO, this); + m_http.Create(IDD_OPT_HTTP, this); + m_font.Create(IDD_OPT_FONT, this); + m_stream.Create(IDD_OPT_STREAM, this); + m_cache.Create(IDD_OPT_MCACHE, this); + m_files.Create(IDD_OPT_FILETYPES, this); + m_logs.Create(IDD_OPT_LOGS, this); + + m_Selector.AddString("General"); + m_Selector.AddString("MPEG-4 Systems"); + m_Selector.AddString("Media Decoders"); + m_Selector.AddString("Compositor"); + m_Selector.AddString("2D Drawing"); + m_Selector.AddString("3D Drawing"); + m_Selector.AddString("Video Output"); + m_Selector.AddString("Audio Output"); + m_Selector.AddString("Text Engine"); + m_Selector.AddString("File Download"); + m_Selector.AddString("Real-Time Streaming"); + m_Selector.AddString("Streaming Cache"); + m_Selector.AddString("File Types"); + m_Selector.AddString("Log System"); + + HideAll(); + + const char *sOpt = gf_cfg_get_key(GetApp()->m_user.config, "General", "ConfigPanel"); + u32 sel = sOpt ? atoi(sOpt) : 0; + if (sel>13) sel=13; + m_Selector.SetCurSel(sel); + m_general.ShowWindow(SW_SHOW); + + OnSelchangeSelect(); + + return TRUE; +} + + +///////////////////////////////////////////////////////////////////////////// +// COptions message handlers + +void COptions::HideAll() +{ + m_general.ShowWindow(SW_HIDE); + m_systems.ShowWindow(SW_HIDE); + m_render.ShowWindow(SW_HIDE); + m_render2d.ShowWindow(SW_HIDE); + m_render3d.ShowWindow(SW_HIDE); + m_audio.ShowWindow(SW_HIDE); + m_video.ShowWindow(SW_HIDE); + m_http.ShowWindow(SW_HIDE); + m_font.ShowWindow(SW_HIDE); + m_stream.ShowWindow(SW_HIDE); + m_decoder.ShowWindow(SW_HIDE); + m_cache.ShowWindow(SW_HIDE); + m_files.ShowWindow(SW_HIDE); + m_files.ShowWindow(SW_HIDE); + m_logs.ShowWindow(SW_HIDE); +} + +void COptions::OnSelchangeSelect() +{ + HideAll(); + switch (m_Selector.GetCurSel()) { + case 0: + m_general.ShowWindow(SW_SHOW); + break; + case 1: + m_systems.ShowWindow(SW_SHOW); + break; + case 2: + m_decoder.ShowWindow(SW_SHOW); + break; + case 3: + m_render.ShowWindow(SW_SHOW); + break; + case 4: + m_render2d.ShowWindow(SW_SHOW); + break; + case 5: + m_render3d.ShowWindow(SW_SHOW); + break; + case 6: + m_video.ShowWindow(SW_SHOW); + break; + case 7: + m_audio.ShowWindow(SW_SHOW); + break; + case 8: + m_font.ShowWindow(SW_SHOW); + break; + case 9: + m_http.ShowWindow(SW_SHOW); + break; + case 10: + m_stream.ShowWindow(SW_SHOW); + break; + case 11: + m_cache.ShowWindow(SW_SHOW); + break; + case 12: + m_files.ShowWindow(SW_SHOW); + break; + case 13: + m_logs.ShowWindow(SW_SHOW); + break; + } +} + +void COptions::OnSaveopt() +{ + m_general.SaveOptions(); + m_systems.SaveOptions(); + m_decoder.SaveOptions(); + m_render.SaveOptions(); + m_render2d.SaveOptions(); + m_render3d.SaveOptions(); + m_audio.SaveOptions(); + m_video.SaveOptions(); + m_http.SaveOptions(); + m_font.SaveOptions(); + m_stream.SaveOptions(); + m_cache.SaveOptions(); + m_logs.SaveOptions(); + + Osmo4 *gpac = GetApp(); + gf_term_set_option(gpac->m_term, GF_OPT_RELOAD_CONFIG, 1); + m_render2d.SetYUV(); +} + +void COptions::OnClose() +{ + char str[20]; + sprintf(str, "%d", m_Selector.GetCurSel()); + gf_cfg_set_key(GetApp()->m_user.config, "General", "ConfigPanel", str); + + DestroyWindow(); +} + +void COptions::OnDestroy() +{ + CDialog::OnDestroy(); + delete this; + ((CMainFrame *)GetApp()->m_pMainWnd)->m_pOpt = NULL; +} + + +COptGen::COptGen(CWnd* pParent /*=NULL*/) + : CDialog(COptGen::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptGen) + //}}AFX_DATA_INIT +} + + +void COptGen::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptGen) + DDX_Control(pDX, IDC_LOOKFORSUB, m_LookForSubs); + DDX_Control(pDX, IDC_DUMP_XMT, m_ViewXMT); + DDX_Control(pDX, IDC_NO_CONSOLE, m_NoConsole); + DDX_Control(pDX, IDC_LOOP, m_Loop); + DDX_Control(pDX, IDC_SINGLE_INSTANCE, m_SingleInstance); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptGen, CDialog) + //{{AFX_MSG_MAP(COptGen) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptGen message handlers + + + +BOOL COptGen::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "Loop"); + m_Loop.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "LookForSubtitles"); + m_LookForSubs.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "ConsoleOff"); + m_NoConsole.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "ViewXMT"); + m_ViewXMT.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "SingleInstance"); + m_SingleInstance.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + return TRUE; +} + +void COptGen::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + + gpac->m_Loop = (Bool) m_Loop.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "Loop", gpac->m_Loop ? "yes" : "no"); + gpac->m_LookForSubtitles = (Bool) m_LookForSubs.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "LookForSubtitles", gpac->m_LookForSubtitles ? "yes" : "no"); + gpac->m_NoConsole = (Bool) m_NoConsole.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "ConsoleOff", gpac->m_NoConsole ? "yes" : "no"); + gpac->m_ViewXMTA = (Bool) m_ViewXMT.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "ViewXMT", gpac->m_ViewXMTA ? "yes" : "no"); + gpac->m_SingleInstance = (Bool) m_SingleInstance.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "SingleInstance", gpac->m_SingleInstance ? "yes" : "no"); +} + +COptSystems::COptSystems(CWnd* pParent /*=NULL*/) + : CDialog(COptSystems::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptSystems) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void COptSystems::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptSystems) + DDX_Control(pDX, IDC_FORCE_DURATION, m_ForceDuration); + DDX_Control(pDX, IDC_DEC_THREAD, m_Threading); + DDX_Control(pDX, IDC_BIFSDROP, m_LateFramesAlwaysDrawn); + DDX_Control(pDX, IDC_LANG, m_Lang); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptSystems, CDialog) + //{{AFX_MSG_MAP(COptSystems) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptSystems message handlers + + + + + +BOOL COptSystems::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "Language3CC"); + if (!sOpt) sOpt = "eng"; + s32 select = 0; + while (m_Lang.GetCount()) m_Lang.DeleteString(0); + u32 i, count = gf_lang_get_count(); + for (i=0; im_user.config, "Systems", "ThreadingPolicy"); + select = 0; + while (m_Threading.GetCount()) m_Threading.DeleteString(0); + m_Threading.AddString("Single Thread"); + m_Threading.AddString("Mutli Thread"); + if (sOpt && !stricmp(sOpt, "Multi")) select = 1; + m_Threading.AddString("Free"); + if (sOpt && !stricmp(sOpt, "Free")) select = 2; + m_Threading.SetCurSel(select); + + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "ForceSingleClock"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_ForceDuration.SetCheck(1); + } else { + m_ForceDuration.SetCheck(0); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "DrawLateFrames"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_LateFramesAlwaysDrawn.SetCheck(1); + } else { + m_LateFramesAlwaysDrawn.SetCheck(0); + } + + + return TRUE; +} + + +void COptSystems::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + + s32 sel = m_Lang.GetCurSel(); + u32 i=0; + + gf_cfg_set_key(gpac->m_user.config, "Systems", "LanguageName", gf_lang_get_name(i) ); + gf_cfg_set_key(gpac->m_user.config, "Systems", "Language3CC", gf_lang_get_3cc(i) ); + gf_cfg_set_key(gpac->m_user.config, "Systems", "Language2CC", gf_lang_get_2cc(i) ); + + sel = m_Threading.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Systems", "ThreadingPolicy", (sel==0) ? "Single" : ( (sel==1) ? "Multi" : "Free")); + gf_cfg_set_key(gpac->m_user.config, "Systems", "ForceSingleClock", m_ForceDuration.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Systems", "DrawLateFrames", m_LateFramesAlwaysDrawn.GetCheck() ? "yes" : "no"); +} + + +OptDecoder::OptDecoder(CWnd* pParent /*=NULL*/) + : CDialog(OptDecoder::IDD, pParent) +{ + //{{AFX_DATA_INIT(OptDecoder) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void OptDecoder::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(OptDecoder) + DDX_Control(pDX, IDC_VIDEC_LIST, m_Video); + DDX_Control(pDX, IDC_AUDEC_LIST, m_Audio); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(OptDecoder, CDialog) + //{{AFX_MSG_MAP(OptDecoder) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// OptDecoder message handlers + + + +BOOL OptDecoder::OnInitDialog() +{ + u32 i; + const char *sOpt; + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + + /*audio dec enum*/ + while (m_Audio.GetCount()) m_Audio.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "DefAudioDec"); + u32 count = gf_modules_get_count(gpac->m_user.modules); + GF_BaseDecoder *ifce; + s32 select = 0; + s32 to_sel = 0; + for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); + if (!ifce) continue; + + if (ifce->CanHandleStream(ifce, GF_STREAM_AUDIO, NULL, 0)) { + if (sOpt && !stricmp(ifce->module_name, sOpt)) select = to_sel; + m_Audio.AddString(ifce->module_name); + to_sel++; + } + gf_modules_close_interface((GF_BaseInterface *)ifce); + } + m_Audio.SetCurSel(select); + + /*video dec enum*/ + while (m_Video.GetCount()) m_Video.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "DefVideoDec"); + count = gf_modules_get_count(gpac->m_user.modules); + select = 0; + to_sel = 0; + for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); + if (!ifce) continue; + + if (ifce->CanHandleStream(ifce, GF_STREAM_VISUAL, NULL, 0)) { + if (sOpt && !stricmp(ifce->module_name, sOpt)) select = to_sel; + m_Video.AddString(ifce->module_name); + to_sel++; + } + gf_modules_close_interface((GF_BaseInterface *)ifce); + } + m_Video.SetCurSel(select); + return TRUE; +} + +void OptDecoder::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + char str[100]; + m_Audio.GetWindowText(str, 100); + gf_cfg_set_key(gpac->m_user.config, "Systems", "DefAudioDec", str); + m_Video.GetWindowText(str, 100); + gf_cfg_set_key(gpac->m_user.config, "Systems", "DefVideoDec", str); + +} + +COptRender::COptRender(CWnd* pParent /*=NULL*/) + : CDialog(COptRender::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptRender) + //}}AFX_DATA_INIT +} + + +void COptRender::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptRender) + DDX_Control(pDX, IDC_DRAW_BOUNDS, m_DrawBounds); + DDX_Control(pDX, IDC_GD_LIST, m_Graphics); + DDX_Control(pDX, IDC_USE_RENDER3D, m_Use3DRender); + DDX_Control(pDX, IDC_AA_LIST, m_AntiAlias); + DDX_Control(pDX, IDC_FORCE_SIZE, m_ForceSize); + DDX_Control(pDX, IDC_FAST_RENDER, m_HighSpeed); + DDX_Control(pDX, IDC_BIFS_RATE, m_BIFSRate); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptRender, CDialog) + //{{AFX_MSG_MAP(COptRender) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptRender message handlers + + + +#define NUM_RATES 11 +static char *BIFSRates[11] = +{ + "5.0", + "7.5", + "10.0", + "12.5", + "15.0", + "24.0", + "25.0", + "30.0", + "50.0", + "60.0", + "100.0", +}; + + + +BOOL COptRender::OnInitDialog() +{ + s32 i; + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "OpenGLMode"); + m_Use3DRender.SetCheck( (sOpt && !strcmp(sOpt, "always")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "ForceSceneSize"); + m_ForceSize.SetCheck( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "FrameRate"); + if (!sOpt) sOpt = "30.0"; + s32 select = 0; + while (m_BIFSRate.GetCount()) m_BIFSRate.DeleteString(0); + for (i = 0; im_user.config, "Compositor", "HighSpeed"); + m_HighSpeed.SetCheck( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "AntiAlias"); + while (m_AntiAlias.GetCount()) m_AntiAlias.DeleteString(0); + + m_AntiAlias.AddString("None"); + m_AntiAlias.AddString("Text only"); + m_AntiAlias.AddString("Complete"); + select = 2; + if (sOpt && !stricmp(sOpt, "Text")) select = 1; + else if (sOpt && !stricmp(sOpt, "None")) select = 0; + m_AntiAlias.SetCurSel(select); + + /*graphics driver enum*/ + while (m_Graphics.GetCount()) m_Graphics.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "core", "raster2d"); + s32 count = gf_modules_get_count(gpac->m_user.modules); + GF_BaseInterface *ifce; + select = 0; + u32 to_sel = 0; + for (i=0; im_user.modules, i, GF_RASTER_2D_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(ifce->module_name, sOpt)) select = to_sel; + m_Graphics.AddString(ifce->module_name); + gf_modules_close_interface(ifce); + to_sel++; + } + m_Graphics.SetCurSel(select); + + + m_DrawBounds.AddString("None"); + m_DrawBounds.AddString("Box/Rect"); + m_DrawBounds.AddString("AABB Tree"); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "BoundingVolume"); + if (sOpt && !stricmp(sOpt, "Box")) m_DrawBounds.SetCurSel(1); + else if (sOpt && !stricmp(sOpt, "AABB")) m_DrawBounds.SetCurSel(2); + else m_DrawBounds.SetCurSel(0); + + return TRUE; +} + + +Bool COptRender::SaveOptions() +{ + char str[50]; + Osmo4 *gpac = GetApp(); + + gf_cfg_set_key(gpac->m_user.config, "Compositor", "HighSpeed", m_HighSpeed.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "ForceSceneSize", m_ForceSize.GetCheck() ? "yes" : "no"); + + s32 sel = m_BIFSRate.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "FrameRate", BIFSRates[sel]); + + sel = m_AntiAlias.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "AntiAlias", (sel==0) ? "None" : ( (sel==1) ? "Text" : "All")); + + sel = m_DrawBounds.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "BoundingVolume", (sel==2) ? "AABB" : (sel==1) ? "Box" : "None"); + + m_Graphics.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "core", "raster2d", str); + + gf_cfg_set_key(gpac->m_user.config, "Compositor", "OpenGLMode", m_Use3DRender.GetCheck() ? "always" : "disable"); + return GF_FALSE; +} + + +COptRender2D::COptRender2D(CWnd* pParent /*=NULL*/) + : CDialog(COptRender2D::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptRender2D) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void COptRender2D::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptRender2D) + DDX_Control(pDX, IDC_FORMAT_YUV, m_YUVFormat); + DDX_Control(pDX, IDC_YUV, m_NoYUV); + DDX_Control(pDX, IDC_ZOOM_SCALABLE, m_Scalable); + DDX_Control(pDX, IDC_DIRECTRENDER, m_DirectRender); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptRender2D, CDialog) + //{{AFX_MSG_MAP(COptRender2D) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptRender2D message handlers + +BOOL COptRender2D::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + 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); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "ScalableZoom"); + if (sOpt && !stricmp(sOpt, "no")) { + m_Scalable.SetCheck(0); + } else { + m_Scalable.SetCheck(1); + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "DisableYUV"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_NoYUV.SetCheck(1); + } else { + m_NoYUV.SetCheck(0); + } + + SetYUV(); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void COptRender2D::SetYUV() +{ + Osmo4 *gpac = GetApp(); + u32 yuv_format = gf_term_get_option(gpac->m_term, GF_OPT_YUV_FORMAT); + if (!yuv_format) { + m_YUVFormat.SetWindowText("(No YUV used)"); + } else { + char str[100]; + sprintf(str, "(%s used)", gf_4cc_to_str(yuv_format)); + m_YUVFormat.SetWindowText(str); + } +} + +void COptRender2D::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + 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"); +} + + +COptRender3D::COptRender3D(CWnd* pParent /*=NULL*/) + : CDialog(COptRender3D::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptRender3D) + //}}AFX_DATA_INIT +} + + +void COptRender3D::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptRender3D) + DDX_Control(pDX, IDC_BITMAP_USE_PIXEL, m_BitmapPixels); + DDX_Control(pDX, IDC_DISABLE_TX_RECT, m_DisableTXRect); + DDX_Control(pDX, IDC_RASTER_OUTLINE, m_RasterOutlines); + DDX_Control(pDX, IDC_EMUL_POW2, m_EmulPow2); + DDX_Control(pDX, IDC_DISABLE_POLY_AA, m_PolyAA); + DDX_Control(pDX, IDC_DRAW_NORMALS, m_DrawNormals); + DDX_Control(pDX, IDC_BACK_CULL, m_BackCull); + DDX_Control(pDX, IDC_DRAW_MODE, m_Wireframe); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptRender3D, CDialog) + //{{AFX_MSG_MAP(COptRender3D) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptRender3D message handlers + + +BOOL COptRender3D::OnInitDialog() +{ + CDialog::OnInitDialog(); + + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + m_DrawNormals.AddString("Never"); + m_DrawNormals.AddString("Per Face"); + m_DrawNormals.AddString("Per Vertex"); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "DrawNormals"); + if (sOpt && !stricmp(sOpt, "PerFace")) m_DrawNormals.SetCurSel(1); + else if (sOpt && !stricmp(sOpt, "PerVertex")) m_DrawNormals.SetCurSel(2); + else m_DrawNormals.SetCurSel(0); + + m_BackCull.AddString("Off"); + m_BackCull.AddString("On"); + m_BackCull.AddString("Alpha"); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "BackFaceCulling"); + if (sOpt && !stricmp(sOpt, "Off")) m_BackCull.SetCurSel(0); + else if (sOpt && !stricmp(sOpt, "Alpha")) m_BackCull.SetCurSel(2); + else m_BackCull.SetCurSel(1); + + m_Wireframe.AddString("Solid"); + m_Wireframe.AddString("Wireframe"); + m_Wireframe.AddString("Both"); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "Wireframe"); + if (sOpt && !stricmp(sOpt, "WireOnly")) m_Wireframe.SetCurSel(1); + else if (sOpt && !stricmp(sOpt, "WireOnSolid")) m_Wireframe.SetCurSel(2); + else m_Wireframe.SetCurSel(0); + + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "RasterOutlines"); + m_RasterOutlines.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "EmulatePOW2"); + m_EmulPow2.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "PolygonAA"); + m_PolyAA.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "BitmapCopyPixels"); + m_BitmapPixels.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "DisableRectExt"); + m_DisableTXRect.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void COptRender3D::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + + u32 sel = m_DrawNormals.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "DrawNormals", (sel==2) ? "PerVertex" : (sel==1) ? "PerFace" : "Never"); + sel = m_BackCull.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "BackFaceCulling", (sel==2) ? "Alpha" : (sel==1) ? "On" : "Off"); + sel = m_Wireframe.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "Wireframe", (sel==2) ? "WireOnSolid" : (sel==1) ? "WireOnly" : "WireNone"); + + gf_cfg_set_key(gpac->m_user.config, "Compositor", "RasterOutlines", m_RasterOutlines.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "EmulatePOW2", m_EmulPow2.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "PolygonAA", m_PolyAA.GetCheck() ? "yes" : "no"); + + gf_cfg_set_key(gpac->m_user.config, "Compositor", "DisableRectExt", m_DisableTXRect.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "BitmapCopyPixels", m_BitmapPixels.GetCheck() ? "yes" : "no"); +} + +COptVideo::COptVideo(CWnd* pParent /*=NULL*/) + : CDialog(COptVideo::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptVideo) + //}}AFX_DATA_INIT +} + + +void COptVideo::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptVideo) + DDX_Control(pDX, IDC_SWITCH_RES, m_SwitchRes); + DDX_Control(pDX, IDC_VIDEO_LIST, m_Videos); + DDX_Control(pDX, IDC_HWMEMORY, m_UseHWMemory); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptVideo, CDialog) + //{{AFX_MSG_MAP(COptVideo) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptVideo message handlers + +BOOL COptVideo::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + m_SwitchRes.SetCheck(gf_cfg_get_bool(gpac->m_user.config, "core", "switch-vres") ); + sOpt = gf_cfg_get_bool(gpac->m_user.config, "core", "hwvmem"); + m_UseHWMemory.SetCheck(sOpt && !stricmp(sOpt, "Always") ? 1 : 0); + + + u32 count = gf_modules_get_count(gpac->m_user.modules); + GF_BaseInterface *ifce; + s32 to_sel = 0; + s32 select = 0; + /*video drivers enum*/ + while (m_Videos.GetCount()) m_Videos.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "core", "video-output"); + + for (u32 i=0; im_user.modules, i, GF_VIDEO_OUTPUT_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(ifce->module_name, sOpt)) select = to_sel; + m_Videos.AddString(ifce->module_name); + gf_modules_close_interface(ifce); + to_sel++; + } + m_Videos.SetCurSel(select); + + return TRUE; + +} + +void COptVideo::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + char str[50]; + + gf_cfg_set_key(gpac->m_user.config, "core", "switch-vres", m_SwitchRes.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "core", "hwvmem", m_UseHWMemory.GetCheck() ? "Always" : "Auto"); + m_Videos.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "core", "video-output", str); +} + + +COptAudio::COptAudio(CWnd* pParent /*=NULL*/) + : CDialog(COptAudio::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptAudio) + //}}AFX_DATA_INIT +} + + +void COptAudio::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptAudio) + DDX_Control(pDX, IDC_AUDIO_NOTIFS, m_Notifs); + DDX_Control(pDX, IDC_DRIVER_LIST, m_DriverList); + DDX_Control(pDX, IDC_AUDIO_RESYNC, m_AudioResync); + DDX_Control(pDX, IDC_AUDIO_MULTICH, m_AudioMultiCH); + DDX_Control(pDX, IDC_AUDIO_FPS, m_AudioDur); + DDX_Control(pDX, IDC_SPIN_FPS, m_SpinFPS); + DDX_Control(pDX, IDC_FORCE_AUDIO, m_ForceConfig); + DDX_Control(pDX, IDC_SPIN_AUDIO, m_AudioSpin); + DDX_Control(pDX, IDC_EDIT_AUDIO, m_AudioEdit); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptAudio, CDialog) + //{{AFX_MSG_MAP(COptAudio) + ON_BN_CLICKED(IDC_FORCE_AUDIO, OnForceAudio) + ON_CBN_SELCHANGE(IDC_DRIVER_LIST, OnSelchangeDriverList) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptAudio message handlers + +BOOL COptAudio::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_AudioSpin.SetBuddy(& m_AudioEdit); + m_SpinFPS.SetBuddy(& m_AudioDur); + m_SpinFPS.SetRange(0, 2000); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "ForceConfig"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_ForceConfig.SetCheck(1); + } else { + m_ForceConfig.SetCheck(0); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "NumBuffers"); + if (sOpt) { + m_AudioEdit.SetWindowText(sOpt); + } else { + m_AudioEdit.SetWindowText("2"); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "TotalDuration"); + if (sOpt) { + m_AudioDur.SetWindowText(sOpt); + } else { + m_AudioDur.SetWindowText("120"); + } + + OnForceAudio(); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "NoResync"); + m_AudioResync.SetCheck( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "DisableMultiChannel"); + m_AudioMultiCH.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + /*driver enum*/ + while (m_DriverList.GetCount()) m_DriverList.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "core", "audio-output"); + u32 count = gf_modules_get_count(gpac->m_user.modules); + GF_BaseInterface *ifce; + s32 select = 0; + s32 to_sel = 0; + for (u32 i=0; im_user.modules, i, GF_AUDIO_OUTPUT_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(ifce->module_name, sOpt)) select = to_sel; + m_DriverList.AddString(ifce->module_name); + gf_modules_close_interface(ifce); + to_sel++; + } + m_DriverList.SetCurSel(select); + + m_Notifs.ShowWindow(SW_HIDE); + if (sOpt && strstr(sOpt, "DirectSound")) m_Notifs.ShowWindow(SW_SHOW); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "DisableNotification"); + if (sOpt && !stricmp(sOpt, "yes")) + m_Notifs.SetCheck(1); + else + m_Notifs.SetCheck(0); + + return TRUE; +} + + +void COptAudio::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + char str[50]; + + gf_cfg_set_key(gpac->m_user.config, "Audio", "ForceConfig", m_ForceConfig.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Audio", "NoResync", m_AudioResync.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Audio", "DisableMultiChannel", m_AudioMultiCH.GetCheck() ? "yes" : "no"); + + m_AudioEdit.GetWindowText(str, 20); + gf_cfg_set_key(gpac->m_user.config, "Audio", "NumBuffers", str); + m_AudioDur.GetWindowText(str, 20); + gf_cfg_set_key(gpac->m_user.config, "Audio", "TotalDuration", str); + + m_DriverList.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "core", "audio-output", str); + + if (strstr(str, "DirectSound")) { + gf_cfg_set_key(gpac->m_user.config, "Audio", "DisableNotification", m_Notifs.GetCheck() ? "yes" : "no"); + } + +} + +void COptAudio::OnForceAudio() +{ + BOOL en = m_ForceConfig.GetCheck(); + + m_AudioSpin.EnableWindow(en); + m_AudioEdit.EnableWindow(en); + m_SpinFPS.EnableWindow(en); + m_AudioDur.EnableWindow(en); +} + +void COptAudio::OnSelchangeDriverList() +{ + char str[50]; + m_DriverList.GetWindowText(str, 50); + if (strstr(str, "DirectSound")) { + m_Notifs.ShowWindow(SW_SHOW); + } else { + m_Notifs.ShowWindow(SW_HIDE); + } +} + + + + +COptFont::COptFont(CWnd* pParent /*=NULL*/) + : CDialog(COptFont::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptFont) + //}}AFX_DATA_INIT +} + + +void COptFont::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptFont) + DDX_Control(pDX, IDC_TEXTURE_MODE, m_TextureModes); + DDX_Control(pDX, IDC_FONT_LIST, m_Fonts); + DDX_Control(pDX, IDC_BROWSE_FONT, m_BrowseFont); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptFont, CDialog) + //{{AFX_MSG_MAP(COptFont) + ON_BN_CLICKED(IDC_BROWSE_FONT, OnBrowseFont) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptFont message handlers + +BOOL COptFont::OnInitDialog() +{ + u32 i; + GF_BaseInterface *ifce; + + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + /*video drivers enum*/ + while (m_Fonts.GetCount()) m_Fonts.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "FontCache", "FontReader"); + s32 to_sel = 0; + s32 select = 0; + u32 count = gf_modules_get_count(gpac->m_user.modules); + for (i=0; im_user.modules, i, GF_FONT_READER_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(ifce->module_name, sOpt)) select = to_sel; + m_Fonts.AddString(ifce->module_name); + gf_modules_close_interface(ifce); + to_sel++; + } + m_Fonts.SetCurSel(select); + + + sOpt = gf_cfg_get_key(gpac->m_user.config, "FontCache", "FontDirectory"); + if (sOpt) m_BrowseFont.SetWindowText(sOpt); + + /*text texturing modes*/ + while (m_TextureModes.GetCount()) m_TextureModes.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "TextureTextMode"); + m_TextureModes.AddString("Default"); + m_TextureModes.AddString("Never"); + m_TextureModes.AddString("Always"); + if (sOpt && !stricmp(sOpt, "3D")) m_TextureModes.SetCurSel(1); + else if (sOpt && !stricmp(sOpt, "Always")) m_TextureModes.SetCurSel(2); + else m_TextureModes.SetCurSel(0); + + return TRUE; +} + + + +static char szCacheDir[MAX_PATH]; + +static int CALLBACK LocCbck(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) +{ + char dir[MAX_PATH]; + if (uMsg == BFFM_INITIALIZED) { + strcpy(dir, szCacheDir); + SendMessage(hwnd, BFFM_SETSELECTION, TRUE,(LPARAM) dir); + } + return 0; +} + +void COptFont::OnBrowseFont() +{ + BROWSEINFO brw; + LPMALLOC pMalloc; + LPITEMIDLIST ret; + char dir[MAX_PATH]; + + if (NOERROR == ::SHGetMalloc(&pMalloc) ) { + + m_BrowseFont.GetWindowText(szCacheDir, MAX_PATH); + + memset(&brw, 0, sizeof(BROWSEINFO)); + brw.hwndOwner = this->GetSafeHwnd(); + brw.pszDisplayName = dir; + brw.lpszTitle = "Select Font Directory..."; + brw.ulFlags = 0L; + brw.lpfn = LocCbck; + + ret = SHBrowseForFolder(&brw); + if (ret != NULL) { + if (::SHGetPathFromIDList(ret, dir)) { + m_BrowseFont.SetWindowText(dir); + } + pMalloc->Free(ret); + } + pMalloc->Release(); + } +} + + +void COptFont::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + char str[MAX_PATH]; + + m_Fonts.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "FontCache", "FontReader", str); + m_BrowseFont.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "FontCache", "FontDirectory", str); + switch (m_TextureModes.GetCurSel()) { + case 2: + gf_cfg_set_key(gpac->m_user.config, "Compositor", "TextureTextMode", "Always"); + break; + case 1: + gf_cfg_set_key(gpac->m_user.config, "Compositor", "TextureTextMode", "Never"); + break; + default: + gf_cfg_set_key(gpac->m_user.config, "Compositor", "TextureTextMode", "Default"); + break; + } +} + + +COptHTTP::COptHTTP(CWnd* pParent /*=NULL*/) + : CDialog(COptHTTP::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptHTTP) + //}}AFX_DATA_INIT +} + + +void COptHTTP::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptHTTP) + DDX_Control(pDX, IDC_HTTP_PROXY, m_ProxyName); + DDX_Control(pDX, IDC_HTTP_USE_PROXY, m_useProxy); + DDX_Control(pDX, IDC_SAX_DELAY, m_SAXDuration); + DDX_Control(pDX, IDC_SAX_PROGRESSIVE, m_Progressive); + DDX_Control(pDX, IDC_RESTART_CACHE, m_DisableCache); + DDX_Control(pDX, IDC_CLEAN_CACHE, m_CleanCache); + DDX_Control(pDX, IDC_BROWSE_CACHE, m_CacheDir); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptHTTP, CDialog) + //{{AFX_MSG_MAP(COptHTTP) + ON_BN_CLICKED(IDC_BROWSE_CACHE, OnBrowseCache) + ON_BN_CLICKED(IDC_SAX_PROGRESSIVE, OnSaxProgressive) + ON_BN_CLICKED(IDC_HTTP_USE_PROXY, OnUseProxy) + //}}AFX_MSG_MAP + ON_BN_CLICKED(IDC_RESTART_CACHE, &COptHTTP::OnBnClickedRestartCache) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptHTTP message handlers + + +void COptHTTP::OnBrowseCache() +{ + BROWSEINFO brw; + LPMALLOC pMalloc; + LPITEMIDLIST ret; + char dir[MAX_PATH]; + + if (NOERROR == ::SHGetMalloc(&pMalloc) ) { + + m_CacheDir.GetWindowText(szCacheDir, MAX_PATH); + + memset(&brw, 0, sizeof(BROWSEINFO)); + brw.hwndOwner = this->GetSafeHwnd(); + brw.pszDisplayName = dir; + brw.lpszTitle = "Select HTTP Cache Directory..."; + brw.ulFlags = 0L; + brw.lpfn = LocCbck; + + ret = SHBrowseForFolder(&brw); + if (ret != NULL) { + if (::SHGetPathFromIDList(ret, dir)) { + m_CacheDir.SetWindowText(dir); + } + pMalloc->Free(ret); + } + pMalloc->Release(); + } +} + +BOOL COptHTTP::OnInitDialog() +{ + char proxy[GF_MAX_PATH]; + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "CacheDirectory"); + if (sOpt) m_CacheDir.SetWindowText(sOpt); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "CleanCache"); + m_CleanCache.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "DisableCache"); + m_DisableCache.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "SAXLoader", "Progressive"); + m_Progressive.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + OnSaxProgressive(); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "SAXLoader", "MaxDuration"); + if (sOpt) { + m_SAXDuration.SetWindowText(sOpt); + } else { + m_SAXDuration.SetWindowText("0"); + } + //if (m_Progressive.GetCheck()) m_SAXDuration.EnableWindow(1); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "HTTPProxyEnabled"); + m_useProxy.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + OnUseProxy(); + strcpy(proxy, ""); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "HTTPProxyName"); + if (sOpt) { + strcpy(proxy, sOpt); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "HTTPProxyPort"); + if (sOpt) { + strcat(proxy, ":"); + strcat(proxy, sOpt); + } + } + m_ProxyName.SetWindowText(proxy); + return TRUE; +} + +void COptHTTP::OnSaxProgressive() +{ + if (m_Progressive.GetCheck()) { + m_SAXDuration.EnableWindow(1); + } else { + m_SAXDuration.EnableWindow(0); + } +} + + +void COptHTTP::OnUseProxy() +{ + if (m_useProxy.GetCheck()) { + m_ProxyName.EnableWindow(1); + } else { + m_ProxyName.EnableWindow(0); + } +} + +void COptHTTP::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + + gf_cfg_set_key(gpac->m_user.config, "Core", "CleanCache", m_CleanCache.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Core", "DisableCache", m_DisableCache.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "SAXLoader", "Progressive", m_Progressive.GetCheck() ? "yes" : "no"); + + m_SAXDuration.GetWindowText(szCacheDir, MAX_PATH); + gf_cfg_set_key(gpac->m_user.config, "SAXLoader", "MaxDuration", szCacheDir); + + gf_cfg_set_key(gpac->m_user.config, "Core", "HTTPProxyEnabled", m_useProxy.GetCheck() ? "yes" : "no"); + m_ProxyName.GetWindowText(szCacheDir, MAX_PATH); + char *sep = strrchr(szCacheDir, ':'); + if (sep) { + sep[0] = 0; + gf_cfg_set_key(gpac->m_user.config, "Core", "HTTPProxyName", szCacheDir); + sep[0] = ':'; + gf_cfg_set_key(gpac->m_user.config, "Core", "HTTPProxyPort", sep+1); + } else { + gf_cfg_set_key(gpac->m_user.config, "Core", "HTTPProxyName", szCacheDir); + gf_cfg_set_key(gpac->m_user.config, "Core", "HTTPProxyPort", NULL); + } + m_CacheDir.GetWindowText(szCacheDir, MAX_PATH); + gf_cfg_set_key(gpac->m_user.config, "Core", "CacheDirectory", szCacheDir); +} + + +COptStream::COptStream(CWnd* pParent /*=NULL*/) + : CDialog(COptStream::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptStream) + //}}AFX_DATA_INIT +} + + +void COptStream::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptStream) + DDX_Control(pDX, IDC_REBUFFER_LEN, m_RebufferLen); + DDX_Control(pDX, IDC_REBUFFER, m_Rebuffer); + DDX_Control(pDX, IDC_BUFFER, m_Buffer); + DDX_Control(pDX, IDC_TIMEOUT, m_Timeout); + DDX_Control(pDX, IDC_REORDER, m_Reorder); + DDX_Control(pDX, IDC_RTSP, m_UseRTSP); + DDX_Control(pDX, IDC_PORT, m_Port); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptStream, CDialog) + //{{AFX_MSG_MAP(COptStream) + ON_CBN_SELCHANGE(IDC_PORT, OnSelchangePort) + ON_BN_CLICKED(IDC_RTSP, OnRtsp) + ON_BN_CLICKED(IDC_REBUFFER, OnRebuffer) + ON_EN_UPDATE(IDC_REBUFFER_LEN, OnUpdateRebufferLen) + ON_EN_UPDATE(IDC_BUFFER, OnUpdateBuffer) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptStream message handlers + +BOOL COptStream::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + while (m_Port.GetCount()) m_Port.DeleteString(0); + m_Port.AddString("554 (RTSP standard)"); + m_Port.AddString("7070 (RTSP ext)"); + m_Port.AddString("80 (RTSP / HTTP tunnel)"); + m_Port.AddString("8080 (RTSP / HTTP tunnel)"); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "DefaultPort"); + u32 port = 554; + Bool force_rtsp = GF_FALSE; + if (sOpt) port = atoi(sOpt); + switch (port) { + case 8080: + m_Port.SetCurSel(3); + force_rtsp = GF_TRUE; + break; + case 80: + m_Port.SetCurSel(2); + force_rtsp = GF_TRUE; + break; + case 7070: + m_Port.SetCurSel(1); + break; + default: + m_Port.SetCurSel(0); + break; + } + + Bool use_rtsp = GF_FALSE; + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "RTPoverRTSP"); + if (sOpt && !stricmp(sOpt, "yes")) use_rtsp = GF_TRUE; + + if (force_rtsp) { + m_UseRTSP.SetCheck(1); + m_UseRTSP.EnableWindow(0); + m_Reorder.SetCheck(0); + m_Reorder.EnableWindow(0); + } else { + m_UseRTSP.SetCheck(use_rtsp); + m_UseRTSP.EnableWindow(1); + m_Reorder.EnableWindow(1); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "ReorderSize"); + if (sOpt && !stricmp(sOpt, "0")) { + m_Reorder.SetCheck(0); + } else { + m_Reorder.SetCheck(1); + } + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "RTSPTimeout"); + if (sOpt) { + m_Timeout.SetWindowText(sOpt); + } else { + m_Timeout.SetWindowText("30000"); + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Network", "BufferLength"); + if (sOpt) { + m_Buffer.SetWindowText(sOpt); + } else { + m_Buffer.SetWindowText("3000"); + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Network", "RebufferLength"); + u32 buf_len = 0; + if (sOpt) buf_len = atoi(sOpt); + if (buf_len) { + m_RebufferLen.SetWindowText(sOpt); + m_Rebuffer.SetCheck(1); + m_RebufferLen.EnableWindow(1); + } else { + m_RebufferLen.SetWindowText("0"); + m_Rebuffer.SetCheck(0); + m_RebufferLen.EnableWindow(0); + } + + return TRUE; +} + + +void COptStream::OnSelchangePort() +{ + s32 sel = m_Port.GetCurSel(); + switch (sel) { + case 3: + case 2: + m_UseRTSP.SetCheck(1); + m_UseRTSP.EnableWindow(0); + m_Reorder.SetCheck(0); + m_Reorder.EnableWindow(0); + break; + case 1: + default: + m_UseRTSP.SetCheck(0); + m_UseRTSP.EnableWindow(1); + m_Reorder.SetCheck(1); + m_Reorder.EnableWindow(1); + break; + } +} + +void COptStream::OnRtsp() +{ + if (m_UseRTSP.GetCheck()) { + m_Reorder.SetCheck(0); + m_Reorder.EnableWindow(0); + } else { + m_Reorder.SetCheck(1); + m_Reorder.EnableWindow(1); + } + +} + +void COptStream::CheckRebuffer() +{ + char str[50]; + s32 buf, rebuf; + m_Buffer.GetWindowText(str, 50); + buf = atoi(str); + m_RebufferLen.GetWindowText(str, 50); + rebuf = atoi(str); + if (rebuf*2 > buf) { + rebuf = buf/2; + sprintf(str, "%d", rebuf); + m_RebufferLen.SetWindowText(str); + } +} + +void COptStream::OnRebuffer() +{ + if (!m_Rebuffer.GetCheck()) { + m_RebufferLen.EnableWindow(0); + } else { + m_RebufferLen.EnableWindow(1); + CheckRebuffer(); + } +} + +void COptStream::OnUpdateRebufferLen() +{ + CheckRebuffer(); +} + +void COptStream::OnUpdateBuffer() +{ + CheckRebuffer(); +} + +void COptStream::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + Bool force_rtsp = GF_FALSE; + s32 sel = m_Port.GetCurSel(); + switch (sel) { + case 3: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "8080"); + force_rtsp = GF_TRUE; + break; + case 2: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "80"); + force_rtsp = GF_TRUE; + break; + case 1: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "7070"); + break; + default: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "554"); + break; + } + + if (force_rtsp) { + gf_cfg_set_key(gpac->m_user.config, "Streaming", "RTPoverRTSP", "yes"); + } else { + gf_cfg_set_key(gpac->m_user.config, "Streaming", "RTPoverRTSP", m_UseRTSP.GetCheck() ? "yes" : "no"); + if (!m_UseRTSP.GetCheck()) gf_cfg_set_key(gpac->m_user.config, "Streaming", "ReorderSize", m_Reorder.GetCheck() ? "30" : "0"); + } + + char str[50]; + + m_Timeout.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "Streaming", "RTSPTimeout", str); + + m_Buffer.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "Network", "BufferLength", str); + if (m_Rebuffer.GetCheck()) { + m_RebufferLen.GetWindowText(str, 50); + gf_cfg_set_key(gpac->m_user.config, "Network", "RebufferLength", str); + } else { + gf_cfg_set_key(gpac->m_user.config, "Network", "RebufferLength", "0"); + } +} + + + + +COptMCache::COptMCache(CWnd* pParent /*=NULL*/) + : CDialog(COptMCache::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptMCache) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void COptMCache::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptMCache) + DDX_Control(pDX, IDC_BASEPRES, m_BaseName); + DDX_Control(pDX, IDC_MCACHE_USENAME, m_UseBase); + DDX_Control(pDX, IDC_MCACHE_OVERWRITE, m_Overwrite); + DDX_Control(pDX, IDC_BROWSE_MCACHE, m_RecDir); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptMCache, CDialog) + //{{AFX_MSG_MAP(COptMCache) + ON_BN_CLICKED(IDC_BROWSE_MCACHE, OnBrowseMcache) + ON_BN_CLICKED(IDC_MCACHE_USENAME, OnMcacheUsename) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptMCache message handlers + +void COptMCache::OnBrowseMcache() +{ + BROWSEINFO brw; + LPMALLOC pMalloc; + LPITEMIDLIST ret; + char dir[MAX_PATH]; + + if (NOERROR == ::SHGetMalloc(&pMalloc) ) { + + m_RecDir.GetWindowText(szCacheDir, MAX_PATH); + + memset(&brw, 0, sizeof(BROWSEINFO)); + brw.hwndOwner = this->GetSafeHwnd(); + brw.pszDisplayName = dir; + brw.lpszTitle = "Select HTTP Cache Directory..."; + brw.ulFlags = 0L; + brw.lpfn = LocCbck; + + ret = SHBrowseForFolder(&brw); + if (ret != NULL) { + if (::SHGetPathFromIDList(ret, dir)) { + m_RecDir.SetWindowText(dir); + } + pMalloc->Free(ret); + } + pMalloc->Release(); + } +} + +BOOL COptMCache::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "StreamingCache", "RecordDirectory"); + if (!sOpt) sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "CacheDirectory"); + if (sOpt) m_RecDir.SetWindowText(sOpt); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "StreamingCache", "KeepExistingFiles"); + m_Overwrite.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 0 : 1); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "StreamingCache", "BaseFileName"); + if (sOpt) { + m_UseBase.SetCheck(1); + m_BaseName.EnableWindow(TRUE); + m_BaseName.SetWindowText(sOpt); + } else { + m_UseBase.SetCheck(0); + m_BaseName.EnableWindow(FALSE); + m_BaseName.SetWindowText("uses service URL"); + } + return TRUE; +} + +void COptMCache::OnMcacheUsename() +{ + if (m_UseBase.GetCheck()) { + m_BaseName.EnableWindow(TRUE); + m_BaseName.SetWindowText("record"); + } else { + m_BaseName.EnableWindow(FALSE); + m_BaseName.SetWindowText("uses service URL"); + } +} + +void COptMCache::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + + gf_cfg_set_key(gpac->m_user.config, "StreamingCache", "KeepExistingFiles", m_Overwrite.GetCheck() ? "no" : "yes"); + if (m_UseBase.GetCheck()) { + m_BaseName.GetWindowText(szCacheDir, MAX_PATH); + gf_cfg_set_key(gpac->m_user.config, "StreamingCache", "BaseFileName", szCacheDir); + } else { + gf_cfg_set_key(gpac->m_user.config, "StreamingCache", "BaseFileName", NULL); + } + m_RecDir.GetWindowText(szCacheDir, MAX_PATH); + gf_cfg_set_key(gpac->m_user.config, "StreamingCache", "RecordDirectory", szCacheDir); +} + + +OptFiles::OptFiles(CWnd* pParent /*=NULL*/) + : CDialog(OptFiles::IDD, pParent) +{ + //{{AFX_DATA_INIT(OptFiles) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void OptFiles::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(OptFiles) + DDX_Control(pDX, IDC_ASSOCIATE, m_DoAssociate); + DDX_Control(pDX, IDC_FILES_PLUG, m_PlugName); + DDX_Control(pDX, IDC_FILES_MIMES, m_mimes); + DDX_Control(pDX, IDC_FILES_EXT, m_extensions); + DDX_Control(pDX, IDC_FILELIST, m_FileDescs); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(OptFiles, CDialog) + //{{AFX_MSG_MAP(OptFiles) + ON_CBN_SELCHANGE(IDC_FILELIST, OnSelchangeFilelist) + ON_BN_CLICKED(IDC_ASSOCIATE, OnAssociate) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// OptFiles message handlers + +BOOL OptFiles::OnInitDialog() +{ + CDialog::OnInitDialog(); + + Osmo4 *gpac = GetApp(); + u32 count, i; + + while (m_FileDescs.GetCount()) m_FileDescs.DeleteString(0); + count = gf_cfg_get_key_count(gpac->m_user.config, "MimeTypes"); + for (i=0; im_user.config, "MimeTypes", i); + if (!sMime) continue; + sOpt = gf_cfg_get_key(gpac->m_user.config, "MimeTypes", sMime); + if (!sOpt) continue; + sKey = (char *) strstr(sOpt, "\" \""); + if (!sKey) continue; + strcpy(sDesc, sKey+3); + sKey = strchr(sDesc, '\"'); + if (!sKey) continue; + sKey[0] = 0; + m_FileDescs.AddString(sDesc); + } + m_FileDescs.SetCurSel(0); + SetSelection(0); + return TRUE; +} + +void OptFiles::OnSelchangeFilelist() +{ + SetSelection(m_FileDescs.GetCurSel()); +} + +void OptFiles::SetSelection(u32 sel) +{ + Osmo4 *gpac = GetApp(); + char *sMime, *sKey, sDesc[200], sText[200]; + sMime = (char *) gf_cfg_get_key_name(gpac->m_user.config, "MimeTypes", sel); + sprintf(sText, "Mime Type: %s", sMime); + m_mimes.SetWindowText(sText); + strcpy(cur_mime, sMime); + sMime = (char *) gf_cfg_get_key(gpac->m_user.config, "MimeTypes", sMime); + strcpy(sDesc, sMime+1); + sKey = strchr(sDesc, '\"'); + sKey[0] = 0; + sprintf(sText, "Extensions: %s", sDesc); + strcpy(cur_ext, sDesc); + m_extensions.SetWindowText(sText); + sKey = strrchr(sMime, '\"'); + sprintf(sText, "Module: %s", sKey+2); + m_PlugName.SetWindowText(sText); + + Bool has_asso, need_asso, go = GF_TRUE; + sKey = cur_ext; + need_asso = has_asso = GF_FALSE; + + HKEY hKey; + DWORD dwSize; + while (go) { + Bool ok; + char szExt[50], szReg[60], c; + char *tmp = strchr(sKey, ' '); + if (!tmp) { + go = GF_FALSE; + } + else { + c = tmp[0]; + tmp[0] = 0; + } + sprintf(szExt, ".%s", sKey); + sprintf(szReg, "GPAC\\%s", sKey); + if (tmp) { + tmp[0] = c; + tmp += 1; + } + + if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szExt, 0, KEY_READ, &hKey ) == ERROR_SUCCESS) { + dwSize = 200; + ok = GF_TRUE; + if (RegQueryValueEx(hKey, "", NULL, NULL,(unsigned char*) sDesc, &dwSize) != ERROR_SUCCESS) ok = GF_FALSE; + RegCloseKey(hKey); + if (ok && !stricmp((char *)sDesc, szReg)) has_asso = GF_TRUE; + else need_asso = GF_TRUE; + } else need_asso = GF_TRUE; + sKey = tmp; + + } + m_DoAssociate.SetCheck(has_asso); + if (need_asso && has_asso) + OnAssociate(); +} + + +void OptFiles::OnAssociate() +{ + char *sKey, sDesc[200]; + unsigned char szApp[MAX_PATH]; + unsigned char szIco[MAX_PATH]; + + strcpy((char *) szApp, GetApp()->szApplicationPath); + strcpy((char *) szIco, (const char *) szApp); + strcat((char *) szIco, "Osmo4.ico"); + strcat((char *) szApp, "Osmo4.exe \"%L\""); + + if (m_DoAssociate.GetCheck()) { + Bool go = GF_TRUE; + sKey = cur_ext; + + HKEY hKey; + DWORD dwSize; + while (go) { + Bool ok; + char szExt[50], szReg[60], szOld[80], szPath[1024], c; + char *tmp = strchr(sKey, ' '); + if (!tmp) { + go = GF_FALSE; + } + else { + c = tmp[0]; + tmp[0] = 0; + } + sprintf(szExt, ".%s", sKey); + sprintf(szReg, "GPAC\\%s", sKey); + if (tmp) { + tmp[0] = c; + tmp += 1; + } + + RegOpenKeyEx(HKEY_CLASSES_ROOT, szExt, 0, 0, &hKey ); + dwSize = 200; + ok = GF_TRUE; + if (RegQueryValueEx(hKey, "", NULL, NULL,(unsigned char*) sDesc, &dwSize) != ERROR_SUCCESS) ok = GF_FALSE; + RegCloseKey(hKey); + strcpy(szOld, ""); + if (ok && stricmp((char *)sDesc, szReg)) strcpy(szOld, sDesc); + + strcpy(szPath, szReg); + strcat(szPath, "\\DefaultIcon"); + RegCreateKeyEx(HKEY_CLASSES_ROOT, szPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwSize); + RegSetValueEx(hKey, "", 0, REG_SZ, szIco, (DWORD) strlen((const char *) szIco)+1); + RegCloseKey(hKey); + + strcpy(szPath, szReg); + strcat(szPath, "\\Shell\\open\\command"); + RegCreateKeyEx(HKEY_CLASSES_ROOT, szPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwSize); + RegSetValueEx(hKey, "", 0, REG_SZ, szApp, (DWORD) strlen((const char *) szApp)+1); + RegCloseKey(hKey); + + if (strlen(szOld)) { + strcpy(szPath, szReg); + strcat(szPath, "\\Backup"); + RegCreateKeyEx(HKEY_CLASSES_ROOT, szPath, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwSize); + RegSetValueEx(hKey, "", 0, REG_SZ, (unsigned char *) szOld, (DWORD) strlen((const char *) szIco)+1); + RegCloseKey(hKey); + } + + RegCreateKeyEx(HKEY_CLASSES_ROOT, szExt, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwSize); + RegSetValueEx(hKey, "", 0, REG_SZ, (const unsigned char *) szReg, (DWORD) strlen(szReg)+1); + RegCloseKey(hKey); + + sKey = tmp; + } + } else { + Bool go = GF_TRUE; + sKey = cur_ext; + + HKEY hKey; + DWORD dwSize; + while (go) { + Bool ok; + char szExt[50], szReg[60], szPath[1024], c; + char *tmp = strchr(sKey, ' '); + if (!tmp) { + go = GF_FALSE; + } + else { + c = tmp[0]; + tmp[0] = 0; + } + sprintf(szExt, ".%s", sKey); + sprintf(szReg, "GPAC\\%s", sKey); + if (tmp) { + tmp[0] = c; + tmp += 1; + } + + strcpy(szPath, szReg); + strcat(szPath, "\\Backup"); + RegOpenKeyEx(HKEY_CLASSES_ROOT, szPath, 0, 0, &hKey ); + dwSize = 200; + ok = GF_TRUE; + if (RegQueryValueEx(hKey, "", NULL, NULL,(unsigned char*) sDesc, &dwSize) != ERROR_SUCCESS) ok = GF_FALSE; + RegCloseKey(hKey); + if (ok && strlen((char *)sDesc)) { + RegCreateKeyEx(HKEY_CLASSES_ROOT, szExt, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwSize); + RegSetValueEx(hKey, "", 0, REG_SZ, (unsigned char*) sDesc, (DWORD) strlen((const char *) sDesc)+1); + RegCloseKey(hKey); + } + + RegOpenKeyEx(HKEY_CLASSES_ROOT, szReg, 0, 0, &hKey ); + RegDeleteKey(hKey, "Backup"); + RegDeleteKey(hKey, "DefaultIcon"); + RegDeleteKey(hKey, "Shell\\open\\command"); + RegDeleteKey(hKey, "Shell\\open"); + RegDeleteKey(hKey, "Shell"); + RegCloseKey(hKey); + RegDeleteKey(HKEY_CLASSES_ROOT, szReg); + + sKey = tmp; + } + } +} + +COptLogs::COptLogs(CWnd* pParent /*=NULL*/) + : CDialog(COptLogs::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptLogs) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void COptLogs::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptLogs) + DDX_Control(pDX, IDC_TOOL_SYNC, m_sync); + DDX_Control(pDX, IDC_TOOL_SCRIPT, m_script); + DDX_Control(pDX, IDC_TOOL_SCENE, m_scene); + DDX_Control(pDX, IDC_TOOL_RTP, m_rtp); + DDX_Control(pDX, IDC_TOOL_RENDER, m_render); + DDX_Control(pDX, IDC_TOOL_PARSER, m_parser); + DDX_Control(pDX, IDC_TOOL_NET, m_net); + DDX_Control(pDX, IDC_TOOL_MMIO, m_mmio); + DDX_Control(pDX, IDC_TOOL_MEDIA, m_media); + DDX_Control(pDX, IDC_TOOL_CORE, m_core); + DDX_Control(pDX, IDC_TOOL_CONTAINER, m_container); + DDX_Control(pDX, IDC_TOOL_COMPOSE, m_compose); + DDX_Control(pDX, IDC_TOOL_CODING, m_coding); + DDX_Control(pDX, IDC_TOOL_CODEC, m_codec); + DDX_Control(pDX, IDC_TOOL_AUTHOR, m_author); + DDX_Control(pDX, IDC_LOG_LEVEL, m_Level); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptLogs, CDialog) + //{{AFX_MSG_MAP(COptLogs) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptLogs message handlers + +BOOL COptLogs::OnInitDialog() +{ + CDialog::OnInitDialog(); + +#if 0 + Osmo4 *gpac = GetApp(); + switch (gpac->m_log_level) { + case GF_LOG_ERROR: + m_Level.SetCurSel(1); + break; + case GF_LOG_WARNING: + m_Level.SetCurSel(2); + break; + case GF_LOG_INFO: + m_Level.SetCurSel(3); + break; + case GF_LOG_DEBUG: + m_Level.SetCurSel(4); + break; + default: + m_Level.SetCurSel(0); + break; + } + + m_sync.SetCheck(gpac->m_log_tools & GF_LOG_SYNC); + m_script.SetCheck(gpac->m_log_tools & GF_LOG_SCRIPT); + m_scene.SetCheck(gpac->m_log_tools & GF_LOG_SCENE); + m_rtp.SetCheck(gpac->m_log_tools & GF_LOG_RTP); + m_render.SetCheck(gpac->m_log_tools & GF_LOG_COMPOSE); + m_parser.SetCheck(gpac->m_log_tools & GF_LOG_PARSER); + m_net.SetCheck(gpac->m_log_tools & GF_LOG_NETWORK); + m_mmio.SetCheck(gpac->m_log_tools & GF_LOG_MMIO); + m_media.SetCheck(gpac->m_log_tools & GF_LOG_MEDIA); + m_core.SetCheck(gpac->m_log_tools & GF_LOG_CORE); + m_container.SetCheck(gpac->m_log_tools & GF_LOG_CONTAINER); + m_compose.SetCheck(gpac->m_log_tools & GF_LOG_INTERACT); + m_coding.SetCheck(gpac->m_log_tools & GF_LOG_CODING); + m_codec.SetCheck(gpac->m_log_tools & GF_LOG_CODEC); + m_author.SetCheck(gpac->m_log_tools & GF_LOG_AUTHOR); +#endif + + return TRUE; +} + +void COptLogs::SaveOptions() +{ + Osmo4 *gpac = GetApp(); + CString str = ""; + const char *level = "error"; + u32 flags = 0; + + switch (m_Level.GetCurSel()) { + case 1: + level = "error"; + break; + case 2: + level = "warning"; + break; + case 3: + level = "info"; + break; + case 4: + level = "debug"; + break; + default: + level = "none"; + break; + } + + if (m_sync.GetCheck()) { + str +="sync:"; + } + if (m_script.GetCheck()) { + str +="script:"; + } + if (m_scene.GetCheck()) { + str +="scene:"; + } + if (m_rtp.GetCheck()) { + str +="rtp:"; + } + if (m_render.GetCheck()) { + str +="compose:"; + } + if (m_parser.GetCheck()) { + str +="parser:"; + } + if (m_net.GetCheck()) { + str +="network:"; + } + if (m_mmio.GetCheck()) { + str +="mmio:"; + } + if (m_media.GetCheck()) { + str +="media:"; + } + if (m_core.GetCheck()) { + str +="core:"; + } + if (m_container.GetCheck()) { + str +="container:"; + } + if (m_compose.GetCheck()) { + str +="interact:"; + } + if (m_coding.GetCheck()) { + str +="coding:"; + } + if (m_codec.GetCheck()) { + str +="codec:"; + } + if (m_author.GetCheck()) { + str +="author:"; + } + + gf_cfg_set_key(gpac->m_user.config, "General", "Logs", str); + str += "@"; + str += level; + gf_log_set_tools_levels(str); +} + +void COptHTTP::OnBnClickedRestartCache() +{ + // TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle +} diff --git a/applications/deprecated/old_arch/osmo4_w32/Options.h b/applications/deprecated/old_arch/osmo4_w32/Options.h new file mode 100644 index 0000000..9c8efd1 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Options.h @@ -0,0 +1,624 @@ +#if !defined(AFX_OPTIONS_H__5C839953_58C0_4D9D_89CE_2820C7686C1B__INCLUDED_) +#define AFX_OPTIONS_H__5C839953_58C0_4D9D_89CE_2820C7686C1B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// Options.h : header file +// + + +class COptAudio : public CDialog +{ +// Construction +public: + COptAudio(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptAudio) + enum { IDD = IDD_OPT_AUDIO }; + CButton m_Notifs; + CComboBox m_DriverList; + CButton m_AudioResync; + CButton m_AudioMultiCH; + CEdit m_AudioDur; + CSpinButtonCtrl m_SpinFPS; + CButton m_ForceConfig; + CSpinButtonCtrl m_AudioSpin; + CEdit m_AudioEdit; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptAudio) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptAudio) + virtual BOOL OnInitDialog(); + afx_msg void OnForceAudio(); + afx_msg void OnSelchangeDriverList(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// OptDecoder dialog + +class OptDecoder : public CDialog +{ +// Construction +public: + OptDecoder(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(OptDecoder) + enum { IDD = IDD_OPT_DECODER }; + CComboBox m_Video; + CComboBox m_Audio; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(OptDecoder) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(OptDecoder) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class OptFiles : public CDialog +{ +// Construction +public: + OptFiles(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(OptFiles) + enum { IDD = IDD_OPT_FILETYPES }; + CButton m_DoAssociate; + CStatic m_PlugName; + CStatic m_mimes; + CStatic m_extensions; + CComboBox m_FileDescs; + //}}AFX_DATA + + void SetSelection(u32 sel); + char cur_ext[200], cur_mime[200]; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(OptFiles) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(OptFiles) + virtual BOOL OnInitDialog(); + afx_msg void OnSelchangeFilelist(); + afx_msg void OnAssociate(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// COptFont dialog + +class COptFont : public CDialog +{ +// Construction +public: + COptFont(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptFont) + enum { IDD = IDD_OPT_FONT }; + CComboBox m_TextureModes; + CComboBox m_Fonts; + CButton m_BrowseFont; + //}}AFX_DATA + + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptFont) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptFont) + virtual BOOL OnInitDialog(); + afx_msg void OnBrowseFont(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// COptGen dialog + +class COptGen : public CDialog +{ +// Construction +public: + COptGen(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptGen) + enum { IDD = IDD_OPT_GEN }; + CButton m_LookForSubs; + CButton m_ViewXMT; + CButton m_NoConsole; + CButton m_Loop; + CButton m_SingleInstance; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptGen) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptGen) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// +// COptHTTP dialog + +class COptHTTP : public CDialog +{ +// Construction +public: + COptHTTP(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptHTTP) + enum { IDD = IDD_OPT_HTTP }; + CEdit m_ProxyName; + CButton m_useProxy; + CEdit m_SAXDuration; + CButton m_Progressive; + CButton m_DisableCache; + CButton m_CleanCache; + CButton m_CacheDir; + //}}AFX_DATA + + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptHTTP) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptHTTP) + afx_msg void OnBrowseCache(); + virtual BOOL OnInitDialog(); + afx_msg void OnSaxProgressive(); + afx_msg void OnUseProxy(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedRestartCache(); +}; + + +class COptMCache : public CDialog +{ +// Construction +public: + COptMCache(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptMCache) + enum { IDD = IDD_OPT_MCACHE }; + CEdit m_BaseName; + CButton m_UseBase; + CButton m_Overwrite; + CButton m_RecDir; + //}}AFX_DATA + + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptMCache) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptMCache) + virtual BOOL OnInitDialog(); + afx_msg void OnBrowseMcache(); + afx_msg void OnMcacheUsename(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptRender : public CDialog +{ +// Construction +public: + COptRender(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptRender) + enum { IDD = IDD_OPT_RENDER }; + CComboBox m_DrawBounds; + CComboBox m_Graphics; + CButton m_Use3DRender; + CComboBox m_AntiAlias; + CButton m_ForceSize; + CButton m_HighSpeed; + CComboBox m_BIFSRate; + //}}AFX_DATA + + + Bool SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptRender) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptRender) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptRender2D : public CDialog +{ +// Construction +public: + COptRender2D(CWnd* pParent = NULL); // standard constructor + + void SaveOptions(); + void SetYUV(); + +// Dialog Data + //{{AFX_DATA(COptRender2D) + enum { IDD = IDD_OPT_RENDER2D }; + CStatic m_YUVFormat; + CButton m_NoYUV; + CButton m_Scalable; + CButton m_DirectRender; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptRender2D) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptRender2D) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptRender3D : public CDialog +{ +// Construction +public: + COptRender3D(CWnd* pParent = NULL); // standard constructor + + void SaveOptions(); + +// Dialog Data + //{{AFX_DATA(COptRender3D) + enum { IDD = IDD_OPT_RENDER3D }; + CButton m_BitmapPixels; + CButton m_DisableTXRect; + CButton m_RasterOutlines; + CButton m_EmulPow2; + CButton m_PolyAA; + CComboBox m_BackCull; + CComboBox m_DrawNormals; + CComboBox m_Wireframe; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptRender3D) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptRender3D) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptStream : public CDialog +{ +// Construction +public: + COptStream(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptStream) + enum { IDD = IDD_OPT_STREAM }; + CEdit m_RebufferLen; + CButton m_Rebuffer; + CEdit m_Buffer; + CEdit m_Timeout; + CButton m_Reorder; + CButton m_UseRTSP; + CComboBox m_Port; + //}}AFX_DATA + + + void SaveOptions(); + + void CheckRebuffer(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptStream) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptStream) + virtual BOOL OnInitDialog(); + afx_msg void OnSelchangePort(); + afx_msg void OnRtsp(); + afx_msg void OnRebuffer(); + afx_msg void OnUpdateRebufferLen(); + afx_msg void OnUpdateBuffer(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptSystems : public CDialog +{ +// Construction +public: + COptSystems(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptSystems) + enum { IDD = IDD_OPT_SYSTEMS }; + CButton m_ForceDuration; + CComboBox m_Threading; + CButton m_LateFramesAlwaysDrawn; + CComboBox m_Lang; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptSystems) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptSystems) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptVideo : public CDialog +{ +// Construction +public: + COptVideo(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptVideo) + enum { IDD = IDD_OPT_VIDEO }; + CButton m_SwitchRes; + CButton m_UseHWMemory; + CComboBox m_Videos; + //}}AFX_DATA + + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptVideo) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptVideo) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// COptLogs dialog + +class COptLogs : public CDialog +{ +// Construction +public: + COptLogs(CWnd* pParent = NULL); // standard constructor + void SaveOptions(); + +// Dialog Data + //{{AFX_DATA(COptLogs) + enum { IDD = IDD_OPT_LOGS }; + CButton m_sync; + CButton m_script; + CButton m_scene; + CButton m_rtp; + CButton m_render; + CButton m_parser; + CButton m_net; + CButton m_mmio; + CButton m_media; + CButton m_core; + CButton m_container; + CButton m_compose; + CButton m_coding; + CButton m_codec; + CButton m_author; + CComboBox m_Level; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptLogs) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptLogs) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + + +///////////////////////////////////////////////////////////////////////////// +// COptions dialog + +class COptions : public CDialog +{ +// Construction +public: + COptions(CWnd* pParent = NULL); // standard constructor + BOOL Create(CWnd * pParent) + { + return CDialog::Create( COptions::IDD, pParent); + } + +// Dialog Data + //{{AFX_DATA(COptions) + enum { IDD = IDD_OPTIONS }; + CComboBox m_Selector; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptions) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + COptGen m_general; + COptSystems m_systems; + COptRender m_render; + COptRender2D m_render2d; + COptRender3D m_render3d; + COptAudio m_audio; + OptDecoder m_decoder; + COptVideo m_video; + COptHTTP m_http; + COptFont m_font; + COptStream m_stream; + COptMCache m_cache; + OptFiles m_files; + COptLogs m_logs; + + void HideAll(); + + // Generated message map functions + //{{AFX_MSG(COptions) + virtual BOOL OnInitDialog(); + afx_msg void OnSaveopt(); + afx_msg void OnClose(); + afx_msg void OnDestroy(); + afx_msg void OnSelchangeSelect(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OPTIONS_H__5C839953_58C0_4D9D_89CE_2820C7686C1B__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/Osmo4.cpp b/applications/deprecated/old_arch/osmo4_w32/Osmo4.cpp new file mode 100644 index 0000000..2446c12 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Osmo4.cpp @@ -0,0 +1,944 @@ +// GPAC.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "Osmo4.h" +#include +#include +#include "MainFrm.h" +#include "OpenUrl.h" +#include "resource.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// Osmo4 + +BEGIN_MESSAGE_MAP(Osmo4, CWinApp) + //{{AFX_MSG_MAP(Osmo4) + ON_COMMAND(ID_OPEN_FILE, OnOpenFile) + ON_COMMAND(ID_FILE_STEP, OnFileStep) + ON_COMMAND(ID_OPEN_URL, OnOpenUrl) + ON_COMMAND(ID_FILE_RELOAD, OnFileReload) + ON_COMMAND(ID_CONFIG_RELOAD, OnConfigReload) + ON_COMMAND(ID_FILE_PLAY, OnFilePlay) + ON_UPDATE_COMMAND_UI(ID_FILE_PLAY, OnUpdateFilePlay) + ON_UPDATE_COMMAND_UI(ID_FILE_STEP, OnUpdateFileStep) + ON_COMMAND(ID_FILE_STOP, OnFileStop) + ON_UPDATE_COMMAND_UI(ID_FILE_STOP, OnUpdateFileStop) + ON_COMMAND(ID_SWITCH_RENDER, OnSwitchRender) + ON_UPDATE_COMMAND_UI(ID_FILE_RELOAD, OnUpdateFileStop) + ON_COMMAND(ID_H_ABOUT, OnAbout) + ON_COMMAND(ID_FILE_MIGRATE, OnFileMigrate) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// Osmo4 construction + +Osmo4::Osmo4() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only Osmo4 object + +Osmo4 theApp; + + + +class UserPassDialog : public CDialog +{ +// Construction +public: + UserPassDialog(CWnd* pParent = NULL); // standard constructor + + Bool GetPassword(const char *site_url, char *user, char *password); + +// Dialog Data + //{{AFX_DATA(UserPassDialog) + enum { IDD = IDD_PASSWD }; + CStatic m_SiteURL; + CEdit m_User; + CEdit m_Pass; + //}}AFX_DATA + + void SetSelection(u32 sel); + char cur_ext[200], cur_mime[200]; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(UserPassDialog) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + const char *m_site_url; + char *m_user, *m_password; + + // Generated message map functions + //{{AFX_MSG(UserPassDialog) + virtual BOOL OnInitDialog(); + afx_msg void OnClose(); + //}}AFX_MSG +}; + +UserPassDialog::UserPassDialog(CWnd* pParent /*=NULL*/) + : CDialog(UserPassDialog::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptStream) + //}}AFX_DATA_INIT +} + +void UserPassDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(UserPassDialog) + DDX_Control(pDX, IDC_TXT_SITE, m_SiteURL); + DDX_Control(pDX, IDC_EDIT_USER, m_User); + DDX_Control(pDX, IDC_EDIT_PASSWORD, m_Pass); + //}}AFX_DATA_MAP +} + +BOOL UserPassDialog::OnInitDialog() +{ + CDialog::OnInitDialog(); + m_SiteURL.SetWindowText(m_site_url); + m_User.SetWindowText(m_user); + m_Pass.SetWindowText(""); + return TRUE; +} + +void UserPassDialog::OnClose() +{ + m_User.GetWindowText(m_user, 50); + m_Pass.GetWindowText(m_password, 50); +} + +Bool UserPassDialog::GetPassword(const char *site_url, char *user, char *password) +{ + m_site_url = site_url; + m_user = user; + if (DoModal() != IDOK) return GF_FALSE; + return GF_TRUE; +} + + +static void Osmo4_progress_cbk(const void *usr, const char *title, u64 done, u64 total) +{ + if (!total) return; + CMainFrame *pFrame = (CMainFrame *) ((Osmo4 *) usr)->m_pMainWnd; + s32 prog = (s32) ( (100 * (u64)done) / total); + if (pFrame->m_last_prog < prog) { + pFrame->console_err = GF_OK; + pFrame->m_last_prog = prog; + pFrame->console_message.Format("%s %02d %%", title, prog); + pFrame->PostMessage(WM_CONSOLEMSG, 0, 0); + if (done==total) pFrame->m_last_prog = -1; + } +} + +#define W32_MIN_WIDTH 120 + +static void log_msg(char *msg) +{ + ::MessageBox(NULL, msg, "GPAC", MB_OK); +} +Bool Osmo4_EventProc(void *priv, GF_Event *evt) +{ + u32 dur; + Osmo4 *gpac = (Osmo4 *) priv; + CMainFrame *pFrame = (CMainFrame *) gpac->m_pMainWnd; + /*shutdown*/ + if (!pFrame) return GF_FALSE; + + switch (evt->type) { + case GF_EVENT_DURATION: + dur = (u32) (1000 * evt->duration.duration); + //if (dur<1100) dur = 0; + pFrame->m_pPlayList->SetDuration((u32) evt->duration.duration ); + gpac->max_duration = dur; + gpac->can_seek = evt->duration.can_seek; + if (!gpac->can_seek) { + pFrame->m_Sliders.m_PosSlider.EnableWindow(FALSE); + } else { + pFrame->m_Sliders.m_PosSlider.EnableWindow(TRUE); + pFrame->m_Sliders.m_PosSlider.SetRangeMin(0); + pFrame->m_Sliders.m_PosSlider.SetRangeMax(dur); + } + break; + + case GF_EVENT_MESSAGE: + if (!evt->message.service || !strcmp(evt->message.service, (LPCSTR) pFrame->m_pPlayList->GetURL() )) { + pFrame->console_service = "main service"; + } else { + pFrame->console_service = evt->message.service; + } + if (evt->message.error!=GF_OK) { + if (evt->message.errorm_NoConsole) { + pFrame->console_err = evt->message.error; + pFrame->console_message = evt->message.message; + gpac->m_pMainWnd->PostMessage(WM_CONSOLEMSG, 0, 0); + + /*any error before connection confirm is a service connection error*/ + if (!gpac->m_isopen) pFrame->m_pPlayList->SetDead(); + } + return GF_FALSE; + } + if (gpac->m_NoConsole) return GF_FALSE; + + /*process user message*/ + pFrame->console_err = GF_OK; + pFrame->console_message = evt->message.message; + gpac->m_pMainWnd->PostMessage(WM_CONSOLEMSG, 0, 0); + break; + case GF_EVENT_PROGRESS: + char *szType; + if (evt->progress.progress_type==0) szType = "Buffer "; + else if (evt->progress.progress_type==1) szType = "Download "; + else if (evt->progress.progress_type==2) szType = "Import "; + gf_set_progress(szType, evt->progress.done, evt->progress.total); + break; + case GF_EVENT_NAVIGATE_INFO: + pFrame->console_message = evt->navigate.to_url; + gpac->m_pMainWnd->PostMessage(WM_CONSOLEMSG, 1000, 0); + break; + + case GF_EVENT_SCENE_SIZE: + if (evt->size.width && evt->size.height) { + gpac->orig_width = evt->size.width; + gpac->orig_height = evt->size.height; + if (gpac->m_term && !pFrame->m_bFullScreen) + pFrame->PostMessage(WM_SETSIZE, evt->size.width, evt->size.height); + } + 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) ) + 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; + + pFrame->BuildStreamList(GF_TRUE); + if (evt->connect.is_connected) { + pFrame->BuildChapterList(GF_FALSE); + gpac->m_isopen = GF_TRUE; + //resetting sliders when opening a new file creates a deadlock on the window thread which is disconnecting + pFrame->m_wndToolBar.SetButtonInfo(5, ID_FILE_PLAY, TBBS_BUTTON, gpac->m_isopen ? 4 : 3); + pFrame->m_Sliders.m_PosSlider.SetPos(0); + pFrame->SetProgTimer(GF_TRUE); + } else { + gpac->max_duration = 0; + gpac->m_isopen = GF_FALSE; + pFrame->BuildChapterList(GF_TRUE); + } + if (!pFrame->m_bFullScreen) { + pFrame->SetFocus(); + pFrame->SetForegroundWindow(); + } + break; + + case GF_EVENT_QUIT: + pFrame->PostMessage(WM_CLOSE, 0L, 0L); + break; + case GF_EVENT_MIGRATE: + { + } + break; + case GF_EVENT_KEYDOWN: + 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; + case GF_KEY_H: + if ((evt->key.flags & GF_KEY_MOD_CTRL) && gpac->m_isopen) + gf_term_switch_quality(gpac->m_term, GF_TRUE); + break; + case GF_KEY_L: + if ((evt->key.flags & GF_KEY_MOD_CTRL) && gpac->m_isopen) + gf_term_switch_quality(gpac->m_term, GF_FALSE); + break; + case GF_KEY_LEFT: + case GF_KEY_RIGHT: + if (gpac->m_isopen && (gf_term_get_option(gpac->m_term, GF_OPT_NAVIGATION) == GF_NAVIGATE_NONE)) { + if (evt->key.flags & GF_KEY_MOD_CTRL) { + if (evt->key.key_code==GF_KEY_LEFT) pFrame->m_pPlayList->PlayPrev(); + else if (evt->key.key_code==GF_KEY_RIGHT) pFrame->m_pPlayList->PlayNext(); + } + else if (gpac->can_seek && (evt->key.flags & GF_KEY_MOD_ALT)) { + u32 duration = gpac->max_duration; + s32 current_time = gf_term_get_time_in_ms(gpac->m_term); + + if (evt->key.key_code==GF_KEY_LEFT) { + current_time -= 5*duration/100; + if (current_time<0) current_time=0; + gf_term_play_from_time(gpac->m_term, (u64) current_time, 0); + } + else if (evt->key.key_code==GF_KEY_RIGHT) { + current_time += 5*duration/100; + if ((u32) current_time < duration) { + gf_term_play_from_time(gpac->m_term, (u64) current_time, 0); + } + } + } + } + break; + } + break; + case GF_EVENT_NAVIGATE: + /*fixme - a proper browser would require checking mime type & co*/ + /*store URL since it may be destroyed, and post message*/ + gpac->m_navigate_url = evt->navigate.to_url; + pFrame->PostMessage(WM_NAVIGATE, NULL, NULL); + return GF_TRUE; + case GF_EVENT_VIEWPOINTS: + pFrame->BuildViewList(); + return GF_FALSE; + case GF_EVENT_STREAMLIST: + pFrame->BuildStreamList(GF_FALSE); + return GF_FALSE; + case GF_EVENT_SET_CAPTION: + pFrame->SetWindowText(evt->caption.caption); + break; + case GF_EVENT_DBLCLICK: + pFrame->PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN); + return GF_FALSE; + case GF_EVENT_AUTHORIZATION: + { + UserPassDialog passdlg; + return passdlg.GetPassword(evt->auth.site_url, evt->auth.user, evt->auth.password); + } + } + return GF_FALSE; +} + + +/*here's the trick: use a storage section shared among all processes for the wnd handle and for the command line +NOTE: this has to be static memory of course, don't try to alloc anything there...*/ +#pragma comment(linker, "/SECTION:.shr,RWS") +#pragma data_seg(".shr") +HWND static_gpac_hwnd = NULL; +char static_szCmdLine[MAX_PATH] = ""; +#pragma data_seg() + +const char *static_gpac_get_url() +{ + return (const char *) static_szCmdLine; +} + +static void osmo4_do_log(void *cbk, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list list) +{ + FILE *logs = (FILE *) cbk; + vfprintf(logs, fmt, list); + fflush(logs); +} + +BOOL Osmo4::InitInstance() +{ + CCommandLineInfo cmdInfo; + + afxAmbientActCtx = FALSE; + + m_logs = NULL; + + m_term = NULL; + + memset(&m_user, 0, sizeof(GF_User)); + + /*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, "\\"); + + gf_sys_init(GF_MemTrackerNone); + + /*setup user*/ + memset(&m_user, 0, sizeof(GF_User)); + + Bool first_launch = GF_FALSE; + /*init config and modules*/ + m_user.config = gf_cfg_init(NULL, &first_launch); + if (!m_user.config) { + MessageBox(NULL, "GPAC Configuration file not found", "Fatal Error", MB_OK); + m_pMainWnd->PostMessage(WM_CLOSE); + } + + char *name = gf_cfg_get_filename(m_user.config); + char *sep = strrchr(name, '\\'); + if (sep) sep[0] = 0; + strcpy(szUserPath, name); + if (sep) sep[0] = '\\'; + + const char *opt = gf_cfg_get_key(m_user.config, "General", "SingleInstance"); + m_SingleInstance = (opt && !stricmp(opt, "yes")) ? GF_TRUE : GF_FALSE; + + m_hMutex = NULL; + if (m_SingleInstance) { + m_hMutex = CreateMutex(NULL, FALSE, "Osmo4_GPAC_INSTANCE"); + if ( GetLastError() == ERROR_ALREADY_EXISTS ) { + char szDIR[1024]; + if (m_hMutex) CloseHandle(m_hMutex); + m_hMutex = NULL; + + if (!static_gpac_hwnd || !IsWindow(static_gpac_hwnd) ) { + ::MessageBox(NULL, "Osmo4 ghost process detected", "Error at last shutdown" , MB_OK); + } else { + ::SetForegroundWindow(static_gpac_hwnd); + + if (m_lpCmdLine && strlen(m_lpCmdLine)) { + DWORD_PTR res; + size_t len; + char *the_url, *cmd; + GetCurrentDirectory(1024, szDIR); + if (szDIR[strlen(szDIR)-1] != '\\') strcat(szDIR, "\\"); + cmd = (char *)(const char *) m_lpCmdLine; + strcpy(static_szCmdLine, ""); + if (cmd[0]=='"') cmd+=1; + + if (!strnicmp(cmd, "-queue ", 7)) { + strcat(static_szCmdLine, "-queue "); + cmd += 7; + } + the_url = gf_url_concatenate(szDIR, cmd); + if (!the_url) { + strcat(static_szCmdLine, cmd); + } else { + strcat(static_szCmdLine, the_url); + gf_free(the_url); + } + while ( (len = strlen(static_szCmdLine)) ) { + char s = static_szCmdLine[len-1]; + if ((s==' ') || (s=='"')) static_szCmdLine[len-1]=0; + else break; + } + ::SendMessageTimeout(static_gpac_hwnd, WM_NEWINSTANCE, 0, 0, 0, 1000, &res); + } + } + + return FALSE; + } + } + +#if 0 + // Standard initialization +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + +#endif + + SetRegistryKey(_T("GPAC")); + CMainFrame* pFrame = new CMainFrame; + m_pMainWnd = pFrame; + pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); + pFrame->LoadAccelTable( MAKEINTRESOURCE(IDR_MAINACCEL)); + + m_pMainWnd->DragAcceptFiles(); + + if (m_SingleInstance) static_gpac_hwnd = m_pMainWnd->m_hWnd; + + m_user.modules = gf_modules_new(NULL, m_user.config); + if (!m_user.modules || ! gf_modules_get_count(m_user.modules) ) { + MessageBox(NULL, "No modules available - system cannot work", "Fatal Error", MB_OK); + m_pMainWnd->PostMessage(WM_CLOSE); + } + else if (first_launch) { + /*first launch, register all files ext*/ + u32 i; + for (i=0; iCanHandleURL(ifce, "test.test"); + gf_modules_close_interface((GF_BaseInterface *)ifce); + } + } + /*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+ "); + } + + /*check log file*/ + const char *str = gf_cfg_get_key(m_user.config, "General", "LogFile"); + if (str) { + m_logs = gf_fopen(str, "wt"); + gf_log_set_callback(m_logs, osmo4_do_log); + } + else m_logs = NULL; + + /*set log level*/ + if (gf_log_set_tools_levels(gf_cfg_get_key(m_user.config, "General", "Logs")) != GF_OK) + fprintf(stdout, "osmo4: invalid log level specified\n"); + + m_user.opaque = this; + m_user.os_window_handler = pFrame->m_pWndView->m_hWnd; + m_user.EventProc = Osmo4_EventProc; + + m_reset = GF_FALSE; + orig_width = 320; + orig_height = 240; + + gf_set_progress_callback(this, Osmo4_progress_cbk); + + m_term = gf_term_new(&m_user); + if (! m_term) { + MessageBox(NULL, "Cannot load GPAC Terminal", "Fatal Error", MB_OK); + m_pMainWnd->PostMessage(WM_CLOSE); + return TRUE; + } + SetOptions(); + UpdateRenderSwitch(); + + pFrame->SendMessage(WM_SETSIZE, orig_width, orig_height); + pFrame->m_Address.ReloadURLs(); + + pFrame->m_Sliders.SetVolume(); + + m_reconnect_time = 0; + + + ParseCommandLine(cmdInfo); + + start_mode = 0; + + if (! cmdInfo.m_strFileName.IsEmpty()) { + pFrame->m_pPlayList->QueueURL(cmdInfo.m_strFileName); + pFrame->m_pPlayList->RefreshList(); + pFrame->m_pPlayList->PlayNext(); + } else { + char sPL[MAX_PATH]; + 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"); + if (sOpt) { + s32 count = (s32)gf_list_count(pFrame->m_pPlayList->m_entries); + pFrame->m_pPlayList->m_cur_entry = atoi(sOpt); + if (pFrame->m_pPlayList->m_cur_entry>=count) + pFrame->m_pPlayList->m_cur_entry = count-1; + } else { + pFrame->m_pPlayList->m_cur_entry = -1; + } +#if 0 + if (pFrame->m_pPlayList->m_cur_entry>=0) { + start_mode = 1; + pFrame->m_pPlayList->Play(); + } +#endif + + sOpt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + if (sOpt && !strstr(sOpt, "gui") ) gf_term_connect(m_term, sOpt); + + sOpt = gf_cfg_get_key(m_user.config, "General", "PlaylistLoop"); + m_Loop = (sOpt && !strcmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; + } + pFrame->SetFocus(); + pFrame->SetForegroundWindow(); + return TRUE; +} + +int Osmo4::ExitInstance() +{ + if (m_term) gf_term_del(m_term); + if (m_user.modules) gf_modules_del(m_user.modules); + if (m_user.config) gf_cfg_del(m_user.config); + gf_sys_close(); + /*last instance*/ + if (m_hMutex) { + CloseHandle(m_hMutex); + static_gpac_hwnd = NULL; + } + if (m_logs) gf_fclose(m_logs); + return CWinApp::ExitInstance(); +} + + + +///////////////////////////////////////////////////////////////////////////// +// Osmo4 message handlers + + + + + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + virtual BOOL OnInitDialog(); + afx_msg void OnGogpac(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + ON_BN_CLICKED(IDC_GOGPAC, OnGogpac) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +void Osmo4::OnAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +BOOL CAboutDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + CString str = "GPAC/Osmo4 - version " GPAC_FULL_VERSION; + SetWindowText(str); + return TRUE; +} + +void CAboutDlg::OnGogpac() +{ + ShellExecute(NULL, "open", "http://gpac.io", NULL, NULL, SW_SHOWNORMAL); +} + +///////////////////////////////////////////////////////////////////////////// +// Osmo4 message handlers + + +void Osmo4::SetOptions() +{ + const char *sOpt = gf_cfg_get_key(m_user.config, "General", "Loop"); + m_Loop = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; + sOpt = gf_cfg_get_key(m_user.config, "General", "LookForSubtitles"); + m_LookForSubtitles = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; + sOpt = gf_cfg_get_key(m_user.config, "General", "ConsoleOff"); + m_NoConsole = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; + sOpt = gf_cfg_get_key(m_user.config, "General", "ViewXMT"); + m_ViewXMTA = (sOpt && !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; + sOpt = gf_cfg_get_key(m_user.config, "General", "NoMIMETypeFetch"); + m_NoMimeFetch = (!sOpt || !stricmp(sOpt, "yes")) ? GF_TRUE : GF_FALSE; +} + + +void Osmo4::OnOpenUrl() +{ + COpenUrl url; + if (url.DoModal() != IDOK) return; + + CMainFrame *pFrame = (CMainFrame *) m_pMainWnd; + pFrame->m_pPlayList->Truncate(); + pFrame->m_pPlayList->QueueURL(url.m_url); + pFrame->m_pPlayList->RefreshList(); + pFrame->m_pPlayList->PlayNext(); +} + + +CString Osmo4::GetFileFilter() +{ + u32 keyCount, i; + CString sFiles; + CString sExts; + CString supportedFiles; + + /*force MP4 and 3GP files at beginning to make sure they are selected (Win32 bug with too large filters)*/ + supportedFiles = "All Known Files|*.m3u;*.pls;*.mp4;*.3gp;*.3g2"; + + sExts = ""; + sFiles = ""; + keyCount = gf_cfg_get_key_count(m_user.config, "MimeTypes"); + for (i=0; i=0) continue; + /*if same extensions for # mime types skip (don't polluate the file list)*/ + if (sExts.Find(szKeyList)>=0) continue; + + sExts += szKeyList; + sExts += " "; + sFiles += sDesc; + sFiles += "|"; + + first = GF_TRUE; + + sOpt = CString(szKeyList); + while (1) { + + int pos = sOpt.Find(' '); + CString ext = (pos==-1) ? sOpt : sOpt.Left(pos); + /*WATCHOUT: we do have some "double" ext , eg .wrl.gz - these are NOT supported by windows*/ + if (ext.Find(".")<0) { + if (!first) { + sFiles += ";"; + } else { + first = GF_FALSE; + } + sFiles += "*."; + sFiles += ext; + + CString sext = ext; + sext += ";"; + if (supportedFiles.Find(sext)<0) { + supportedFiles += ";*."; + supportedFiles += ext; + } + } + + if (sOpt==ext) break; + CString rem; + rem.Format("%s ", (LPCTSTR) ext); + sOpt.Replace((LPCTSTR) rem, ""); + } + sFiles += "|"; + } + supportedFiles += "|"; + supportedFiles += sFiles; + supportedFiles += "M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|All Files |*.*|"; + return supportedFiles; +} + +void Osmo4::OnOpenFile() +{ + CString sFiles = GetFileFilter(); + u32 nb_items; + + /*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 *) gf_malloc(sizeof(char) * fd.m_ofn.nMaxFile); + fd.m_ofn.lpstrFile[0] = 0; + + if (fd.DoModal()!=IDOK) { + gf_free(fd.m_ofn.lpstrFile); + return; + } + + CMainFrame *pFrame = (CMainFrame *) m_pMainWnd; + + nb_items = 0; + POSITION pos = fd.GetStartPosition(); + while (pos) { + CString file = fd.GetNextPathName(pos); + nb_items++; + } + /*if several items, act as playlist (replace playlist), otherwise as browser (lost all "next" context)*/ + if (nb_items==1) + pFrame->m_pPlayList->Truncate(); + else + pFrame->m_pPlayList->Clear(); + + pos = fd.GetStartPosition(); + while (pos) { + CString file = fd.GetNextPathName(pos); + pFrame->m_pPlayList->QueueURL(file); + } + gf_free(fd.m_ofn.lpstrFile); + pFrame->m_pPlayList->RefreshList(); + pFrame->m_pPlayList->PlayNext(); +} + + +void Osmo4::Pause() +{ + if (!m_isopen) return; + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) ? GF_STATE_PAUSED : GF_STATE_PLAYING); +} + +void Osmo4::OnMainPause() +{ + Pause(); +} + +void Osmo4::OnFileStep() +{ + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); + ((CMainFrame *) m_pMainWnd)->m_wndToolBar.SetButtonInfo(5, ID_FILE_PLAY, TBBS_BUTTON, 3); +} +void Osmo4::OnUpdateFileStep(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(m_isopen && !m_reset); +} + +void Osmo4::PlayFromTime(u32 time) +{ + Bool do_pause; + if (start_mode==1) do_pause = GF_TRUE; + else if (start_mode==2) do_pause = GF_FALSE; + else do_pause = /*!m_AutoPlay*/GF_FALSE; + gf_term_play_from_time(m_term, time, do_pause); + m_reset = GF_FALSE; +} + + +void Osmo4::OnFileReload() +{ + gf_term_disconnect(m_term); + m_pMainWnd->PostMessage(WM_OPENURL); +} + +void Osmo4::OnFileMigrate() +{ +} + +void Osmo4::OnConfigReload() +{ + gf_term_set_option(m_term, GF_OPT_RELOAD_CONFIG, 1); +} + +void Osmo4::UpdatePlayButton(Bool force_play) +{ + if (!force_play && gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { + ((CMainFrame *) m_pMainWnd)->m_wndToolBar.SetButtonInfo(5, ID_FILE_PLAY, TBBS_BUTTON, 4); + } else { + ((CMainFrame *) m_pMainWnd)->m_wndToolBar.SetButtonInfo(5, ID_FILE_PLAY, TBBS_BUTTON, 3); + } +} + +void Osmo4::OnFilePlay() +{ + if (m_isopen) { + if (m_reset) { + m_reset = GF_FALSE; + PlayFromTime(0); + ((CMainFrame *)m_pMainWnd)->SetProgTimer(GF_TRUE); + } else { + Pause(); + } + UpdatePlayButton(); + } else { + ((CMainFrame *) m_pMainWnd)->m_pPlayList->Play(); + } +} + +void Osmo4::OnUpdateFilePlay(CCmdUI* pCmdUI) +{ + if (m_isopen) { + pCmdUI->Enable(TRUE); + if (pCmdUI->m_nID==ID_FILE_PLAY) { + if (!m_isopen) { + pCmdUI->SetText("Play/Pause\tCtrl+P"); + } else if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { + pCmdUI->SetText("Pause\tCtrl+P"); + } else { + pCmdUI->SetText("Resume\tCtrl+P"); + } + } + } else { + pCmdUI->Enable(((CMainFrame *)m_pMainWnd)->m_pPlayList->HasValidEntries() ); + pCmdUI->SetText("Play\tCtrl+P"); + } +} + +void Osmo4::OnFileStop() +{ + CMainFrame *pFrame = (CMainFrame *) m_pMainWnd; + if (m_reset) return; + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) Pause(); + m_reset = GF_TRUE; + pFrame->m_Sliders.m_PosSlider.SetPos(0); + pFrame->SetProgTimer(GF_FALSE); + pFrame->m_wndToolBar.SetButtonInfo(5, ID_FILE_PLAY, TBBS_BUTTON, 3); + start_mode = 2; +} + +void Osmo4::OnUpdateFileStop(CCmdUI* pCmdUI) +{ +// pCmdUI->Enable(m_isopen); +} + +void Osmo4::OnSwitchRender() +{ + const char *opt = gf_cfg_get_key(m_user.config, "Compositor", "OpenGLMode"); + Bool use_gl = (opt && !stricmp(opt, "always")) ? GF_TRUE : GF_FALSE; + gf_cfg_set_key(m_user.config, "Compositor", "OpenGLMode", use_gl ? "disable" : "always"); + + gf_term_set_option(m_term, GF_OPT_USE_OPENGL, !use_gl); + + UpdateRenderSwitch(); +} + +void Osmo4::UpdateRenderSwitch() +{ + const char *opt = gf_cfg_get_key(m_user.config, "Compositor", "OpenGLMode"); + if (opt && !stricmp(opt, "disable")) + ((CMainFrame *) m_pMainWnd)->m_wndToolBar.SetButtonInfo(12, ID_SWITCH_RENDER, TBBS_BUTTON, 10); + else + ((CMainFrame *) m_pMainWnd)->m_wndToolBar.SetButtonInfo(12, ID_SWITCH_RENDER, TBBS_BUTTON, 9); +} diff --git a/applications/deprecated/old_arch/osmo4_w32/Osmo4.h b/applications/deprecated/old_arch/osmo4_w32/Osmo4.h new file mode 100644 index 0000000..cfc3c16 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Osmo4.h @@ -0,0 +1,115 @@ +// GPAC.h : main header file for the GPAC application +// + +#if !defined(AFX_GPAC_H__8B06A368_E142_47E3_ABE7_0B459FC0E853__INCLUDED_) +#define AFX_GPAC_H__8B06A368_E142_47E3_ABE7_0B459FC0E853__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ +#error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// Osmo4: +// See GPAC.cpp for the implementation of this class +// + + +/*GPAC terminal*/ +#include +/*GPAC terminal info (OD browsing)*/ +#include + +enum { + WM_SCENE_DONE = WM_USER + 1, + WM_NAVIGATE, + WM_SETSIZE, + WM_OPENURL, + WM_RESTARTURL, + WM_CONSOLEMSG, + WM_NEWINSTANCE, +}; + +const char *static_gpac_get_url(); + +class Osmo4 : public CWinApp +{ +public: + Osmo4(); + + GF_Terminal *m_term; + GF_User m_user; + + Bool m_isopen, m_reset; + u32 max_duration; + Bool can_seek; + u32 orig_width,orig_height, m_reconnect_time; + + CString m_navigate_url; + void Pause(); + void PlayFromTime(u32 time); + + void SetOptions(); + void UpdateRenderSwitch(); + void UpdatePlayButton(Bool force_play = GF_FALSE); + + /*general options*/ + Bool m_Loop, m_LookForSubtitles, m_NoConsole, m_ViewXMTA, m_SingleInstance, m_NoMimeFetch; + u32 start_mode; + + CString GetFileFilter(); + + char szApplicationPath[GF_MAX_PATH]; + char szUserPath[GF_MAX_PATH]; + + FILE *m_logs; + + HANDLE m_hMutex; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(Osmo4) +public: + virtual BOOL InitInstance(); + virtual int ExitInstance(); + //}}AFX_VIRTUAL + +// Implementation + +public: + //{{AFX_MSG(Osmo4) + afx_msg void OnOpenFile(); + afx_msg void OnMainPause(); + afx_msg void OnFileStep(); + afx_msg void OnOpenUrl(); + afx_msg void OnFileReload(); + afx_msg void OnFileMigrate(); + afx_msg void OnConfigReload(); + afx_msg void OnFilePlay(); + afx_msg void OnUpdateFilePlay(CCmdUI* pCmdUI); + afx_msg void OnUpdateFileStep(CCmdUI* pCmdUI); + afx_msg void OnFileStop(); + afx_msg void OnUpdateFileStop(CCmdUI* pCmdUI); + afx_msg void OnSwitchRender(); + afx_msg void OnAbout(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +inline Osmo4 *GetApp() { + return (Osmo4 *)AfxGetApp(); +} + + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_GPAC_H__8B06A368_E142_47E3_ABE7_0B459FC0E853__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/Osmo4.rc b/applications/deprecated/old_arch/osmo4_w32/Osmo4.rc new file mode 100644 index 0000000..66a0ba5 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Osmo4.rc @@ -0,0 +1,885 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open File\tCtrl+O", ID_OPEN_FILE + MENUITEM "Open &URL\tCtrl+U", ID_OPEN_URL + MENUITEM SEPARATOR + MENUITEM "File Propert&ies\tCtrl+I", ID_FILE_PROP + POPUP "Streaming Cache" + BEGIN + MENUITEM "&Enable", ID_REC_ENABLE + MENUITEM "&Stop and Save", ID_REC_STOP + MENUITEM "&Abort", ID_REC_ABORT + END + MENUITEM SEPARATOR + MENUITEM "Copy", ID_FILE_COPY + MENUITEM "Paste", ID_FILE_PASTE + MENUITEM SEPARATOR + MENUITEM "Exit", ID_FILE_EXIT + END + POPUP "View" + BEGIN + POPUP "Viewpoint" + BEGIN + MENUITEM "", ID_VIEWPORT_EMPTY + END + POPUP "&Navigation" + BEGIN + MENUITEM "Headlight", ID_HEADLIGHT + MENUITEM SEPARATOR + MENUITEM "&None", ID_NAVIGATE_NONE + MENUITEM "&Walk", ID_NAVIGATE_WALK + MENUITEM "&Fly", ID_NAVIGATE_FLY + MENUITEM "&Examine", ID_NAVIGATE_EXAM + MENUITEM "&Pan", ID_NAVIGATE_PAN + MENUITEM "&Slide", ID_NAVIGATE_SLIDE + MENUITEM "&Orbit", ID_NAVIGATE_ORBIT + MENUITEM "&VR", ID_NAVIGATE_VR + MENUITEM "&Game", ID_NAVIGATE_GAME + MENUITEM SEPARATOR + POPUP "Collision" + BEGIN + MENUITEM "Off", ID_COLLIDE_NONE + MENUITEM "Regular", ID_COLLIDE_REG + MENUITEM "Displacement", ID_COLLIDE_DISP + END + MENUITEM "Gravity", ID_GRAVITY + MENUITEM SEPARATOR + MENUITEM "&Reset", ID_NAV_RESET + END + MENUITEM SEPARATOR + MENUITEM "&Fullscreen", ID_VIEW_FULLSCREEN + MENUITEM "Original &Aspect", ID_VIEW_ORIGINAL + POPUP "Aspect &Ratio" + BEGIN + MENUITEM "&Keep Original", ID_AR_KEEP + MENUITEM "&Fill Screen", ID_AR_FILL + MENUITEM "Ratio 4/3", ID_AR_43 + MENUITEM "Ratio 16/9", ID_AR_169 + END + MENUITEM SEPARATOR + MENUITEM "Resource Usage", ID_VIEW_CPU + MENUITEM SEPARATOR + MENUITEM "&Options", IDD_CONFIGURE + END + POPUP "Play" + BEGIN + POPUP "Stream &Selection" + BEGIN + POPUP "Audio" + BEGIN + MENUITEM "", ID_AUDIO_EMPTY + END + POPUP "Video" + BEGIN + MENUITEM "", ID_VIDEO_EMPTY + END + POPUP "Subtitle" + BEGIN + MENUITEM "", ID_SUBS_EMPTY + END + MENUITEM SEPARATOR + MENUITEM "Add Subtitle", ID_ADD_SUBTITLE + END + POPUP "&Chapters" + BEGIN + MENUITEM "", ID_SETCHAP_FIRST + END + MENUITEM SEPARATOR + MENUITEM "Playlist\tF3", ID_VIEW_PL, CHECKED + MENUITEM "&Loop Playlist", ID_PLAYLIST_LOOP + MENUITEM SEPARATOR + MENUITEM "Play/Pause\tCtrl+P", ID_FILE_PLAY + MENUITEM "Step-by-Step\tCtrl+S", ID_FILE_STEP + MENUITEM "Stop", ID_FILE_STOP + MENUITEM SEPARATOR + MENUITEM "Reload File\tF5", ID_FILE_RELOAD + MENUITEM SEPARATOR + MENUITEM "Clear History", ID_CLEAR_NAV + MENUITEM "Reload Config", ID_CONFIG_RELOAD + END + POPUP "?" + BEGIN + MENUITEM "Shortcut List", ID_SHORTCUTS + MENUITEM "Navigation Keys", ID_NAV_INFO + MENUITEM SEPARATOR + MENUITEM "&About ...", ID_H_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOGEX 0, 0, 209, 137 +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) 2000-2013 Telecom ParisTech\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.io",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 +END + +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 "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 + LTEXT "Site",IDC_STATIC,7,4,13,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "Osmo4-GPAC" + VALUE "FileVersion", "0.8.0" + VALUE "InternalName", "Osmo4" + VALUE "LegalCopyright", "Copyright (C) Telecom ParisTech 2005-2012" + VALUE "OriginalFilename", "Osmo4.EXE" + VALUE "ProductName", "Osmo4-GPAC" + VALUE "ProductVersion", "0.8.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + BOTTOMMARGIN, 136 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_MAINTOOLS TOOLBAR 16, 15 +BEGIN + BUTTON ID_OPEN_FILE + BUTTON ID_NAV_PREV + BUTTON ID_NAV_NEXT + BUTTON ID_FILE_PLAY + BUTTON ID_FILE_PLAY + BUTTON ID_FILE_STEP + BUTTON ID_FILE_STOP + BUTTON ID_FILE_PROPS + BUTTON IDD_CONFIGURE + BUTTON ID_SWITCH_RENDER + BUTTON ID_SWITCH_RENDER +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINTOOLS BITMAP "res\\maintool.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDR_MAINFRAME "Osmo4" +END + +STRINGTABLE +BEGIN + AFX_IDS_APP_TITLE "Osmo4" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE +BEGIN + ID_FILE_EXIT "Quit the application; prompts to save documents\nExit" + ID_H_ABOUT "Display program information, version number and copyright\nAbout" + ID_PLAYLIST_LOOP "Restarts playlist from beginning when playlist is over" + ID_OPEN_FILE "Opens local file" + ID_VIEW_ORIGINAL "restore Original Aspect of presentation" +END + +STRINGTABLE +BEGIN + ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + +STRINGTABLE +BEGIN + ID_FILE_STOP "Stops current presentation" + ID_SWITCH_RENDER "Switch between 2D and 3D renderers" + ID_COLLIDE_NONE "Turns collision detection off" + ID_COLLIDE_REG "Turns collision detection on" + ID_COLLIDE_DISP "Collision with camera displacement" + ID_HEADLIGHT "Turns headlight on/off" +END + +STRINGTABLE +BEGIN + ID_CLEAR_NAV "Clears navigation history" + ID_TIMER " " + ID_FPS " " + ID_VIEW_PL "View navigation history as a playlist" +END + +STRINGTABLE +BEGIN + ID_VIEW_FULLSCREEN "Move to Full Screen mode (Esc to exit)" + ID_AR_KEEP "Keep Aspect Ratio of presentation" + ID_SHORTCUTS "List of available shortcuts" + ID_FILE_PROP "Show presentation properties" + ID_FILE_STEP "Step one frame into presentation" + IDD_CONFIGURE "Configure Player" + ID_VIEW_SCALABLE "Uses vectorial zooming when resizing the window" + ID_OPEN_URL "Open remote presentation" + ID_FILE_RELOAD "Reload current presentation" + ID_FILE_PLAY "Play/Pause presentation" + ID_NAVIGATE_NONE "Disable navigation" +END + +STRINGTABLE +BEGIN + ID_NAVIGATE_WALK "Turn walk navigation on" + ID_AR_FILL "Ignores Aspect Ratio and always fill screen" + ID_AR_43 "Forces Aspect Ratio of 4/3" + ID_AR_169 "Forces Aspect Ratio of 16/9" + ID_NAV_RESET "Restore last viewpoint" +END + +STRINGTABLE +BEGIN + ID_NAVIGATE_VR "QT-VR like navigation" + ID_REC_ENABLE "Enable recording of streaming data" + ID_REC_STOP "Stops recording and save to file" + ID_REC_ABORT "Stops recording and discard data" +END + +STRINGTABLE +BEGIN + ID_FILE_COPY "Copy selected text to clipboard" + ID_FILE_PASTE "Paste clipboard" +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +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 + DEFPUSHBUTTON "OK",IDC_BUTGO,279,5,19,13 +END + +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 + LTEXT "Category",IDC_STATIC,7,4,29,8 +END + +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 +END + +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 + 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 + 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 + LTEXT "Bounds",IDC_STATIC,82,64,25,8 +END + +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 + 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 + LTEXT "buffers",IDC_STATIC,43,18,23,8 + 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 + LTEXT "ms total length",IDC_STATIC,118,18,49,8 +END + +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 + 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 DIALOGEX 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + PUSHBUTTON "...",IDC_BROWSE_CACHE,57,4,109,12 + CONTROL "Clean cache at exit",IDC_CLEAN_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,23,77,10 + CONTROL "Disable Cache",IDC_RESTART_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,22,62,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 + 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 +END + +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 + 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 + LTEXT "Text Texturing Mode",IDC_STATIC,7,60,69,8 +END + +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 + 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 +END + +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 + LTEXT "milliseconds",IDC_STATIC,117,63,41,8 +END + +IDD_PROPERTIES DIALOGEX 0, 0, 338, 150 +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 + 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 +END + +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 + LTEXT "Prefered Video Module",-1,48,40,69,8 + COMBOBOX IDC_VIDEC_LIST,25,52,113,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + +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 + 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 +END + +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 "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 + LTEXT "Draw Normals",IDC_STATIC,4,17,45,8 + 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 + LTEXT "Draw Mode",IDC_STATIC,113,17,55,8 + COMBOBOX IDC_DRAW_MODE,111,25,53,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + +IDD_SLIDERS DIALOGEX 0, 0, 218, 18 +STYLE DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "Slider1",ID_SLIDER,"msctls_trackbar32",TBS_TOP | TBS_NOTICKS,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 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 + LTEXT "Address",IDC_DUMTXT,1,4,26,8 +END + +IDD_PLAYLIST DIALOGEX 0, 0, 186, 54 +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 +END + +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 + LTEXT "Record To",IDC_STATIC,4,4,35,8 + EDITTEXT IDC_BASEPRES,81,31,82,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER +END + +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 + 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 + LTEXT "Plugin",IDC_FILES_PLUG,8,49,154,8 +END + +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 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT_VIDEO, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_OPT_FONT, DIALOG + BEGIN + LEFTMARGIN, 1 + RIGHTMARGIN, 168 + BOTTOMMARGIN, 74 + END + + IDD_OPT_SYSTEMS, DIALOG + BEGIN + RIGHTMARGIN, 167 + TOPMARGIN, 1 + BOTTOMMARGIN, 75 + END + + IDD_OPT_STREAM, DIALOG + BEGIN + LEFTMARGIN, 1 + RIGHTMARGIN, 167 + TOPMARGIN, 1 + END + + IDD_PROPERTIES, DIALOG + BEGIN + RIGHTMARGIN, 335 + TOPMARGIN, 1 + END + + IDD_OPT_DECODER, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_OPT_RENDER3D, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_NAVBAR, DIALOG + BEGIN + RIGHTMARGIN, 167 + END + + IDD_OPT_FILETYPES, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_OPT_LOGS, DIALOG + BEGIN + RIGHTMARGIN, 168 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_PLAYLIST TOOLBAR 16, 15 +BEGIN + BUTTON ID_PL_OPEN + BUTTON ID_PL_SAVE + BUTTON ID_PL_ADD_FILE + BUTTON ID_PL_REM_FILE + BUTTON ID_PL_UP + BUTTON ID_PL_DOWN + BUTTON ID_PL_SORT_FILE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_PLAYLIST BITMAP "res\\playlist.bmp" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\Osmo4.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +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" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_OPT_RENDER DLGINIT +BEGIN + IDC_BIFS_RATE, 0x403, 4, 0 +0x2e35, 0x0030, + IDC_BIFS_RATE, 0x403, 4, 0 +0x2e37, 0x0035, + IDC_BIFS_RATE, 0x403, 5, 0 +0x3031, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3231, 0x352e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3531, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3432, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3532, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3033, 0x302e, "\000" + 0 +END + +IDD_OPT_SYSTEMS DLGINIT +BEGIN + IDC_LANG, 0x403, 8, 0 +0x6e45, 0x6c67, 0x7369, 0x0068, + IDC_LANG, 0x403, 7, 0 +0x7246, 0x6e65, 0x6863, "\000" + IDC_LANG, 0x403, 7, 0 +0x6547, 0x6d72, 0x6e61, "\000" + IDC_LANG, 0x403, 8, 0 +0x7449, 0x6c61, 0x6169, 0x006e, + IDC_LANG, 0x403, 8, 0 +0x7053, 0x6e61, 0x7369, 0x0068, + IDC_LANG, 0x403, 9, 0 +0x6843, 0x6e69, 0x6565, 0x6573, "\000" + IDC_LANG, 0x403, 10, 0 +0x614a, 0x6170, 0x656e, 0x7365, 0x0065, + IDC_DEC_THREAD, 0x403, 14, 0 +0x6953, 0x676e, 0x656c, 0x5420, 0x7268, 0x6165, 0x0064, + IDC_DEC_THREAD, 0x403, 13, 0 +0x754d, 0x6c74, 0x2069, 0x6854, 0x6572, 0x6461, "\000" + IDC_DEC_THREAD, 0x403, 5, 0 +0x7246, 0x6565, "\000" + 0 +END + +IDD_OPT_LOGS DLGINIT +BEGIN + IDC_LOG_LEVEL, 0x403, 9, 0 +0x6944, 0x6173, 0x6c62, 0x6465, "\000" + IDC_LOG_LEVEL, 0x403, 6, 0 +0x7245, 0x6f72, 0x0072, + IDC_LOG_LEVEL, 0x403, 8, 0 +0x6157, 0x6e72, 0x6e69, 0x0067, + IDC_LOG_LEVEL, 0x403, 5, 0 +0x6e49, 0x6f66, "\000" + IDC_LOG_LEVEL, 0x403, 6, 0 +0x6544, 0x7562, 0x0067, + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_MAINACCEL ACCELERATORS +BEGIN + "^P", ID_FILE_PLAY, ASCII, NOINVERT + "\t", ID_FILE_PROP, ASCII, NOINVERT + VK_F5, ID_FILE_RELOAD, VIRTKEY, NOINVERT + "^S", ID_FILE_STEP, ASCII, NOINVERT + "^O", ID_OPEN_FILE, ASCII, NOINVERT + "^U", ID_OPEN_URL, ASCII, NOINVERT + VK_F3, ID_VIEW_PL, VIRTKEY, NOINVERT +END + +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\Osmo4.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/applications/deprecated/old_arch/osmo4_w32/Osmo4.vcxproj b/applications/deprecated/old_arch/osmo4_w32/Osmo4.vcxproj new file mode 100644 index 0000000..bd46ba3 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Osmo4.vcxproj @@ -0,0 +1,387 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C79C2D73-06E9-4622-92CE-F166B1B51792} + Osmo4 + MFCProj + + + + Application + Dynamic + MultiByte + v140 + + + Application + Dynamic + MultiByte + v140 + + + Application + Dynamic + MultiByte + v140 + + + Application + Dynamic + MultiByte + v140 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + false + false + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + true + true + true + true + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\obj/osmo4_w32_rel/Osmo4.tlb + + + + + MaxSpeed + OnlyExplicitInline + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)$(TargetName)$(TargetExt) + true + $(IntDir)$(ProjectName).pdb + Windows + 8388608 + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\obj/osmo4_w32_rel/Osmo4.tlb + + + + + Disabled + Default + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x040c + + + $(OutDir)$(TargetName)$(TargetExt) + true + $(IntDir)$(ProjectName).pdb + Windows + 8388608 + + + true + $(IntDir)$(ProjectName).bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\obj/osmo4_w32_deb/Osmo4.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + ../../include + + + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(IntDir)$(ProjectName).pdb + Windows + MachineX86 + + + true + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\obj/osmo4_w32_deb/Osmo4.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x040c + ../../include + + + $(OutDir)$(TargetName)$(TargetExt) + true + true + $(IntDir)$(ProjectName).pdb + Windows + + + true + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + \gpac\applications\osmo4_w32;%(AdditionalIncludeDirectories) + \gpac\applications\osmo4_w32;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + \gpac\applications\osmo4_w32;%(AdditionalIncludeDirectories) + \gpac\applications\osmo4_w32;%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + {d3540754-e0cf-4604-ac11-82de9bd4d814} + false + + + + + + \ No newline at end of file diff --git a/applications/deprecated/old_arch/osmo4_w32/Playlist.cpp b/applications/deprecated/old_arch/osmo4_w32/Playlist.cpp new file mode 100644 index 0000000..9adea5d --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Playlist.cpp @@ -0,0 +1,969 @@ +// Playlist.cpp : implementation file +// + +#include "stdafx.h" +#include "osmo4.h" +#include "MainFrm.h" +#include "OpenURL.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// Playlist dialog + +PLEntry::PLEntry(CString url, char *path) +{ + if (!path || strrchr(url, '\\') || strstr(url, "://")) { + m_url = gf_strdup(url); + } else { + char szPath[MAX_PATH]; + strcpy(szPath, path); + strcat(szPath, url); + m_url = gf_strdup(szPath); + } + char *str = (char *) strrchr(url, '\\'); + if (!str) str = (char *) strrchr(url, '/'); + if (str && strlen(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 = gf_strdup(str); + } else { + m_disp_name = gf_strdup(url); + str = strrchr(m_disp_name, '.'); + if (str) str[0] = 0; + } + } + m_duration = 0; + m_bIsDead = GF_FALSE; + m_bIsPlaying = GF_FALSE; + m_bIsSelected = GF_FALSE; +} + +PLEntry::~PLEntry() +{ + if (m_url) gf_free(m_url); + if (m_disp_name) gf_free(m_disp_name); + +} + + +static char szCacheDir[MAX_PATH]; + +Playlist::Playlist() + : CDialog(Playlist::IDD, NULL) +{ + //{{AFX_DATA_INIT(Playlist) + //}}AFX_DATA_INIT + + m_entries = gf_list_new(); + m_cur_entry = -1; + m_all_dead_entries=-1; + GetCurrentDirectory(MAX_PATH, szCacheDir); +} + +Playlist::~Playlist() +{ + Clear(); + gf_list_del(m_entries); +} + +void Playlist::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(Playlist) + DDX_Control(pDX, IDC_FILELIST, m_FileList); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(Playlist, CDialog) + //{{AFX_MSG_MAP(Playlist) + ON_WM_SIZE() + ON_COMMAND(ID_PL_ADD_FILE, OnPlAddFile) + ON_COMMAND(ID_PL_REM_FILE, OnPlRemFile) + ON_COMMAND(ID_PL_UP, OnSelUp) + ON_COMMAND(ID_PL_DOWN, OnSelDown) + ON_COMMAND(ID_PL_SAVE, OnPlSave) + ON_WM_DROPFILES() + ON_WM_CLOSE() + ON_WM_DESTROY() + ON_COMMAND(ID_PL_REM_DEAD, OnPlRemDead) + ON_COMMAND(ID_PL_REM_ALL, OnPlRemAll) + ON_COMMAND(ID_PL_ADD_DIR, OnPlAddDir) + ON_COMMAND(ID_PL_ADD_DIR_REC, OnPlAddDirRec) + ON_COMMAND(ID_PL_ADD_URL, OnPlAddUrl) + ON_COMMAND(ID_PL_OPEN, OnPlOpen) + ON_COMMAND(ID_PL_PLAY, OnPlPlay) + ON_COMMAND(ID_PL_SEL_REV, OnReverseSelection) + ON_COMMAND(ID_PL_SORT_REV, OnReverseList) + ON_COMMAND(ID_PL_RANDOM, OnRandomize) + ON_COMMAND(ID_PL_SORT_TITLE, OnSortTitle) + ON_COMMAND(ID_PL_SORT_FILE, OnSortFile) + ON_COMMAND(ID_PL_SORT_DUR, OnSortDuration) + ON_NOTIFY(NM_RCLICK, IDC_FILELIST, OnRclickFilelist) + ON_NOTIFY(NM_DBLCLK, IDC_FILELIST, OnDblclkFilelist) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// Playlist message handlers + +BOOL Playlist::OnInitDialog() +{ + UINT buttonArray[50]; + TBBUTTONINFO bi; + u32 *ba; + CDialog::OnInitDialog(); + + + SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE); + SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE); + + if (!m_toolBar.CreateEx(this, WS_CHILD | CBRS_TOP | CBRS_FLYBY) || + !m_toolBar.LoadBitmap(IDR_PLAYLIST)) + { + TRACE0("Failed to create toolbar\n"); + return 0; + } + + ba = &buttonArray[0]; + *ba = ID_PL_OPEN; + ba++; + *ba = ID_PL_SAVE; + ba++; + *ba = ID_SEPARATOR; + ba++; + *ba = ID_PL_ADD_FILE; + ba++; + *ba = ID_PL_REM_FILE; + ba++; + *ba = ID_SEPARATOR; + ba++; + *ba = ID_PL_UP; + ba++; + *ba = ID_PL_DOWN; + ba++; + *ba = ID_SEPARATOR; + ba++; + *ba = ID_PL_SORT_FILE; + ba++; + m_toolBar.SetButtons(buttonArray, 9); + m_toolBar.SetButtonInfo(0, ID_PL_OPEN, TBBS_BUTTON, 0); + m_toolBar.SetButtonInfo(1, ID_PL_SAVE, TBBS_BUTTON, 1); + m_toolBar.SetButtonInfo(2, ID_SEPARATOR, TBBS_SEPARATOR, 0); + m_toolBar.SetButtonInfo(3, ID_PL_ADD_FILE, TBBS_DROPDOWN | TBBS_BUTTON, 2); + m_toolBar.SetButtonInfo(4, ID_PL_REM_FILE, TBBS_DROPDOWN | TBBS_BUTTON, 3); + m_toolBar.SetButtonInfo(5, ID_SEPARATOR, TBBS_SEPARATOR, 0); + m_toolBar.SetButtonInfo(6, ID_PL_UP, TBBS_BUTTON, 4); + m_toolBar.SetButtonInfo(7, ID_PL_DOWN, TBBS_BUTTON, 5); +// m_toolBar.SetButtonInfo(8, ID_SEPARATOR, TBBS_SEPARATOR, 0); + m_toolBar.SetButtonInfo(8, ID_PL_SORT_FILE, TBBS_DROPDOWN | TBBS_BUTTON, 6); + + CToolBarCtrl &ctrl = m_toolBar.GetToolBarCtrl(); + ctrl.SetStyle(TBSTYLE_FLAT | TBSTYLE_DROPDOWN); + ctrl.SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS); + + memset(&bi, 0, sizeof(bi)); + bi.cbSize = sizeof(bi); + ctrl.GetButtonInfo(3, &bi); + bi.fsStyle |= TBSTYLE_DROPDOWN; + ctrl.SetButtonInfo(ID_PL_ADD_FILE, &bi); + + memset(&bi, 0, sizeof(bi)); + bi.cbSize = sizeof(bi); + ctrl.GetButtonInfo(4, &bi); + bi.fsStyle |= TBBS_DROPDOWN | TBSTYLE_DROPDOWN; + ctrl.SetButtonInfo(ID_PL_REM_FILE, &bi); + + memset(&bi, 0, sizeof(bi)); + bi.cbSize = sizeof(bi); + ctrl.GetButtonInfo(9, &bi); + bi.fsStyle |= TBSTYLE_DROPDOWN; + ctrl.SetButtonInfo(ID_PL_SORT_FILE, &bi); + + m_FileList.InsertColumn(0, "", LVCFMT_LEFT, 30, 0); + m_FileList.InsertColumn(1, "Title", LVCFMT_LEFT, 200, 1); + m_FileList.InsertColumn(2, "Duration", LVCFMT_LEFT, 200, 2); + + + m_toolBar.UpdateWindow(); + m_toolBar.ShowWindow(SW_SHOW); + + SetWindowPos(NULL, 0, 0, 400, 600, SWP_NOZORDER | SWP_NOMOVE); + + PostMessage(WM_NULL); + DragAcceptFiles(); + + return TRUE; +} + +void Playlist::OnSize(UINT nType, int cx, int cy) +{ + u32 tool_h; + CDialog::OnSize(nType, cx, cy); + RECT rc; + if (!m_toolBar.m_hWnd) return; + if (!m_FileList.m_hWnd) return; + + m_toolBar.GetClientRect(&rc); + tool_h = rc.bottom - rc.top; + m_toolBar.SetWindowPos(this, 0, 0, cx, tool_h, SWP_NOZORDER); + m_FileList.SetWindowPos(this, 0, tool_h, cx, cy-tool_h, SWP_NOZORDER); + + m_FileList.SetExtendedStyle(m_FileList.GetExtendedStyle() | LVS_EX_FULLROWSELECT); + + m_FileList.SetColumnWidth(0, 30); + m_FileList.SetColumnWidth(2, 60); + m_FileList.SetColumnWidth(1, cx-95); + +} + +void Playlist::OnDropFiles(HDROP hDropInfo) +{ + u32 i, count; + Osmo4 *app = GetApp(); + char fileName[MAX_PATH]; + count = ::DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0); + if (!count) return; + for (i=0; icode == TBN_DROPDOWN) { + RECT rc; + POINT pt; + CMenu *pPopup = new CMenu(); + pPopup->CreatePopupMenu(); + + m_toolBar.GetWindowRect(&rc); + pt.y = rc.bottom; + pt.x = rc.left; + + if ( ((LPNMTOOLBAR)lParam)->iItem == ID_PL_ADD_FILE) { + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_ADD_DIR, "Directory..."); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_ADD_DIR_REC, "Directory and subfolders..."); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_ADD_URL, "URL..."); + m_toolBar.GetToolBarCtrl().GetItemRect(3, &rc); + pt.x += rc.left; + } else if ( ((LPNMTOOLBAR)lParam)->iItem == ID_PL_REM_FILE) { + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_REM_ALL, "Clear"); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_REM_DEAD, "Remove dead entries"); + + m_toolBar.GetToolBarCtrl().GetItemRect(4, &rc); + pt.x += rc.left; + } else if ( ((LPNMTOOLBAR)lParam)->iItem == ID_PL_SORT_FILE) { + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_TITLE, "Sort Files by title"); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_FILE, "Sort Files by filename"); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_DUR, "Sort Files by duration"); + pPopup->AppendMenu(MF_SEPARATOR,0); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_REV, "Reverse Playlist"); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_RANDOM, "Shuffle Playlist"); + + m_toolBar.GetToolBarCtrl().GetItemRect(8, &rc); + pt.x += rc.left; + } + pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this); + delete pPopup; + + return FALSE; + } + return CDialog::OnNotify(wParam, lParam, pResult); +} + +void Playlist::Clear() +{ + m_FileList.DeleteAllItems(); + while (gf_list_count(m_entries)) { + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, 0); + gf_list_rem(m_entries, 0); + delete ple; + } + m_cur_entry = -1; +} + +void Playlist::ClearButPlaying() +{ + PLEntry *p=NULL; + if (m_cur_entry>=0) p = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (p) gf_list_rem(m_entries, m_cur_entry); + + Clear(); + if (p) { + gf_list_add(m_entries, p); + m_cur_entry = 0; + } + RefreshList(); +} + +void Playlist::UpdateEntry(u32 i) +{ + char szText[20]; + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, i); + if (i+1<10) sprintf(szText, "00%d", i+1); + else if (i+1<100) sprintf(szText, "0%d", i+1); + else sprintf(szText, "%d", i+1); + m_FileList.SetItem(i, 0, LVIF_TEXT, szText, 0, 0, 0, 0); + + CString str; + if (ple->m_bIsDead) { + str = "!! DEAD !! "; + str += ple->m_disp_name; + } + else if (ple->m_bIsPlaying) { + str = ">> "; + str += ple->m_disp_name; + str += " >>"; + } + else str = ple->m_disp_name; + m_FileList.SetItem(i, 1, LVIF_TEXT, str, 0, 0, 0, 0); + + if (ple->m_duration) { + u32 h = (u32) (ple->m_duration / 3600); + u32 m = (u32) (ple->m_duration / 60) - h*60; + u32 s = (u32) (ple->m_duration) - h*3600 - m*60; + sprintf(szText, "%02d:%02d:%02d", h, m, s); + m_FileList.SetItem(i, 2, LVIF_TEXT, szText, 0, 0, 0, 0); + } else { + m_FileList.SetItem(i, 2, LVIF_TEXT, "Unknown", 0, 0, 0, 0); + } + +} + +void Playlist::RefreshList() +{ + u32 i, top_idx; + char szPath[GF_MAX_PATH]; + + top_idx = m_FileList.GetTopIndex(); + m_FileList.DeleteAllItems(); + + for (i=0; im_bIsPlaying) m_cur_entry = i; + + if (ple->m_bIsSelected) { + m_FileList.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED); + ple->m_bIsSelected = GF_FALSE; + } + } + + if (m_cur_entry >= (s32)gf_list_count(m_entries)) m_cur_entry = gf_list_count(m_entries); + else { + s32 last_idx = top_idx + m_FileList.GetCountPerPage(); + m_FileList.EnsureVisible(top_idx, 0); + if (gf_list_count(m_entries)<(u32) last_idx) last_idx = gf_list_count(m_entries); + m_FileList.EnsureVisible(last_idx, 1); + } + + + strcpy((char *) szPath, GetApp()->szUserPath); + strcat(szPath, "gpac_pl.m3u"); + Save(szPath, GF_TRUE); +} + +void Playlist::OnPlAddFile() +{ + Osmo4 *app = GetApp(); + CString sFiles = app->GetFileFilter(); + + CFileDialog fd(TRUE,NULL,NULL, OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST , sFiles); + fd.m_ofn.nMaxFile = 25000; + fd.m_ofn.lpstrFile = (char *) gf_malloc(sizeof(char) * fd.m_ofn.nMaxFile); + fd.m_ofn.lpstrFile[0] = 0; + + if (fd.DoModal() == IDOK) { + s32 cur = m_FileList.GetItemCount(); + POSITION pos = fd.GetStartPosition(); + while (pos) { + QueueURL(fd.GetNextPathName(pos)); + } + } + gf_free(fd.m_ofn.lpstrFile); + m_all_dead_entries=-1; + RefreshList(); +} + +void Playlist::OnClose() +{ + ShowWindow(SW_HIDE); +} + +void Playlist::OnPlRemFile() +{ + if (!m_FileList.GetSelectedCount()) return; + POSITION pos = m_FileList.GetFirstSelectedItemPosition(); + while (pos != NULL) { + int nItem = m_FileList.GetNextSelectedItem(pos); + PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); + gf_list_del_item(m_entries, ple); + delete ple; + } + m_all_dead_entries=-1; + RefreshList(); +} + +void Playlist::OnSelUp() +{ + s32 i; + if (!m_FileList.GetSelectedCount()) return; + POSITION pos = m_FileList.GetFirstSelectedItemPosition(); + int nItem = m_FileList.GetNextSelectedItem(pos); + if (nItem==0) return; + + pos = m_FileList.GetFirstSelectedItemPosition(); + while (pos != NULL) { + nItem = m_FileList.GetNextSelectedItem(pos); + PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); + i = gf_list_del_item(m_entries, ple); + assert(i>=1); + gf_list_insert(m_entries, ple, i-1); + ple->m_bIsSelected = GF_TRUE; + } + RefreshList(); +} + +void Playlist::OnSelDown() +{ + s32 i, nItem; + if (!m_FileList.GetSelectedCount()) return; + POSITION pos = m_FileList.GetFirstSelectedItemPosition(); + while (pos != NULL) nItem = m_FileList.GetNextSelectedItem(pos); + + if ((u32) nItem + 1 == gf_list_count(m_entries)) return; + + pos = m_FileList.GetFirstSelectedItemPosition(); + while (pos != NULL) { + nItem = m_FileList.GetNextSelectedItem(pos); + PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); + i = gf_list_del_item(m_entries, ple); + gf_list_insert(m_entries, ple, i+1); + ple->m_bIsSelected = GF_TRUE; + } + RefreshList(); +} + +void Playlist::OnPlRemAll() +{ + Clear(); + RefreshList(); + m_cur_entry = -1; +} + +void Playlist::OnPlRemDead() +{ + for (u32 i=0; im_bIsDead) continue; + gf_list_rem(m_entries, i); + i--; + delete ple; + } + m_all_dead_entries=-1; + RefreshList(); +} + + +static int CALLBACK LocCbck(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData) +{ + char dir[MAX_PATH]; + if (uMsg == BFFM_INITIALIZED) { + strcpy(dir, szCacheDir); + SendMessage(hwnd, BFFM_SETSELECTION, TRUE,(LPARAM) dir); + } + return 0; +} +static Bool pl_enum_dir_item(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) +{ + Osmo4 *gpac = GetApp(); + Playlist *_this = (Playlist *)cbck; + + if (gf_term_is_supported_url(gpac->m_term, item_name, GF_FALSE, GF_TRUE)) { + _this->QueueURL(item_path); + } + return GF_FALSE; +} + +static Bool pl_enum_dir_dirs(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) +{ + gf_enum_directory(item_path, GF_FALSE, pl_enum_dir_item, cbck, NULL); + gf_enum_directory(item_path, GF_TRUE, pl_enum_dir_dirs, cbck, NULL); + return GF_FALSE; +} + + +void Playlist::AddDir(Bool do_recurse) +{ + BROWSEINFO brw; + LPMALLOC pMalloc; + LPITEMIDLIST ret; + char dir[MAX_PATH]; + + Bool res = GF_FALSE; + if (NOERROR == ::SHGetMalloc(&pMalloc) ) { + memset(&brw, 0, sizeof(BROWSEINFO)); + brw.hwndOwner = this->GetSafeHwnd(); + brw.pszDisplayName = dir; + brw.lpszTitle = "Select Directory..."; + brw.ulFlags = 0L; + brw.lpfn = LocCbck; + + ret = SHBrowseForFolder(&brw); + if (ret != NULL) { + if (::SHGetPathFromIDList(ret, dir)) res = GF_TRUE; + pMalloc->Free(ret); + } + pMalloc->Release(); + } + if (!res) return; + strcpy(szCacheDir, dir); + + gf_enum_directory(dir, GF_FALSE, pl_enum_dir_item, this, NULL); + if (do_recurse) gf_enum_directory(dir, GF_FALSE, pl_enum_dir_dirs, this, NULL); + m_all_dead_entries=-1; + RefreshList(); +} +void Playlist::OnPlAddDir() +{ + AddDir(GF_FALSE); +} +void Playlist::OnPlAddDirRec() +{ + AddDir(GF_TRUE); +} + +void Playlist::OnPlAddUrl() +{ + COpenUrl url; + if (url.DoModal() != IDOK) return; + PLEntry *ple = new PLEntry(url.m_url); + gf_list_add(m_entries, ple); + m_all_dead_entries=-1; + RefreshList(); +} + +void Playlist::OnPlSave() +{ + Bool save_m3u; + char szPath[GF_MAX_PATH]; + if (!gf_list_count(m_entries)) return; + CFileDialog fd(FALSE,NULL,NULL, OFN_OVERWRITEPROMPT, "M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"); + if (fd.DoModal() != IDOK) return; + + strcpy(szPath, fd.GetPathName()); + strlwr(szPath); + save_m3u = (fd.m_ofn.nFilterIndex==1) ? GF_TRUE : GF_FALSE; + if (save_m3u) { + if (!strstr(szPath, ".m3u")) { + strcpy(szPath, fd.GetPathName()); + strcat(szPath, ".m3u"); + } else { + strcpy(szPath, fd.GetPathName()); + } + } else { + if (!strstr(szPath, ".pls")) { + strcpy(szPath, fd.GetPathName()); + strcat(szPath, ".pls"); + } else { + strcpy(szPath, fd.GetPathName()); + } + } + Save(szPath, save_m3u); +} + +void Playlist::Save(char *szPath, Bool save_m3u) +{ + FILE *out = gf_fopen(szPath, "wt"); + if (!save_m3u) + fprintf(out, "[playlist]\nNumberOfEntries=%d\n", gf_list_count(m_entries)); + + for (u32 i=0; im_url); + } else { + fprintf(out, "File%d=%s\n", i+1, ple->m_url); + fprintf(out, "Title%d=%s\n", i+1, ple->m_disp_name); + fprintf(out, "Length%d=%d\n", i+1, ple->m_duration ? ple->m_duration : -1); + + } + } + if (!save_m3u) fprintf(out, "Version=2\n"); + + fprintf(out, "\n"); + gf_fclose(out); +} + +void Playlist::OnPlOpen() +{ + CFileDialog fd(TRUE,NULL,NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, "M3U & PLS Playlists|*.m3u;*.pls|M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"); + if (fd.DoModal() != IDOK) return; + + Clear(); + OpenPlayList(fd.GetPathName()); + m_cur_entry = 0; + Play(); +} + +void Playlist::OpenPlayList(CString fileName) +{ + FILE *pl; + PLEntry *ple; + Bool load_m3u, go; + char szLine[GF_MAX_PATH], *sep; + char szPath[GF_MAX_PATH]; + + strcpy(szPath, fileName); + sep = strrchr(szPath, '\\'); + if (sep) sep[1] = 0; + else szPath[0] = 0; + + pl = gf_fopen(fileName, "rt"); + if (!pl) return; + ple = NULL; + load_m3u = GF_TRUE; + while (!feof(pl)) { + fgets(szLine, GF_MAX_PATH, pl); + go = GF_TRUE; + while (go) { + switch (szLine[strlen(szLine)-1]) { + case '\n': + case '\r': + case ' ': + szLine[strlen(szLine)-1] = 0; + break; + default: + go = GF_FALSE; + break; + } + } + if (!strlen(szLine)) continue; + if (!stricmp(szLine, "[playlist]")) { + load_m3u = GF_FALSE; + } else if (load_m3u) { + ple = new PLEntry(szLine, szPath); + gf_list_add(m_entries, ple); + } else if (!strnicmp(szLine, "file", 4)) { + char *st = strchr(szLine, '='); + if (!st) ple = NULL; + else { + ple = new PLEntry(st + 1, szPath); + gf_list_add(m_entries, ple); + } + } else if (ple && !strnicmp(szLine, "Length", 6)) { + char *st = strchr(szLine, '='); + s32 d = atoi(st + 1); + if (d>0) ple->m_duration = d; + } else if (ple && !strnicmp(szLine, "Title", 5)) { + char *st = strchr(szLine, '='); + gf_free(ple->m_disp_name); + ple->m_disp_name = gf_strdup(st + 6); + } + } + gf_fclose(pl); + m_all_dead_entries=-1; + m_cur_entry = -1; + RefreshList(); +} + + +void Playlist::OnRclickFilelist(NMHDR* pNMHDR, LRESULT* pResult) +{ + if (!m_FileList.GetItemCount()) return; + + CMenu *pPopup = new CMenu(); + pPopup->CreatePopupMenu(); + + if (m_FileList.GetSelectedCount()==1) { + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_PLAY, "Play"); + pPopup->AppendMenu(MF_SEPARATOR, 0, ""); + } + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SEL_REV, "Inverse Selection"); + if (m_FileList.GetSelectedCount()) pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_REM_FILE, "Remove File(s)"); + if (m_FileList.GetItemCount()>1) { + pPopup->AppendMenu(MF_SEPARATOR, 0, ""); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_TITLE, "Sort By Title"); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_FILE, "Sort By File Name"); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_DUR, "Sort By Duration"); + pPopup->AppendMenu(MF_SEPARATOR, 0, ""); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_SORT_REV, "Reverse List"); + pPopup->AppendMenu(MF_STRING | MF_ENABLED, ID_PL_RANDOM, "Randomize"); + } + + POINT pt; + GetCursorPos(&pt); + pPopup->TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, this); + delete pPopup; + + *pResult = 0; +} + +void Playlist::OnReverseSelection() +{ + u32 i; + POSITION pos = m_FileList.GetFirstSelectedItemPosition(); + while (pos != NULL) { + int nItem = m_FileList.GetNextSelectedItem(pos); + PLEntry *ple = (PLEntry *) m_FileList.GetItemData(nItem); + ple->m_bIsSelected = GF_TRUE; + } + + for (i=0; im_bIsSelected = (Bool) !ple->m_bIsSelected; + } + RefreshList(); +} + +void Playlist::OnReverseList() +{ + u32 count = gf_list_count(m_entries); + u32 hcount = count / 2; + count--; + for (u32 i=0; i1) { + u32 pos = gf_rand() % (gf_list_count(m_entries)-1); + PLEntry *ple = (PLEntry *)gf_list_get(m_entries, pos); + gf_list_rem(m_entries, pos); + gf_list_add(new_entries, ple); + } + PLEntry *ple = (PLEntry *)gf_list_get(m_entries, 0); + gf_list_rem(m_entries, 0); + gf_list_add(new_entries, ple); + + gf_list_del(m_entries); + m_entries = new_entries; + m_cur_entry = -1; + RefreshList(); +} + +void Playlist::Sort(u32 type) +{ + u32 i, j, smallest; + if (gf_list_count(m_entries)<=1) return; + + for (i=0; im_url, ple2->m_url); + break; + case 1: + test = stricmp(ple1->m_disp_name, ple2->m_disp_name); + break; + case 2: + test = ple1->m_duration - ple2->m_duration; + break; + } + if (test<0) smallest = j; + } + PLEntry *ple = (PLEntry *)gf_list_get(m_entries, smallest); + gf_list_rem(m_entries, smallest); + gf_list_insert(m_entries, ple, i); + } + m_cur_entry = -1; + RefreshList(); +} + +void Playlist::OnSortFile() { + Sort(0); +} +void Playlist::OnSortTitle() { + Sort(1); +} +void Playlist::OnSortDuration() { + Sort(2); +} + + +Bool Playlist::HasValidEntries() +{ + u32 nb_dead = 0; + if (m_all_dead_entries==-1) { + for (u32 i=0; im_bIsPlaying = GF_FALSE; + if (ple->m_bIsDead) nb_dead ++; + } + m_all_dead_entries = (nb_dead==gf_list_count(m_entries)) ? 1 : 0; + } + if (m_all_dead_entries==1) return GF_FALSE; + return GF_TRUE; +} + +void Playlist::RefreshCurrent() +{ + if (m_cur_entry==-1) return; + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple && ple->m_bIsPlaying) { + ple->m_bIsPlaying = GF_FALSE; + UpdateEntry(m_cur_entry); + } +} + +void Playlist::Play() +{ + PLEntry *ple; + + if (!HasValidEntries()) return; + + RefreshCurrent(); + if (m_cur_entry==-1) m_cur_entry = 0; + + if (m_cur_entry >= (s32)gf_list_count(m_entries)) { + if (!GetApp()->m_Loop) return; + m_cur_entry = 0; + } + + ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + assert(ple); + if (ple->m_bIsDead) { + m_cur_entry++; + Play(); + } else { + char szPLE[20]; + ple->m_bIsPlaying = GF_TRUE; + UpdateEntry(m_cur_entry); + sprintf(szPLE, "%d", m_cur_entry); + gf_cfg_set_key(GetApp()->m_user.config, "General", "PLEntry", szPLE); + GetApp()->m_pMainWnd->PostMessage(WM_OPENURL); + } +} + +void Playlist::OnDblclkFilelist(NMHDR* pNMHDR, LRESULT* pResult) +{ + POSITION pos = m_FileList.GetFirstSelectedItemPosition(); + RefreshCurrent(); + m_cur_entry = m_FileList.GetNextSelectedItem(pos); + Play(); + *pResult = 0; +} + +void Playlist::OnPlPlay() +{ + POSITION pos = m_FileList.GetFirstSelectedItemPosition(); + + RefreshCurrent(); + m_cur_entry = m_FileList.GetNextSelectedItem(pos); + Play(); +} + +void Playlist::Truncate() +{ + while (m_cur_entry+1 < (s32)gf_list_count(m_entries)) { + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry+1); + gf_list_rem(m_entries, m_cur_entry+1); + delete ple; + } + RefreshList(); +} + + +void Playlist::QueueURL(CString filename) +{ + char *ext = (char *) strrchr(filename, '.'); + if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls")) ) { + OpenPlayList(filename); + } else { + PLEntry *ple = new PLEntry(filename); + gf_list_add(m_entries, ple); + } + m_all_dead_entries=-1; +} + +void Playlist::PlayNext() +{ + s32 count = (s32)gf_list_count(m_entries); + + RefreshCurrent(); + if (1+m_cur_entry < count) { + m_cur_entry++; + Play(); + } else if ((1+m_cur_entry == count) && GetApp()->m_Loop) { + m_cur_entry=0; + Play(); + } +} + +void Playlist::PlayPrev() +{ + RefreshCurrent(); + if (m_cur_entry>0) { + m_cur_entry--; + Play(); + } +} + +void Playlist::SetDead() +{ + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) { + ple->m_bIsDead = GF_TRUE; + UpdateEntry(m_cur_entry); + m_all_dead_entries=-1; + if (ple->m_bIsPlaying) PlayNext(); + } +} +void Playlist::SetDuration(u32 duration) +{ + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) { + ple->m_duration = duration; + UpdateEntry(m_cur_entry); + } +} + +CString Playlist::GetDisplayName() +{ + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) return CString(ple->m_disp_name); + return CString(""); +} + +CString Playlist::GetURL() +{ + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) return CString(ple->m_url); + return CString(""); +} + diff --git a/applications/deprecated/old_arch/osmo4_w32/Playlist.h b/applications/deprecated/old_arch/osmo4_w32/Playlist.h new file mode 100644 index 0000000..f42cfe2 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Playlist.h @@ -0,0 +1,120 @@ +#if !defined(AFX_PLAYLIST_H__EA74376A_83DF_435E_8484_A15BF5B77A32__INCLUDED_) +#define AFX_PLAYLIST_H__EA74376A_83DF_435E_8484_A15BF5B77A32__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// Playlist.h : header file +// + + +class PLEntry +{ +public: + PLEntry(CString url, char *path = NULL); + ~PLEntry(); + + char *m_url; + char *m_disp_name; + u32 m_duration; + + Bool m_bIsSelected; + Bool m_bIsDead; + Bool m_bIsPlaying; +}; + + +///////////////////////////////////////////////////////////////////////////// +// Playlist dialog + +class Playlist : public CDialog +{ +// Construction +public: + Playlist(); + virtual ~Playlist(); + + virtual BOOL Create() { + /*use desktop window to enable playlist behind player*/ + return CDialog::Create(IDD_PLAYLIST, GetDesktopWindow()); + } + + CToolBar m_toolBar; + GF_List *m_entries; + + void Clear(); + void ClearButPlaying(); + void RefreshList(); + void AddDir(Bool do_recurse); + void Truncate(); + void SetDead(); + void SetDuration(u32 duration); + + void Play(); + void PlayNext(); + void PlayPrev(); + Bool HasValidEntries(); + CString GetDisplayName(); + CString GetURL(); + + void OpenPlayList(CString fileName); + + void QueueURL(CString filename); + s32 m_cur_entry; + +// Dialog Data + //{{AFX_DATA(Playlist) + enum { IDD = IDD_PLAYLIST}; + CListCtrl m_FileList; + //}}AFX_DATA + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(Playlist) +protected: + virtual void DoDataExchange(CDataExchange* pDX); + virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); + //}}AFX_VIRTUAL + +// Implementation +protected: + s32 m_all_dead_entries; + void UpdateEntry(u32 idx); + void RefreshCurrent(); + void Sort(u32 type); + void Save(char *szPath, Bool save_m3u); + + // Generated message map functions + //{{AFX_MSG(Playlist) + virtual BOOL OnInitDialog() ; + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnDropFiles(HDROP hDropInfo); + afx_msg void OnPlAddFile(); + afx_msg void OnPlRemFile(); + afx_msg void OnSelUp(); + afx_msg void OnSelDown(); + afx_msg void OnPlSave(); + afx_msg void OnClose(); + afx_msg void OnPlRemDead(); + afx_msg void OnPlRemAll(); + afx_msg void OnPlAddDir(); + afx_msg void OnPlAddDirRec(); + afx_msg void OnPlAddUrl(); + afx_msg void OnPlOpen(); + afx_msg void OnReverseSelection(); + afx_msg void OnReverseList(); + afx_msg void OnRandomize(); + afx_msg void OnSortTitle(); + afx_msg void OnSortFile(); + afx_msg void OnSortDuration(); + afx_msg void OnPlPlay(); + afx_msg void OnRclickFilelist(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDblclkFilelist(NMHDR* pNMHDR, LRESULT* pResult); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PLAYLIST_H__EA74376A_83DF_435E_8484_A15BF5B77A32__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/Sliders.cpp b/applications/deprecated/old_arch/osmo4_w32/Sliders.cpp new file mode 100644 index 0000000..dc73f50 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Sliders.cpp @@ -0,0 +1,148 @@ +// Sliders.cpp : implementation file +// + +#include "stdafx.h" +#include "osmo4.h" +#include "Sliders.h" +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// Sliders dialog + +Sliders::Sliders(CWnd* pParent /*=NULL*/) + : CDialog(Sliders::IDD, pParent) +{ + //{{AFX_DATA_INIT(Sliders) + //}}AFX_DATA_INIT + + m_grabbed = GF_FALSE; +} + + +void Sliders::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(Sliders) + DDX_Control(pDX, ID_AUDIO_VOL, m_AudioVol); + DDX_Control(pDX, ID_SLIDER, m_PosSlider); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(Sliders, CDialog) + //{{AFX_MSG_MAP(Sliders) + ON_WM_HSCROLL() + ON_WM_SIZE() + ON_WM_CLOSE() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// Sliders message handlers + +void Sliders::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + + Osmo4 *app = GetApp(); + if (pScrollBar->GetDlgCtrlID() == ID_SLIDER) { + switch (nSBCode) { + case TB_PAGEUP: + case TB_PAGEDOWN: + case TB_LINEUP: + case TB_LINEDOWN: + case TB_TOP: + case TB_BOTTOM: +// m_grabbed = GF_TRUE; + break; + case TB_THUMBPOSITION: + case TB_THUMBTRACK: + m_grabbed = GF_TRUE; + break; + case TB_ENDTRACK: + if (m_grabbed) { + if (!app->can_seek || !app->m_isopen) { + m_PosSlider.SetPos(0); + } else { + u32 range = m_PosSlider.GetRangeMax() - m_PosSlider.GetRangeMin(); + u32 seek_to = m_PosSlider.GetPos(); + app->PlayFromTime(seek_to); + } + m_grabbed = GF_FALSE; + } + break; + } + } + if (pScrollBar->GetDlgCtrlID() == ID_AUDIO_VOL) { + u32 vol = m_AudioVol.GetPos(); + gf_term_set_option(app->m_term, GF_OPT_AUDIO_VOLUME, vol); + } + CDialog::OnHScroll(nSBCode, nPos, pScrollBar); +} + +void Sliders::OnSize(UINT nType, int cx, int cy) +{ + CDialog::OnSize(nType, cx, cy); + + if (!m_PosSlider.m_hWnd) return; + RECT rc, rc2; + + u32 tw = 40; + //m_PosSlider.GetClientRect(&rc); + //rc.right = rc.left + cx; + //m_PosSlider.SetWindowPos(this, rc.left, rc.top, rc.right, rc.bottom, SWP_NOZORDER | SWP_NOMOVE); + + m_PosSlider.GetClientRect(&rc); + rc.right = rc.left + cx - tw; + rc.top += 10; + rc.bottom += 10; + m_PosSlider.SetWindowPos(this, rc.left, rc.top, rc.right, rc.bottom, SWP_NOZORDER | SWP_NOMOVE); + + const UINT nPixelsLength = 24; + m_PosSlider.ModifyStyle(0,TBS_FIXEDLENGTH,FALSE); + m_PosSlider.SendMessage(TBM_SETTHUMBLENGTH,nPixelsLength,0); + + m_AudioVol.GetClientRect(&rc2); + rc2.top = rc2.bottom = cy/2; + rc2.top -= cy/3; + rc2.bottom += cy/3; + rc2.left = rc.right; + rc2.right = rc.right+tw; + m_AudioVol.MoveWindow(&rc2); + +} + +/*we sure don't want to close this window*/ +void Sliders::OnClose() +{ + u32 i = 0; + return; +} + +BOOL Sliders::PreTranslateMessage(MSG* pMsg) +{ + if (pMsg->message == WM_KEYDOWN) { + GetApp()->m_pMainWnd->SetFocus(); + GetApp()->m_pMainWnd->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam); + return TRUE; + } + return CDialog::PreTranslateMessage(pMsg); +} + + +BOOL Sliders::OnInitDialog() +{ + CDialog::OnInitDialog(); + m_AudioVol.SetRange(0, 100); + return TRUE; +} + +void Sliders::SetVolume() +{ + m_AudioVol.SetPos(gf_term_get_option(GetApp()->m_term, GF_OPT_AUDIO_VOLUME)); +} diff --git a/applications/deprecated/old_arch/osmo4_w32/Sliders.h b/applications/deprecated/old_arch/osmo4_w32/Sliders.h new file mode 100644 index 0000000..c1a6319 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/Sliders.h @@ -0,0 +1,62 @@ +#if !defined(AFX_SLIDERS_H__3542255E_1376_4FB7_91E7_B4841BB4F173__INCLUDED_) +#define AFX_SLIDERS_H__3542255E_1376_4FB7_91E7_B4841BB4F173__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// Sliders.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// Sliders dialog +class MySliderCtrl : public CSliderCtrl +{ +public: + MySliderCtrl () {} // standard constructor + +protected: + afx_msg virtual void OnLButtonDown(UINT nFlags, CPoint point); +}; + +class Sliders : public CDialog +{ +// Construction +public: + Sliders(CWnd* pParent = NULL); // standard constructor + + void SetVolume(); + Bool m_grabbed; + +// Dialog Data + //{{AFX_DATA(Sliders) + enum { IDD = IDD_SLIDERS }; + CSliderCtrl m_AudioVol; + CSliderCtrl m_PosSlider; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(Sliders) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(Sliders) + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnClose(); + virtual BOOL OnInitDialog(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_SLIDERS_H__3542255E_1376_4FB7_91E7_B4841BB4F173__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/StdAfx.cpp b/applications/deprecated/old_arch/osmo4_w32/StdAfx.cpp new file mode 100644 index 0000000..cdfba52 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// GPAC.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/applications/deprecated/old_arch/osmo4_w32/StdAfx.h b/applications/deprecated/old_arch/osmo4_w32/StdAfx.h new file mode 100644 index 0000000..879a8b4 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/StdAfx.h @@ -0,0 +1,30 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#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 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__1EEB44C5_1152_4872_8CA7_BD2994085EDC__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_w32/res/Osmo4.rc2 b/applications/deprecated/old_arch/osmo4_w32/res/Osmo4.rc2 new file mode 100644 index 0000000..b593608 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/res/Osmo4.rc2 @@ -0,0 +1,13 @@ +// +// Osmo4.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/applications/deprecated/old_arch/osmo4_w32/res/error.ico b/applications/deprecated/old_arch/osmo4_w32/res/error.ico new file mode 100644 index 0000000000000000000000000000000000000000..8a2d46cccd645a3ffde4476766fb4cbef301a5d0 GIT binary patch literal 766 zcmdUtF$w}P5JlgrAX{l=Yf5jSH#0}D4SN#VX1$4EV`-;_?D%6KZoopz{gXeF$x8x( zK&5bQNz`=$E7gtcd>X4KlqV^cV zA@^xRZXxmyhPr9P07KIbu{M+#N?e>BS))Jjv(8NI#@rq(?8(}Cw)#PPGp{R7@V_%5Jefp0b?LQa*UJ#a)b1_%T%Ek*g~CJb%X#TXYdWQ-NFD5qpWx*?R z_9vasiWq#9Vk$Qqpf}aEbEcbdqfl6ZyU&vc1$1a|JV{cV`{m*QOJX`Sl|x2!zsuWzq| z#eMI6@LvFhk3xfKLeno&Xk}t1j_bAgac*(V#<_8Sbs5d`x7_l3 vOSy}B6z_TKgP?Kc6kczBu3e6bCic&HRrNvV=H|VK_-ZHcWpVA{_W$f3h9LYm literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_w32/res/message.ico b/applications/deprecated/old_arch/osmo4_w32/res/message.ico new file mode 100644 index 0000000000000000000000000000000000000000..95f120e148570e8679a718544de9bfe0cec4e987 GIT binary patch literal 766 zcmdUtI}QRd3`8e@M1#auw4~%194$xl0elF`Jq6}@DYC54QX#=4<4?wkrifHnwGK** z8|g&8zzVOhXh)P9+Iuual-8b!NGUTTrx4RtL{^ZMM;ZPB2Y0ubQTK4~Ju-bC_(K0; pVEMile#F4cPB;346@OqIw{wIYBif$dvW>gSDsyI<%{zJb10H3Su}J^` literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_w32/res/osmo4.ico b/applications/deprecated/old_arch/osmo4_w32/res/osmo4.ico new file mode 100644 index 0000000000000000000000000000000000000000..36ff66711771065305f263aee09bda915091c6b0 GIT binary patch literal 15086 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 Ih+0ATC&$&)D*ylh literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_w32/res/pause.ico b/applications/deprecated/old_arch/osmo4_w32/res/pause.ico new file mode 100644 index 0000000000000000000000000000000000000000..7fab3531842d5177d069e52f04a883c6ade58364 GIT binary patch literal 1078 zcmd6mO-{ow5QSe_q_VJRj*u1VE#OwL!#g${$_MZvy5tC5Ak6n1tOnC85E5dNnK%Ek zl4ohqM$xvE*RYRofzCqvtYxZM3%n3 zWM?ATth0@c<6x5ajoCeR7$&^$%uean!95~g1rWCUrDG~?u!y;zTg9Ei$6$c@se-qZLz-L<&*)1%A`S8Cs%)q*w9&$eJa*kUjr7QZy*hoLko|js=np^5ruYFcT zbFRrB(K_dje_bLo4#P|r!;1UcIiEYF9=LveD9s4zw%C+g)E jRZog~t9{rHXEJhsJqR6VKBxLtIBc64?7;cPAk2i57?sr{ zYpkusoV)qX)uiA9juAU$bq_zT6V~^Q5VU3Nrf{F?mldvA@y+x63Do>KSN@~I_It2n>1-Ww=r#f?viR8qwyj-s@H{9KfVQ-ZVl L^ZljK^e_DY4LCYJ literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_w32/res/stop.ico b/applications/deprecated/old_arch/osmo4_w32/res/stop.ico new file mode 100644 index 0000000000000000000000000000000000000000..52e1a3b6ac8b5d228d1b3e16570ebda9cedbccf1 GIT binary patch literal 1078 zcmd6mF>b;@5JkTs5+GTDBe;sVMRF_X*pebeT5jV5>>(&~1d1q|_t&g37B136`DS+J z&z~8#n3XEc)HE9zpEKzNzu9zrTS?DzX-lrb-mpqfoKm3nF#;k=2%Y03RNJfi7E-g+GuG`i1|JP*n| c56;fv4VSfa=3TeEZ(Bf`vQp!E_xYLr0IvM^sQ>@~ literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_w32/resource.h b/applications/deprecated/old_arch/osmo4_w32/resource.h new file mode 100644 index 0000000..3a13e88 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_w32/resource.h @@ -0,0 +1,323 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Osmo4.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDR_GPACTYPE 129 +#define IDD_CONTROL 132 +#define IDI_PLAY 141 +#define IDI_STOP 142 +#define IDI_PAUSE 143 +#define IDI_MESSAGE 144 +#define IDI_ERR 145 +#define IDD_OPTIONS 152 +#define IDD_OPT_GEN 154 +#define IDD_OPT_RENDER 155 +#define IDD_OPT_AUDIO 157 +#define IDD_OPT_VIDEO 158 +#define IDD_OPT_HTTP 159 +#define IDD_OPT_FONT 161 +#define IDD_OPT_SYSTEMS 162 +#define IDD_OPT_STREAM 164 +#define IDD_PROPERTIES 166 +#define IDD_OPT_DECODER 167 +#define IDD_OPT_RENDER2D 168 +#define IDD_OPT_RENDER3D 169 +#define IDR_MAINTOOLS 170 +#define ID_MAINSLIDER 171 +#define IDD_SLIDERS 173 +#define IDD_NAVBAR 176 +#define IDD_PLAYLIST 177 +#define IDR_PLAYLIST 178 +#define IDD_OPT_FILETYPES 179 +#define IDR_MENUPL 182 +#define IDD_PASSWD 188 +#define IDR_MAINACCEL 190 +#define IDC_FILES_MIMES 1000 +#define IDC_FILES_PLUG 1001 +#define ID_AUDIO_VOL 1002 +#define IDC_TXT_SITE 1003 +#define IDC_EDIT_USER 1004 +#define IDC_EDIT_PASSWORD 1005 +#define IDC_PLAY 1006 +#define IDC_STOP 1007 +#define IDC_COMBOURL 1008 +#define IDC_BROWSE 1009 +#define IDC_BUTGO 1010 +#define IDC_SPIN_OPT 1011 +#define IDC_OPT_SET_NAME 1012 +#define IDC_LANG 1013 +#define IDC_LOOP 1014 +#define IDC_AUTOSTART 1015 +#define IDC_FILEASSOC 1016 +#define IDC_NO_CONSOLE 1017 +#define IDC_BIFS_RATE 1018 +#define IDC_DEC_THREAD 1019 +#define IDC_DIRECTRENDER 1020 +#define IDC_HWMEMORY 1021 +#define IDC_BIFSDROP 1023 +#define IDC_SPIN_AUDIO 1024 +#define IDC_EDIT_AUDIO 1025 +#define IDC_FORCE_AUDIO 1026 +#define IDC_SPIN_FPS 1027 +#define IDC_AUDIO_FPS 1028 +#define IDC_AUDIO_MULTICH 1029 +#define IDC_GD_LIST 1031 +#define IDC_FAST_RENDER 1032 +#define IDC_FORCE_DURATION 1033 +#define IDC_YUV 1034 +#define IDC_AUDIO_RESYNC 1035 +#define IDC_AUDIO_NOTIFS 1036 +#define IDC_STOPATEND 1037 +#define IDC_CLEAN_CACHE 1038 +#define IDC_RESTART_CACHE 1039 +#define IDC_NOTIFY_PROG 1040 +#define IDC_BROWSE_CACHE 1041 +#define IDC_LOOKFORSUB 1042 +#define IDD_OPT_MCACHE 1043 +#define IDC_DRIVER_LIST 1044 +#define IDC_AA_LIST 1045 +#define IDC_ZOOM_SCALABLE 1046 +#define IDD_OPENFILE 1047 +#define IDC_SINGLE_INSTANCE 1048 +#define IDC_VIDEO_LIST 1049 +#define IDC_FONT_LIST 1050 +#define IDC_BROWSE_FONT 1051 +#define IDC_USE_FONT 1052 +#define IDC_SAVEOPT 1053 +#define IDC_PORT 1054 +#define IDC_RTSP 1055 +#define IDC_TIMEOUT 1056 +#define IDC_BUFFER 1057 +#define IDC_REBUFFER_LEN 1058 +#define IDC_REBUFFER 1059 +#define IDC_ODTREE 1060 +#define IDC_VIEWSG 1061 +#define IDC_FORCE_SIZE 1062 +#define IDC_USE_RENDER3D 1063 +#define IDC_ODINFO 1064 +#define IDC_WORLD 1065 +#define IDC_GOGPAC 1066 +#define IDC_GOOSMO4 1067 +#define IDC_DUMP_XMT 1068 +#define IDC_OBJECT_TIME 1069 +#define IDC_FORMAT_YUV 1070 +#define IDC_DRAW_BOUNDS 1071 +#define IDC_REORDER 1072 +#define IDC_TEXTURE_MODE 1073 +#define IDC_SWITCH_RES 1074 +#define IDC_AUDEC_LIST 1075 +#define IDC_VIDEC_LIST 1076 +#define IDC_ASSOCIATE 1077 +#define IDC_RASTER_OUTLINE 1078 +#define IDC_EMUL_POW2 1079 +#define IDC_DISABLE_POLY_AA 1080 +#define IDC_WIRE_NONE 1081 +#define IDC_WIRE_ONLY 1082 +#define IDC_WIRE_BOTH 1083 +#define IDC_DISABLE_TX_RECT 1084 +#define IDC_BITMAP_USE_PIXEL 1085 +#define IDC_TEXTURE_TEXT 1086 +#define IDC_SLIDER 1087 +#define ID_SLIDER 1088 +#define IDC_SELECT 1089 +#define IDC_NO_BACKCULL 1090 +#define IDC_FILES_EXT 1091 +#define IDC_VIEWSEL 1094 +#define IDC_ADDRESS 1096 +#define IDC_DUMTXT 1097 +#define IDC_FILELIST 1109 +#define IDC_BROWSE_MCACHE 1110 +#define IDC_MCACHE_OVERWRITE 1111 +#define IDC_MCACHE_USENAME 1112 +#define IDC_BASEPRES 1113 +#define ID_FILE_EXIT 1114 +#define ID_H_ABOUT 1115 +#define ID_PLAYLIST_LOOP 1116 +#define ID_OPEN_FILE 1117 +#define ID_VIEW_CONTROL 1118 +#define ID_VIEW_ORIGINAL 1119 +#define ID_VIEW_FULLSCREEN 1120 +#define ID_AR_KEEP 1121 +#define IDC_DRAW_NORMALS 1122 +#define IDC_BACK_CULL 1123 +#define IDC_DRAW_MODE 1124 +#define ID_SHORTCUTS 1125 +#define ID_FILE_RESTART 1126 +#define ID_OPT_QUALITY 1127 +#define ID_FILE_PROP 1128 +#define ID_FILE_STEP 1129 +#define IDD_CONFIGURE 1130 +#define ID_VIEW_SCALABLE 1131 +#define ID_OPEN_URL 1132 +#define ID_FILE_RELOAD 1133 +#define ID_FILE_PLAY 1134 +#define ID_NAVIGATE_NONE 1135 +#define ID_NAVIGATE_WALK 1136 +#define ID_NAVIGATE_FLY 1137 +#define ID_NAVIGATE_EXAM 1138 +#define ID_NAVIGATE_PAN 1139 +#define ID_NAVIGATE_SLIDE 1140 +#define ID_NAVIGATE_GAME 1141 +#define ID_AR_FILL 1142 +#define ID_AR_43 1143 +#define ID_AR_169 1144 +#define ID_FILE_MIGRATE 1145 +#define ID_NAV_RESET 1151 +#define ID_FILE_STOP 1152 +#define ID_FILE_PREV 1155 +#define ID_FILE_NEXT 1156 +#define ID_FILE_PROPS 1157 +#define ID_SWITCH_RENDER 1158 +#define ID_RELOAD_TERMINAL 1159 +#define ID_VIEW_PLAYLIST 1160 +#define ID_NAVIGATE_ORBIT 1161 +#define ID_COLLIDE_NONE 1162 +#define ID_COLLIDE_REG 1163 +#define ID_COLLIDE_DISP 1164 +#define ID_GRAVITY 1165 +#define ID_HEADLIGHT 1166 +#define ID_NAV_INFO 1167 +#define ID_NAV_PREV 1168 +#define ID_NAV_NEXT 1169 +#define ID_CLEAR_NAV 1170 +#define ID_TIMER 1171 +#define ID_FPS 1172 +#define ID_VIEWPORT_EMPTY 1173 +#define ID_PL_REM_ALL 1174 +#define ID_PL_REM_DEAD 1175 +#define ID_PL_ADD_DIR_REC 1176 +#define ID_PL_ADD_FILE 1177 +#define ID_PL_REM_FILE 1178 +#define ID_PL_OPEN 1179 +#define ID_PL_SAVE 1180 +#define ID_PL_UP 1181 +#define ID_PL_DOWN 1182 +#define ID_VIEW_PL 1183 +#define ID_PL_ADD_DIR 1184 +#define ID_PL_ADD_URL 1185 +#define ID_PL_PLAY 1186 +#define ID_PL_SEL_REV 1187 +#define ID_PL_SORT_TITLE 1188 +#define ID_PL_SORT_FILE 1189 +#define ID_PL_SORT_DUR 1190 +#define ID_PL_SORT_REV 1191 +#define ID_PL_RANDOM 1192 +#define ID_ADD_SUBTITLE 1193 +#define ID_NAVIGATE_VR 1194 +#define ID_REC_ENABLE 1195 +#define ID_REC_STOP 1196 +#define ID_REC_ABORT 1197 +#define ID_AUDIO_EMPTY 1198 +#define ID_VIDEO_EMPTY 1199 +#define ID_SUBS_EMPTY 1200 +#define ID_VIEW_CPU 1201 +#define IDC_SAX_PROGRESSIVE 1202 +#define IDC_SAX_DELAY 1203 +#define IDC_HTTP_PROXY 1204 +#define IDC_HTTP_USE_PROXY 1205 +#define IDC_LOG_LEVEL 1210 +#define IDC_TOOL_CORE 1211 +#define IDC_TOOL_CODING 1212 +#define IDC_TOOL_CONTAINER 1213 +#define IDC_TOOL_NET 1214 +#define IDC_TOOL_RTP 1215 +#define IDC_TOOL_AUTHOR 1216 +#define IDC_TOOL_CODEC 1217 +#define IDC_TOOL_PARSER 1218 +#define IDC_TOOL_MEDIA 1219 +#define IDC_TOOL_SCENE 1220 +#define IDC_TOOL_SCRIPT 1221 +#define IDC_TOOL_COMPOSE 1222 +#define IDC_TOOL_RENDER 1223 +#define IDC_TOOL_MMIO 1224 +#define IDC_TOOL_SYNC 1225 +#define IDD_OPT_LOGS 1226 +#define ID_VP_0 1300 +#define ID_VP_1 1301 +#define ID_VP_2 1302 +#define ID_VP_3 1303 +#define ID_VP_4 1304 +#define ID_VP_5 1305 +#define ID_VP_6 1306 +#define ID_VP_7 1307 +#define ID_VP_8 1308 +#define ID_VP_9 1309 +#define ID_VP_10 1310 +#define ID_VP_11 1311 +#define ID_VP_12 1312 +#define ID_VP_13 1313 +#define ID_VP_14 1314 +#define ID_VP_15 1315 +#define ID_VP_16 1316 +#define ID_VP_17 1317 +#define ID_VP_18 1318 +#define ID_VP_19 1319 +#define ID_NAV_PREV_0 1320 +#define ID_NAV_PREV_1 1321 +#define ID_NAV_PREV_2 1322 +#define ID_NAV_PREV_3 1323 +#define ID_NAV_PREV_4 1324 +#define ID_NAV_PREV_5 1325 +#define ID_NAV_PREV_6 1326 +#define ID_NAV_PREV_7 1327 +#define ID_NAV_PREV_8 1328 +#define ID_NAV_PREV_9 1329 +#define ID_NAV_NEXT_0 1330 +#define ID_NAV_NEXT_1 1331 +#define ID_NAV_NEXT_2 1332 +#define ID_NAV_NEXT_3 1333 +#define ID_NAV_NEXT_4 1334 +#define ID_NAV_NEXT_5 1335 +#define ID_NAV_NEXT_6 1336 +#define ID_NAV_NEXT_7 1337 +#define ID_NAV_NEXT_8 1338 +#define ID_NAV_NEXT_9 1339 +#define ID_SELOBJ_0 1340 +#define ID_SELOBJ_1 1341 +#define ID_SELOBJ_2 1342 +#define ID_SELOBJ_3 1343 +#define ID_SELOBJ_4 1344 +#define ID_SELOBJ_5 1345 +#define ID_SELOBJ_6 1346 +#define ID_SELOBJ_7 1347 +#define ID_SELOBJ_8 1348 +#define ID_SELOBJ_9 1349 +#define ID_SELOBJ_10 1350 +#define ID_SELOBJ_11 1351 +#define ID_SELOBJ_12 1352 +#define ID_SELOBJ_13 1353 +#define ID_SELOBJ_14 1354 +#define ID_SELOBJ_15 1355 +#define ID_SELOBJ_16 1356 +#define ID_SELOBJ_17 1357 +#define ID_SELOBJ_18 1358 +#define ID_SELOBJ_19 1359 +#define ID_SELOBJ_20 1360 +#define ID_SELOBJ_21 1361 +#define ID_SELOBJ_22 1362 +#define ID_SELOBJ_23 1363 +#define ID_SELOBJ_24 1364 +#define ID_SELOBJ_25 1365 +#define ID_SELOBJ_26 1366 +#define ID_SELOBJ_27 1367 +#define ID_SELOBJ_28 1368 +#define ID_SELOBJ_29 1369 +#define ID_SETCHAP_FIRST 2000 +#define ID_SETCHAP_LAST 2200 +#define ID_FILE_COPY 32961 +#define ID_FILE_PASTE 32962 +#define ID_CONFIG_RELOAD 32963 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 192 +#define _APS_NEXT_COMMAND_VALUE 32981 +#define _APS_NEXT_CONTROL_VALUE 1131 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/applications/deprecated/old_arch/osmo4_wce/MainFrm.cpp b/applications/deprecated/old_arch/osmo4_wce/MainFrm.cpp new file mode 100644 index 0000000..f13c6cb --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/MainFrm.cpp @@ -0,0 +1,661 @@ +// MainFrm.cpp : implementation of the CMainFrame class +// + +#ifdef _DEBUG +#include "stdafx.h" +#else +#include "stdafx.h" +#undef _DEBUG +#endif + +#include "Osmo4.h" + +#include +#include + +#include "MainFrm.h" +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + + +CChildView::CChildView() +{ +} + +CChildView::~CChildView() +{ + /*since the wndproc is overwritten by the terminal, we detach the handle otherwise we get a nice assertion + failure from windows*/ + HWND hWnd = Detach(); + ::PostMessage(hWnd, WM_QUIT, 0, 0); +} + + +BEGIN_MESSAGE_MAP(CChildView,CWnd ) + //{{AFX_MSG_MAP(CChildView) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CChildView message handlers + +BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) +{ + if (!CWnd::PreCreateWindow(cs)) + return FALSE; + + cs.style &= ~WS_BORDER; + cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, + NULL, HBRUSH(COLOR_WINDOW+1), NULL); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_SETFOCUS() + ON_COMMAND(ID_APP_EXIT, OnAppExit) + ON_MESSAGE(WM_OPENURL, Open) + ON_MESSAGE(WM_SETTINGCHANGE, OnSIPChange) + ON_MESSAGE(WM_SETSIZE,OnSetSize) + ON_MESSAGE(WM_NAVIGATE,OnNavigate) + ON_WM_SIZE() + ON_COMMAND(ID_FILE_STEP, OnFileStep) + ON_UPDATE_COMMAND_UI(ID_FILE_STEP, OnUpdateFileStep) + ON_COMMAND(ID_FILE_PAUSE, OnFilePause) + ON_UPDATE_COMMAND_UI(ID_FILE_PAUSE, OnUpdateFilePause) + ON_COMMAND(ID_FILE_STOP, OnFileStop) + ON_UPDATE_COMMAND_UI(ID_FILE_STOP, OnUpdateFileStop) + ON_COMMAND(ID_VIEW_FULLSCREEN, OnViewFullscreen) + ON_UPDATE_COMMAND_UI(ID_VIEW_FULLSCREEN, OnUpdateViewFullscreen) + ON_WM_CLOSE() + ON_COMMAND(ID_VIEW_FIT, OnViewFit) + ON_UPDATE_COMMAND_UI(ID_VIEW_FIT, OnUpdateViewFit) + ON_COMMAND(ID_VIEW_AR_ORIG, OnViewArOrig) + ON_COMMAND(ID_VIEW_AR_FILL, OnViewArFill) + ON_COMMAND(ID_VIEW_AR_43, OnViewAr43) + ON_COMMAND(ID_VIEW_AR_169, OnViewAr169) + ON_COMMAND(ID_NAV_NONE, OnNavNone) + ON_COMMAND(ID_NAV_SLIDE, OnNavSlide) + ON_COMMAND(ID_NAV_RESET, OnNaveReset) + ON_COMMAND_RANGE(ID_NAV_NONE, ID_NAV_EXAMINE, OnSetNavigation) + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_COMMAND(ID_VIEW_TIMING, OnViewTiming) + ON_UPDATE_COMMAND_UI(ID_VIEW_TIMING, OnUpdateViewTiming) + ON_WM_INITMENUPOPUP() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + GXOpenInput(); + m_view_timing = 0; + m_restore_fs = 0; +} + +CMainFrame::~CMainFrame() +{ + GXCloseInput(); +} + +void CMainFrame::OnSetFocus(CWnd* pOldWnd) +{ + if (m_restore_fs) { + m_restore_fs = 0; + GetApp()->ShowTaskBar(0); + OnViewFullscreen(); + } +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + COsmo4 *app = GetApp(); + + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + + // create a view to occupy the client area of the frame + if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW | WS_BORDER, + CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) + { + TRACE0("Failed to create view window\n"); + return -1; + } + m_wndView.ShowWindow(SW_HIDE); + + + if (!m_dumbWnd.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW | WS_BORDER, + CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) + { + TRACE0("Failed to create dumb window\n"); + return -1; + } + m_dumbWnd.SetWindowPos(this, 0, 0, app->m_screen_width, app->m_screen_height-app->m_menu_height, 0L); + m_dumbWnd.ShowWindow(SW_HIDE); + + if (!m_progBar.Create(IDD_CONTROL , this) ) { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + m_progBar.UpdateWindow(); + m_progBar.SetWindowPos(this, 0, 0, app->m_screen_width, app->m_menu_height, 0L); + m_progBar.ShowWindow(SW_SHOWNORMAL); + + +// m_wndCommandBar.m_bShowSharedNewButton = FALSE; + + if (!m_wndCommandBar.Create(this) + || !m_wndCommandBar.InsertMenuBar(IDR_MENU) + || !m_wndCommandBar.AddAdornments() + || !m_wndCommandBar.LoadBitmap(IDR_MAINFRAME) + ) + { + TRACE0("Failed to create CommandBar\n"); + return -1; // fail to create + } + + CToolBarCtrl & toolBar = m_wndCommandBar.GetToolBarCtrl(); + TBBUTTON tb; + memset(&tb, 0, sizeof(tb)); + tb.idCommand = ID_OPEN_FILE; + tb.iBitmap = 0; + tb.fsStyle = TBSTYLE_BUTTON; + toolBar.AddButtons(1, &tb); + tb.idCommand = 0; + tb.iBitmap = 0; + tb.fsStyle = TBSTYLE_SEP; + toolBar.AddButtons(1, &tb); + tb.idCommand = ID_FILE_PAUSE; + tb.iBitmap = 1; + tb.fsStyle = TBSTYLE_BUTTON; + toolBar.AddButtons(1, &tb); + tb.idCommand = ID_FILE_STEP; + tb.iBitmap = 2; + tb.fsStyle = TBSTYLE_BUTTON; + toolBar.AddButtons(1, &tb); + tb.idCommand = ID_FILE_STOP; + tb.iBitmap = 3; + tb.fsStyle = TBSTYLE_BUTTON; + toolBar.AddButtons(1, &tb); + tb.idCommand = 0; + tb.iBitmap = 0; + tb.fsStyle = TBSTYLE_SEP; + toolBar.AddButtons(1, &tb); + + SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE); + SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE); + SetWindowPos(NULL, 0, 0, app->m_screen_width, app->m_screen_height, 0L); + + SetWindowText(_T("Osmo4")); + return 0; +} + +void CMainFrame::SetPauseButton(Bool force_play_button) +{ + CToolBarCtrl & toolBar = m_wndCommandBar.GetToolBarCtrl(); + TBBUTTON tb; + memset(&tb, 0, sizeof(tb)); + tb.idCommand = ID_FILE_PAUSE; + tb.fsStyle = TBSTYLE_BUTTON; + + 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; + } + toolBar.DeleteButton(5); + toolBar.InsertButton(5, &tb); +} + + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + // TODO: Modify the Window class or styles here by modifying + // the CREATESTRUCT cs + + + cs.lpszClass = AfxRegisterWndClass(0); + return TRUE; +} + + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +/* +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG +*/ + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers +BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + // let the view have first crack at the command + if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) + return TRUE; + + // otherwise, do default handling + return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); +} + +#define PROGRESS_TIMER 20 +#define PROGRESS_REFRESH_MS 500 + +void CALLBACK EXPORT ProgressTimer(HWND , UINT , UINT nID , DWORD ) +{ + if (nID != PROGRESS_TIMER) return; + ((CMainFrame *) GetApp()->m_pMainWnd)->UpdateTime(); +} + +void CMainFrame::UpdateTime() +{ + u32 now; + + COsmo4 *app = GetApp(); + if (!app->m_open || app->m_stopped) return; + now = gf_term_get_time_in_ms(app->m_term); + if (!now) return; + + if (app->m_can_seek && (now>=app->m_duration + 100)) { + if (gf_term_get_option(app->m_term, GF_OPT_IS_FINISHED)) { + if (app->m_Loop && m_full_screen) { + gf_term_play_from_time(app->m_term, 0, 0); + } else { + OnFileStop(); + if (app->m_Loop) OnFilePause(); + } + return; + } + } + + if (!m_full_screen) m_progBar.SetPosition(now); +} + +void CMainFrame::CloseURL() +{ + COsmo4 *app = GetApp(); + if (!app->m_open) return; + if (m_view_timing) KillTimer(PROGRESS_TIMER); + gf_term_disconnect(app->m_term); + app->m_open = 0; + app->m_can_seek = 0; + app->m_duration = (u32) -1; + m_progBar.m_prev_time = 0; + m_progBar.SetPosition(0); +} + +void CMainFrame::OnAppExit() +{ + CloseURL(); + PostMessage(WM_QUIT); +} + +void CMainFrame::OnSize(UINT nType, int cx, int cy) +{ + COsmo4 *app = GetApp(); + u32 disp_w, disp_h, c_w, c_h, x, y; + + if (m_full_screen) return; + + disp_w = app->m_screen_width; + disp_h = app->m_screen_height; + CFrameWnd::OnSize(nType, disp_w, disp_h); + + x = y = 0; + disp_h -= app->m_menu_height; + + if (m_view_timing) { + disp_h -= app->m_menu_height; + y = app->m_menu_height; + m_progBar.SetWindowPos(this, 0, 0, app->m_screen_width, app->m_menu_height, 0L); + m_progBar.ShowWindow(SW_SHOWNORMAL); + } else { + m_progBar.ShowWindow(SW_HIDE); + } + m_dumbWnd.SetWindowPos(this, 0, y, disp_w, disp_h, 0L); + m_dumbWnd.ShowWindow(SW_SHOW); + + if (m_view_timing) + SetTimer(PROGRESS_TIMER, PROGRESS_REFRESH_MS, ProgressTimer); + + if (!app->m_scene_width || !app->m_scene_height) { + m_wndView.SetWindowPos(this, 0, y, disp_w, disp_h, SWP_SHOWWINDOW); + gf_term_set_size(app->m_term, disp_w, disp_h); + return; + } + + if (!app->m_fit_screen && (app->m_scene_width < disp_w) && (app->m_scene_height < disp_h)) { + c_w = app->m_scene_width; + c_h = app->m_scene_height; + x = (disp_w - c_w) / 2; + y = (disp_h - c_h) / 2; + } else { + c_w = disp_w; + c_h = disp_h; + } + m_wndView.SetWindowPos(this, x, y, c_w, c_h, SWP_SHOWWINDOW | SWP_NOZORDER); + gf_term_set_size(app->m_term, c_w, c_h); +} + + +void CMainFrame::OnViewFullscreen() +{ + COsmo4 *app = GetApp(); + if (!app->m_open) return; + u32 disp_w = app->m_screen_width; + u32 disp_h = app->m_screen_height; + + Bool is_full_screen = !m_full_screen; + + /*prevent resize messages*/ + m_full_screen = 1; + + HWND hWnd = GetSafeHwnd(); + ::SetForegroundWindow(hWnd); + ::CommandBar_Show(m_wndCommandBar.GetSafeHwnd(), is_full_screen ? FALSE : TRUE); + SHFullScreen(hWnd, SHFS_HIDESTARTICON | SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON); + + if (is_full_screen) { + m_dumbWnd.ShowWindow(SW_HIDE); + + ::MoveWindow(m_hWnd, 0, 0, disp_w, disp_h, 0); + m_wndView.GetWindowRect(&m_view_rc); + m_wndView.SetWindowPos(this, 0, 0, disp_w, disp_h, SWP_NOZORDER); + gf_term_set_option(app->m_term, GF_OPT_FULLSCREEN, is_full_screen); + m_full_screen = 1; + } else { + gf_term_set_option(app->m_term, GF_OPT_FULLSCREEN, is_full_screen); + m_full_screen = 0; + OnSetSize(0,0); + m_dumbWnd.ShowWindow(SW_SHOW); + gf_term_set_option(app->m_term, GF_OPT_REFRESH, 0); + } +} + + +void CMainFrame::OnUpdateViewFullscreen(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(GetApp()->m_open ? TRUE : FALSE); +} + +LONG CMainFrame::OnSetSize(WPARAM wParam, LPARAM lParam) +{ + RECT rc; + if (m_full_screen) return 0; + GetWindowRect(&rc); + SetWindowPos(NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top, SWP_NOZORDER | SWP_NOMOVE); + return 1; +} + +LONG CMainFrame::Open(WPARAM wParam, LPARAM lParam) +{ + COsmo4 *app = GetApp(); + CloseURL(); + char filename[5000]; + CE_WideToChar((u16 *) (LPCTSTR) app->m_filename, filename); + app->m_stopped = 0; + + if (app->m_reconnect_time) { + gf_term_connect_from_time(app->m_term, filename, app->m_reconnect_time, 0); + app->m_reconnect_time = 0; + } else { + gf_term_connect(app->m_term, filename); + } + app->SetBacklightState(1); + return 1; +} + + + + +LONG CMainFrame::OnNavigate(WPARAM /*wParam*/, LPARAM /*lParam*/) +{ + COsmo4 *app = GetApp(); + char to_url[MAX_PATH]; + CE_WideToChar((u16 *) (LPCTSTR) app->m_navigate_url, to_url); + + if (gf_term_is_supported_url(app->m_term, to_url, 1, app->m_no_mime_fetch)) { + char fileName[MAX_PATH]; + 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 = gf_strdup(to_url); + CE_CharToWide(str, (u16 *)w_to_url); + gf_free(str); + app->m_filename = w_to_url; + Open(0, 0); + } else { + SHELLEXECUTEINFO info; + console_message = app->m_navigate_url; + console_err = GF_OK; + PostMessage(WM_CONSOLEMSG); + + + if (m_full_screen) { + OnViewFullscreen(); + app->ShowTaskBar(1); + m_restore_fs = 1; + } + + memset(&info, 0, sizeof(SHELLEXECUTEINFO)); + info.cbSize = sizeof(SHELLEXECUTEINFO); + info.lpVerb = L"open"; + info.fMask = SEE_MASK_NOCLOSEPROCESS; + info.lpFile = L"iexplore"; + info.lpParameters = (LPCTSTR) app->m_navigate_url; + info.nShow = SW_SHOWNORMAL; + ShellExecuteEx(&info); + } + return 1; +} + +void CMainFrame::OnFilePause() +{ + COsmo4 *app = GetApp(); + if (app->m_stopped) { + char filename[5000]; + CE_WideToChar((u16 *) (LPCTSTR) app->m_filename, filename); + app->m_stopped = 0; + gf_term_connect(app->m_term, filename); + app->SetBacklightState(1); + + if (m_view_timing) + SetTimer(PROGRESS_TIMER, PROGRESS_REFRESH_MS, ProgressTimer); + + SetPauseButton(); + } else { + app->Pause(); + } +} +void CMainFrame::OnUpdateFilePause(CCmdUI* pCmdUI) +{ + COsmo4 *app = GetApp(); + 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_stopped = 1; + if (m_view_timing) KillTimer(PROGRESS_TIMER); + gf_term_disconnect(app->m_term); + m_progBar.SetPosition(0); + app->SetBacklightState(0); + SetPauseButton(); +} + +void CMainFrame::OnUpdateFileStop(CCmdUI* pCmdUI) +{ + pCmdUI->Enable( GetApp()->m_open ? TRUE : FALSE); +} + +void CMainFrame::OnFileStep() +{ + COsmo4 *app = GetApp(); + gf_term_set_option(app->m_term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); + app->SetBacklightState(0); + SetPauseButton(1); +} +void CMainFrame::OnUpdateFileStep(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(GetApp()->m_open ? TRUE : FALSE); +} + +void CMainFrame::OnClose() +{ + PostMessage(WM_DESTROY); +} + +LONG CMainFrame::OnSIPChange(WPARAM wParam, LPARAM lParam) +{ + if (wParam == SPI_SETSIPINFO) GetApp()->ShowTaskBar(0); + return 1; +} + +void CMainFrame::OnViewFit() +{ + COsmo4 *app = GetApp(); + app->m_fit_screen = !app->m_fit_screen; + if (app->m_open) OnSetSize(0, 0); +} + +void CMainFrame::OnUpdateViewFit(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(GetApp()->m_fit_screen ? TRUE : FALSE); +} + +void CMainFrame::OnViewArOrig() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); +} +void CMainFrame::OnViewArFill() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); +} +void CMainFrame::OnViewAr43() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); +} +void CMainFrame::OnViewAr169() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); +} + +void CMainFrame::OnNavNone() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE); +} + +void CMainFrame::OnNavSlide() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE); +} + +void CMainFrame::OnNaveReset() +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_NAVIGATION_TYPE, 0); +} + +void CMainFrame::ForwardMessage() +{ + const MSG *msg = GetCurrentMessage(); + m_wndView.SendMessage(msg->message, msg->wParam, msg->lParam); +} +void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + ForwardMessage(); +} +void CMainFrame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) +{ + ForwardMessage(); +} + + +void CMainFrame::OnViewTiming() +{ + if (m_full_screen) return; + if (m_view_timing) KillTimer(PROGRESS_TIMER); + m_view_timing = !m_view_timing; + OnSetSize(0, 0); +} + +void CMainFrame::OnUpdateViewTiming(CCmdUI* pCmdUI) +{ + pCmdUI->SetCheck(m_view_timing ? TRUE : FALSE); +} + +void CMainFrame::OnSetNavigation(UINT nID) +{ + gf_term_set_option(GetApp()->m_term, GF_OPT_NAVIGATION, nID - ID_NAV_NONE); +} + + +void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) +{ + COsmo4 *app = GetApp(); + CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); + + u32 opt = gf_term_get_option(GetApp()->m_term, GF_OPT_ASPECT_RATIO); + CheckMenuItem(pPopupMenu->m_hMenu, ID_VIEW_AR_ORIG, MF_BYCOMMAND| (opt==GF_ASPECT_RATIO_KEEP) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(pPopupMenu->m_hMenu, ID_VIEW_AR_FILL, MF_BYCOMMAND| (opt==GF_ASPECT_RATIO_FILL_SCREEN) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(pPopupMenu->m_hMenu, ID_VIEW_AR_43, MF_BYCOMMAND| (opt==GF_ASPECT_RATIO_4_3) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(pPopupMenu->m_hMenu, ID_VIEW_AR_169, MF_BYCOMMAND| (opt==GF_ASPECT_RATIO_16_9) ? MF_CHECKED : MF_UNCHECKED); + + CheckMenuItem(pPopupMenu->m_hMenu, ID_VIEW_FIT, MF_BYCOMMAND| app->m_fit_screen ? MF_CHECKED : MF_UNCHECKED); + + u32 type; + if (!app->m_open) type = GF_NAVIGATE_TYPE_NONE; + else type = gf_term_get_option(app->m_term, GF_OPT_NAVIGATION_TYPE); + + EnableMenuItem(pPopupMenu->m_hMenu, ID_NAV_NONE, MF_BYCOMMAND | ((type==GF_NAVIGATE_TYPE_NONE) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_NAV_SLIDE, MF_BYCOMMAND | ((type==GF_NAVIGATE_TYPE_NONE) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_NAV_RESET, MF_BYCOMMAND | ((type==GF_NAVIGATE_TYPE_NONE) ? MF_GRAYED : MF_ENABLED) ); + + EnableMenuItem(pPopupMenu->m_hMenu, ID_NAV_WALK, MF_BYCOMMAND | ( (type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_NAV_FLY, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_NAV_EXAMINE, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_COLLIDE_OFF, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_COLLIDE_REG, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_COLLIDE_DISP, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) ); + EnableMenuItem(pPopupMenu->m_hMenu, ID_NAV_GRAVITY, MF_BYCOMMAND | ((type!=GF_NAVIGATE_TYPE_3D) ? MF_GRAYED : MF_ENABLED) ); + + if (type==GF_NAVIGATE_TYPE_NONE) { + u32 mode = gf_term_get_option(app->m_term, GF_OPT_NAVIGATION); + CheckMenuItem(pPopupMenu->m_hMenu, ID_NAV_NONE, MF_BYCOMMAND | ( (mode==GF_NAVIGATE_NONE) ? MF_CHECKED : MF_UNCHECKED) ); + CheckMenuItem(pPopupMenu->m_hMenu, ID_NAV_SLIDE, MF_BYCOMMAND | ( (mode==GF_NAVIGATE_SLIDE) ? MF_CHECKED : MF_UNCHECKED) ); + CheckMenuItem(pPopupMenu->m_hMenu, ID_NAV_WALK, MF_BYCOMMAND | ( (mode==GF_NAVIGATE_WALK) ? MF_CHECKED : MF_UNCHECKED) ); + CheckMenuItem(pPopupMenu->m_hMenu, ID_NAV_FLY, MF_BYCOMMAND | ((mode==GF_NAVIGATE_FLY) ? MF_CHECKED : MF_UNCHECKED) ); + CheckMenuItem(pPopupMenu->m_hMenu, ID_NAV_EXAMINE, MF_BYCOMMAND | ((mode==GF_NAVIGATE_EXAMINE) ? MF_CHECKED : MF_UNCHECKED) ); + } +} diff --git a/applications/deprecated/old_arch/osmo4_wce/MainFrm.h b/applications/deprecated/old_arch/osmo4_wce/MainFrm.h new file mode 100644 index 0000000..55de690 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/MainFrm.h @@ -0,0 +1,151 @@ +// MainFrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__1DEE4BC7_6B56_48A8_BDD7_5DC14EF6AD3E__INCLUDED_) +#define AFX_MAINFRM_H__1DEE4BC7_6B56_48A8_BDD7_5DC14EF6AD3E__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#include "ProgressBar.h" + + +class CChildView : public CWnd +{ +// Construction +public: + CChildView(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CChildView) +protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CChildView(); + // Generated message map functions +protected: + //{{AFX_MSG(CChildView) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class CMainFrame : public CFrameWnd +{ +public: + CMainFrame(); + + + +protected: + DECLARE_DYNAMIC(CMainFrame) + +// Attributes +public: + + ProgressBar m_progBar; + Bool m_full_screen, m_restore_fs, m_view_timing; + u32 m_timer_on; + CString console_message; + GF_Err console_err; + u32 m_aspect_ratio; + +// Operations +public: + void SetPauseButton(Bool force_play_button = 0); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + afx_msg void OnSetFocus(CWnd *pOldWnd); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CMainFrame(); + + /* + #ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; + #endif + */ + +protected: // control bar embedded members + +#if (_MSC_VER >= 1300) + CCommandBar m_wndCommandBar; +#else + CCeCommandBar m_wndCommandBar; +#endif + + void CloseURL(); + void ForwardMessage(); + +private: + RECT m_view_rc; + +public: + /*m_dumbWnd is used to clean the screen...*/ + CChildView m_wndView, m_dumbWnd; + void UpdateTime(); + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnAppExit(); + afx_msg LONG Open(WPARAM wParam, LPARAM lParam); + afx_msg LONG OnSIPChange(WPARAM wParam, LPARAM lParam); + afx_msg LONG OnSetSize(WPARAM wParam, LPARAM lParam); + afx_msg LONG OnNavigate(WPARAM wParam, LPARAM lParam); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnFileStep(); + afx_msg void OnUpdateFileStep(CCmdUI* pCmdUI); + afx_msg void OnFilePause(); + afx_msg void OnUpdateFilePause(CCmdUI* pCmdUI); + afx_msg void OnFileStop(); + afx_msg void OnUpdateFileStop(CCmdUI* pCmdUI); + afx_msg void OnViewFullscreen(); + afx_msg void OnUpdateViewFullscreen(CCmdUI* pCmdUI); + afx_msg void OnClose(); + afx_msg void OnViewFit(); + afx_msg void OnUpdateViewFit(CCmdUI* pCmdUI); + afx_msg void OnViewArOrig(); + afx_msg void OnViewArFill(); + afx_msg void OnViewAr43(); + afx_msg void OnViewAr169(); + afx_msg void OnNavNone(); + afx_msg void OnNavSlide(); + afx_msg void OnNaveReset(); + afx_msg void OnSetNavigation(UINT nID); + + afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags); + afx_msg void OnViewTiming(); + afx_msg void OnUpdateViewTiming(CCmdUI* pCmdUI); + afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); + //}}AFX_MSG + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__1DEE4BC7_6B56_48A8_BDD7_5DC14EF6AD3E__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_wce/OpenDlg.cpp b/applications/deprecated/old_arch/osmo4_wce/OpenDlg.cpp new file mode 100644 index 0000000..938e030 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/OpenDlg.cpp @@ -0,0 +1,92 @@ +// OpenDlg.cpp : implementation file +// +#include "stdafx.h" +#include "resource.h" +#include "OpenDlg.h" +#include "Osmo4.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// OpenDlg dialog + + +OpenDlg::OpenDlg(CWnd* pParent /*=NULL*/) + : CDialog(OpenDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(OpenDlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void OpenDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(OpenDlg) + DDX_Control(pDX, IDC_FILELIST, m_URLs); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(OpenDlg, CDialog) + //{{AFX_MSG_MAP(OpenDlg) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +void OpenDlg::OnOK() +{ + CString URL; + char szUrl[5000]; + + int sel = m_URLs.GetCurSel(); + if (sel == CB_ERR) { + m_URLs.GetWindowText(URL); + } else { + m_URLs.GetLBText(sel, URL); + } + if (!URL.GetLength()) { + EndDialog(IDCANCEL); + return; + } + COsmo4 *app = GetApp(); + u32 nb_entries; + + app->m_filename = URL; + + CE_WideToChar((unsigned short *) (LPCTSTR) URL, szUrl); + + gf_cfg_set_key(app->m_user.config, "RecentFiles", szUrl, NULL); + gf_cfg_insert_key(app->m_user.config, "RecentFiles", szUrl, "", 0); + /*remove last entry if needed*/ + nb_entries = gf_cfg_get_key_count(app->m_user.config, "RecentFiles"); + if (nb_entries>20) { + gf_cfg_set_key(app->m_user.config, "RecentFiles", gf_cfg_get_key_name(app->m_user.config, "RecentFiles", nb_entries-1), NULL); + } + EndDialog(IDOK); +} + +BOOL OpenDlg::OnInitDialog() +{ + TCHAR w_str[5000]; + CDialog::OnInitDialog(); + COsmo4 *app = GetApp(); + const char *sOpt; + u32 i=0; + + while (m_URLs.GetCount()) m_URLs.DeleteString(0); + while (1) { + sOpt = gf_cfg_get_key_name(app->m_user.config, "RecentFiles", i); + if (!sOpt) break; + CE_CharToWide((char *) sOpt, (u16 *)w_str); + m_URLs.AddString(w_str); + i++; + } + + SetFocus(); + return TRUE; +} diff --git a/applications/deprecated/old_arch/osmo4_wce/OpenDlg.h b/applications/deprecated/old_arch/osmo4_wce/OpenDlg.h new file mode 100644 index 0000000..6a55b96 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/OpenDlg.h @@ -0,0 +1,47 @@ +#if !defined(AFX_OPENDLG_H__DD903B38_EA45_4251_A8C9_4E4B08BECCCC__INCLUDED_) +#define AFX_OPENDLG_H__DD903B38_EA45_4251_A8C9_4E4B08BECCCC__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 +// OpenDlg.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// OpenDlg dialog + +class OpenDlg : public CDialog +{ +// Construction +public: + OpenDlg(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(OpenDlg) + enum { IDD = IDD_OPENFILE }; + CComboBox m_URLs; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(OpenDlg) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(OpenDlg) + virtual void OnOK(); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OPENDLG_H__DD903B38_EA45_4251_A8C9_4E4B08BECCCC__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_wce/Options.cpp b/applications/deprecated/old_arch/osmo4_wce/Options.cpp new file mode 100644 index 0000000..96805d9 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/Options.cpp @@ -0,0 +1,1237 @@ +// Options.cpp : implementation file +// + +#include "stdafx.h" +#include "Osmo4.h" +#include +#include +#include +#include +#include +#include + +#include "Options.h" +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// COptions dialog + + +COptions::COptions(CWnd* pParent /*=NULL*/) + : CDialog(COptions::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptions) + //}}AFX_DATA_INIT + +} + + +void COptions::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptions) + DDX_Control(pDX, IDC_COMBOSEL, m_Selection); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptions, CDialog) + //{{AFX_MSG_MAP(COptions) + ON_BN_CLICKED(IDC_SAVEOPT, OnSaveopt) + ON_CBN_SELCHANGE(IDC_COMBOSEL, OnSelchangeCombosel) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptions message handlers + + +void COptions::OnSelchangeCombosel() +{ + HideAll(); + switch (m_Selection.GetCurSel()) { + case 0: + m_general.ShowWindow(SW_SHOW); + break; + case 1: + m_systems.ShowWindow(SW_SHOW); + break; + case 2: + m_decoder.ShowWindow(SW_SHOW); + break; + case 3: + m_render.ShowWindow(SW_SHOW); + break; + case 4: + m_render3D.ShowWindow(SW_SHOW); + break; + case 5: + m_audio.ShowWindow(SW_SHOW); + break; + case 6: + m_font.ShowWindow(SW_SHOW); + break; + case 7: + m_http.ShowWindow(SW_SHOW); + break; + case 8: + m_stream.ShowWindow(SW_SHOW); + break; + } +} + +void COptions::HideAll() +{ + m_general.ShowWindow(SW_HIDE); + m_systems.ShowWindow(SW_HIDE); + m_render.ShowWindow(SW_HIDE); + m_render3D.ShowWindow(SW_HIDE); + m_audio.ShowWindow(SW_HIDE); + m_http.ShowWindow(SW_HIDE); + m_font.ShowWindow(SW_HIDE); + m_stream.ShowWindow(SW_HIDE); + m_decoder.ShowWindow(SW_HIDE); +} + +BOOL COptions::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_general.Create(IDD_OPT_GEN, this); + m_systems.Create(IDD_OPT_SYSTEMS, this); + m_decoder.Create(IDD_OPT_DECODER, this); + m_render.Create(IDD_OPT_RENDER, this); + m_render3D.Create(IDD_OPT_RENDER3D, this); + m_audio.Create(IDD_OPT_AUDIO, this); + m_http.Create(IDD_OPT_HTTP, this); + m_font.Create(IDD_OPT_FONT, this); + m_stream.Create(IDD_OPT_STREAM, this); + + m_Selection.AddString(_T("General")); + m_Selection.AddString(_T("MPEG-4 Systems")); + m_Selection.AddString(_T("Decoders")); + m_Selection.AddString(_T("Compositor")); + m_Selection.AddString(_T("3D Rendering")); + m_Selection.AddString(_T("Audio")); + m_Selection.AddString(_T("Text")); + m_Selection.AddString(_T("Download")); + m_Selection.AddString(_T("Streaming")); + HideAll(); + + const char *sOpt = gf_cfg_get_key(GetApp()->m_user.config, "General", "ConfigPanel"); + u32 sel = sOpt ? atoi(sOpt) : 0; + if (sel>8) sel=8; + m_Selection.SetCurSel(sel); + OnSelchangeCombosel(); + + SetFocus(); + return TRUE; +} + +void COptions::OnSaveopt() +{ + m_general.SaveOptions(); + m_systems.SaveOptions(); + m_render.SaveOptions(); + m_render3D.SaveOptions(); + m_audio.SaveOptions(); + m_http.SaveOptions(); + m_font.SaveOptions(); + m_stream.SaveOptions(); + m_decoder.SaveOptions(); + + COsmo4 *gpac = GetApp(); + gf_term_set_option(gpac->m_term, GF_OPT_RELOAD_CONFIG, 1); +} + +void COptions::OnOK() +{ + char str[20]; + sprintf(str, "%d", m_Selection.GetCurSel()); + gf_cfg_set_key(GetApp()->m_user.config, "General", "ConfigPanel", str); + + EndDialog(IDCANCEL); +} + + + +COptAudio::COptAudio(CWnd* pParent /*=NULL*/) + : CDialog(COptAudio::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptAudio) + //}}AFX_DATA_INIT +} + + +void COptAudio::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptAudio) + DDX_Control(pDX, IDC_DRIVER_LIST, m_DriverList); + DDX_Control(pDX, IDC_AUDIO_RESYNC, m_AudioResync); + DDX_Control(pDX, IDC_AUDIO_DUR, m_AudioDur); + DDX_Control(pDX, IDC_SPIN_DUR, m_SpinDur); + DDX_Control(pDX, IDC_FORCE_AUDIO, m_ForceConfig); + DDX_Control(pDX, IDC_SPIN_AUDIO, m_AudioSpin); + DDX_Control(pDX, IDC_EDIT_AUDIO, m_AudioEdit); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptAudio, CDialog) + //{{AFX_MSG_MAP(COptAudio) + ON_BN_CLICKED(IDC_FORCE_AUDIO, OnForceAudio) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptAudio message handlers + +BOOL COptAudio::OnInitDialog() +{ + CDialog::OnInitDialog(); + + m_AudioSpin.SetBuddy(& m_AudioEdit); + m_SpinDur.SetBuddy(& m_AudioDur); + m_SpinDur.SetRange(0, 1000); + + COsmo4 *gpac = GetApp(); + const char *sOpt; + TCHAR wTmp[500]; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "ForceConfig"); + m_ForceConfig.SetCheck( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "NumBuffers"); + if (sOpt) { + CE_CharToWide((char *)sOpt, (u16 *)wTmp); + m_AudioEdit.SetWindowText(wTmp); + } else { + m_AudioEdit.SetWindowText(_T("2")); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "TotalDuration"); + if (sOpt) { + CE_CharToWide((char *)sOpt, (u16 *)wTmp); + m_AudioDur.SetWindowText(wTmp); + } else { + m_AudioDur.SetWindowText(_T("200")); + } + + OnForceAudio(); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Audio", "NoResync"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_AudioResync.SetCheck(1); + } else { + m_AudioResync.SetCheck(0); + } + + /*driver enum*/ + while (m_DriverList.GetCount()) m_DriverList.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "core", "audio-output"); + u32 count = gf_modules_get_count(gpac->m_user.modules); + GF_BaseInterface *ifce; + s32 select = 0; + s32 to_sel = 0; + for (u32 i=0; im_user.modules, i, GF_AUDIO_OUTPUT_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + CE_CharToWide((char *) ((GF_BaseInterface *)ifce)->module_name, (u16 *)wTmp); + m_DriverList.AddString(wTmp); + gf_modules_close_interface(ifce); + to_sel++; + } + m_DriverList.SetCurSel(select); + + + return TRUE; +} + + +void COptAudio::SaveOptions() +{ + COsmo4 *gpac = GetApp(); + TCHAR wstr[50]; + char str[50]; + + gf_cfg_set_key(gpac->m_user.config, "Audio", "ForceConfig", m_ForceConfig.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Audio", "NoResync", m_AudioResync.GetCheck() ? "yes" : "no"); + + m_AudioEdit.GetWindowText(wstr, 20); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "Audio", "NumBuffers", str); + m_AudioDur.GetWindowText(wstr, 20); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "Audio", "TotalDuration", str); + + m_DriverList.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "core", "audio-output", str); + +} + +void COptAudio::OnForceAudio() +{ + BOOL en = m_ForceConfig.GetCheck(); + + m_AudioSpin.EnableWindow(en); + m_AudioEdit.EnableWindow(en); + m_SpinDur.EnableWindow(en); + m_AudioDur.EnableWindow(en); +} + + +COptDecoder::COptDecoder(CWnd* pParent /*=NULL*/) + : CDialog(COptDecoder::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptDecoder) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void COptDecoder::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptDecoder) + DDX_Control(pDX, IDC_VIDEC_LIST, m_Video); + DDX_Control(pDX, IDC_AUDEC_LIST, m_Audio); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptDecoder, CDialog) + //{{AFX_MSG_MAP(COptDecoder) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptDecoder message handlers + +BOOL COptDecoder::OnInitDialog() +{ + u32 i; + CDialog::OnInitDialog(); + + COsmo4 *gpac = GetApp(); + const char *sOpt; + + /*audio dec enum*/ + while (m_Audio.GetCount()) m_Audio.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "DefAudioDec"); + u32 count = gf_modules_get_count(gpac->m_user.modules); + GF_BaseDecoder *ifce; + s32 select = 0; + s32 to_sel = 0; + for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); + if (!ifce) continue; + if (ifce->CanHandleStream(ifce, GF_STREAM_AUDIO, NULL, 0)) { + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + TCHAR wzTmp[500]; + CE_CharToWide((char *) ifce->module_name, (u16 *)wzTmp); + m_Audio.AddString(wzTmp); + to_sel++; + } + gf_modules_close_interface((GF_BaseInterface *) ifce); + } + m_Audio.SetCurSel(select); + + /*audio dec enum*/ + while (m_Video.GetCount()) m_Video.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "DefVideoDec"); + count = gf_modules_get_count(gpac->m_user.modules); + select = 0; + to_sel = 0; + for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); + if (!ifce) continue; + if (ifce->CanHandleStream(ifce, GF_STREAM_VISUAL, NULL, 0)) { + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + TCHAR wzTmp[500]; + CE_CharToWide((char *) ifce->module_name, (u16 *)wzTmp); + m_Video.AddString(wzTmp); + to_sel++; + } + gf_modules_close_interface((GF_BaseInterface *) ifce); + } + m_Video.SetCurSel(select); + + return TRUE; +} + +void COptDecoder::SaveOptions() +{ + COsmo4 *gpac = GetApp(); + TCHAR wstr[100]; + char str[100]; + + m_Audio.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "Systems", "DefAudioDec", str); + m_Video.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "Systems", "DefVideoDec", str); +} + + + +COptFont::COptFont(CWnd* pParent /*=NULL*/) + : CDialog(COptFont::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptFont) + //}}AFX_DATA_INIT +} + + +void COptFont::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptFont) + DDX_Control(pDX, IDC_USE_TEXTURE, m_UseTexture); + DDX_Control(pDX, IDC_FONT_LIST, m_Fonts); + DDX_Control(pDX, IDC_BROWSE_FONT, m_BrowseFont); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptFont, CDialog) + //{{AFX_MSG_MAP(COptFont) + ON_BN_CLICKED(IDC_BROWSE_FONT, OnBrowseFont) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptFont message handlers + +BOOL COptFont::OnInitDialog() +{ + u32 i; + GF_BaseInterface *ifce; + + CDialog::OnInitDialog(); + + COsmo4 *gpac = GetApp(); + TCHAR wTmp[500]; + const char *sOpt; + + /*video drivers enum*/ + while (m_Fonts.GetCount()) m_Fonts.DeleteString(0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "FontCache", "FontReader"); + s32 to_sel = 0; + s32 select = 0; + u32 count = gf_modules_get_count(gpac->m_user.modules); + for (i=0; im_user.modules, i, GF_FONT_READER_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + CE_CharToWide((char *) ifce->module_name, (u16 *)wTmp); + m_Fonts.AddString(wTmp); + gf_modules_close_interface(ifce); + to_sel++; + } + m_Fonts.SetCurSel(select); + + + sOpt = gf_cfg_get_key(gpac->m_user.config, "FontCache", "FontDirectory"); + CE_CharToWide((char *)sOpt, (u16 *)wTmp); + if (sOpt) m_BrowseFont.SetWindowText(wTmp); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "TextureTextMode"); + m_UseTexture.SetCheck( (!sOpt || stricmp(sOpt, "Never")) ? 1 : 0); + + return TRUE; +} + +void COptFont::OnBrowseFont() +{ + +} + + +void COptFont::SaveOptions() +{ + COsmo4 *gpac = GetApp(); + char str[MAX_PATH]; + TCHAR wstr[MAX_PATH]; + + m_Fonts.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "FontCache", "FontReader", str); + m_BrowseFont.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "FontCache", "FontDirectory", str); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "TextureTextMode", m_UseTexture.GetCheck() ? "Default" : "Never"); +} + + + +COptGen::COptGen(CWnd* pParent /*=NULL*/) + : CDialog(COptGen::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptGen) + //}}AFX_DATA_INIT +} + + +void COptGen::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptGen) + DDX_Control(pDX, IDC_NO_BACKLIGHT, m_NoBacklight); + DDX_Control(pDX, IDC_FILL_SCREEN, m_Fill); + DDX_Control(pDX, IDC_LOOP, m_Loop); + DDX_Control(pDX, IDC_ENABLE_LOGS, m_Logs); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptGen, CDialog) + //{{AFX_MSG_MAP(COptGen) + ON_BN_CLICKED(IDC_FILEASSOC, OnFileassoc) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptGen message handlers + + + +BOOL COptGen::OnInitDialog() +{ + CDialog::OnInitDialog(); + COsmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "Loop"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_Loop.SetCheck(1); + } else { + m_Loop.SetCheck(0); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "FillScreen"); + m_Fill.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "DisableBackLight"); + m_NoBacklight.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "General", "Logs"); + m_Logs.SetCheck((sOpt && !strstr(sOpt, "none")) ? 1 : 0); + return TRUE; +} + +void COptGen::SaveOptions() +{ + COsmo4 *gpac = GetApp(); + + gpac->m_Loop = m_Loop.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "Loop", gpac->m_Loop ? "yes" : "no"); + gpac->m_fit_screen = m_Fill.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "FillScreen", gpac->m_fit_screen ? "yes" : "no"); + gpac->m_disable_backlight = m_NoBacklight.GetCheck(); + gf_cfg_set_key(gpac->m_user.config, "General", "DisableBackLight", gpac->m_disable_backlight ? "yes" : "no"); + + gpac->EnableLogs(m_Logs.GetCheck() ? 1 : 0); +} + +void COptGen::OnFileassoc() +{ + HKEY hSection; + TCHAR szDir[MAX_PATH]; + char szTemp[MAX_PATH]; + TCHAR cmd[MAX_PATH]; + DWORD ioSize = MAX_PATH; + DWORD dwDisp; + + RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Osmo4"), 0, KEY_READ, &hSection); + + GetModuleFileName(NULL, szDir, MAX_PATH); + + while (szDir[strlen((char *) szDir)-1] != (TCHAR) '\\') szDir[strlen((char *) szDir)-1] = 0; + if (!hSection) + RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Osmo4"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSection, &dwDisp); + + CE_WideToChar((u16 *)szDir, szTemp); + /*overwrite install dir with current path*/ + RegSetValueEx(hSection, _T("Install_Dir"), 0, REG_SZ, (const unsigned char *) szTemp, strlen(szTemp)+1); + RegCloseKey(hSection); + + + /*overwrite .mp4 file associations */ + RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("mp4file\\DefaultIcon"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSection, &dwDisp); + wcscpy(cmd, szDir); + wcscat(cmd, _T("Osmo4.ico") ); + CE_WideToChar((u16 *)cmd, szTemp); + + RegSetValueEx(hSection, _T(""), 0, REG_SZ, (const unsigned char *) szTemp, strlen((const char *) szTemp)+1); + RegCloseKey(hSection); + + RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("mp4file\\Shell\\open\\command"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSection, &dwDisp); + wcscpy(cmd, szDir); + wcscat(cmd, _T("Osmo4.exe \"%L\"") ); + CE_WideToChar((u16 *)cmd, szTemp); + RegSetValueEx(hSection, _T(""), 0, REG_SZ, (const unsigned char *) szTemp, strlen(szTemp)+1); + RegCloseKey(hSection); + + RegCreateKeyEx(HKEY_CLASSES_ROOT, _T(".mp4"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSection, &dwDisp); + RegSetValueEx(hSection, _T(""), 0, REG_SZ, (const unsigned char *) "mp4file", strlen("mp4file")+1); + RegCloseKey(hSection); +} + + + +COptHTTP::COptHTTP(CWnd* pParent /*=NULL*/) + : CDialog(COptHTTP::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptHTTP) + //}}AFX_DATA_INIT +} + + +void COptHTTP::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptHTTP) + DDX_Control(pDX, IDC_RESTART_CACHE, m_RestartFile); + DDX_Control(pDX, IDC_CLEAN_CACHE, m_CleanCache); + DDX_Control(pDX, IDC_BROWSE_CACHE, m_CacheDir); + DDX_Control(pDX, IDC_SAX_PROGRESSIVE, m_Progressive); + DDX_Control(pDX, IDC_SAX_DURATION, m_SaxDuration); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptHTTP, CDialog) + //{{AFX_MSG_MAP(COptHTTP) + ON_BN_CLICKED(IDC_BROWSE_CACHE, OnBrowseCache) + ON_BN_CLICKED(IDC_SAX_PROGRESSIVE, OnProgressive) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptHTTP message handlers + + +void COptHTTP::OnBrowseCache() +{ + +} + +BOOL COptHTTP::OnInitDialog() +{ + CDialog::OnInitDialog(); + + COsmo4 *gpac = GetApp(); + TCHAR wTmp[500]; + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "CleanCache"); + m_CleanCache.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "RestartFiles"); + m_RestartFile.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "SAXLoader", "Progressive"); + m_Progressive.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "SAXLoader", "MaxDuration"); + if (sOpt) { + CE_CharToWide((char *) sOpt, (u16 *)wTmp); + m_SaxDuration.SetWindowText(wTmp); + } else { + m_SaxDuration.SetWindowText( _T("30") ); + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Core", "CacheDirectory"); + CE_CharToWide((char *) sOpt, (u16 *)wTmp); + if (sOpt) m_CacheDir.SetWindowText(wTmp); + + OnProgressive(); + return TRUE; +} + +void COptHTTP::OnProgressive() +{ + m_SaxDuration.EnableWindow( m_Progressive.GetCheck() ? TRUE : FALSE ); +} + +void COptHTTP::SaveOptions() +{ + TCHAR wTmp[500]; + char szCacheDir[500]; + COsmo4 *gpac = GetApp(); + + gf_cfg_set_key(gpac->m_user.config, "Core", "CleanCache", m_CleanCache.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Core", "RestartFiles", m_RestartFile.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "SAXLoader", "Progressive", m_Progressive.GetCheck() ? "yes" : "no"); + + m_SaxDuration.GetWindowText(wTmp, MAX_PATH); + CE_WideToChar((u16 *)wTmp, szCacheDir); + gf_cfg_set_key(gpac->m_user.config, "SAXLoader", "MaxDuration", szCacheDir); + + m_CacheDir.GetWindowText(wTmp, MAX_PATH); + CE_WideToChar((u16 *)wTmp, szCacheDir); + gf_cfg_set_key(gpac->m_user.config, "Core", "CacheDirectory", szCacheDir); +} + + + +COptRender::COptRender(CWnd* pParent /*=NULL*/) + : CDialog(COptRender::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptRender) + //}}AFX_DATA_INIT +} + + +void COptRender::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptRender) + DDX_Control(pDX, IDC_AA_LIST, m_Antialias); + DDX_Control(pDX, IDC_FORCE_SIZE, m_ForceSize); + DDX_Control(pDX, IDC_FAST_RENDER, m_HighSpeed); + DDX_Control(pDX, IDC_ZOOM_SCALABLE, m_Scalable); + DDX_Control(pDX, IDC_DIRECTRENDER, m_DirectRender); + DDX_Control(pDX, IDC_BIFS_RATE, m_BIFSRate); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptRender, CDialog) + //{{AFX_MSG_MAP(COptRender) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptRender message handlers + + + +#define NUM_RATES 11 +static char *BIFSRates[11] = +{ + "5.0", + "7.5", + "10.0", + "12.5", + "15.0", + "24.0", + "25.0", + "30.0", + "50.0", + "60.0", + "100.0", +}; + + + +BOOL COptRender::OnInitDialog() +{ + CDialog::OnInitDialog(); + + COsmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "DirectDraw"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_DirectRender.SetCheck(1); + } else { + m_DirectRender.SetCheck(0); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "ScalableZoom"); + if (sOpt && !stricmp(sOpt, "no")) { + m_Scalable.SetCheck(0); + } else { + m_Scalable.SetCheck(1); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "ForceSceneSize"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_ForceSize.SetCheck(1); + } else { + m_ForceSize.SetCheck(0); + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "FrameRate"); + if (!sOpt) sOpt = "30.0"; + s32 select = 0; + while (m_BIFSRate.GetCount()) m_BIFSRate.DeleteString(0); + for (s32 i = 0; im_user.config, "Compositor", "HighSpeed"); + m_HighSpeed.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "AntiAlias"); + while (m_Antialias.GetCount()) m_Antialias.DeleteString(0); + + m_Antialias.AddString(_T("None")); + m_Antialias.AddString(_T("Text only")); + m_Antialias.AddString(_T("Complete")); + select = 2; + if (sOpt && !stricmp(sOpt, "Text")) select = 1; + else if (sOpt && !stricmp(sOpt, "None")) select = 0; + m_Antialias.SetCurSel(select); + + return TRUE; +} + + +void COptRender::SaveOptions() +{ + COsmo4 *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", "ScalableZoom", m_Scalable.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "HighSpeed", m_HighSpeed.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "ForceSceneSize", m_ForceSize.GetCheck() ? "yes" : "no"); + + s32 sel = m_BIFSRate.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "FrameRate", BIFSRates[sel]); + + sel = m_Antialias.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "AntiAlias", (sel==0) ? "None" : ( (sel==1) ? "Text" : "All")); +} + + + + +COptRender3D::COptRender3D(CWnd* pParent /*=NULL*/) + : CDialog(COptRender3D::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptRender) + //}}AFX_DATA_INIT +} + + +void COptRender3D::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptRender) + DDX_Control(pDX, IDC_WIRE_MODE, m_WireMode); + DDX_Control(pDX, IDC_DRAW_NORMALS, m_DrawNormals); + DDX_Control(pDX, IDC_USE_3D_REN, m_Use3DRender); + DDX_Control(pDX, IDC_NO_BACKCULL, m_NoBackFace); + DDX_Control(pDX, IDC_EMULATE_POW2, m_EmulatePOW2); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptRender3D, CDialog) + //{{AFX_MSG_MAP(COptRender3D) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +BOOL COptRender3D::OnInitDialog() +{ + CDialog::OnInitDialog(); + + COsmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "ForceOpenGL"); + m_Use3DRender.SetCheck( (sOpt && !strcmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "BackFaceCulling"); + m_NoBackFace.SetCheck( (sOpt && !stricmp(sOpt, "Off")) ? 1 : 0); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "EmulatePOW2"); + m_EmulatePOW2.SetCheck( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + m_WireMode.ResetContent(); + m_WireMode.AddString(_T("Solid Draw")); + m_WireMode.AddString(_T("Wireframe")); + m_WireMode.AddString(_T("Both")); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "Wireframe"); + if (sOpt && !stricmp(sOpt, "WireOnly")) m_WireMode.SetCurSel(1); + else if (sOpt && !stricmp(sOpt, "WireOnSolid")) m_WireMode.SetCurSel(2); + else m_WireMode.SetCurSel(0); + + + m_DrawNormals.ResetContent(); + m_DrawNormals.AddString(_T("Never")); + m_DrawNormals.AddString(_T("Per Face")); + m_DrawNormals.AddString(_T("Per Vertex")); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "DrawNormals"); + if (sOpt && !stricmp(sOpt, "PerFace")) m_DrawNormals.SetCurSel(1); + else if (sOpt && !stricmp(sOpt, "PerVertex")) m_DrawNormals.SetCurSel(2); + else m_DrawNormals.SetCurSel(0); + + return TRUE; +} + + +void COptRender3D::SaveOptions() +{ + COsmo4 *gpac = GetApp(); + + u32 sel = m_DrawNormals.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "DrawNormals", (sel==2) ? "PerVertex" : (sel==1) ? "PerFace" : "Never"); + + sel = m_WireMode.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "Wireframe", (sel==2) ? "WireOnSolid" : (sel==1) ? "WireOnly" : "WireNone"); + + gf_cfg_set_key(gpac->m_user.config, "Compositor", "BackFaceCulling", m_NoBackFace.GetCheck() ? "Off" : "On"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "EmulatePOW2", m_EmulatePOW2.GetCheck() ? "yes" : "no"); +} + + +COptStream::COptStream(CWnd* pParent /*=NULL*/) + : CDialog(COptStream::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptStream) + //}}AFX_DATA_INIT +} + + +void COptStream::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptStream) + DDX_Control(pDX, IDC_REBUFFER_LEN, m_RebufferLen); + DDX_Control(pDX, IDC_REBUFFER, m_Rebuffer); + DDX_Control(pDX, IDC_BUFFER, m_Buffer); + DDX_Control(pDX, IDC_TIMEOUT, m_Timeout); + DDX_Control(pDX, IDC_REORDER, m_Reorder); + DDX_Control(pDX, IDC_RTSP, m_UseRTSP); + DDX_Control(pDX, IDC_PORT, m_Port); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptStream, CDialog) + //{{AFX_MSG_MAP(COptStream) + ON_CBN_SELCHANGE(IDC_PORT, OnSelchangePort) + ON_BN_CLICKED(IDC_RTSP, OnRtsp) + ON_BN_CLICKED(IDC_REBUFFER, OnRebuffer) + ON_EN_UPDATE(IDC_REBUFFER_LEN, OnUpdateRebufferLen) + ON_EN_UPDATE(IDC_BUFFER, OnUpdateBuffer) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptStream message handlers + +BOOL COptStream::OnInitDialog() +{ + CDialog::OnInitDialog(); + + COsmo4 *gpac = GetApp(); + TCHAR wTmp[500]; + const char *sOpt; + + while (m_Port.GetCount()) m_Port.DeleteString(0); + m_Port.AddString(_T("554 (RTSP standard)")); + m_Port.AddString(_T("7070 (RTSP ext)")); + m_Port.AddString(_T("80 (RTSP / HTTP tunnel)")); + m_Port.AddString(_T("8080 (RTSP / HTTP tunnel)")); + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "DefaultPort"); + u32 port = 554; + Bool force_rtsp = 0;; + if (sOpt) port = atoi(sOpt); + switch (port) { + case 8080: + m_Port.SetCurSel(3); + force_rtsp = 1; + break; + case 80: + m_Port.SetCurSel(2); + force_rtsp = 1; + break; + case 7070: + m_Port.SetCurSel(1); + break; + default: + m_Port.SetCurSel(0); + break; + } + + Bool use_rtsp = 0; + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "RTPoverRTSP"); + if (sOpt && !stricmp(sOpt, "yes")) use_rtsp = 1; + + if (force_rtsp) { + m_UseRTSP.SetCheck(1); + m_UseRTSP.EnableWindow(0); + m_Reorder.SetCheck(0); + m_Reorder.EnableWindow(0); + } else { + m_UseRTSP.SetCheck(use_rtsp); + m_UseRTSP.EnableWindow(1); + m_Reorder.EnableWindow(1); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "ReorderSize"); + if (sOpt && !stricmp(sOpt, "0")) { + m_Reorder.SetCheck(0); + } else { + m_Reorder.SetCheck(1); + } + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Streaming", "RTSPTimeout"); + if (sOpt) { + CE_CharToWide((char *) sOpt, (u16 *)wTmp); + m_Timeout.SetWindowText(wTmp); + } else { + m_Timeout.SetWindowText(_T("30000")); + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Network", "BufferLength"); + if (sOpt) { + CE_CharToWide((char *) sOpt, (u16 *)wTmp); + m_Buffer.SetWindowText(wTmp); + } else { + m_Buffer.SetWindowText(_T("3000")); + } + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Network", "RebufferLength"); + u32 buf_len = 0; + if (sOpt) buf_len = atoi(sOpt); + if (buf_len) { + CE_CharToWide((char *) sOpt, (u16 *)wTmp); + m_RebufferLen.SetWindowText(wTmp); + m_Rebuffer.SetCheck(1); + m_RebufferLen.EnableWindow(1); + } else { + m_RebufferLen.SetWindowText(_T("0")); + m_Rebuffer.SetCheck(0); + m_RebufferLen.EnableWindow(0); + } + + return TRUE; +} + + +void COptStream::OnSelchangePort() +{ + s32 sel = m_Port.GetCurSel(); + switch (sel) { + case 3: + case 2: + m_UseRTSP.SetCheck(1); + m_UseRTSP.EnableWindow(0); + m_Reorder.SetCheck(0); + m_Reorder.EnableWindow(0); + break; + case 1: + default: + m_UseRTSP.SetCheck(0); + m_UseRTSP.EnableWindow(1); + m_Reorder.SetCheck(1); + m_Reorder.EnableWindow(1); + break; + } +} + +void COptStream::OnRtsp() +{ + if (m_UseRTSP.GetCheck()) { + m_Reorder.SetCheck(0); + m_Reorder.EnableWindow(0); + } else { + m_Reorder.SetCheck(1); + m_Reorder.EnableWindow(1); + } + +} + +void COptStream::CheckRebuffer() +{ + TCHAR wstr[50]; + char str[50]; + s32 buf, rebuf; + m_Buffer.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + buf = atoi(str); + m_RebufferLen.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + rebuf = atoi(str); + if (rebuf*2 > buf) { + rebuf = buf/2; + wsprintf(wstr, _T("%d"), rebuf); + m_RebufferLen.SetWindowText(wstr); + } +} + +void COptStream::OnRebuffer() +{ + if (!m_Rebuffer.GetCheck()) { + m_RebufferLen.EnableWindow(0); + } else { + m_RebufferLen.EnableWindow(1); + CheckRebuffer(); + } +} + +void COptStream::OnUpdateRebufferLen() +{ + CheckRebuffer(); +} + +void COptStream::OnUpdateBuffer() +{ + CheckRebuffer(); +} + +void COptStream::SaveOptions() +{ + COsmo4 *gpac = GetApp(); + Bool force_rtsp = 0; + s32 sel = m_Port.GetCurSel(); + switch (sel) { + case 3: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "8080"); + force_rtsp = 1; + break; + case 2: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "80"); + force_rtsp = 1; + break; + case 1: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "7070"); + break; + default: + gf_cfg_set_key(gpac->m_user.config, "Streaming", "DefaultPort", "554"); + break; + } + + if (force_rtsp) { + gf_cfg_set_key(gpac->m_user.config, "Streaming", "RTPoverRTSP", "yes"); + } else { + gf_cfg_set_key(gpac->m_user.config, "Streaming", "RTPoverRTSP", m_UseRTSP.GetCheck() ? "yes" : "no"); + if (!m_UseRTSP.GetCheck()) gf_cfg_set_key(gpac->m_user.config, "Streaming", "ReorderSize", m_Reorder.GetCheck() ? "30" : "0"); + } + + TCHAR wstr[50]; + char str[50]; + + m_Timeout.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "Streaming", "RTSPTimeout", str); + + m_Buffer.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "Network", "BufferLength", str); + if (m_Rebuffer.GetCheck()) { + m_RebufferLen.GetWindowText(wstr, 50); + CE_WideToChar((u16 *)wstr, str); + gf_cfg_set_key(gpac->m_user.config, "Network", "RebufferLength", str); + } else { + gf_cfg_set_key(gpac->m_user.config, "Network", "RebufferLength", "0"); + } +} + + + +COptSystems::COptSystems(CWnd* pParent /*=NULL*/) + : CDialog(COptSystems::IDD, pParent) +{ + //{{AFX_DATA_INIT(COptSystems) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void COptSystems::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(COptSystems) + DDX_Control(pDX, IDC_FORCE_DURATION, m_ForceDuration); + DDX_Control(pDX, IDC_DEC_THREAD, m_Threading); + DDX_Control(pDX, IDC_BIFSDROP, m_BifsAlwaysDrawn); + DDX_Control(pDX, IDC_LANG, m_Lang); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(COptSystems, CDialog) + //{{AFX_MSG_MAP(COptSystems) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COptSystems message handlers + + + +BOOL COptSystems::OnInitDialog() +{ + CDialog::OnInitDialog(); + + COsmo4 *gpac = GetApp(); + const char *sOpt; + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "Language3CC"); + if (!sOpt) sOpt = "eng"; + s32 select = 0; + while (m_Lang.GetCount()) m_Lang.DeleteString(0); + s32 idx = gf_lang_find(sOpt); + u32 i, count = gf_lang_get_count(); + for (i=0; i=0 && (i==idx)) + select = i; + } + m_Lang.SetCurSel(select); + + + /*system config*/ + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "ThreadingPolicy"); + select = 0; + while (m_Threading.GetCount()) m_Threading.DeleteString(0); + m_Threading.AddString(_T("Single Thread")); + m_Threading.AddString(_T("Mutli Thread")); + if (sOpt && !stricmp(sOpt, "Multi")) select = 1; + m_Threading.AddString(_T("Free")); + if (sOpt && !stricmp(sOpt, "Free")) select = 2; + m_Threading.SetCurSel(select); + + + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "ForceSingleClock"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_ForceDuration.SetCheck(1); + } else { + m_ForceDuration.SetCheck(0); + } + sOpt = gf_cfg_get_key(gpac->m_user.config, "Systems", "AlwaysDrawBIFS"); + if (sOpt && !stricmp(sOpt, "yes")) { + m_BifsAlwaysDrawn.SetCheck(1); + } else { + m_BifsAlwaysDrawn.SetCheck(0); + } + + + return TRUE; +} + + +void COptSystems::SaveOptions() +{ + COsmo4 *gpac = GetApp(); + + s32 sel = m_Lang.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Systems", "LanguageName", gf_lang_get_name(sel) ); + gf_cfg_set_key(gpac->m_user.config, "Systems", "Language3CC", gf_lang_get_3cc(sel) ); + gf_cfg_set_key(gpac->m_user.config, "Systems", "Language2CC", gf_lang_get_2cc(sel) ); + + sel = m_Threading.GetCurSel(); + gf_cfg_set_key(gpac->m_user.config, "Systems", "ThreadingPolicy", (sel==0) ? "Single" : ( (sel==1) ? "Multi" : "Free")); + + /*reset duration flag*/ + gpac->m_duration = (u32) -1; + gf_cfg_set_key(gpac->m_user.config, "Systems", "ForceSingleClock", m_ForceDuration.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Systems", "AlwaysDrawBIFS", m_BifsAlwaysDrawn.GetCheck() ? "yes" : "no"); + +} + diff --git a/applications/deprecated/old_arch/osmo4_wce/Options.h b/applications/deprecated/old_arch/osmo4_wce/Options.h new file mode 100644 index 0000000..99e98f4 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/Options.h @@ -0,0 +1,388 @@ +#if !defined(AFX_OPTIONS_H__5C839953_58C0_4D9D_89CE_2820C7686C1B__INCLUDED_) +#define AFX_OPTIONS_H__5C839953_58C0_4D9D_89CE_2820C7686C1B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// Options.h : header file +// + + +class COptSystems : public CDialog +{ +// Construction +public: + COptSystems(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptSystems) + enum { IDD = IDD_OPT_SYSTEMS }; + CButton m_ForceDuration; + CComboBox m_Threading; + CButton m_BifsAlwaysDrawn; + CComboBox m_Lang; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptSystems) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptSystems) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptStream : public CDialog +{ +// Construction +public: + COptStream(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptStream) + enum { IDD = IDD_OPT_STREAM }; + CEdit m_RebufferLen; + CButton m_Rebuffer; + CEdit m_Buffer; + CEdit m_Timeout; + CButton m_Reorder; + CButton m_UseRTSP; + CComboBox m_Port; + //}}AFX_DATA + + + void SaveOptions(); + + void CheckRebuffer(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptStream) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptStream) + virtual BOOL OnInitDialog(); + afx_msg void OnSelchangePort(); + afx_msg void OnRtsp(); + afx_msg void OnRebuffer(); + afx_msg void OnUpdateRebufferLen(); + afx_msg void OnUpdateBuffer(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; +class COptRender : public CDialog +{ +// Construction +public: + COptRender(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptRender) + enum { IDD = IDD_OPT_RENDER }; + CComboBox m_Antialias; + CButton m_ForceSize; + CButton m_HighSpeed; + CButton m_Scalable; + CButton m_DirectRender; + CComboBox m_BIFSRate; + //}}AFX_DATA + + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptRender) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptRender) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; +class COptHTTP : public CDialog +{ +// Construction +public: + COptHTTP(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptHTTP) + enum { IDD = IDD_OPT_HTTP }; + CButton m_RestartFile; + CButton m_Progressive; + CButton m_CleanCache; + CButton m_CacheDir; + CEdit m_SaxDuration; + //}}AFX_DATA + + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptHTTP) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptHTTP) + afx_msg void OnBrowseCache(); + afx_msg void OnProgressive(); + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; +class COptGen : public CDialog +{ +// Construction +public: + COptGen(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptGen) + enum { IDD = IDD_OPT_GEN }; + CButton m_NoBacklight; + CButton m_Fill; + CButton m_Loop; + CButton m_Logs; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptGen) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptGen) + virtual BOOL OnInitDialog(); + afx_msg void OnFileassoc(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; +class COptFont : public CDialog +{ +// Construction +public: + COptFont(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptFont) + enum { IDD = IDD_OPT_FONT }; + CButton m_UseTexture; + CComboBox m_Fonts; + CButton m_BrowseFont; + //}}AFX_DATA + + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptFont) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptFont) + virtual BOOL OnInitDialog(); + afx_msg void OnBrowseFont(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; +class COptDecoder : public CDialog +{ +// Construction +public: + COptDecoder(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptDecoder) + enum { IDD = IDD_OPT_DECODER }; + CComboBox m_Video; + CComboBox m_Audio; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptDecoder) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptDecoder) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +class COptAudio : public CDialog +{ +// Construction +public: + COptAudio(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptAudio) + enum { IDD = IDD_OPT_AUDIO }; + CComboBox m_DriverList; + CButton m_AudioResync; + CEdit m_AudioDur; + CSpinButtonCtrl m_SpinDur; + CButton m_ForceConfig; + CSpinButtonCtrl m_AudioSpin; + CEdit m_AudioEdit; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptAudio) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptAudio) + virtual BOOL OnInitDialog(); + afx_msg void OnForceAudio(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +class COptRender3D : public CDialog +{ +// Construction +public: + COptRender3D(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptRender) + enum { IDD = IDD_OPT_RENDER3D }; + CComboBox m_WireMode; + CComboBox m_DrawNormals; + CButton m_Use3DRender; + CButton m_NoBackFace; + CButton m_EmulatePOW2; + //}}AFX_DATA + + void SaveOptions(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptRender) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(COptRender) + virtual BOOL OnInitDialog(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// COptions dialog + +class COptions : public CDialog +{ +// Construction +public: + COptions(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(COptions) + enum { IDD = IDD_OPTIONS }; + CComboBox m_Selection; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COptions) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + COptGen m_general; + COptSystems m_systems; + COptRender m_render; + COptRender3D m_render3D; + COptAudio m_audio; + COptHTTP m_http; + COptFont m_font; + COptStream m_stream; + COptDecoder m_decoder; + + + void HideAll(); + + // Generated message map functions + //{{AFX_MSG(COptions) + virtual BOOL OnInitDialog(); + virtual void OnOK(); + afx_msg void OnSaveopt(); + afx_msg void OnSelchangeCombosel(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OPTIONS_H__5C839953_58C0_4D9D_89CE_2820C7686C1B__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_wce/Osmo4.cpp b/applications/deprecated/old_arch/osmo4_wce/Osmo4.cpp new file mode 100644 index 0000000..cbd8c56 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/Osmo4.cpp @@ -0,0 +1,638 @@ +// Osmo4.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "Osmo4.h" + +#include +#include +#include "MainFrm.h" +#include "OpenDlg.h" +#include "Options.h" +#include + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// COsmo4 + +BEGIN_MESSAGE_MAP(COsmo4, CWinApp) + //{{AFX_MSG_MAP(COsmo4) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + ON_COMMAND(IDD_CONFIGURE, OnConfigure) + ON_COMMAND(ID_OPEN_FILE, OnOpenFile) + ON_COMMAND(ID_OPEN_URL, OnOpenUrl) + ON_COMMAND(ID_SHORTCUTS, OnShortcuts) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + + + + + +Bool Osmo4CE_EventProc(void *priv, GF_Event *event) +{ + u32 dur; + COsmo4 *app = (COsmo4 *) priv; + CMainFrame *pFrame = (CMainFrame *) app->m_pMainWnd; + /*shutdown*/ + if (!pFrame) return 0; + + switch (event->type) { + case GF_EVENT_MESSAGE: + if (event->message.error!=GF_OK) { + if (event->message.errorconsole_err = event->message.error; + pFrame->console_message = event->message.message; + pFrame->PostMessage(WM_CONSOLEMSG, 0, 0); + } + return 0; + } + if (1) return 0; + /*process user message*/ + pFrame->console_err = GF_OK; + pFrame->console_message = event->message.message; + pFrame->PostMessage(WM_CONSOLEMSG, 0, 0); + break; + case GF_EVENT_SIZE: + break; + case GF_EVENT_SCENE_SIZE: + app->m_scene_width = event->size.width; + app->m_scene_height = event->size.height; + if (!pFrame->m_full_screen) + pFrame->PostMessage(WM_SETSIZE, event->size.width, event->size.height); + break; + case GF_EVENT_CONNECT: + app->m_open = event->connect.is_connected; + break; + case GF_EVENT_DURATION: + dur = (u32) (1000 * event->duration.duration); + if (dur<2000) dur = 0; + app->m_duration = dur; + app->m_can_seek = event->duration.can_seek && dur; + pFrame->m_progBar.m_range_invalidated = 1; + /*by default, don't display timing if not seekable and vice-versa*/ + if (app->m_can_seek != pFrame->m_view_timing) { + pFrame->m_view_timing = app->m_can_seek; + if (!pFrame->m_full_screen) + pFrame->PostMessage(WM_SETSIZE, 0, 0); + } + break; + case GF_EVENT_NAVIGATE: + /*store URL since it may be destroyed, and post message*/ + app->m_navigate_url = event->navigate.to_url; + pFrame->PostMessage(WM_NAVIGATE, NULL, NULL); + return 1; + case GF_EVENT_QUIT: + pFrame->PostMessage(WM_CLOSE, 0L, 0L); + break; + /*ipaq keys*/ + case GF_EVENT_KEYDOWN: + switch (event->key.key_code) { + case GF_KEY_F1: + pFrame->PostMessage(WM_COMMAND, ID_FILE_OPEN); + break; + case GF_KEY_F2: + pFrame->PostMessage(WM_QUIT); + break; + case GF_KEY_F3: + pFrame->PostMessage(WM_COMMAND, ID_FILE_RESTART); + break; + case GF_KEY_F5: + pFrame->PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN); + break; + case GF_KEY_ENTER: + pFrame->PostMessage(WM_COMMAND, ID_FILE_PAUSE); + break; + case GF_KEY_LEFT: + if (app->m_duration>=2000) { + s32 res = gf_term_get_time_in_ms(app->m_term) - 5*app->m_duration/100; + if (res<0) res=0; + gf_term_play_from_time(app->m_term, res, 0); + } + break; + case GF_KEY_RIGHT: + if (app->m_duration>=2000) { + u32 res = gf_term_get_time_in_ms(app->m_term) + 5*app->m_duration/100; + if (res>=app->m_duration) res = 0; + gf_term_play_from_time(app->m_term, res, 0); + } + break; + case GF_KEY_UP: + if (app->m_duration>=2000) pFrame->PostMessage(WM_COMMAND, ID_FILE_STEP); + break; + case GF_KEY_DOWN: + gf_term_set_option(app->m_term, GF_OPT_REFRESH, 0); + break; + } + break; + case GF_EVENT_DBLCLICK: + pFrame->PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN); + return 0; + } + + return 0; +} + +COsmo4::COsmo4() + : CWinApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance + m_logs = NULL; +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only COsmo4 object + +COsmo4 theApp; + +static void osmo4_do_log(void *cbk, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list list) +{ + FILE *logs = (FILE *) cbk; + if (logs) { + vfprintf(logs, fmt, list); + fflush(logs); + } +} + +void COsmo4::EnableLogs(Bool turn_on) +{ + if (turn_on) { + const char *filename = gf_cfg_get_key(m_user.config, "General", "LogFile"); + if (!filename) { + gf_cfg_set_key(m_user.config, "General", "LogFile", "\\gpac_logs.txt"); + filename = "\\gpac_logs.txt"; + } + m_logs = gf_fopen(filename, "wt"); + if (!m_logs) { + MessageBox(NULL, _T("Couldn't open log file on file system"), _T("Disabling logs"), MB_OK); + turn_on = 0; + } else { + gf_log_set_tools_levels("network:rtp:sync:codec:media@debug"); + gf_log_set_callback(m_logs, osmo4_do_log); + gf_cfg_set_key(m_user.config, "General", "Logs", "network:rtp:sync:codec:media@debug"); + } + } + if (!turn_on) { + if (m_logs) { + gf_fclose(m_logs); + m_logs = 0; + } + gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_NONE); + gf_log_set_callback(NULL, NULL); + gf_cfg_set_key(m_user.config, "General", "Logs", "all@quiet"); + } +} + +///////////////////////////////////////////////////////////////////////////// +// COsmo4 initialization + +BOOL COsmo4::InitInstance() +{ + Bool first_load = 0; + if (!AfxSocketInit()) + { + AfxMessageBox(IDP_SOCKETS_INIT_FAILED); + return FALSE; + } + + gf_sys_init(GF_MemTrackerNone); + + SetRegistryKey(_T("GPAC")); + + m_prev_batt_bl = m_prev_ac_bl = 0; + + m_screen_width = GetSystemMetrics(SM_CXSCREEN); + m_screen_height = GetSystemMetrics(SM_CYSCREEN); + m_menu_height = GetSystemMetrics(SM_CYMENU); + m_scene_width = m_scene_height = 0; + + CMainFrame* pFrame = new CMainFrame; + m_pMainWnd = pFrame; + + pFrame->LoadFrame(IDR_MAINFRAME, WS_VISIBLE, NULL, NULL); + + pFrame->ShowWindow(m_nCmdShow); + pFrame->UpdateWindow(); + + TCHAR w_config_path[MAX_PATH]; + char config_path[MAX_PATH]; + GetModuleFileName(NULL, w_config_path, MAX_PATH); + CE_WideToChar((u16 *) w_config_path, (char *) config_path); + + while (config_path[strlen((char *) config_path)-1] != '\\') config_path[strlen((char *) config_path)-1] = 0; + + /*setup user*/ + memset(&m_user, 0, sizeof(GF_User)); + + /*init config and plugins*/ + m_user.config = gf_cfg_init(NULL, &first_load); + if (!m_user.config) { + MessageBox(NULL, _T("GPAC Configuration file not found"), _T("Fatal Error"), MB_OK); + m_pMainWnd->PostMessage(WM_CLOSE); + } + + const char *str = gf_cfg_get_key(m_user.config, "General", "Logs"); + EnableLogs((str && strcmp(str, "all@quiet") ) ? 1 : 0); + + if (first_load) { + /*first launch, register all files ext*/ + u32 i; + for (i=0; iCanHandleURL(ifce, "test.test"); + gf_modules_close_interface((GF_BaseInterface *)ifce); + } + } + ::MessageBox(NULL, _T("Osmo4/GPAC Setup complete"), _T("Initial launch"), MB_OK); + } + + + str = gf_cfg_get_key(m_user.config, "Core", "ModulesDirectory"); + m_user.modules = gf_modules_new(str, m_user.config); + if (!m_user.modules || ! gf_modules_get_count(m_user.modules) ) { + MessageBox(NULL, _T("No plugins available - system cannot work"), _T("Fatal Error"), MB_OK); + m_pMainWnd->PostMessage(WM_QUIT); + return FALSE; + } + + m_user.config = m_user.config; + m_user.modules = m_user.modules; + m_user.EventProc = Osmo4CE_EventProc; + m_user.opaque = this; + m_user.os_window_handler = pFrame->m_wndView.m_hWnd; + + + m_term = gf_term_new(&m_user); + if (! m_term) { + MessageBox(NULL, _T("Cannot load MPEG-4 Terminal"), _T("Fatal Error"), MB_OK); + m_pMainWnd->PostMessage(WM_QUIT); + } + + m_stopped = 0; + m_open = 0; + m_can_seek = 0; + m_DoResume = 0; + SetOptions(); + pFrame->SendMessage(WM_SETSIZE, 0, 0); + ShowTaskBar(0); + + CCommandLineInfo cmdInfo; + ParseCommandLine(cmdInfo); + + if (! cmdInfo.m_strFileName.IsEmpty()) { + m_filename = cmdInfo.m_strFileName; + m_pMainWnd->PostMessage(WM_OPENURL); + } else { + str = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + if (str) gf_term_connect(m_term, str); + } + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// COsmo4 message handlers + + + + + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + CStatic m_AbtTxt; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + virtual BOOL OnInitDialog(); // Added for WCE apps + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + DDX_Control(pDX, IDC_ABT_TEXT, m_AbtTxt); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// COsmo4 commands +// Added for WCE apps + +BOOL CAboutDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + CString str = _T("Osmo4 Player\nGPAC V"); + str += _T(GPAC_VERSION); + str += _T(" (build"); + str += _T(GPAC_BUILD_NUMBER); + str += _T(")"); + m_AbtTxt.SetWindowText(str); + return TRUE; +} + + + +void COsmo4::OnAppAbout() +{ + CAboutDlg aboutDlg; + ShowTaskBar(1); + aboutDlg.DoModal(); + ShowTaskBar(0); +} + + +int COsmo4::ExitInstance() +{ + gf_term_del(m_term); + gf_modules_del(m_user.modules); + gf_cfg_del(m_user.config); + ShowTaskBar(1); + gf_sys_close(); + if (m_logs) gf_fclose(m_logs); + return CWinApp::ExitInstance(); +} + +void COsmo4::SetOptions() +{ + const char *sOpt = gf_cfg_get_key(m_user.config, "General", "Loop"); + m_Loop = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; + sOpt = gf_cfg_get_key(m_user.config, "General", "FillScreen"); + m_fit_screen = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; + sOpt = gf_cfg_get_key(m_user.config, "General", "DisableBackLight"); + m_disable_backlight = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; + gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); + sOpt = gf_cfg_get_key(m_user.config, "General", "NoMIMETypeFetch"); + m_no_mime_fetch = (!sOpt || !stricmp(sOpt, "yes")) ? 1 : 0; + + //gf_term_set_option(m_term, GF_OPT_AUDIO_VOLUME, 100); +} + +void COsmo4::Pause() +{ + if (!m_open) return; + + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + SetBacklightState(0); + } else { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + SetBacklightState(1); + } + ((CMainFrame*)m_pMainWnd)->SetPauseButton(); +} + + +void COsmo4::OnConfigure() +{ + COptions dlg; + + ShowTaskBar(1); + dlg.DoModal(); + ShowTaskBar(0); +} + +void COsmo4::ShowTaskBar(Bool showIt, Bool pause_only) +{ + if (showIt) { + m_DoResume = 0; + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { + m_DoResume = 1; + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + } + gf_term_set_option(m_term, GF_OPT_FREEZE_DISPLAY, 1); + if (!pause_only) { + SHFullScreen(GetForegroundWindow(), SHFS_HIDESTARTICON | SHFS_SHOWTASKBAR| SHFS_SHOWSIPBUTTON); + ::ShowWindow(::FindWindow(_T("HHTaskbar"),NULL), SW_SHOWNA); + } + SetBacklightState(0); + } else { + if (!pause_only) { + SHFullScreen(GetForegroundWindow(), SHFS_HIDESTARTICON | SHFS_HIDETASKBAR| SHFS_HIDESIPBUTTON); + ::ShowWindow(::FindWindow(_T("HHTaskbar"),NULL), SW_HIDE); + } + gf_term_set_option(m_term, GF_OPT_FREEZE_DISPLAY, 0); + gf_term_set_option(m_term, GF_OPT_REFRESH, 0); + if (m_DoResume) { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + SetBacklightState(1); + m_DoResume = 0; + } + m_pMainWnd->SetFocus(); + } +} + + +CString COsmo4::GetFileFilter() +{ + u32 keyCount, i; + CString sFiles; + CString sExts; + CString supportedFiles; + + return CString("All Files |*.*|"); + + supportedFiles = "All Known Files|*.m3u;*.pls"; + + sExts = ""; + sFiles = ""; + keyCount = gf_cfg_get_key_count(m_user.config, "MimeTypes"); + for (i=0; i + name*/ + strcpy(szKeyList, opt+1); + sKey = strrchr(szKeyList, '\"'); + if (!sKey) continue; + sKey[0] = 0; + /*get description*/ + sKey = strrchr(szKeyList, '\"'); + if (!sKey) continue; + strcpy(sDesc, sKey+1); + sKey[0] = 0; + sKey = strrchr(szKeyList, '\"'); + if (!sKey) continue; + sKey[0] = 0; + + CE_CharToWide(sDesc, (unsigned short *)swDesc); + CE_CharToWide(szKeyList, (unsigned short *)swKeyList); + + /*if same description for # mime types skip (means an old mime syntax)*/ + if (sFiles.Find((LPCTSTR) swDesc)>=0) continue; + /*if same extensions for # mime types skip (don't polluate the file list)*/ + if (sExts.Find((LPCTSTR) swKeyList)>=0) continue; + + sExts += (LPCTSTR) swKeyList; + sExts += " "; + sFiles += (LPCTSTR) swDesc; + sFiles += "|"; + + first = 1; + + sOpt = CString(szKeyList); + while (1) { + + int pos = sOpt.Find(' '); + CString ext = (pos==-1) ? sOpt : sOpt.Left(pos); + /*WATCHOUT: we do have some "double" ext , eg .wrl.gz - these are NOT supported by windows*/ + if (ext.Find(_T("."))<0) { + if (!first) { + sFiles += ";"; + } else { + first = 0; + } + sFiles += "*."; + sFiles += ext; + + CString sext = ext; + sext += ";"; + if (supportedFiles.Find(sext)<0) { + supportedFiles += ";*."; + supportedFiles += ext; + } + } + + if (sOpt==ext) break; + CString rem; + rem.Format(_T("%s "), (LPCTSTR) ext); + sOpt.Replace((LPCTSTR) rem, _T("")); + } + sFiles += "|"; + } + supportedFiles += "|"; + supportedFiles += sFiles; + //supportedFiles += "M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|All Files |*.*|"; + supportedFiles += "All Files |*.*|"; + return supportedFiles; +} + +void COsmo4::OnOpenFile() +{ + Bool res; + CFileDialog fd(TRUE,NULL,_T("\\"),OFN_HIDEREADONLY, GetFileFilter()); + + ShowTaskBar(1); + res = 0; + if (fd.DoModal()==IDOK) { + res = 1; + m_filename = fd.GetPathName(); + m_DoResume = 0;/*done by term*/ + } + ShowTaskBar(0); + if (res) m_pMainWnd->PostMessage(WM_OPENURL); +} + +void COsmo4::OnOpenUrl() +{ + OpenDlg dlg; + Bool res; + ShowTaskBar(1, 1); + res = 0; + if (dlg.DoModal() == IDOK) { + res = 1; + m_DoResume = 0;/*done by term*/ + } + ShowTaskBar(0, 1); + if (res) m_pMainWnd->PostMessage(WM_OPENURL); +} + +void COsmo4::SetBacklightState(Bool disable) +{ + HKEY hKey = 0; + DWORD dwSize; + DWORD dwValue; + HANDLE hBL; + + if (!m_disable_backlight) return; + + if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("ControlPanel\\Backlight"), 0, 0, &hKey ) != ERROR_SUCCESS) return; + + if (disable) { + dwSize = 4; + RegQueryValueEx(hKey, _T("BatteryTimeout"), NULL, NULL,(unsigned char*) &m_prev_batt_bl, &dwSize); + dwSize = 4; + RegQueryValueEx(hKey, _T("ACTimeout"), NULL, NULL, (unsigned char*) &m_prev_ac_bl,&dwSize); + dwSize = 4; + dwValue = 0xefff ; + RegSetValueEx(hKey, _T("BatteryTimeout"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize); + dwSize = 4; + dwValue = 0xefff ; + RegSetValueEx( hKey, _T("ACTimeout"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize); + } else { + if (m_prev_batt_bl) { + dwSize = 4; + RegSetValueEx(hKey, _T("BatteryTimeout"), NULL, REG_DWORD, (unsigned char *)&m_prev_batt_bl, dwSize); + } + if (m_prev_ac_bl) { + dwSize = 4; + RegSetValueEx(hKey, _T("ACTimeout"), NULL, REG_DWORD,(unsigned char *)&m_prev_ac_bl, dwSize); + } + } + RegCloseKey(hKey); + hBL = CreateEvent(NULL, FALSE, FALSE, _T("BackLightChangeEvent")); + if (hBL) { + SetEvent(hBL); + CloseHandle(hBL); + } +} + +void COsmo4::OnShortcuts() +{ + ShowTaskBar(1); + + MessageBox(NULL, + _T("Double Click: Fullscreen on/off\n"), + + _T("Osmo4 Shortcuts"), + MB_OK); + + ShowTaskBar(0); +} + diff --git a/applications/deprecated/old_arch/osmo4_wce/Osmo4.h b/applications/deprecated/old_arch/osmo4_wce/Osmo4.h new file mode 100644 index 0000000..94820a2 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/Osmo4.h @@ -0,0 +1,113 @@ +// Osmo4.h : main header file for the OSMO4 application +// + +#if !defined(AFX_OSMO4_H__7E4A02D1_F77D_4E97_9E10_032054B29E33__INCLUDED_) +#define AFX_OSMO4_H__7E4A02D1_F77D_4E97_9E10_032054B29E33__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#ifndef __AFXWIN_H__ +#error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// COsmo4: +// See Osmo4.cpp for the implementation of this class +// + +/*MPEG4 term*/ +#include + +enum { + WM_SCENE_DONE = WM_USER + 1, + WM_NAVIGATE, + WM_SETSIZE, + WM_OPENURL, + WM_CONSOLEMSG, +}; + + +#define IPAQ_TRANSLATE_KEY(vk) (LOWORD(vk) != 0x5b ? LOWORD(vk) : vk ) +/*navigation pad keys*/ +#define VK_IPAQ_LEFT 0x25 +#define VK_IPAQ_UP 0x26 +#define VK_IPAQ_RIGHT 0x27 +#define VK_IPAQ_DOWN 0x28 +/*"enter" key*/ +#define VK_IPAQ_START 0x86 +/*ipaq keys from left to right*/ +#define VK_IPAQ_A 0xC1 +#define VK_IPAQ_B 0xC2 +#define VK_IPAQ_C 0xC3 +#define VK_IPAQ_D 0xC4 +/*record button*/ +#define VK_IPAQ_E 0xC5 + +class COsmo4 : public CWinApp +{ +public: + COsmo4(); + + GF_Terminal *m_term; + GF_User m_user; + CString m_filename; + + u32 m_duration; + CString m_navigate_url; + 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; + u32 m_screen_width, m_screen_height, m_menu_height; + /*task bar on/off*/ + void ShowTaskBar(Bool showIt, Bool pause_only = 0); + + CString GetFileFilter(); + + void SetBacklightState(Bool disable); + void EnableLogs(Bool turn_on); + +private: + Bool m_DoResume; + + void SetOptions(); + + /*power management*/ + u32 m_prev_batt_bl, m_prev_ac_bl; + + FILE *m_logs; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(COsmo4) +public: + virtual BOOL InitInstance(); + virtual int ExitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(COsmo4) + afx_msg void OnAppAbout(); + afx_msg void OnConfigure(); + afx_msg void OnOpenFile(); + afx_msg void OnOpenUrl(); + afx_msg void OnShortcuts(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +inline COsmo4 *GetApp() { + return (COsmo4 *)AfxGetApp(); +} + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_OSMO4_H__7E4A02D1_F77D_4E97_9E10_032054B29E33__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_wce/Osmo4.rc b/applications/deprecated/old_arch/osmo4_wce/Osmo4.rc new file mode 100644 index 0000000..de8973a --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/Osmo4.rc @@ -0,0 +1,758 @@ +//Microsoft eMbedded Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" +#include "newres.h" + +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON DISCARDABLE "res\\Osmo4.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINFRAME BITMAP MOVEABLE PURE "res\\Cmdbar.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_MAINFRAME TOOLBAR DISCARDABLE 16, 16 +BEGIN + BUTTON ID_OPEN_FILE + BUTTON ID_FILE_PAUSE + BUTTON ID_FILE_STEP + BUTTON ID_FILE_STOP + BUTTON ID_VIEW_FULLSCREEN +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE +BEGIN + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "Q", ID_APP_EXIT, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + "X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT + "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 140, 153 +STYLE WS_POPUP | WS_CAPTION +EXSTYLE 0x80000000L +CAPTION "About Osmo4" +FONT 8, "System" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,15,3,21,20 + CTEXT "Osmo4 player\nGPAC MPEG-4 SDK",IDC_ABT_TEXT,44,4,64,17 + CTEXT "This program is free software and may be distributed according to the terms of the GNU Lesser General Public License", + IDC_STATIC,3,24,131,24 + CTEXT "GPAC Copyright (C) Telecom ParisTech 2000 - 2012 - All Rights Reserved http://gpac.io", + IDC_STATIC,4,52,129,26 + LTEXT "Authors: Jean Le Feuvre, Cyril Concolato",IDC_STATIC,11,100,109,8 + LTEXT "Mozilla SpiderMonkey (JavaScript)",IDC_STATIC,11,110, + 109,8 + LTEXT "The FreeType Project",IDC_STATIC,11,120,70,8 + LTEXT "The PNG Group, The I.J.G.",IDC_STATIC,12,130,87,8 + LTEXT "XVID, FAAD, MAD, 3GPP",IDC_STATIC,13,139,80,8 + LTEXT "------------ With many thanks to: -------------", + IDC_STATIC,0,91,139,8 +END + +IDD_OPENFILE DIALOG DISCARDABLE 0, 0, 133, 116 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Select file location" +FONT 8, "System" +BEGIN + DEFPUSHBUTTON "OK",IDOK,92,33,27,14 + COMBOBOX IDC_FILELIST,4,17,127,52,CBS_DROPDOWN | CBS_AUTOHSCROLL | + CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Cancel",IDCANCEL,14,34,27,14 + LTEXT "Enter path to remote file",IDC_STATIC,25,6,80,8 +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "\0" + VALUE "FileDescription", "Osmo4-GPAC\0" + VALUE "FileVersion", GPAC_VERSION"\0" + VALUE "InternalName", "Osmo4\0" + VALUE "LegalCopyright", "Copyright (C) Telecom ParisTech 2005-2012\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "Osmo4.EXE\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Osmo4-GPAC\0" + VALUE "ProductVersion", GPAC_VERSION"\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + RIGHTMARGIN, 138 + TOPMARGIN, 1 + END + + IDD_OPENFILE, DIALOG + BEGIN + LEFTMARGIN, 2 + TOPMARGIN, 2 + BOTTOMMARGIN, 113 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menubar +// + +IDR_MENU MENU DISCARDABLE +BEGIN + POPUP "File" + BEGIN + MENUITEM "Open", ID_OPEN_FILE + MENUITEM "Open URL", ID_OPEN_URL + MENUITEM SEPARATOR + MENUITEM "Exit", ID_APP_EXIT + END + POPUP "View" + BEGIN + POPUP "Viewpoint" + BEGIN + MENUITEM "", ID_VIEWPORT_EMPTY + END + POPUP "Navigation" + BEGIN + MENUITEM "Reset", ID_NAV_RESET + MENUITEM SEPARATOR + MENUITEM "None", ID_NAV_NONE + MENUITEM "Walk", ID_NAV_WALK + MENUITEM "Fly", ID_NAV_FLY + MENUITEM "Examine", ID_NAV_EXAMINE + MENUITEM "Slide", ID_NAV_SLIDE + MENUITEM SEPARATOR + MENUITEM "Headlight", ID_NAV_HEADLIGHT + MENUITEM "Gravity", ID_NAV_GRAVITY + POPUP "Collision" + BEGIN + MENUITEM "Off", ID_COLLIDE_OFF + MENUITEM "Regular", ID_COLLIDE_REG + MENUITEM "Displacement", ID_COLLIDE_DISP + END + END + MENUITEM SEPARATOR + MENUITEM "Fullscreen", ID_VIEW_FULLSCREEN + POPUP "Aspect Ratio" + BEGIN + MENUITEM "Keep Original", ID_VIEW_AR_ORIG + MENUITEM "Fill Screen", ID_VIEW_AR_FILL + MENUITEM "Ratio 4/3", ID_VIEW_AR_43 + MENUITEM "Ratio 16/9", ID_VIEW_AR_169 + MENUITEM SEPARATOR + MENUITEM "Fit Screen", ID_VIEW_FIT + END + MENUITEM SEPARATOR + MENUITEM "Time Control", ID_VIEW_TIMING + MENUITEM SEPARATOR + MENUITEM "Settings", IDD_CONFIGURE + END + POPUP "?" + BEGIN + MENUITEM "Shortcuts", ID_SHORTCUTS + MENUITEM "About ...", ID_APP_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Data +// + +IDR_MENU SHMENUBAR DISCARDABLE +BEGIN + IDR_MENU, 3, + I_IMAGENONE, ID_FILE, TBSTATE_ENABLED, + TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_FILE, 0, 0, + I_IMAGENONE, ID_VIEW, TBSTATE_ENABLED, + TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_VIEW, 0, 1, + I_IMAGENONE, ID_MENUITEM32789, TBSTATE_ENABLED, + TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_MENUITEM32790, 0, 2, +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_EDIT "File" + IDS_TOOL "Tools" + IDP_SOCKETS_INIT_FAILED "Windows sockets initialization failed." +END + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + IDR_MAINFRAME "Osmo4\n\nOsmo4\n\n\nOsmo4.Document\nOsmo4 Document" +END + +STRINGTABLE PRELOAD DISCARDABLE +BEGIN + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_FILE_SAVE_AS "Save the active document with a new name\nSave As" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright\nAbout" + ID_APP_EXIT "Quit the application; prompts to save documents\nExit" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane\nNext Pane" + ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_WINDOW_SPLIT "Split the active window into panes\nSplit" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection\nErase" + ID_EDIT_CLEAR_ALL "Erase everything\nErase All" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut" + ID_EDIT_FIND "Find the specified text\nFind" + ID_EDIT_PASTE "Insert Clipboard contents\nPaste" + ID_EDIT_REPEAT "Repeat the last action\nRepeat" + ID_EDIT_REPLACE "Replace specific text with different text\nReplace" + ID_EDIT_SELECT_ALL "Select the entire document\nSelect All" + ID_EDIT_UNDO "Undo the last action\nUndo" + ID_EDIT_REDO "Redo the previously undone action\nRedo" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE DISCARDABLE +BEGIN + AFX_IDS_SCTASKLIST "Activate Task List" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_NEW "New" + IDS_FILE "File" + IDS_MHELP "Help" + IDS_SAVE "Save" + IDS_CUT "Cut" + IDS_COPY "Copy" + IDS_PASTE "Paste" + IDS_ABOUT "About" +END + +STRINGTABLE DISCARDABLE +BEGIN + ID_INDICATOR_CAPS "CAP" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_CAP_FILE "File" + ID_FILE_RESTART "Restart presentation" + IDS_CAP_MENUITEM32790 "?" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_CAP_VIEW "View" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CONTROL DIALOG DISCARDABLE 0, 0, 161, 15 +STYLE DS_SETFOREGROUND | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_STATICEDGE +FONT 8, "System" +BEGIN + CONTROL "Slider1",IDC_SLIDER,"msctls_trackbar32",TBS_BOTH | + TBS_NOTICKS | WS_TABSTOP,0,1,101,12 + LTEXT "00:00 FPS 30.00",IDC_TIME,102,3,56,10 +END + +IDD_OPTIONS DIALOG DISCARDABLE 0, 0, 134, 121 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Osmo4 Options" +FONT 8, "System" +BEGIN + PUSHBUTTON "Apply",IDC_SAVEOPT,108,3,24,14 + COMBOBOX IDC_COMBOSEL,3,5,99,80,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "-------------------------------------------------------", + IDC_STATIC,0,17,133,8 +END + +IDD_OPT_GEN DIALOG DISCARDABLE 0, 120, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + CONTROL "Loop at end",IDC_LOOP,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,6,28,54,10 + PUSHBUTTON "Make Default MPEG-4 Player",IDC_FILEASSOC,5,90,124,20, + BS_MULTILINE + CONTROL "Stretch display to fill screen",IDC_FILL_SCREEN,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,6,45,104,10 + CONTROL "Disable Backlight while playing",IDC_NO_BACKLIGHT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,61,111,10 + CONTROL "Enable logs",IDC_ENABLE_LOGS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,6,74,52,10 +END + +IDD_OPT_RENDER DIALOG DISCARDABLE 0, 20, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + LTEXT "Rendering Frame Rate",IDC_STATIC,27,27,73,8 + COMBOBOX IDC_BIFS_RATE,29,39,68,47,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + CONTROL "Direct Rendering",IDC_DIRECTRENDER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,1,64,69,10 + CONTROL "Scalable Zoom",IDC_ZOOM_SCALABLE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,70,64,61,10 + CONTROL "Fast Rendering",IDC_FAST_RENDER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,70,79,60,10 + CONTROL "Force Scene Size",IDC_FORCE_SIZE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,1,79,70,10 + LTEXT "Anti-Aliasing",IDC_STATIC,6,103,40,8 + COMBOBOX IDC_AA_LIST,56,99,71,47,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP +END + +IDD_OPT_SYSTEMS DIALOG DISCARDABLE 0, 20, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + LTEXT "Prefered Language for stream selection",IDC_STATIC,3,46, + 64,19 + COMBOBOX IDC_LANG,69,48,60,72,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Decoder Threading",IDC_STATIC,4,75,62,8 + COMBOBOX IDC_DEC_THREAD,69,72,60,30,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + CONTROL "Always draw late BIFS frames",IDC_BIFSDROP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,4,91,111,10 + CONTROL "Force Single Timeline",IDC_FORCE_DURATION,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,4,106,82,10 +END + +IDD_OPT_VIDEO DIALOG DISCARDABLE 0, 20, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + LTEXT "Graphics Driver",IDC_STATIC,5,54,50,8 + LTEXT "Anti-Aliasing",IDC_STATIC,6,77,40,8 + LTEXT "Video Driver",IDC_STATIC,5,98,40,8 + COMBOBOX IDC_GD_LIST,56,53,71,30,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_AA_LIST,56,73,71,47,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + COMBOBOX IDC_VIDEO_LIST,56,95,71,30,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP +END + +IDD_OPT_AUDIO DIALOG DISCARDABLE 0, 20, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + CONTROL "Force Audio Config",IDC_FORCE_AUDIO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,5,33,77,10 + LTEXT "Number of buffers",IDC_STATIC,5,51,60,8 + LTEXT "Total Duration in ms",IDC_STATIC,4,69,64,8 + EDITTEXT IDC_EDIT_AUDIO,68,48,34,14,ES_AUTOHSCROLL | ES_READONLY + CONTROL "Spin1",IDC_SPIN_AUDIO,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ARROWKEYS | UDS_HORZ,105,49,19,12 + EDITTEXT IDC_AUDIO_DUR,68,67,34,14,ES_AUTOHSCROLL + CONTROL "Spin1",IDC_SPIN_DUR,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ARROWKEYS | UDS_HORZ,105,68,19,12 + CONTROL "Disable Audio Resync",IDC_AUDIO_RESYNC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,5,85,84,10 + LTEXT "Default Plugin",IDC_STATIC,5,103,45,8 + COMBOBOX IDC_DRIVER_LIST,52,100,73,30,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP +END + +IDD_OPT_FONT DIALOG DISCARDABLE 0, 20, 133, 119 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + LTEXT "Font Engine",IDC_STATIC,35,33,39,8 + COMBOBOX IDC_FONT_LIST,12,45,98,30,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "Systems Font Directory",IDC_STATIC,19,87,76,8 + PUSHBUTTON "...",IDC_BROWSE_FONT,6,98,115,12 + CONTROL "Draw text through texturing",IDC_USE_TEXTURE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,68,107,10 +END + +IDD_OPT_HTTP DIALOG DISCARDABLE 0, 20, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + LTEXT "Cache Directory",IDC_STATIC,35,9,53,8 + PUSHBUTTON "...",IDC_BROWSE_CACHE,7,22,113,14 + CONTROL "Remove temp files",IDC_CLEAN_CACHE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,43,75,10 + CONTROL "Always redownload incomplete cached files", + IDC_RESTART_CACHE,"Button",BS_AUTOCHECKBOX | + BS_MULTILINE | WS_TABSTOP,7,54,102,22 + CONTROL "XML Progressive Load",IDC_SAX_PROGRESSIVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,8,77,85,10 + EDITTEXT IDC_SAX_DURATION,27,89,35,14,ES_CENTER | ES_AUTOHSCROLL | + ES_NUMBER +END + +IDD_OPT_STREAM DIALOG DISCARDABLE 0, 20, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + LTEXT "Default RTSP Port",IDC_STATIC,33,33,58,8 + COMBOBOX IDC_PORT,15,42,95,30,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + CONTROL "RTP over RTSP",IDC_RTSP,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,1,58,64,10 + CONTROL "RTP Reordering",IDC_REORDER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,66,58,66,10 + EDITTEXT IDC_TIMEOUT,1,72,35,14,ES_CENTER | ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "ms before control timeout",IDC_STATIC,44,75,83,8 + EDITTEXT IDC_BUFFER,1,87,35,14,ES_CENTER | ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "ms of Media Buffering ",IDC_STATIC,44,90,72,8 + CONTROL "Rebuffer if less than",IDC_REBUFFER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,2,106,78,10 + EDITTEXT IDC_REBUFFER_LEN,81,105,35,12,ES_CENTER | ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "ms",IDC_STATIC,121,108,10,8 +END + +IDD_OPT_DECODER DIALOG DISCARDABLE 0, 20, 133, 121 +STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "System" +BEGIN + LTEXT "Prefered Audio Output",-1,33,9,70,8 + LTEXT "Prefered Video Output",-1,33,44,80,8 + COMBOBOX IDC_AUDEC_LIST,11,22,109,54,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_VIDEC_LIST,12,57,109,47,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP +END + +IDD_OPT_RENDER3D DIALOG DISCARDABLE 0, 0, 133, 121 +STYLE DS_MODALFRAME | WS_CHILD +FONT 8, "System" +BEGIN + CONTROL "Use 3D Renderer",IDC_USE_3D_REN,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,3,29,121,10 + CONTROL "Disable Backface Culling",IDC_NO_BACKCULL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,3,41,92,10 + CONTROL "Emulate pow2 textures for video",IDC_EMULATE_POW2, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,1,97,121,10 + LTEXT "Drawing Mode",IDC_STATIC,5,56,46,8 + COMBOBOX IDC_WIRE_MODE,61,54,61,35,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + LTEXT "Draw Normals",IDC_STATIC,5,73,45,8 + COMBOBOX IDC_DRAW_NORMALS,62,72,61,35,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_CONTROL, DIALOG + BEGIN + RIGHTMARGIN, 160 + BOTTOMMARGIN, 14 + END + + IDD_OPTIONS, DIALOG + BEGIN + RIGHTMARGIN, 133 + BOTTOMMARGIN, 120 + END + + IDD_OPT_GEN, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END + + IDD_OPT_RENDER, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END + + IDD_OPT_SYSTEMS, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END + + IDD_OPT_VIDEO, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END + + IDD_OPT_AUDIO, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END + + IDD_OPT_FONT, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 118 + END + + IDD_OPT_HTTP, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END + + IDD_OPT_STREAM, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END + + IDD_OPT_DECODER, DIALOG + BEGIN + RIGHTMARGIN, 132 + BOTTOMMARGIN, 120 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""newres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\Osmo4.rc2"" // non-Microsoft eMbedded Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#include ""wceres.rc"" // WCE-specific components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_OPT_RENDER DLGINIT +BEGIN + IDC_BIFS_RATE, 0x403, 8, 0 +0x0035, 0x002e, 0x0030, 0x0000, + IDC_BIFS_RATE, 0x403, 8, 0 +0x0037, 0x002e, 0x0035, 0x0000, + IDC_BIFS_RATE, 0x403, 10, 0 +0x0031, 0x0030, 0x002e, 0x0030, 0x0000, + IDC_BIFS_RATE, 0x403, 10, 0 +0x0031, 0x0032, 0x002e, 0x0035, 0x0000, + IDC_BIFS_RATE, 0x403, 10, 0 +0x0031, 0x0035, 0x002e, 0x0030, 0x0000, + IDC_BIFS_RATE, 0x403, 10, 0 +0x0032, 0x0034, 0x002e, 0x0030, 0x0000, + IDC_BIFS_RATE, 0x403, 10, 0 +0x0032, 0x0035, 0x002e, 0x0030, 0x0000, + IDC_BIFS_RATE, 0x403, 10, 0 +0x0033, 0x0030, 0x002e, 0x0030, 0x0000, + 0 +END + +IDD_OPT_SYSTEMS DLGINIT +BEGIN + IDC_DEC_THREAD, 0x403, 28, 0 +0x0053, 0x0069, 0x006e, 0x0067, 0x006c, 0x0065, 0x0020, 0x0054, 0x0068, +0x0072, 0x0065, 0x0061, 0x0064, 0x0000, + IDC_DEC_THREAD, 0x403, 26, 0 +0x004d, 0x0075, 0x0074, 0x006c, 0x0069, 0x0020, 0x0054, 0x0068, 0x0072, +0x0065, 0x0061, 0x0064, 0x0000, + IDC_DEC_THREAD, 0x403, 10, 0 +0x0046, 0x0072, 0x0065, 0x0065, 0x0000, + 0 +END + +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\Osmo4.rc2" // non-Microsoft eMbedded Visual C++ edited resources +#include "afxres.rc" // Standard components +//#include "wceres.rc" // WCE-specific components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/applications/deprecated/old_arch/osmo4_wce/ProgressBar.cpp b/applications/deprecated/old_arch/osmo4_wce/ProgressBar.cpp new file mode 100644 index 0000000..dea5b8c --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/ProgressBar.cpp @@ -0,0 +1,133 @@ +// ProgressBar.cpp : implementation file +// + +#include "stdafx.h" +#include "Osmo4.h" +#include "ProgressBar.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// ProgressBar dialog + + +ProgressBar::ProgressBar(CWnd* pParent /*=NULL*/) + : CDialog(ProgressBar::IDD, pParent) +{ + //{{AFX_DATA_INIT(ProgressBar) + //}}AFX_DATA_INIT + + m_grabbed = 0; + m_range_invalidated = 0; +} + + +void ProgressBar::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(ProgressBar) + DDX_Control(pDX, IDC_TIME, m_Time); + DDX_Control(pDX, IDC_SLIDER, m_Slider); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(ProgressBar, CDialog) + //{{AFX_MSG_MAP(ProgressBar) + ON_WM_SIZE() + ON_WM_HSCROLL() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// ProgressBar message handlers +#define TEXT_RIGHT_PAD 2 +void ProgressBar::OnSize(UINT nType, int cx, int cy) +{ + u32 tw; + CDialog::OnSize(nType, cx, cy); + + if (!m_Slider.m_hWnd) return; + + RECT rc; + m_Time.GetClientRect(&rc); + tw = rc.right-rc.left; + rc.left = cx - tw - TEXT_RIGHT_PAD; + rc.right = cx - TEXT_RIGHT_PAD; + m_Time.MoveWindow(&rc); + m_Slider.GetClientRect(&rc); + rc.left = 0; + rc.right = cx - tw - TEXT_RIGHT_PAD; + m_Slider.MoveWindow(&rc); +} + +void ProgressBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) +{ + COsmo4 *app = GetApp(); + + if (pScrollBar->GetDlgCtrlID() == IDC_SLIDER) { + if (!app->m_can_seek) return; + switch (nSBCode) { + case TB_LINEUP: + case TB_LINEDOWN: + case TB_PAGEUP: + case TB_PAGEDOWN: + case TB_THUMBPOSITION: + case TB_THUMBTRACK: + case TB_TOP: + case TB_BOTTOM: + m_grabbed = 1; + break; + case TB_ENDTRACK: + if (!app->m_open) { + SetPosition(0); + } else { + u32 seek_to = m_Slider.GetPos(); + gf_term_play_from_time(app->m_term, seek_to, 0); + } + m_grabbed = 0; + return; + } + } + CDialog::OnHScroll(nSBCode, nPos, pScrollBar); +} + +void ProgressBar::SetPosition(u32 now) +{ + TCHAR swText[20]; + u32 nb_s, nb_m; + COsmo4 *app = GetApp(); + + if (m_range_invalidated) { + if (app->m_can_seek) { + m_Slider.SetRangeMin(0); + m_Slider.SetRangeMax(app->m_duration); + m_Slider.ShowWindow(SW_SHOWNORMAL); + m_Slider.EnableWindow(TRUE); + } else { + m_Slider.ShowWindow(SW_SHOWNORMAL); + m_Slider.EnableWindow(FALSE); + + } + m_range_invalidated = 0; + } + if (now==m_prev_time) return; + + if (nowm_term, 0); + m_prev_time = now; + } + nb_s = now/1000; + nb_m = nb_s/60; + nb_s -= nb_m*60; + wsprintf(swText, _T("%02d:%02d FPS %02.2f"), nb_m, nb_s, m_FPS); + m_Time.SetWindowText(swText); + + if (!m_grabbed) m_Slider.SetPos(now); +} diff --git a/applications/deprecated/old_arch/osmo4_wce/ProgressBar.h b/applications/deprecated/old_arch/osmo4_wce/ProgressBar.h new file mode 100644 index 0000000..e8f6f10 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/ProgressBar.h @@ -0,0 +1,53 @@ +#if !defined(AFX_PROGRESSBAR_H__85FCAC2B_9C83_4C83_8E66_D712FC88B221__INCLUDED_) +#define AFX_PROGRESSBAR_H__85FCAC2B_9C83_4C83_8E66_D712FC88B221__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// ProgressBar.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// ProgressBar dialog + +class ProgressBar : public CDialog +{ +// Construction +public: + ProgressBar(CWnd* pParent = NULL); // standard constructor + + Bool m_grabbed, m_range_invalidated; + Double m_FPS; + u32 m_prev_time; + void SetPosition(u32 time_ms); + +// Dialog Data + //{{AFX_DATA(ProgressBar) + enum { IDD = IDD_CONTROL }; + CStatic m_Time; + CSliderCtrl m_Slider; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(ProgressBar) +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(ProgressBar) + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_PROGRESSBAR_H__85FCAC2B_9C83_4C83_8E66_D712FC88B221__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_wce/Resource.h b/applications/deprecated/old_arch/osmo4_wce/Resource.h new file mode 100644 index 0000000..7cf3b7f --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/Resource.h @@ -0,0 +1,170 @@ +//{{NO_DEPENDENCIES}} +// Microsoft eMbedded Visual C++ generated include file. +// Used by Osmo4.rc +// +#define IDD_ABOUTBOX 100 +#define IDM_MENU 101 +#define IDS_EDIT 102 +#define IDS_TOOL 103 +#define IDP_SOCKETS_INIT_FAILED 104 +#define IDR_MAIN_EDIT 105 +#define IDR_MAIN_TOOL 106 +#define IDI_PAUSE 120 +#define IDD_OPT_HTTP 121 +#define IDR_MAINFRAME 128 +#define IDD_OPT_AUDIO 129 +#define IDD_OPENFILE 130 +#define IDD_CONTROL 131 +#define IDD_OPTIONS 132 +#define IDD_OPT_GEN 133 +#define IDD_OPT_RENDER 134 +#define IDD_OPT_SYSTEMS 135 +#define IDD_OPT_VIDEO 136 +#define IDI_PLAY 137 +#define IDD_OPT_FONT 138 +#define IDI_STOP 139 +#define IDD_OPT_STREAM 140 +#define IDR_MENU 141 +#define IDD_OPT_RENDER3D 142 +#define IDD_OPT_DECODER 143 +#define IDC_FILELIST 1000 +#define IDC_BROWSE 1001 +#define IDC_SEEK 1002 +#define IDC_PLAY 1003 +#define IDC_STOP 1004 +#define IDC_OPT_SET_NAME 1005 +#define IDC_SAVEOPT 1006 +#define IDC_LOOP 1007 +#define IDC_AUTOSTART 1008 +#define IDC_NO_CONSOLE 1009 +#define IDC_FILEASSOC 1010 +#define IDC_BIFS_RATE 1011 +#define IDC_DIRECTRENDER 1012 +#define IDC_ZOOM_SCALABLE 1013 +#define IDC_FAST_RENDER 1014 +#define IDC_FORCE_SIZE 1015 +#define IDC_COLOR 1016 +#define IDC_LANG 1017 +#define IDC_DEC_THREAD 1018 +#define IDC_BIFSDROP 1019 +#define IDC_FORCE_DURATION 1020 +#define IDC_SLIDER 1021 +#define IDC_GD_LIST 1022 +#define IDC_AA_LIST 1023 +#define IDC_VIDEO_LIST 1024 +#define IDC_FORCE_AUDIO 1025 +#define IDC_EDIT_AUDIO 1026 +#define IDC_SPIN_AUDIO 1027 +#define IDC_AUDIO_FPS 1028 +#define IDC_SPIN_DUR 1029 +#define IDC_AUDIO_RESYNC 1030 +#define IDC_DRIVER_LIST 1031 +#define IDC_FONT_LIST 1032 +#define IDC_BROWSE_FONT 1033 +#define IDC_BROWSE_CACHE 1034 +#define IDC_CLEAN_CACHE 1035 +#define IDC_RESTART_CACHE 1036 +#define IDC_PORT 1037 +#define IDC_RTSP 1038 +#define IDC_REORDER 1039 +#define IDC_TIMEOUT 1040 +#define IDC_BUFFER 1041 +#define IDC_REBUFFER 1042 +#define IDC_REBUFFER_LEN 1043 +#define IDC_VERSION 1044 +#define IDC_AUDEC_LIST 1046 +#define IDC_VIDEC_LIST 1047 +#define IDC_COMBOSEL 1048 +#define IDC_TIME 1049 +#define IDC_ABT_TEXT 1050 +#define IDC_CTRL_PLAY 1051 +#define IDC_USE_TEXTURE 1052 +#define IDC_USE_3D_REN 1053 +#define IDC_NO_BACKCULL 1054 +#define IDC_CTRL_STOP 1055 +#define IDC_EMULATE_POW2 1056 +#define IDC_WIRE_MODE 1057 +#define IDC_SAX_DURATION 1058 +#define IDC_DRAW_NORMALS 1059 +#define IDC_SPIN_OPT 1060 +#define IDC_AUDIO_DUR 1061 +#define IDC_SPIN_FPS 1062 +#define IDC_FILL_SCREEN 1063 +#define IDC_VIEW_FPS 1064 +#define IDC_NO_BACKLIGHT 1065 +#define IDC_SAX_PROGRESSIVE 1066 +#define IDC_ENABLE_LOGS 1067 +#define IDS_CAP_FILE 32772 +#define ID_FILE_RESTART 32773 +#define ID_FPS_DISP 32774 +#define IDD_CONFIGURE 32775 +#define ID_VIEW_CONTROL 32776 +#define ID_FILE_PAUSE 32777 +#define ID_FILE_STEP 32778 +#define ID_FILE_STOP 32779 +#define ID_VIEW_FULLSCREEN 32780 +#define ID_FILE 32781 +#define ID_MENUITEM32789 32782 +#define IDS_CAP_MENUITEM32790 32783 +#define ID_VIEW 32784 +#define IDS_CAP_VIEW 32785 +#define ID_OPEN_FILE 32786 +#define ID_OPEN_URL 32787 +#define ID_SHORTCUTS 32788 +#define ID_VIEW_FIT 32789 +#define ID_NAV_NONE 32806 +#define ID_NAV_SLIDE 32807 +#define ID_NAV_RESET 32808 +#define ID_NAV_WALK 32810 +#define ID_NAV_FLY 32811 +#define ID_NAV_EXAMINE 32812 +#define ID_NAV_GRAVITY 32813 +#define ID_COLLIDE_OFF 32815 +#define ID_COLLIDE_REG 32816 +#define ID_COLLIDE_DISP 32817 +#define ID_VIEWPORT_EMPTY 32818 +#define ID_NAV_HEADLIGHT 32819 +#define ID_VP_0 32820 +#define ID_VP_1 32821 +#define ID_VP_2 32822 +#define ID_VP_3 32823 +#define ID_VP_4 32824 +#define ID_VP_5 32825 +#define ID_VP_6 32826 +#define ID_VP_7 32827 +#define ID_VP_8 32828 +#define ID_VP_9 32829 +#define ID_VP_10 32830 +#define ID_VP_11 32831 +#define ID_VP_12 32832 +#define ID_VP_13 32833 +#define ID_VP_14 32834 +#define ID_VP_15 32835 +#define ID_VP_16 32836 +#define ID_VP_17 32837 +#define ID_VP_18 32838 +#define ID_VP_19 32839 +#define ID_VIEW_AR_ORIG 32890 +#define ID_VIEW_AR_FILL 32891 +#define ID_VIEW_AR_43 32892 +#define ID_VIEW_AR_169 32893 +#define ID_VIEW_TIMING 32894 +#define IDS_NEW 65000 +#define IDS_FILE 65001 +#define IDS_MHELP 65002 +#define IDS_SAVE 65003 +#define IDS_CUT 65004 +#define IDS_COPY 65005 +#define IDS_PASTE 65006 +#define IDS_ABOUT 65007 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 143 +#define _APS_NEXT_COMMAND_VALUE 32820 +#define _APS_NEXT_CONTROL_VALUE 1059 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/applications/deprecated/old_arch/osmo4_wce/StdAfx.cpp b/applications/deprecated/old_arch/osmo4_wce/StdAfx.cpp new file mode 100644 index 0000000..e6caa79 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/StdAfx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// Osmo4.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + diff --git a/applications/deprecated/old_arch/osmo4_wce/StdAfx.h b/applications/deprecated/old_arch/osmo4_wce/StdAfx.h new file mode 100644 index 0000000..93d8297 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/StdAfx.h @@ -0,0 +1,39 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__C81DFFE9_41A3_474E_A044_3A730DB4FFD6__INCLUDED_) +#define AFX_STDAFX_H__C81DFFE9_41A3_474E_A044_3A730DB4FFD6__INCLUDED_ + +#if _MSC_VER >= 1000 +#pragma once +#endif // _MSC_VER >= 1000 + +#if (_WIN32_WCE <= 200) +#error This project does not support MFCCE 2.00 or earlier, because it requires CControlBar, available only in MFCCE 2.01 or later +#endif + +#if (_WIN32_WCE <= 211) +#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 +#include // MFC extensions + +#if defined(_AFXDLL) +#include // MFC support for Internet Explorer 4 Common Controls +#endif + +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include // MFC socket extensions + +//{{AFX_INSERT_LOCATION}} +// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__C81DFFE9_41A3_474E_A044_3A730DB4FFD6__INCLUDED_) diff --git a/applications/deprecated/old_arch/osmo4_wce/newres.h b/applications/deprecated/old_arch/osmo4_wce/newres.h new file mode 100644 index 0000000..6cd34bb --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/newres.h @@ -0,0 +1,28 @@ +#ifndef __NEWRES_H__ +#define __NEWRES_H__ + +#define SHMENUBAR RCDATA +#if !(defined(_WIN32_WCE_PSPC) && (_WIN32_WCE >= 300)) +#undef HDS_HORZ +#undef HDS_BUTTONS +#undef HDS_HIDDEN + +#include +// for MenuBar +#define I_IMAGENONE (-2) +#define NOMENU 0xFFFF +#define IDS_SHNEW 1 +#define IDM_SHAREDNEW 10 +#define IDM_SHAREDNEWDEFAULT 11 + +// for Tab Control +#define TCS_SCROLLOPPOSITE 0x0001 // assumes multiline tab +#define TCS_BOTTOM 0x0002 +#define TCS_RIGHT 0x0002 +#define TCS_VERTICAL 0x0080 +#define TCS_MULTISELECT 0x0004 // allow multi-select in button mode +#define TCS_FLATBUTTONS 0x0008 +#endif //_WIN32_WCE_PSPC + + +#endif //__NEWRES_H__ diff --git a/applications/deprecated/old_arch/osmo4_wce/res/Cmdbar.bmp b/applications/deprecated/old_arch/osmo4_wce/res/Cmdbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..90764e4ac4815fd667742681ca767037578c6fa9 GIT binary patch literal 886 zcmcJNK@!3s5CpNbDmnTL-{IXq_ykUgM{fG8{0w_`2~Z|gIk|=n%ghb~@&1_3!D1rc z7*EEPaS9hQQE)H%oI>CUDfx@cG%U-)TR^raz8#=!ENbY0f2Lsm7@m0sf zZRR{wpR2wci_r6_D?hT)D1mZb4ASt!4~;*Md}q5Tzn@+G&JUfEZ~8m_1+V_uS@M-% s=)He~8$U|E<6GJBg`$s;-<;Kr?{poS;4}s1>lMTo4)XecJD_dgFMk0!djJ3c literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_wce/res/Osmo4.ico b/applications/deprecated/old_arch/osmo4_wce/res/Osmo4.ico new file mode 100644 index 0000000000000000000000000000000000000000..96d9091d07264eb11ae7347b213d673a6961cc51 GIT binary patch literal 1078 zcmb7DJ8Hu~5Ph-@LXD+1l?8#|E2OfI6vzR*;6h!ZGKN5|BBLBc>QcINz`V0$q6QufMM=!G7K_ej6W!;qG=kQ z3Rw4twbID^$t7`%vJL4JaOP%H2Tw2uhff|#6jmk=R}oC-pqt^)$ZM3LFDn=s!Y);I z414{`&SE!Z(fHjywNw7txIflM7~;H(`_(t@I~2I5Ucc9);BW8Va)p-wyTFqZBKfB% z!BHF(9MN<@p2K#AfOf#zF1OYs_6V#Fz+w-~cI71RmZP*YNxC)3x&>Ns1@w_$P12|2 zsu}lHm-f{z@7IULwmq)e?P0O*_OrBmnx^Wdp6aa`n&oD4wD!Cpm*lwT4fWe(;1`_x z%>+q9<$rrFs92m)xP2o`)Me6v%%PUme?CK<>!l_tbj4wg+LH9C?Q) gpaccab.inf +ECHO Provider = "GPAC %gpac_version%" >> gpaccab.inf +type gpac.inf >> gpaccab.inf + +CabWiz gpaccab.inf + +ECHO off + +ECHO [CEAppManager]> gpac.ini +ECHO Version = %gpac_version%>> gpac.ini +ECHO Component = GPAC for Windows Mobile>> gpac.ini +ECHO [GPAC for Windows Mobile]>> gpac.ini +ECHO Description = GPAC MPEG-4 Player>> gpac.ini +ECHO Uninstall = GPAC Osmophone>> gpac.ini +ECHO IconFile = ..\..\..\..\doc\osmo4.ico>> gpac.ini +ECHO IconIndex = 0 >> gpac.ini +ECHO CabFiles = gpaccab.cab >> gpac.ini + +ECHO on + +ezsetup -l english -i gpac.ini -r readme.txt -e ../../../../COPYING -o gpac.exe +rename gpac.exe "GPAC_%gpac_version%_WindowsMobile.exe" +DEL gpaccab.cab +DEL gpaccab.inf +DEL gpac.ini +DEL *.tmp + +cd /d %OLDDIR% diff --git a/bin/smartphone 2003 (armv4)/release/install/gpac.inf b/applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/gpac.inf similarity index 100% rename from bin/smartphone 2003 (armv4)/release/install/gpac.inf rename to applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/gpac.inf diff --git a/applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/readme.txt b/applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/readme.txt new file mode 100644 index 0000000..19bf9d1 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wce/smartphone 2003 (armv4)/release/install/readme.txt @@ -0,0 +1,6 @@ +This will install GPAC for ARM PocketPC/SmartPhones 2003 Platforms + +GPAC is an open source MPEG-4 framework developped by ENST and available at: + http://gpac.io + +WARNING: THIS RELEASE COMES WITH NO WARRANTY, AND MAY EVEN DAMAGE YOUR HANDHELD DEVICE. PLEASE READ CAREFULLY THE LICENSE HEREJOIN diff --git a/applications/deprecated/old_arch/osmo4_wx/Darwin.Info.plist b/applications/deprecated/old_arch/osmo4_wx/Darwin.Info.plist new file mode 100644 index 0000000..af4919b --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/Darwin.Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Osmo4 + CFBundleIconFile + Osmo + CFBundleIdentifier + org.gpac.Osmo4 + CFBundlePackageType + APPL + CFBundleSignature + Omo4 + NSHumanReadableCopyright + Copyright (c) 2003-2005 TelecomParisTech + NSMainNibFile + NSMainNibFile + NSPrincipalClass + NSApplication + + diff --git a/applications/deprecated/old_arch/osmo4_wx/Darwin.InfoPlist.strings b/applications/deprecated/old_arch/osmo4_wx/Darwin.InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..3eb07750bca68090fcbb11a545940f2233d9e97d GIT binary patch literal 504 zcmb7=OAolIQ9X>Mok-0z+_b1zqw zRgj^9LOHUv)mmq{T2MO@BgIrg1w@0maAHx3a23dVX_>gGvdkY^T@>~&=UEDGH{X*R zs6N$;bZp~l$E=A550A<86&O=>vMHUCX&oqEV`fgcIITO-rH8|zEcJLDA0p6%8#eD` RYo6ZD>T!RytdqaH-vAtHRLB4T literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_wx/Darwin.Osmo.icns b/applications/deprecated/old_arch/osmo4_wx/Darwin.Osmo.icns new file mode 100644 index 0000000000000000000000000000000000000000..a598061aa6d15577ad67469469bec642644b3eca GIT binary patch literal 38570 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 literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_wx/Makefile b/applications/deprecated/old_arch/osmo4_wx/Makefile new file mode 100644 index 0000000..fcfbea8 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/Makefile @@ -0,0 +1,85 @@ +include ../../config.mak + +vpath %.cpp $(SRC_PATH)/applications/osmo4_wx + +CFLAGS= $(CXXFLAGS) -I"$(SRC_PATH)/include" + +ifeq ($(DEBUGBUILD),yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD),yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +ifeq ($(GPACREADONLY),yes) +CFLAGS+=-DGPAC_READ_ONLY +endif + +#common obj +OBJS= wxOsmo4.o wxGPACControl.o fileprops.o Playlist.o menubtn.o + +ifeq ($(CONFIG_WIN32),yes) +EXE=.exe +PROG=Osmo4$(EXE) +else +EXT= +PROG=Osmo4 +endif + +#3 - spidermonkey support +ifeq ($(CONFIG_JS),no) +else +SCENEGRAPH_CFLAGS+=$(JS_FLAGS) +ifeq ($(CONFIG_JS),local) +NEED_LOCAL_LIB=yes +endif +LINKFLAGS+=$(JS_LIBS) +endif + +CFLAGS+=$(WX_CFLAGS) + +SRCS := $(OBJS:.o=.cpp) + +all: $(PROG) + +Osmo4$(EXE): $(OBJS) + $(CC) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(WX_LFLAGS) $(LINKFLAGS) $(LDFLAGS) + +clean: + rm -f $(OBJS) ../../bin/gcc/$(PROG) + +install: +ifeq ($(CONFIG_DARWIN),yes) + mkdir -p $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/MacOS + mkdir -p $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Resources/English.lproj + cp ./Darwin.Info.plist \ + $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Info.plist + cp ./Darwin.InfoPlist.strings \ + $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Resources/English.lproj/InfoPlist.strings + cp ./Darwin.Osmo.icns \ + $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/Resources/Osmo.icns + install -m 755 $(INSTFLAGS) ../../bin/gcc/Osmo4 \ + $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/MacOS + echo -n 'APPLOsm4' > $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/PkgInfo +else + rm -f wxOsmo4.o + mkdir -p $(DESTDIR)$(prefix)/bin + install -m 755 $(INSTFLAGS) ../../bin/gcc/Osmo4 "$(DESTDIR)$(prefix)/bin" +endif + +uninstall: + rm -rf $(DESTDIR)$(prefix)/bin/Osmo4 + +dep: + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + +-include .depend diff --git a/applications/deprecated/old_arch/osmo4_wx/Playlist.cpp b/applications/deprecated/old_arch/osmo4_wx/Playlist.cpp new file mode 100644 index 0000000..0c9e208 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/Playlist.cpp @@ -0,0 +1,836 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 "wxOsmo4.h" +#include "Playlist.h" + + +#include "playlist.xpm" + +PLEntry::PLEntry(wxString url) +{ + 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, "://"); + if (_url) { + _url += 3; + is_remote = 1; + } + else _url = (const char *) the_url; + + char *str = (char*)strrchr(_url, '\\'); + if (!str) str = (char*)strrchr(_url, '/'); + if (str && strlen(str+1)) { + m_disp_name = gf_strdup(str+1); + str = strrchr(m_disp_name, '.'); + if (str) str[0] = 0; + } else { + m_disp_name = gf_strdup(_url); + if (!is_remote) { + str = strrchr(m_disp_name, '.'); + if (str) str[0] = 0; + } + } + m_duration = 0; + m_bIsDead = 0; + m_bIsPlaying = 0; + m_bIsSelected = 0; +} + +PLEntry::~PLEntry() +{ + if (m_url) gf_free(m_url); + if (m_disp_name) gf_free(m_disp_name); + +} + +wxPlaylist::wxPlaylist(wxWindow *parent) + : wxFrame(parent, -1, wxString(_T("Osmo4 Playlist")), wxDefaultPosition, wxDefaultSize, + wxCLOSE_BOX | wxSYSTEM_MENU | wxCAPTION | wxRESIZE_BORDER) +{ + + m_pApp = (wxOsmo4Frame *)parent; + + m_pOpen = new wxBitmap(pl_open); + m_pSave = new wxBitmap(pl_save); + m_pAdd = new wxBitmap(pl_add); + m_pRem = new wxBitmap(pl_rem); + m_pUp = new wxBitmap(pl_up); + m_pDown = new wxBitmap(pl_down); + m_pSort = new wxBitmap(pl_sort); + + m_pToolBar = CreateToolBar(wxTB_HORIZONTAL); + m_pAddBut = new wxMenuButton(m_pToolBar, ID_PL_ADD_FILE, *m_pAdd); + wxMenu *menu = new wxMenu(); + menu->Append(ID_PL_ADD_URL, wxT("&Url")); + menu->Append(ID_PL_ADD_DIR, wxT("&Directory")); + menu->Append(ID_PL_ADD_DIR_REC, wxT("&Directory and subfolders")); + m_pAddBut->AssignMenu(menu); + m_pAddBut->SetToolTip(wxString(wxT("Add Files"))); + + m_pRemBut = new wxMenuButton(m_pToolBar, ID_PL_REM_FILE, *m_pRem); + menu = new wxMenu(); + menu->Append(ID_PL_REM_ALL, wxT("&Clear")); + menu->Append(ID_PL_REM_DEAD, wxT("&Remove dead entries")); + m_pRemBut->AssignMenu(menu); + m_pRemBut->SetToolTip(wxString(wxT("Remove Selected Files"))); + + m_pSortBut = new wxMenuButton(m_pToolBar, ID_PL_SORT_FILE, *m_pSort); + menu = new wxMenu(); + menu->Append(ID_PL_SORT_TITLE, wxT("&Sort by Title")); + menu->Append(ID_PL_SORT_FILE, wxT("&Sort by file name")); + menu->Append(ID_PL_SORT_DUR, wxT("&Sort by Duration")); + menu->AppendSeparator(); + menu->Append(ID_PL_REVERSE, wxT("&Reverse")); + menu->Append(ID_PL_RANDOMIZE, wxT("&Randomize")); + m_pSortBut->AssignMenu(menu); + m_pSortBut->SetToolTip(wxString(wxT("Sort Playlist by filename"))); + + m_pToolBar->AddTool(ID_PL_OPEN, wxT(""), *m_pOpen, wxT("Open Playlist")); + m_pToolBar->AddTool(ID_PL_SAVE, wxT(""), *m_pSave, wxT("Save Playlist")); + m_pToolBar->AddSeparator(); + m_pToolBar->AddControl(m_pAddBut); + m_pToolBar->AddControl(m_pRemBut); + m_pToolBar->AddSeparator(); + m_pToolBar->AddTool(ID_PL_UP, wxT(""), *m_pUp, wxT("Moves Selected Files Up")); + m_pToolBar->AddTool(ID_PL_DOWN, wxT(""), *m_pDown, wxT("Moves Selected Files Down")); + m_pToolBar->AddSeparator(); + m_pToolBar->AddControl(m_pSortBut); + m_pToolBar->Realize(); + + m_FileList = new wxListCtrl(this, ID_FILE_LIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT); + + m_FileList->InsertColumn(0, wxT(""), wxLIST_FORMAT_LEFT, 1); + m_FileList->InsertColumn(1, wxT("Title"), wxLIST_FORMAT_LEFT, 1); + m_FileList->InsertColumn(2, wxT("Duration"), wxLIST_FORMAT_LEFT, 1); + + m_entries = gf_list_new(); + m_cur_entry = -1; + m_all_dead_entries = -1; + + SetSize(220, 380); + Centre(); +} + +wxPlaylist::~wxPlaylist() +{ + Clear(); + gf_list_del(m_entries); + delete m_pAddBut; + delete m_pRemBut; + delete m_pSortBut; + delete m_pOpen; + delete m_pSave; + delete m_pAdd; + delete m_pRem; + delete m_pUp; + delete m_pDown; + delete m_pSort; +} + + +BEGIN_EVENT_TABLE(wxPlaylist, wxWindow) + EVT_CLOSE(wxPlaylist::OnClose) + EVT_SIZE(wxPlaylist::OnSize) + EVT_TOOL(ID_PL_ADD_FILE, wxPlaylist::OnAddFile) + EVT_TOOL(ID_PL_ADD_URL, wxPlaylist::OnAddURL) + EVT_TOOL(ID_PL_ADD_DIR, wxPlaylist::OnAddDir) + EVT_TOOL(ID_PL_ADD_DIR_REC, wxPlaylist::OnAddDirRec) + EVT_TOOL(ID_PL_REM_FILE, wxPlaylist::OnRemFile) + EVT_TOOL(ID_PL_REM_ALL, wxPlaylist::OnRemAll) + EVT_TOOL(ID_PL_REM_DEAD, wxPlaylist::OnRemDead) + EVT_TOOL(ID_PL_UP, wxPlaylist::OnSelUp) + EVT_TOOL(ID_PL_DOWN, wxPlaylist::OnSelDown) + EVT_TOOL(ID_PL_SAVE, wxPlaylist::OnSave) + EVT_TOOL(ID_PL_OPEN, wxPlaylist::OnOpen) + EVT_MENU(ID_PL_PLAY, wxPlaylist::OnPlay) + EVT_MENU(ID_PL_RANDOMIZE, wxPlaylist::OnRandomize) + EVT_MENU(ID_PL_REVERSE, wxPlaylist::OnReverseList) + EVT_MENU(ID_PL_SEL_REV, wxPlaylist::OnReverseSelection) + EVT_MENU(ID_PL_SORT_TITLE, wxPlaylist::OnSortTitle) + EVT_MENU(ID_PL_SORT_FILE, wxPlaylist::OnSortFile) + EVT_MENU(ID_PL_SORT_DUR, wxPlaylist::OnSortDuration) + EVT_LIST_ITEM_ACTIVATED(ID_FILE_LIST, wxPlaylist::OnItemActivate) + EVT_LIST_ITEM_RIGHT_CLICK(ID_FILE_LIST, wxPlaylist::OnRightClick) +END_EVENT_TABLE() + +void wxPlaylist::OnClose(wxCloseEvent &event) +{ + if (event.CanVeto()) { + event.Veto(); + Hide(); + } +} + +void wxPlaylist::OnSize(wxSizeEvent &event) +{ + wxSize s = event.GetSize(); + m_FileList->SetSize(0, 0, s.GetWidth()-2, s.GetHeight()); + m_FileList->SetColumnWidth(0, 30); + m_FileList->SetColumnWidth(2, 60); + m_FileList->SetColumnWidth(1, s.GetWidth()-96); +} + +void wxPlaylist::Clear() +{ + m_FileList->DeleteAllItems(); + while (gf_list_count(m_entries)) { + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, 0); + gf_list_rem(m_entries, 0); + delete ple; + } + m_cur_entry = -1; +} + +void wxPlaylist::ClearButPlaying() +{ + PLEntry *p = NULL; + if (m_cur_entry >= 0) { + p = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + gf_list_rem(m_entries, m_cur_entry); + } + Clear(); + if (p) { + gf_list_add(m_entries, p); + m_cur_entry = 0; + } + RefreshList(); +} + +void wxPlaylist::UpdateEntry(u32 idx) +{ + char szText[20]; + + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, idx); + if (idx+1<10) sprintf(szText, "00%d", idx+1); + else if (idx+1<100) sprintf(szText, "0%d", idx+1); + else sprintf(szText, "%d", idx+1); + m_FileList->SetItem(idx, 0, wxString(szText, wxConvUTF8)); + + wxString str; + if (ple->m_bIsDead) str = wxT("!! ") + wxString(ple->m_disp_name, wxConvUTF8) + wxT(" (DEAD)!!)"); + else if (ple->m_bIsPlaying) str = wxT(">> ") + wxString(ple->m_disp_name, wxConvUTF8) + wxT(" >>"); + else str = wxString(ple->m_disp_name, wxConvUTF8); + m_FileList->SetItem(idx, 1, str); + + if (ple->m_duration) { + u32 h = (u32) (ple->m_duration / 3600); + u32 m = (u32) (ple->m_duration / 60) - h*60; + u32 s = (u32) (ple->m_duration) - h*3600 - m*60; + m_FileList->SetItem(idx, 2, wxString::Format(wxT("%02d:%02d:%02d"), h, m, s) ); + } else { + m_FileList->SetItem(idx, 2, wxT("Unknown")); + } +} + +void wxPlaylist::RefreshList() +{ + u32 i, top_idx; + char szPath[GF_MAX_PATH]; + Bool first_sel; + + top_idx = m_FileList->GetTopItem(); + m_FileList->DeleteAllItems(); + + first_sel = 0; + for (i=0; iInsertItem(i, wxT("")); + /*cast for 64-bit compilation*/ + m_FileList->SetItemData(i, (unsigned long) ple); + UpdateEntry(i); + + if (ple->m_bIsPlaying) m_cur_entry = i; + + if (ple->m_bIsSelected) { + m_FileList->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED | wxLIST_MASK_STATE); + ple->m_bIsSelected = 0; + /*ensure first item of selection is visible*/ + if (!first_sel) { + first_sel = 1; + top_idx = i; + } + } + } + + if (m_cur_entry >= (s32) gf_list_count(m_entries)-1) m_cur_entry = gf_list_count(m_entries)-1; + else { + s32 last_idx = top_idx + m_FileList->GetCountPerPage(); + m_FileList->EnsureVisible(top_idx); + if (gf_list_count(m_entries)<1+ (u32) last_idx) last_idx = gf_list_count(m_entries)-1; + m_FileList->EnsureVisible(last_idx); + } + + strcpy((char *) szPath, m_pApp->szAppPath); +#ifdef WIN32 + strcat(szPath, "gpac_pl.m3u"); +#else + strcat(szPath, ".gpac_pl.m3u"); +#endif + Save(szPath, 1); +} + +void wxPlaylist::OnAddFile(wxCommandEvent &WXUNUSED(event)) +{ + wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), m_pApp->GetFileFilter(), wxOPEN | wxCHANGE_DIR | /*wxHIDE_READONLY |*/ wxMULTIPLE); + + if (dlg.ShowModal() == wxID_OK) { + wxArrayString stra; + dlg.GetPaths(stra); + for (u32 i=0; im_pApp->m_term, item_name, 0, 1)) { + PLEntry *ple = new PLEntry(wxString(item_path, wxConvUTF8) ); + gf_list_add(_this->m_entries, ple); + } + return 0; +} + +static Bool pl_enum_dir_dirs(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) +{ + gf_enum_directory(item_path, 0, pl_enum_dir_item, cbck, NULL); + gf_enum_directory(item_path, 1, pl_enum_dir_dirs, cbck, NULL); + return 0; +} + + +void wxPlaylist::AddDir(Bool do_recurse) +{ + wxDirDialog dlg(this); + dlg.SetPath(wxString(szCacheDir, wxConvUTF8) ); + if (dlg.ShowModal() != wxID_OK) return; + + strcpy(szCacheDir, dlg.GetPath().mb_str(wxConvUTF8)); + gf_enum_directory(szCacheDir, 0, pl_enum_dir_item, this, NULL); + if (do_recurse) gf_enum_directory(szCacheDir, 1, pl_enum_dir_dirs, this, NULL); + m_all_dead_entries = -1; + RefreshList(); +} +void wxPlaylist::OnAddDir(wxCommandEvent &WXUNUSED(event)) +{ + AddDir(0); +} +void wxPlaylist::OnAddDirRec(wxCommandEvent &WXUNUSED(event)) +{ + AddDir(1); +} + +void wxPlaylist::OnAddURL(wxCommandEvent &WXUNUSED(event)) +{ + OpenURLDlg dlg(this, m_pApp->m_user.config); + if (dlg.ShowModal() != wxID_OK) return; + PLEntry *ple = new PLEntry(dlg.m_urlVal); + gf_list_add(m_entries, ple); + m_all_dead_entries = -1; + RefreshList(); +} + +void wxPlaylist::OnRemFile(wxCommandEvent &WXUNUSED(event)) +{ + if (!m_FileList->GetSelectedItemCount()) return; + + long item = -1; + for (;;) { + item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) break; + PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); + gf_list_del_item(m_entries, ple); + delete ple; + } + RefreshList(); +} + +void wxPlaylist::OnRemAll(wxCommandEvent &WXUNUSED(event)) +{ + Clear(); + RefreshList(); + m_cur_entry = -1; + m_all_dead_entries = 1; +} + +void wxPlaylist::OnRemDead(wxCommandEvent &WXUNUSED(event)) +{ + for (u32 i=0; im_bIsDead) continue; + gf_list_rem(m_entries, i); + i--; + delete ple; + } + m_all_dead_entries = gf_list_count(m_entries) ? 0 : 1; + RefreshList(); +} + + +void wxPlaylist::OnSelUp(wxCommandEvent &WXUNUSED(event)) +{ + s32 i; + if (!m_FileList->GetSelectedItemCount()) return; + long item = -1; + item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item <= 0) return; + + item = -1; + for (;;) { + item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) break; + PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); + i = gf_list_del_item(m_entries, ple); + assert(i>=1); + gf_list_insert(m_entries, ple, i-1); + ple->m_bIsSelected = 1; + } + RefreshList(); +} + +void wxPlaylist::OnSelDown(wxCommandEvent &WXUNUSED(event)) +{ + s32 i; + + if (!m_FileList->GetSelectedItemCount()) return; + long item = -1; + for (;;) { + item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) break; + } + if ((u32) item + 1 == gf_list_count(m_entries)) return; + + item = -1; + for (;;) { + item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) break; + PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); + i = gf_list_del_item(m_entries, ple); + assert(i>=1); + gf_list_insert(m_entries, ple, i+1); + ple->m_bIsSelected = 1; + } + RefreshList(); +} + + + +void wxPlaylist::OnSave(wxCommandEvent & WXUNUSED(event)) +{ + Bool save_m3u; + char szPath[GF_MAX_PATH]; + if (!gf_list_count(m_entries)) return; + + wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), wxT("M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"), wxSAVE | wxCHANGE_DIR | wxOVERWRITE_PROMPT); + if (dlg.ShowModal() != wxID_OK) return; + + strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); + strlwr(szPath); + save_m3u = (dlg.GetFilterIndex()==0) ? 1 : 0; + if (save_m3u) { + if (!strstr(szPath, ".m3u")) { + strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); + strcat(szPath, ".m3u"); + } else { + strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); + } + } else { + if (!strstr(szPath, ".pls")) { + strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); + strcat(szPath, ".pls"); + } else { + strcpy(szPath, dlg.GetPath().mb_str(wxConvUTF8)); + } + } + Save(szPath, save_m3u); +} + +void wxPlaylist::Save(char *szPath, Bool save_m3u) +{ + FILE *out = gf_fopen(szPath, "wt"); + if (!save_m3u) + fprintf(out, "[playlist]\nNumberOfEntries=%d\n", gf_list_count(m_entries)); + + for (u32 i=0; im_url); + } else { + fprintf(out, "File%d=%s\n", i+1, ple->m_url); + fprintf(out, "Title%d=%s\n", i+1, ple->m_disp_name); + if (ple->m_duration) fprintf(out, "Length%d=%d\n", i+1, ple->m_duration); + else fprintf(out, "Length%d=-1\n", i+1); + } + } + if (!save_m3u) fprintf(out, "Version=2\n"); + + fprintf(out, "\n"); + gf_fclose(out); +} + +void wxPlaylist::OnOpen(wxCommandEvent & WXUNUSED(event)) +{ + wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), wxT("M3U & PLS Playlists|*.m3u;*.pls|M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|"), wxOPEN | wxCHANGE_DIR/* | wxHIDE_READONLY*/); + if (dlg.ShowModal() != wxID_OK) return; + + Clear(); + OpenPlaylist(dlg.GetPath()); + m_cur_entry = 0; + Play(); +} + +void wxPlaylist::OpenPlaylist(wxString filename) +{ + FILE *pl; + PLEntry *ple; + Bool load_m3u, go; + char szLine[GF_MAX_PATH]; + pl = gf_fopen(filename.mb_str(wxConvUTF8) , "rt"); + if (!pl) return; + + ple = NULL; + load_m3u = 1; + while (!feof(pl)) { + fgets(szLine, GF_MAX_PATH, pl); + go = 1; + while (go) { + switch (szLine[strlen(szLine)-1]) { + case '\n': + case '\r': + case ' ': + szLine[strlen(szLine)-1] = 0; + break; + default: + go = 0; + break; + } + } + if (!strlen(szLine)) continue; + if (!stricmp(szLine, "[playlist]")) { + load_m3u = 0; + } else if (load_m3u) { + ple = new PLEntry(wxString(szLine, wxConvUTF8) ); + gf_list_add(m_entries, ple); + } else if (!strnicmp(szLine, "file", 4)) { + char *st = strchr(szLine, '='); + if (!st) ple = NULL; + else { + ple = new PLEntry(wxString(st + 1, wxConvUTF8) ); + gf_list_add(m_entries, ple); + } + } else if (ple && !strnicmp(szLine, "Length", 6)) { + char *st = strchr(szLine, '='); + s32 d = atoi(st + 1); + if (d>0) ple->m_duration = d; + } else if (ple && !strnicmp(szLine, "Title", 5)) { + char *st = strchr(szLine, '='); + gf_free(ple->m_disp_name); + ple->m_disp_name = gf_strdup(st + 6); + } + } + gf_fclose(pl); + m_all_dead_entries = -1; + m_cur_entry = -1; + RefreshList(); +} + +void wxPlaylist::OnRightClick(wxListEvent & event) +{ + if (!m_FileList->GetItemCount()) return; + + wxMenu *popup = new wxMenu(); + + if (m_FileList->GetSelectedItemCount()==1) { + popup->Append(ID_PL_PLAY, wxT("Play")); + popup->AppendSeparator(); + } + popup->Append(ID_PL_SEL_REV, wxT("Inverse Selection")); + if (m_FileList->GetSelectedItemCount()) popup->Append(ID_PL_REM_FILE, wxT("Remove File(s)")); + if (m_FileList->GetItemCount()>1) { + popup->AppendSeparator(); + popup->Append(ID_PL_SORT_TITLE, wxT("Sort By Title")); + popup->Append(ID_PL_SORT_FILE, wxT("Sort By File Name")); + popup->Append(ID_PL_SORT_DUR, wxT("Sort By Duration")); + popup->AppendSeparator(); + popup->Append(ID_PL_REVERSE, wxT("Reverse List")); + popup->Append(ID_PL_RANDOMIZE, wxT("Randomize")); + } + + PopupMenu(popup, event.GetPoint()); + delete popup; +} + +void wxPlaylist::OnReverseSelection(wxCommandEvent &WXUNUSED(event) ) +{ + u32 i; + long item = -1; + for (;;) { + item = m_FileList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) break; + PLEntry *ple = (PLEntry *) m_FileList->GetItemData(item); + ple->m_bIsSelected = 1; + } + for (i=0; im_bIsSelected = !ple->m_bIsSelected; + } + RefreshList(); +} + +void wxPlaylist::OnReverseList(wxCommandEvent &WXUNUSED(event) ) +{ + u32 count = gf_list_count(m_entries); + u32 hcount = count / 2; + count--; + for (u32 i=0; i1) { + u32 pos = gf_rand() % (gf_list_count(m_entries)-1); + PLEntry *ple = (PLEntry *)gf_list_get(m_entries, pos); + gf_list_rem(m_entries, pos); + gf_list_add(new_entries, ple); + } + PLEntry *ple = (PLEntry *)gf_list_get(m_entries, 0); + gf_list_rem(m_entries, 0); + gf_list_add(new_entries, ple); + + gf_list_del(m_entries); + m_entries = new_entries; + m_cur_entry = -1; + RefreshList(); +} + +void wxPlaylist::Sort(u32 type) +{ + u32 i, j, smallest; + + for (i=0; im_url, ple2->m_url); + break; + case 1: + test = stricmp(ple1->m_disp_name, ple2->m_disp_name); + break; + case 2: + test = ple1->m_duration - ple2->m_duration; + break; + } + if (test<0) smallest = j; + } + PLEntry *ple = (PLEntry *)gf_list_get(m_entries, smallest); + gf_list_rem(m_entries, smallest); + gf_list_insert(m_entries, ple, i); + } + m_cur_entry = -1; + RefreshList(); +} + +void wxPlaylist::OnSortFile(wxCommandEvent &WXUNUSED(event) ) { + Sort(0); +} +void wxPlaylist::OnSortTitle(wxCommandEvent &WXUNUSED(event) ) { + Sort(1); +} +void wxPlaylist::OnSortDuration(wxCommandEvent &WXUNUSED(event) ) { + Sort(2); +} + +void wxPlaylist::RefreshCurrent() +{ + PLEntry *ple; + if (m_cur_entry<0) return; + ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple && ple->m_bIsPlaying) { + ple->m_bIsPlaying = 0; + UpdateEntry(m_cur_entry); + } +} + +Bool wxPlaylist::HasValidEntries() +{ + u32 nb_dead = 0; + if (m_all_dead_entries==-1) { + for (u32 i=0; im_bIsPlaying = 0; + if (ple->m_bIsDead) nb_dead ++; + } + m_all_dead_entries = (nb_dead==gf_list_count(m_entries)) ? 1 : 0; + } + return !m_all_dead_entries; +} + +void wxPlaylist::Play() +{ + PLEntry *ple; + + if (!HasValidEntries()) return; + + RefreshCurrent(); + + if (m_cur_entry >= (s32)gf_list_count(m_entries)) { + if (!m_pApp->m_loop) return; + m_cur_entry = 0; + } + + ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (!ple || ple->m_bIsDead) { + m_cur_entry++; + Play(); + } else { + char szPLE[20]; + ple->m_bIsPlaying = 1; + UpdateEntry(m_cur_entry); + sprintf(szPLE, "%d", m_cur_entry); + gf_cfg_set_key(m_pApp->m_user.config, "General", "PLEntry", szPLE); + m_pApp->DoConnect(); + } +} + +void wxPlaylist::OnItemActivate(wxListEvent &WXUNUSED(event) ) +{ + long item = m_FileList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item==-1) return; + RefreshCurrent(); + m_cur_entry = item; + Play(); +} + + +void wxPlaylist::OnPlay(wxCommandEvent &WXUNUSED(event)) +{ + long item = m_FileList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item==-1) return; + + RefreshCurrent(); + m_cur_entry = item; + Play(); +} + +void wxPlaylist::Truncate() +{ + if (m_cur_entry<0) return; + while ((u32) m_cur_entry+1 < gf_list_count(m_entries)) { + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry+1); + gf_list_rem(m_entries, m_cur_entry+1); + delete ple; + } + RefreshList(); +} + +void wxPlaylist::QueueURL(wxString filename) +{ + char *ext = (char*)strrchr(filename.mb_str(wxConvUTF8), '.'); + if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls")) ) { + OpenPlaylist(filename); + } else { + PLEntry *ple = new PLEntry(filename); + gf_list_add(m_entries, ple); + } +} + +void wxPlaylist::PlayNext() +{ + RefreshCurrent(); + if (1+m_cur_entry < (s32)gf_list_count(m_entries)) { + m_cur_entry++; + Play(); + } +} + +void wxPlaylist::PlayPrev() +{ + RefreshCurrent(); + if (m_cur_entry>0) { + m_cur_entry--; + Play(); + } +} + +void wxPlaylist::SetDead() +{ + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) { + ple->m_bIsDead = 1; + UpdateEntry(m_cur_entry); + if (ple->m_bIsPlaying) PlayNext(); + m_all_dead_entries = -1; + } +} +void wxPlaylist::SetDuration(u32 duration) +{ + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) { + ple->m_duration = duration; + UpdateEntry(m_cur_entry); + } +} + +wxString wxPlaylist::GetDisplayName() +{ + if (m_cur_entry>=0) { + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) return wxString(wxString(ple->m_disp_name, wxConvUTF8) ); + } + return wxT(""); +} + +wxString wxPlaylist::GetURL() +{ + PLEntry *ple = (PLEntry *) gf_list_get(m_entries, m_cur_entry); + if (ple) return wxString(ple->m_url, wxConvUTF8); + return wxT(""); +} + diff --git a/applications/deprecated/old_arch/osmo4_wx/Playlist.h b/applications/deprecated/old_arch/osmo4_wx/Playlist.h new file mode 100644 index 0000000..444aefb --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/Playlist.h @@ -0,0 +1,135 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 _PLAYLIST_H +#define _PLAYLIST_H + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "menubtn.h" + +enum +{ + ID_FILE_LIST = 1000, +}; + +class wxOsmo4Frame; + +class PLEntry +{ +public: + PLEntry(wxString url); + ~PLEntry(); + + char *m_url; + char *m_disp_name; + u32 m_duration; + + Bool m_bIsSelected; + Bool m_bIsDead; + Bool m_bIsPlaying; +}; + + +class wxPlaylist : public wxFrame +{ +public: + wxPlaylist(wxWindow *parent); + virtual ~wxPlaylist(); + + void Clear(); + void ClearButPlaying(); + void RefreshList(); + + void Truncate(); + void QueueURL(wxString filename); + void Play(); + void PlayNext(); + void PlayPrev(); + void SetDead(); + void SetDuration(u32 duration); + Bool HasValidEntries(); + void OpenPlaylist(wxString fileName); + + /*for current entry played*/ + wxString GetDisplayName(); + wxString GetURL(); + + s32 m_cur_entry; + GF_List *m_entries; + + wxOsmo4Frame *m_pApp; + +private: + DECLARE_EVENT_TABLE() + + void OnClose(wxCloseEvent &event); + void OnSize(wxSizeEvent &event); + void OnAddFile(wxCommandEvent &event); + void OnAddURL(wxCommandEvent &event); + void OnAddDir(wxCommandEvent &event); + void OnAddDirRec(wxCommandEvent &event); + void OnRemFile(wxCommandEvent &event); + void OnRemAll(wxCommandEvent &event); + void OnRemDead(wxCommandEvent &event); + void OnSelUp(wxCommandEvent &event); + void OnSelDown(wxCommandEvent &event); + void OnSave(wxCommandEvent &event); + void OnOpen(wxCommandEvent &event); + void OnRightClick(wxListEvent & event); + void OnReverseSelection(wxCommandEvent &event); + void OnReverseList(wxCommandEvent &event); + void OnRandomize(wxCommandEvent &event); + void OnSortFile(wxCommandEvent &event); + void OnSortTitle(wxCommandEvent &event); + void OnSortDuration(wxCommandEvent &event); + void OnItemActivate(wxListEvent &event); + void OnPlay(wxCommandEvent &event); + + + void Sort(u32 type); + void UpdateEntry(u32 idx); + void RefreshCurrent(); + void Save(char *szPath, Bool save_m3u); + + wxBitmap *m_pOpen, *m_pSave, *m_pAdd, *m_pRem, *m_pUp, *m_pDown, *m_pSort; + wxMenuButton *m_pAddBut, *m_pRemBut, *m_pSortBut; + wxToolBar *m_pToolBar; + wxListCtrl *m_FileList; + char szCacheDir[GF_MAX_PATH]; + s32 m_all_dead_entries; + + void AddDir(Bool do_recurse); +}; + + + +#endif + diff --git a/applications/deprecated/old_arch/osmo4_wx/fileprops.cpp b/applications/deprecated/old_arch/osmo4_wx/fileprops.cpp new file mode 100644 index 0000000..c59be08 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/fileprops.cpp @@ -0,0 +1,650 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 "fileprops.h" +#include "wxOsmo4.h" +#include "Playlist.h" +#include +#include +#include +#include +/*ISO 639 languages*/ +#include + + +wxFileProps::wxFileProps(wxWindow *parent) + : wxDialog(parent, -1, wxString(_T("File Properties"))) +{ + + m_pApp = (wxOsmo4Frame *)parent; + SetSize(540, 260); + assert(m_pApp->m_pPlayList); + + m_pTreeView = new wxTreeCtrl(this, ID_TREE_VIEW, wxPoint(4, 2), wxSize(200, 180), wxTR_DEFAULT_STYLE | wxSUNKEN_BORDER); + + new wxStaticText(this, 0, _T("Information"), wxPoint(210, 2), wxSize(60, 20)); + m_pViewSel = new wxComboBox(this, ID_VIEW_SEL, _T(""), wxPoint(280, 2), wxSize(120, 24), 0, NULL, wxCB_READONLY); + m_pViewSel->Append(wxT("General")); + m_pViewSel->Append(wxT("Streams")); + m_pViewSel->Append(wxT("Playback")); + m_pViewSel->Append(wxT("Network")); + m_pViewSel->SetSelection(0); + + m_pViewInfo = new wxTextCtrl(this, -1, wxT(""), wxPoint(210, 30), wxSize(320, 200), wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL | wxSUNKEN_BORDER); + +#ifdef WIN32 + m_pViewInfo->SetBackgroundColour(wxColour(wxT("LIGHT GREY"))); +#endif + + m_pViewWI = new wxButton(this, ID_VIEW_WI, wxT("View World Info"), wxPoint(4, 174), wxSize(200, 40)); + m_pViewSG = new wxButton(this, ID_VIEW_SG, wxT("View Scene Graph"), wxPoint(4, 220), wxSize(200, 40)); + + + wxString str = m_pApp->m_pPlayList->GetDisplayName(); + str += wxT(" Properties"); + SetTitle(str); + + m_pTimer = new wxTimer(); + m_pTimer->SetOwner(this, ID_OD_TIMER); + m_pTimer->Start(500, 0); + RewriteODTree(); + +} + +wxFileProps::~wxFileProps() +{ + m_pTimer->Stop(); + delete m_pTimer; +} + + +BEGIN_EVENT_TABLE(wxFileProps, wxDialog) + EVT_TREE_ITEM_ACTIVATED(ID_TREE_VIEW, wxFileProps::OnSetSelection) + EVT_TREE_SEL_CHANGED(ID_TREE_VIEW, wxFileProps::OnSetSelection) + EVT_TREE_ITEM_EXPANDED(ID_TREE_VIEW, wxFileProps::OnSetSelection) + EVT_TREE_ITEM_COLLAPSED(ID_TREE_VIEW, wxFileProps::OnSetSelection) + EVT_TIMER(ID_OD_TIMER, wxFileProps::OnTimer) + EVT_BUTTON(ID_VIEW_SG, wxFileProps::OnViewSG) + EVT_BUTTON(ID_VIEW_WI, wxFileProps::OnViewWorld) + EVT_COMBOBOX(ID_VIEW_SEL, wxFileProps::OnSelectInfo) +END_EVENT_TABLE() + +void wxFileProps::RewriteODTree() +{ + GF_ObjectManager *root_odm = gf_term_get_root_object(m_pApp->m_term); + if (!root_odm) return; + + m_pTreeView->DeleteAllItems(); + ODTreeData *root = new ODTreeData(root_odm); + m_pTreeView->AddRoot(wxT("Root OD"), -1, -1, root); + wxTreeItemId rootId = m_pTreeView->GetRootItem(); + + WriteInlineTree(root); + SetInfo(root_odm); +} + +void wxFileProps::WriteInlineTree(ODTreeData *root) +{ + /*browse all ODs*/ + u32 count = gf_term_get_object_count(m_pApp->m_term, root->m_pODMan); + + for (u32 i=0; im_term, root->m_pODMan, i); + if (!odm) return; + ODTreeData *odd = new ODTreeData(odm); + m_pTreeView->AppendItem(root->GetId(), wxT("Object Descriptor"), -1, -1, odd); + + /*if inline propagate*/ + switch (gf_term_object_subscene_type(m_pApp->m_term, odm)) { + case 1: + m_pTreeView->SetItemText(odd->GetId(), wxT("Root Scene")); + WriteInlineTree(odd); + break; + case 2: + m_pTreeView->SetItemText(odd->GetId(), wxT("Inline Scene")); + WriteInlineTree(odd); + break; + case 3: + m_pTreeView->SetItemText(odd->GetId(), wxT("Extern Proto Lib")); + break; + default: + break; + } + } +} + +void wxFileProps::OnSetSelection(wxTreeEvent& event) +{ + ODTreeData *odd = (ODTreeData *) m_pTreeView->GetItemData(event.GetItem()); + SetInfo(odd->m_pODMan); +} + +void wxFileProps::SetInfo(GF_ObjectManager *odm) +{ + m_current_odm = odm; + + switch (m_pViewSel->GetSelection()) { + case 3: + SetNetworkInfo(); + break; + case 2: + SetDecoderInfo(); + break; + case 1: + SetStreamsInfo(); + break; + default: + SetGeneralInfo(); + break; + } +} + +void wxFileProps::OnTimer(wxTimerEvent& WXUNUSED(event)) +{ + switch (m_pViewSel->GetSelection()) { + case 2: + SetDecoderInfo(); + break; + } +} +void wxFileProps::OnSelectInfo(wxCommandEvent & WXUNUSED(event) ) +{ + SetInfo(m_current_odm); +} + +void wxFileProps::SetGeneralInfo() +{ + wxString info; + GF_MediaInfo odi; + u32 h, m, s; + u32 i, j; + + info = wxT(""); + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); + + if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi) != GF_OK) return; + + if (odi.has_profiles) info += wxT("Initial "); + info += wxString::Format(wxT("Object Descriptor ID %d\n"), odi.od->objectDescriptorID); + if (odi.duration) { + h = (u32) (odi.duration / 3600); + m = (u32) (odi.duration / 60) - h*60; + s = (u32) (odi.duration) - h*3600 - m*60; + info += wxString::Format(wxT("Duration %02d:%02d:%02d\n"), h, m, s); + } else { + info += wxT("Unknown duration\n"); + } + + if (odi.owns_service) { + info += wxT("Service Handler: ") + wxString(odi.service_handler, wxConvUTF8) + wxT("\n"); + info += wxT("Service URL: ") + wxString(odi.service_url, wxConvUTF8) + wxT("\n"); + } + + if (odi.od->URLString) { + info += wxT("Remote OD - URL: ") + wxString(odi.od->URLString, wxConvUTF8) + wxT("\n"); + } + + if (odi.codec_name) { + switch (odi.od_type) { + case GF_STREAM_VISUAL: + info += wxString::Format(wxT("Video Object: Width %d - Height %d\n"), odi.width, odi.height); + info += wxT("Media Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); + break; + case GF_STREAM_AUDIO: + info += wxString::Format(wxT("Audio Object: Sample Rate %d - %d channels\n"), odi.sample_rate, odi.num_channels); + info += wxT("Media Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); + break; + case GF_STREAM_PRIVATE_SCENE: + case GF_STREAM_SCENE: + if (odi.width && odi.height) { + info += wxString::Format(wxT("Scene Description: Width %d - Height %d\n"), odi.width, odi.height); + } else { + info += wxT("Scene Description: No size specified\n"); + } + info += wxT("Scene Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); + break; + case GF_STREAM_TEXT: + if (odi.width && odi.height) { + info += wxString::Format(wxT("Text Object: Width %d - Height %d\n"), odi.width, odi.height); + } else { + info += wxString::Format(wxT("Text Object: No size specified\n")); + } + info += wxT("Text Codec ") + wxString(odi.codec_name, wxConvUTF8) + wxT("\n"); + break; + } + } + if (odi.protection==2) info += wxT("Encrypted Media NOT UNLOCKED"); + else if (odi.protection==1) info += wxT("Encrypted Media"); + + if (!gf_list_count(odi.od->OCIDescriptors)) { + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); + return; + } + + info += wxT("\nObject Content Information:\n"); + + /*check OCI (not everything interests us) - FIXME: support for unicode*/ + for (i=0; iOCIDescriptors); i++) { + GF_Descriptor *desc = (GF_Descriptor *) gf_list_get(odi.od->OCIDescriptors, i); + switch (desc->tag) { + case GF_ODF_SEGMENT_TAG: + { + GF_Segment *sd = (GF_Segment *) desc; + info += wxT("\nSegment Descriptor:\nName: ") + wxString((char *) sd->SegmentName, wxConvUTF8); + info += wxString::Format(wxT(" - start time %g sec - duration %g sec\n"), sd->startTime, sd->Duration); + } + break; + case GF_ODF_CC_NAME_TAG: + { + GF_CC_Name *ccn = (GF_CC_Name *)desc; + info += wxT("\nContent Creators:\n"); + for (j=0; jContentCreators); j++) { + GF_ContentCreatorInfo *ci = (GF_ContentCreatorInfo *) gf_list_get(ccn->ContentCreators, j); + if (!ci->isUTF8) continue; + info += wxT("\t") + wxString(ci->contentCreatorName, wxConvUTF8) + wxT("\n"); + } + } + break; + + case GF_ODF_SHORT_TEXT_TAG: + { + GF_ShortTextual *std = (GF_ShortTextual *)desc; + info += wxT("\n") + wxString(std->eventName, wxConvUTF8) + wxT(": ") + wxString(std->eventText, wxConvUTF8) + wxT("\n"); + } + break; + /*todo*/ + case GF_ODF_CC_DATE_TAG: + break; + default: + break; + } + + } + + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); +} + +void wxFileProps::SetStreamsInfo() +{ + u32 i, count; + wxString info; + GF_MediaInfo odi; + char code[5]; + + info = wxT(""); + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); + + if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi) != GF_OK) return; + + if (odi.has_profiles) { + info += wxString::Format(wxT("\tOD Profile@Level %d\n"), odi.OD_pl); + info += wxString::Format(wxT("\tScene Profile@Level %d\n"), odi.scene_pl); + info += wxString::Format(wxT("\tGraphics Profile@Level %d\n"), odi.graphics_pl); + info += wxString::Format(wxT("\tAudio Profile@Level %d\n"), odi.audio_pl); + info += wxString::Format(wxT("\tVisual Profile@Level %d\n"), odi.scene_pl); + if (odi.inline_pl) info += wxT("\tInline Content use same profiles\n"); + info += wxT("\n"); + } + + count = gf_list_count(odi.od->ESDescriptors); + + for (i=0; iESDescriptors, i); + + info += wxString::Format(wxT("Stream ID %d - Clock ID %d\n"), esd->ESID, esd->OCRESID); + if (esd->dependsOnESID) { + info += wxString::Format(wxT("\tDepends on Stream ID %d for decoding\n"), esd->dependsOnESID); + } + switch (esd->decoderConfig->streamType) { + case GF_STREAM_OD: + info += wxString::Format(wxT("\tOD Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); + break; + case GF_STREAM_OCR: + info += wxT("\tObject Clock Reference Stream\n"); + break; + case GF_STREAM_SCENE: + info += wxString::Format(wxT("\tScene Description Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); + break; + case GF_STREAM_PRIVATE_SCENE: + info += wxString::Format(wxT("\tGPAC Private Scene Description Stream\n")); + break; + case GF_STREAM_VISUAL: + info += wxT("\tVisual Stream - media type: "); + switch (esd->decoderConfig->objectTypeIndication) { + 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; + info += wxT("GPAC Intern (") + wxString(code, wxConvUTF8) + wxT(")\n"); + break; + default: + info += wxString::Format(wxT("Private/Unknown Type (0x%x)\n"), esd->decoderConfig->objectTypeIndication); + break; + } + break; + + case GF_STREAM_AUDIO: + info += wxT("\tAudio Stream - media type: "); + switch (esd->decoderConfig->objectTypeIndication) { + 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; + case 0x80: + memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); + code[4] = 0; + info += wxT("GPAC Intern (") + wxString(code, wxConvUTF8) + wxT(")\n"); + break; + default: + info += wxString::Format(wxT("Private/Unknown Type (0x%x)\n"), esd->decoderConfig->objectTypeIndication); + break; + } + break; + case GF_STREAM_MPEG7: + info += wxString::Format(wxT("\tMPEG-7 Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); + break; + case GF_STREAM_IPMP: + info += wxString::Format(wxT("\tIPMP Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); + break; + case GF_STREAM_OCI: + info += wxString::Format(wxT("\tOCI Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); + break; + case GF_STREAM_MPEGJ: + info += wxString::Format(wxT("\tMPEGJ Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); + break; + case GF_STREAM_INTERACT: + info += wxString::Format(wxT("\tUser Interaction Stream - version %d\n"), esd->decoderConfig->objectTypeIndication); + break; + default: + info += wxT("Private/Unknown\n"); + break; + } + + info += wxString::Format(wxT("\tBuffer Size %d\n\tAverage Bitrate %d bps\n\tMaximum Bitrate %d bps\n"), esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate); + if (esd->slConfig->predefined==SLPredef_SkipSL) { + info += wxString::Format(wxT("\tNot using MPEG-4 Synchronization Layer\n")); + } else { + info += wxString::Format(wxT("\tStream Clock Resolution %d\n"), esd->slConfig->timestampResolution); + } + if (esd->URLString) + info += wxT("\tStream Location: ") + wxString(esd->URLString, wxConvUTF8) + wxT("\n"); + + /*check language*/ + if (esd->langDesc) { + s32 idx; + char lan[4]; + lan[0] = esd->langDesc->langCode>>16; + lan[1] = (esd->langDesc->langCode>>8)&0xFF; + lan[2] = (esd->langDesc->langCode)&0xFF; + lan[3] = 0; + idx = gf_lang_find(lan); + if (idx>=0) { + info += wxString::Format(wxT("\tStream Language: %s\n"), gf_lang_get_name(idx) ); + } + } + + } + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); +} + + +void wxFileProps::SetDecoderInfo() +{ + GF_MediaInfo odi; + wxString info; + u32 h, m, s; + + if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi)) { + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); + return; + } + + info = wxT("Status: "); + switch (odi.status) { + case 0: + case 1: + case 2: + h = (u32) (odi.current_time / 3600); + m = (u32) (odi.current_time / 60) - h*60; + s = (u32) (odi.current_time) - h*3600 - m*60; + if (odi.status==0) info += wxT("Stopped"); + else if (odi.status==1) info += wxT("Playing"); + else info += wxT("Paused"); + info += wxString::Format(wxT("\nObject Time: %02d:%02d:%02d\n"), h, m, s); + break; + case 3: + info += wxT("Not Setup\n"); + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); + return; + default: + info += wxT("Setup Failed\n"); + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); + return; + } + /*get clock drift*/ + info += wxString::Format(wxT("Clock drift: %d ms\n"), odi.clock_drift); + /*get buffering*/ + if (odi.buffer>=0) info += wxString::Format(wxT("Buffering Time: %d ms\n"), odi.buffer); + else if (odi.buffer==-1) info += wxT("Not buffering\n"); + else info += wxT("Not Playing\n"); + + /*get DB occupation*/ + if (odi.buffer>=0) info += wxString::Format(wxT("Decoding Buffer: %d Access Units\n"), odi.db_unit_count); + /*get CB occupation*/ + if (odi.cb_max_count) + info += wxString::Format(wxT("Composition Memory: %d/%d Units\n"), odi.cb_unit_count, odi.cb_max_count); + + Float avg_dec_time = 0; + if (odi.nb_dec_frames) { + avg_dec_time = (Float) odi.total_dec_time; + avg_dec_time /= odi.nb_dec_frames; + } + info += wxString::Format(wxT("Average Bitrate %d kbps (%d max)\nAverage Decoding Time %.2f ms (%d max)\nTotal decoded frames %d - %d dropped\n"), + (u32) odi.avg_bitrate/1024, odi.max_bitrate/1024, avg_dec_time, odi.max_dec_time, odi.nb_dec_frames, odi.nb_dropped); + + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); +} + +void wxFileProps::SetNetworkInfo() +{ + wxString info; + u32 id; + NetStatCommand com; + GF_MediaInfo odi; + u32 d_enum; + GF_Err e; + + info = wxT(""); + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(wxT("")); + + if (!m_current_odm || gf_term_get_object_info(m_pApp->m_term, m_current_odm, &odi) != GF_OK) return; + + if (odi.owns_service) { + const char *url, *path; + u32 done, total, bps; + info = wxT("Current Downloads in service:\n"); + d_enum = 0; + while (gf_term_get_download_info(m_pApp->m_term, m_current_odm, &d_enum, &url, &path, &done, &total, &bps)) { + info += wxString(url, wxConvUTF8); + if (total) { + info += wxString::Format(wxT(": %d / %d bytes (%.2f %%) - %.2f kBps\n"), done, total, (100.0*done)/total, ((Double)bps)/1024); + } else { + info += wxString::Format(wxT(": %.2f kBps\n"), ((Double)bps)/1024); + } + } + if (!d_enum) info = wxT("No Downloads in service\n"); + info += wxT("\n"); + } + + d_enum = 0; + while (gf_term_get_channel_net_info(m_pApp->m_term, m_current_odm, &d_enum, &id, &com, &e)) { + if (e) continue; + if (!com.bw_down && !com.bw_up) continue; + + info += wxString::Format(wxT("Stream ID %d statistics:\n"), id); + if (com.multiplex_port) { + info += wxString::Format(wxT("\tMultiplex Port %d - multiplex ID %d\n"), com.multiplex_port, com.port); + } else { + info += wxString::Format(wxT("\tPort %d\n"), com.port); + } + info += wxString::Format(wxT("\tPacket Loss Percentage: %.4f\n"), com.pck_loss_percentage); + info += wxString::Format(wxT("\tDown Bandwidth: %.3f bps\n"), ((Float)com.bw_down)/1024); + if (com.bw_up) info += wxString::Format(wxT("\tUp Bandwidth: %d bps\n"), com.bw_up); + if (com.ctrl_port) { + if (com.multiplex_port) { + info += wxString::Format(wxT("\tControl Multiplex Port: %d - Control Multiplex ID %d\n"), com.multiplex_port, com.ctrl_port); + } else { + info += wxString::Format(wxT("\tControl Port: %d\n"), com.ctrl_port); + } + info += wxString::Format(wxT("\tControl Down Bandwidth: %d bps\n"), com.ctrl_bw_down); + info += wxString::Format(wxT("\tControl Up Bandwidth: %d bps\n"), com.ctrl_bw_up); + } + info += wxT("\n"); + } + m_pViewInfo->Clear(); + m_pViewInfo->AppendText(info); +} + + +void wxFileProps::OnViewWorld(wxCommandEvent &WXUNUSED(event)) +{ + wxString wit; + const char *str; + GF_List *descs; + descs = gf_list_new(); + str = gf_term_get_world_info(m_pApp->m_term, m_current_odm, descs); + + if (!str) { + wxMessageDialog(this, wxT("No World Info available"), wxT("Sorry!"), wxOK).ShowModal(); + return; + } + + wit = wxT(""); + for (u32 i=0; gf_list_count(descs); i++) { + const char *d = (const char *) gf_list_get(descs, i); + wit += wxString(d, wxConvUTF8); + wit += wxT("\n"); + } + wxMessageDialog(this, wit, wxString(str, wxConvUTF8), wxOK).ShowModal(); + gf_list_del(descs); +} + +void wxFileProps::OnViewSG(wxCommandEvent &WXUNUSED(event)) +{ + const char *sOpt; + Bool dump_xmt; + wxFileName out_file; + char szOutFile[GF_MAX_PATH]; + wxString fname; + + sOpt = gf_cfg_get_key(m_pApp->m_user.config, "Core", "CacheDirectory"); + out_file.AssignDir(wxString(sOpt, wxConvUTF8) ); + + sOpt = gf_cfg_get_key(m_pApp->m_user.config, "General", "ViewXMT"); + out_file.SetFullName(wxT("scene_dump")); + if (sOpt && !stricmp(sOpt, "yes")) { + dump_xmt = 1; + } else { + dump_xmt = 0; + } + strcpy(szOutFile, out_file.GetFullName().mb_str(wxConvUTF8)); + + 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(); + } else { + wxString cmd = get_pref_browser(m_pApp->m_user.config); + cmd += wxT(" "); + cmd += wxString(szOutFile, wxConvUTF8); + wxExecute(cmd); + } +} diff --git a/applications/deprecated/old_arch/osmo4_wx/fileprops.h b/applications/deprecated/old_arch/osmo4_wx/fileprops.h new file mode 100644 index 0000000..28caaa1 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/fileprops.h @@ -0,0 +1,84 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 _FILEPROPS_H +#define _FILEPROPS_H + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include + +#include + +/*abstract class for all items in the tree*/ +class ODTreeData : public wxTreeItemData +{ +public: + ODTreeData(GF_ObjectManager *odm) : wxTreeItemData(), m_pODMan(odm) {} + GF_ObjectManager *m_pODMan; +}; + + +class wxOsmo4Frame; +class wxFileProps : public wxDialog +{ +public: + wxFileProps(wxWindow *parent); + virtual ~wxFileProps(); + +private: + DECLARE_EVENT_TABLE() + + wxOsmo4Frame *m_pApp; + + wxTreeCtrl *m_pTreeView; + wxTextCtrl *m_pViewInfo; + wxComboBox *m_pViewSel; + wxButton *m_pViewWI, *m_pViewSG; + wxTimer *m_pTimer; + + GF_ObjectManager *m_current_odm; + + void RewriteODTree(); + void SetGeneralInfo(); + void SetStreamsInfo(); + void SetDecoderInfo(); + void SetNetworkInfo(); + void WriteInlineTree(ODTreeData *pRoot); + void OnSetSelection(wxTreeEvent &event); + void OnSelectInfo(wxCommandEvent &event); + void OnTimer(wxTimerEvent &event); + void OnViewWorld(wxCommandEvent &event); + void OnViewSG(wxCommandEvent &event); + void SetInfo(GF_ObjectManager *odm); +}; + +#endif + diff --git a/applications/deprecated/old_arch/osmo4_wx/menubtn.cpp b/applications/deprecated/old_arch/osmo4_wx/menubtn.cpp new file mode 100644 index 0000000..48b6f98 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/menubtn.cpp @@ -0,0 +1,870 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wxMenuButton +// Purpose: A button with a dropdown wxMenu +// Author: John Labenski +// Modified by: +// Created: 11/05/2002 +// RCS-ID: +// Copyright: (c) John Labenki +// Licence: wxWidgets licence +///////////////////////////////////////////////////////////////////////////// + +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) +#pragma implementation "menubtn.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/control.h" +#include "wx/menu.h" +#include "wx/settings.h" +#include "wx/bitmap.h" +#include "wx/pen.h" +#include "wx/dc.h" +#endif // WX_PRECOMP + +#include +#include +#include +#include + +#include "menubtn.h" + + + +// ========================================================================== +// wxCustomButton +// ========================================================================== +IMPLEMENT_DYNAMIC_CLASS( wxCustomButton, wxControl ) + +BEGIN_EVENT_TABLE(wxCustomButton,wxControl) + EVT_MOUSE_EVENTS ( wxCustomButton::OnMouseEvents ) + EVT_PAINT ( wxCustomButton::OnPaint ) + EVT_SIZE ( wxCustomButton::OnSize ) +END_EVENT_TABLE() + +wxCustomButton::~wxCustomButton() +{ + if (HasCapture()) ReleaseMouse(); + if (m_timer) delete m_timer; +} + +void wxCustomButton::Init() +{ + m_focused = FALSE; + m_labelMargin = wxSize(4,4); + m_bitmapMargin = wxSize(2,2); + m_down = 0; + m_timer = NULL; + m_eventType = 0; + m_button_style = wxCUSTBUT_TOGGLE|wxCUSTBUT_BOTTOM; +} + +bool wxCustomButton::Create(wxWindow* parent, wxWindowID id, + const wxString& label, const wxBitmap &bitmap, + const wxPoint& pos, const wxSize& size, + long style, const wxValidator& val, + const wxString& name) +{ + if (!wxControl::Create(parent,id,pos,size,wxNO_BORDER|wxCLIP_CHILDREN,val,name)) + return FALSE; + + wxControl::SetLabel(label); + wxControl::SetBackgroundColour(parent->GetBackgroundColour()); + wxControl::SetForegroundColour(parent->GetForegroundColour()); + wxControl::SetFont(parent->GetFont()); + + if (bitmap.Ok()) m_bmpLabel = bitmap; + + if (!SetButtonStyle(style)) return FALSE; + + wxSize bestSize = DoGetBestSize(); + SetSize(wxSize(size.x<0 ? bestSize.x:size.x, size.y<0 ? bestSize.y:size.y)); +#if (wxMINOR_VERSION<8) + SetBestSize(GetSize()); +#else + SetInitialSize(GetSize()); +#endif + + CalcLayout(TRUE); + return TRUE; +} + +void wxCustomButton::SetValue(bool depressed) +{ + wxCHECK_RET(!(m_button_style & wxCUSTBUT_NOTOGGLE), wxT("can't set button state")); + m_down = depressed ? 1 : 0; + Refresh(FALSE); +} + +bool wxCustomButton::SetButtonStyle(long style) +{ + int n_styles = 0; + if ((style & wxCUSTBUT_LEFT) != 0) n_styles++; + if ((style & wxCUSTBUT_RIGHT) != 0) n_styles++; + if ((style & wxCUSTBUT_TOP) != 0) n_styles++; + if ((style & wxCUSTBUT_BOTTOM) != 0) n_styles++; + wxCHECK_MSG(n_styles < 2, FALSE, wxT("Only one wxCustomButton label position allowed")); + + n_styles = 0; + if ((style & wxCUSTBUT_NOTOGGLE) != 0) n_styles++; + if ((style & wxCUSTBUT_BUTTON) != 0) n_styles++; + if ((style & wxCUSTBUT_TOGGLE) != 0) n_styles++; + if ((style & wxCUSTBUT_BUT_DCLICK_TOG) != 0) n_styles++; + if ((style & wxCUSTBUT_TOG_DCLICK_BUT) != 0) n_styles++; + wxCHECK_MSG(n_styles < 2, FALSE, wxT("Only one wxCustomButton style allowed")); + + m_button_style = style; + + if ((m_button_style & wxCUSTBUT_BUTTON) != 0) + m_down = 0; + + CalcLayout(TRUE); + return TRUE; +} + +void wxCustomButton::SetLabel( const wxString &label ) +{ + wxControl::SetLabel(label); + CalcLayout(TRUE); +} + +// sequence of events in GTK is up, dclick, up. + +void wxCustomButton::OnMouseEvents(wxMouseEvent& event) +{ + if (m_button_style & wxCUSTBUT_NOTOGGLE) return; + + if (event.LeftDown() || event.RightDown()) + { + if (!HasCapture()) + CaptureMouse(); // keep depressed until up + + m_down++; + Redraw(); + } + else if (event.LeftDClick() || event.RightDClick()) + { + m_down++; // GTK eats second down event + Redraw(); + } + else if (event.LeftUp()) + { + if (HasCapture()) + ReleaseMouse(); + + m_eventType = wxEVT_LEFT_UP; + +#if (wxMINOR_VERSION<8) + if (wxRect(wxPoint(0,0), GetSize()).Inside(event.GetPosition())) +#else + if (wxRect(wxPoint(0,0), GetSize()).Contains(event.GetPosition())) +#endif + { + if ((m_button_style & wxCUSTBUT_BUTTON) && (m_down > 0)) + { + m_down = 0; + Redraw(); + SendEvent(); + return; + } + else + { + if (!m_timer) + { + m_timer = new wxTimer(this, m_down+1); + m_timer->Start(200, TRUE); + } + else + { + m_eventType = wxEVT_LEFT_DCLICK; + } + + if ((m_button_style & wxCUSTBUT_TOGGLE) && + (m_button_style & wxCUSTBUT_TOG_DCLICK_BUT)) m_down++; + } + } + + Redraw(); + } + else if (event.RightUp()) + { + if (HasCapture()) + ReleaseMouse(); + + m_eventType = wxEVT_RIGHT_UP; + +#if (wxMINOR_VERSION<8) + if (wxRect(wxPoint(0,0), GetSize()).Inside(event.GetPosition())) +#else + if (wxRect(wxPoint(0,0), GetSize()).Contains(event.GetPosition())) +#endif + { + if ((m_button_style & wxCUSTBUT_BUTTON) && (m_down > 0)) + { + m_down = 0; + Redraw(); + SendEvent(); + return; + } + else + { + m_down++; + + if (!m_timer) + { + m_timer = new wxTimer(this, m_down); + m_timer->Start(250, TRUE); + } + else + { + m_eventType = wxEVT_RIGHT_DCLICK; + } + } + } + + Redraw(); + } + else if (event.Entering()) + { + m_focused = TRUE; + if ((event.LeftIsDown() || event.RightIsDown()) && HasCapture()) + m_down++; + + Redraw(); + } + else if (event.Leaving()) + { + m_focused = FALSE; + if ((event.LeftIsDown() || event.RightIsDown()) && HasCapture()) + m_down--; + + Redraw(); + } +} + + + +void wxCustomButton::SendEvent() +{ + if (((m_button_style & wxCUSTBUT_TOGGLE) && (m_eventType == wxEVT_LEFT_UP)) || + ((m_button_style & wxCUSTBUT_BUT_DCLICK_TOG) && (m_eventType == wxEVT_LEFT_DCLICK)) || + ((m_button_style & wxCUSTBUT_TOG_DCLICK_BUT) && (m_eventType == wxEVT_LEFT_UP))) + { + wxCommandEvent eventOut(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, GetId()); + eventOut.SetInt(m_down%2 ? 1 : 0); + eventOut.SetExtraLong(m_eventType); + eventOut.SetEventObject(this); + GetEventHandler()->ProcessEvent(eventOut); + } + else + { + wxCommandEvent eventOut(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); + eventOut.SetInt(0); + eventOut.SetExtraLong(m_eventType); + eventOut.SetEventObject(this); + GetEventHandler()->ProcessEvent(eventOut); + } +} + +wxBitmap wxCustomButton::CreateBitmapDisabled(const wxBitmap &bitmap) const +{ + wxCHECK_MSG(bitmap.Ok(), wxNullBitmap, wxT("invalid bitmap")); + + unsigned char br = GetBackgroundColour().Red(); + unsigned char bg = GetBackgroundColour().Green(); + unsigned char bb = GetBackgroundColour().Blue(); + + wxImage image = bitmap.ConvertToImage(); + int pos, width = image.GetWidth(), height = image.GetHeight(); + unsigned char *img_data = image.GetData(); + + for (int j=0; j lh ? bh : lh; + if (has_bitmap && has_label) lw -= wxMin(m_labelMargin.x, m_bitmapMargin.x); + return wxSize(lw+bw, h); + } + + int w = bw > lw ? bw : lw; + if (has_bitmap && has_label) lh -= wxMin(m_labelMargin.y, m_bitmapMargin.y); + return wxSize(w, lh+bh); +} + +void wxCustomButton::CalcLayout(bool refresh) +{ + int w, h; + GetSize(&w,&h); + + int bw = 0, bh = 0; + int lw = 0, lh = 0; + + if (m_bmpLabel.Ok()) // assume they're all the same size + { + bw = m_bmpLabel.GetWidth(); + bh = m_bmpLabel.GetHeight(); + } + wxString label = GetLabel(); + if (!label.IsEmpty()) + { + GetTextExtent(label, &lw, &lh); + } + + // Center the label or bitmap if only one or the other + if (!m_bmpLabel.Ok()) + { + m_bitmapPos = wxPoint(0,0); + m_labelPos = wxPoint((w-lw)/2, (h-lh)/2); + } + else if (label.IsEmpty()) + { + m_bitmapPos = wxPoint((w-bw)/2, (h-bh)/2); + m_labelPos = wxPoint(0,0); + } + else if (m_button_style & wxCUSTBUT_LEFT) + { + int mid_margin = wxMax(m_labelMargin.x, m_bitmapMargin.x); + m_labelPos = wxPoint((w - (bw+lw+m_labelMargin.x+m_bitmapMargin.x+mid_margin))/2 + m_labelMargin.x, (h - lh)/2); + m_bitmapPos = wxPoint(m_labelPos.x + lw + mid_margin, (h - bh)/2); + } + else if (m_button_style & wxCUSTBUT_RIGHT) + { + int mid_margin = wxMax(m_labelMargin.x, m_bitmapMargin.x); + m_bitmapPos = wxPoint((w - (bw+lw+m_labelMargin.x+m_bitmapMargin.x+mid_margin))/2 + m_bitmapMargin.x, (h - bh)/2); + m_labelPos = wxPoint(m_bitmapPos.x + bw + mid_margin, (h - lh)/2); + } + else if (m_button_style & wxCUSTBUT_TOP) + { + int mid_margin = wxMax(m_labelMargin.y, m_bitmapMargin.y); + m_labelPos = wxPoint((w - lw)/2, (h - (bh+lh+m_labelMargin.y+m_bitmapMargin.y+mid_margin))/2 + m_labelMargin.y); + m_bitmapPos = wxPoint((w - bw)/2, m_labelPos.y + lh + mid_margin); + } + else // if (m_button_style & wxCUSTBUT_BOTTOM) DEFAULT + { + int mid_margin = wxMax(m_labelMargin.y, m_bitmapMargin.y); + m_bitmapPos = wxPoint((w - bw)/2, (h - (bh+lh+m_labelMargin.y+m_bitmapMargin.y+mid_margin))/2 + m_bitmapMargin.y); + m_labelPos = wxPoint((w - lw)/2, m_bitmapPos.y + bh + mid_margin); + } + + if (refresh) Refresh(FALSE); +} + + +/* XPM */ +static const char *down_arrow_xpm_data[] = { + /* columns rows colors chars-per-pixel */ + "5 3 2 1", + " c None", + "a c Black", + /* pixels */ + "aaaaa", + " aaa ", + " a " +}; + +static wxBitmap s_dropdownBitmap; // all buttons share the same bitmap + +enum +{ + IDD_DROPDOWN_BUTTON = 100 +}; + +//----------------------------------------------------------------------------- +// wxMenuButtonEvents +//----------------------------------------------------------------------------- + +DEFINE_LOCAL_EVENT_TYPE(wxEVT_MENUBUTTON_OPEN) + +// ========================================================================== +// MenuDropButton +// ========================================================================== + +class MenuDropButton : public wxCustomButton +{ +public: + MenuDropButton( wxWindow *parent, wxWindowID id, long style) : wxCustomButton() + { + if (!s_dropdownBitmap.Ok()) + s_dropdownBitmap = wxBitmap(down_arrow_xpm_data); + + Create( parent, id, wxEmptyString, s_dropdownBitmap, wxDefaultPosition, + wxSize(wxMENUBUTTON_DROP_WIDTH, wxMENUBUTTON_DROP_HEIGHT), style); + } + + virtual void Paint( wxDC &dc ) + { + wxCustomButton *labelBut = ((wxMenuButton*)GetParent())->GetLabelButton(); + + // pretend that both buttons have focus (for flat style) + if (labelBut) + { + wxPoint p = GetParent()->ScreenToClient(wxGetMousePosition()); + +#if (wxMINOR_VERSION<8) + if (GetRect().Inside(p) || labelBut->GetRect().Inside(p)) +#else + if (GetRect().Contains(p) || labelBut->GetRect().Contains(p)) +#endif + { + m_focused = TRUE; + + if (!labelBut->GetFocused()) + labelBut->SetFocused(TRUE); + } + else + { + m_focused = FALSE; + + if (labelBut->GetFocused()) + labelBut->SetFocused(FALSE); + } + } + + wxCustomButton::Paint(dc); + } +}; + +// ========================================================================== +// MenuLabelButton +// ========================================================================== + +class MenuLabelButton : public wxCustomButton +{ +public: + MenuLabelButton( wxWindow* parent, wxWindowID id, + const wxString &label, + const wxBitmap &bitmap, + long style ) : wxCustomButton() + { + Create(parent, id, label, bitmap, wxDefaultPosition, wxDefaultSize, style); + } + + virtual void Paint( wxDC &dc ) + { + wxCustomButton *dropBut = ((wxMenuButton*)GetParent())->GetDropDownButton(); + + // pretend that both buttons have focus (for flat style) + if (dropBut) + { + wxPoint p = GetParent()->ScreenToClient(wxGetMousePosition()); + +#if (wxMINOR_VERSION<8) + if (GetRect().Inside(p) || dropBut->GetRect().Inside(p)) +#else + if (GetRect().Contains(p) || dropBut->GetRect().Contains(p)) +#endif + { + m_focused = TRUE; + + if (!dropBut->GetFocused()) + dropBut->SetFocused(TRUE); + } + else + { + m_focused = FALSE; + + if (dropBut->GetFocused()) + dropBut->SetFocused(FALSE); + } + } + + wxCustomButton::Paint(dc); + } +}; + +// ========================================================================== +// wxMenuButton +// ========================================================================== + +IMPLEMENT_DYNAMIC_CLASS( wxMenuButton, wxControl ) + +BEGIN_EVENT_TABLE(wxMenuButton,wxControl) + EVT_BUTTON(wxID_ANY, wxMenuButton::OnButton) + +#ifdef __WXMSW__ + EVT_MENU(wxID_ANY, wxMenuButton::OnMenu) +#endif +END_EVENT_TABLE() + +wxMenuButton::~wxMenuButton() +{ + AssignMenu(NULL, TRUE); +} + +void wxMenuButton::Init() +{ + m_labelButton = NULL; + m_dropdownButton = NULL; + m_menu = NULL; + m_menu_static = FALSE; + m_style = 0; +} + +bool wxMenuButton::Create( wxWindow* parent, wxWindowID id, + const wxString &label, + const wxBitmap &bitmap, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator& val, + const wxString& name) +{ + m_style = style; + + long flat = style & wxMENUBUT_FLAT; + + wxControl::Create(parent,id,pos,size,wxNO_BORDER|wxCLIP_CHILDREN,val,name); + wxControl::SetLabel(label); + SetBackgroundColour(parent->GetBackgroundColour()); + SetForegroundColour(parent->GetForegroundColour()); + SetFont(parent->GetFont()); + + m_labelButton = new MenuLabelButton(this, id, label, bitmap, wxCUSTBUT_BUTTON|flat); + m_dropdownButton = new MenuDropButton(this, IDD_DROPDOWN_BUTTON, wxCUSTBUT_BUTTON|flat); + + wxSize bestSize = DoGetBestSize(); + SetSize( wxSize(size.x < 0 ? bestSize.x : size.x, + size.y < 0 ? bestSize.y : size.y) ); + +#if (wxMINOR_VERSION<8) + SetBestSize(GetSize()); +#else + SetInitialSize(GetSize()); +#endif + + return TRUE; +} + +#ifdef __WXMSW__ +// FIXME - I think there was a patch to fix this +void wxMenuButton::OnMenu( wxCommandEvent &event ) +{ + event.Skip(); + wxMenuItem *mi = m_menu->FindItem(event.GetId()); + if (mi && (mi->GetKind() == wxITEM_RADIO)) + m_menu->Check(event.GetId(), TRUE); +} +#endif // __WXMSW__ + +void wxMenuButton::OnButton( wxCommandEvent &event) +{ + int win_id = event.GetId(); + + if (win_id == IDD_DROPDOWN_BUTTON) + { + wxNotifyEvent mevent(wxEVT_MENUBUTTON_OPEN, GetId()); + mevent.SetEventObject(this); + if (GetEventHandler()->ProcessEvent(mevent) && !mevent.IsAllowed()) + return; + + if (!m_menu) + return; + + PopupMenu(m_menu, wxPoint(0, GetSize().y)); + + m_labelButton->Refresh(FALSE); + m_dropdownButton->Refresh(FALSE); + } + else if (win_id == m_labelButton->GetId()) + { + + wxCommandEvent cevent(wxEVT_COMMAND_MENU_SELECTED, win_id); + cevent.SetEventObject(this); + cevent.SetId(win_id); + GetParent()->GetEventHandler()->ProcessEvent(cevent); + + if (!m_menu) return; + + const wxMenuItemList &items = m_menu->GetMenuItems(); + int first_radio_id = -1; + int checked_id = -1; + bool check_next = FALSE; + + // find the next available radio item to check + for (wxMenuItemList::Node *node = items.GetFirst(); node; node = node->GetNext()) + { + wxMenuItem *mi = (wxMenuItem*)node->GetData(); + if (mi && (mi->GetKind() == wxITEM_RADIO)) + { + if (first_radio_id == -1) + first_radio_id = mi->GetId(); + + if (check_next) + { + check_next = FALSE; + checked_id = mi->GetId(); + break; + } + else if (mi->IsChecked()) + check_next = TRUE; + } + } + // the last item was checked, go back to the first + if (check_next && (first_radio_id != -1)) + checked_id = first_radio_id; + + if (checked_id != -1) + { + m_menu->Check(checked_id, TRUE); + + wxCommandEvent mevent( wxEVT_COMMAND_MENU_SELECTED, checked_id); + mevent.SetEventObject( m_menu ); + mevent.SetInt(1); + GetEventHandler()->ProcessEvent(mevent); + } + } +} + +int wxMenuButton::GetSelection() const +{ + wxCHECK_MSG(m_menu != NULL, wxNOT_FOUND, wxT("No attached menu in wxMenuButton::GetSelection")); + + const wxMenuItemList &items = m_menu->GetMenuItems(); + + for (wxMenuItemList::Node *node = items.GetFirst(); node; node = node->GetNext()) + { + wxMenuItem *mi = (wxMenuItem*)node->GetData(); + if (mi && (mi->GetKind() == wxITEM_RADIO)) + { + if (mi->IsChecked()) + return mi->GetId(); + } + } + + return wxNOT_FOUND; +} + +void wxMenuButton::AssignMenu(wxMenu *menu, bool static_menu) +{ + if (!m_menu_static && m_menu) + delete m_menu; + + m_menu = menu; + m_menu_static = static_menu; +} + +void wxMenuButton::SetToolTip(const wxString &tip) +{ + wxWindow::SetToolTip(tip); + ((wxWindow*)m_labelButton)->SetToolTip(tip); + ((wxWindow*)m_dropdownButton)->SetToolTip(tip); +} +void wxMenuButton::SetToolTip(wxToolTip *tip) +{ + wxWindow::SetToolTip(tip); + ((wxWindow*)m_labelButton)->SetToolTip(tip); + ((wxWindow*)m_dropdownButton)->SetToolTip(tip); +} + +void wxMenuButton::DoSetSize(int x, int y, int width, int height, int sizeFlags) +{ + wxSize curSize( GetSize() ); + wxSize bestSize( DoGetBestSize() ); + + if (width == -1) + width = curSize.GetWidth(); + if (width < 10) + width = bestSize.GetWidth(); + + if (height == -1) + height = curSize.GetHeight(); + if (height < 5) + height = bestSize.GetHeight(); + + wxWindow::DoSetSize(x, y, width, height, sizeFlags); + + if (m_labelButton) + m_labelButton->SetSize(0, 0, width - wxMENUBUTTON_DROP_WIDTH, height); + if (m_dropdownButton) + m_dropdownButton->SetSize(width-wxMENUBUTTON_DROP_WIDTH, 0, wxMENUBUTTON_DROP_WIDTH, height); +} + +wxSize wxMenuButton::DoGetBestSize() +{ + if (!m_labelButton || !m_dropdownButton) + return wxSize(wxMENUBUTTON_DROP_WIDTH+wxMENUBUTTON_DROP_HEIGHT, wxMENUBUTTON_DROP_HEIGHT); + + wxSize size = m_labelButton->GetBestSize(); + size.x += wxMENUBUTTON_DROP_WIDTH; + return size; +} diff --git a/applications/deprecated/old_arch/osmo4_wx/menubtn.h b/applications/deprecated/old_arch/osmo4_wx/menubtn.h new file mode 100644 index 0000000..f82282e --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/menubtn.h @@ -0,0 +1,356 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wxMenuButton +// Purpose: A button with a dropdown wxMenu +// Author: John Labenski +// Modified by: +// Created: 11/05/2002 +// Copyright: (c) John Labenski +// Licence: wxWidgets licence +///////////////////////////////////////////////////////////////////////////// + +/* + +wxMenuButton is a button that drops down an assigned wxMenu + +Create the button with either a text or bitmap label. + Create a new wxMenu and call AssignMenu and thats it. When you press the + dropdown button the menu appears. When you press the label button the next + wxITEM_RADIO (ie wxMenuItem::GetKind) in the menu is selected round robin. + If there are no radio items then it really just acts like a menubar, though + this is probably not too useful. The events sent in this case are EVT_MENUs + either generated by the menu when you click on it or created when you click + on the label to select the next radio item. +*/ + +#ifndef _WX_MENUBTN_H_ +#define _WX_MENUBTN_H_ + +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) +#pragma interface "menubtn.h" +#endif + +class wxMenu; +class wxBitmap; +class wxCustomButton; + +//----------------------------------------------------------------------------- +// wxCustomButton styles +//----------------------------------------------------------------------------- + +enum wxCustomButton_Style +{ + // Position of the label, use only one + wxCUSTBUT_LEFT = 0x0001, + wxCUSTBUT_RIGHT = 0x0002, + wxCUSTBUT_TOP = 0x0004, + wxCUSTBUT_BOTTOM = 0x0008, + // Button style, use only one + wxCUSTBUT_NOTOGGLE = 0x0100, + wxCUSTBUT_BUTTON = 0x0200, + wxCUSTBUT_TOGGLE = 0x0400, + wxCUSTBUT_BUT_DCLICK_TOG = 0x0800, + wxCUSTBUT_TOG_DCLICK_BUT = 0x1000, + // drawing styles + wxCUSTBUT_FLAT = 0x2000 // flat, mouseover raises if not depressed +}; + +//----------------------------------------------------------------------------- +// wxCustomButton +//----------------------------------------------------------------------------- + +class WXDLLEXPORT wxCustomButton : public wxControl +{ +public: + + wxCustomButton() : wxControl() { + Init(); + } + + // wxToggleButton or wxButton compatible constructor (also wxTextCtrl) + wxCustomButton(wxWindow* parent, wxWindowID id, + const wxString& label, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxCUSTBUT_TOGGLE, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxT("wxCustomButton")) + : wxControl() + { + Init(); + Create(parent,id,label,wxNullBitmap,pos,size,style,val,name); + } + + // wxBitmapButton compatible constructor + wxCustomButton(wxWindow *parent, wxWindowID id, + const wxBitmap& bitmap, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxCUSTBUT_TOGGLE, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxT("wxCustomButton")) + : wxControl() + { + Init(); + Create(parent,id,wxEmptyString,bitmap,pos,size,style,val,name); + } + + // Native constructor + wxCustomButton(wxWindow *parent, wxWindowID id, + const wxString& label, const wxBitmap& bitmap, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxCUSTBUT_TOGGLE|wxCUSTBUT_BOTTOM, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxT("wxCustomButton")) + : wxControl() + { + Init(); + Create(parent,id,label,bitmap,pos,size,style,val,name); + } + + virtual ~wxCustomButton(); + + bool Create(wxWindow* parent, + wxWindowID id, + const wxString& label, + const wxBitmap &bitmap, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxT("wxCustomButton")); + + bool GetValue() const { + return m_down%2 != 0; + } + void SetValue( bool depressed ); + + // Use combinations of wxCustomButton_Style(s) + long GetButtonStyle() const { + return m_button_style; + } + bool SetButtonStyle( long style ); + + // Set the text label, wxEmptyString for none + void SetLabel( const wxString &label ); + + // set the bitmaps, ONLY this Label bitmap is used for calculating control size + // all bitmaps will be centered accordingly in any case + // call SetSet(GetBestSize()) if you change their size and want the control to resize appropriately + void SetBitmapLabel(const wxBitmap& bitmap); + void SetBitmapSelected(const wxBitmap& sel) { + m_bmpSelected = sel; + CalcLayout(TRUE); + }; + void SetBitmapFocus(const wxBitmap& focus) { + m_bmpFocus = focus; + CalcLayout(TRUE); + }; + void SetBitmapDisabled(const wxBitmap& disabled) { + m_bmpDisabled = disabled; + CalcLayout(TRUE); + }; + // wxBitmapButton compatibility + void SetLabel(const wxBitmap& bitmap) { + SetBitmapLabel(bitmap); + } + + // retrieve the bitmaps + const wxBitmap& GetBitmapLabel() const { + return m_bmpLabel; + } + const wxBitmap& GetBitmapSelected() const { + return m_bmpSelected; + } + const wxBitmap& GetBitmapFocus() const { + return m_bmpFocus; + } + const wxBitmap& GetBitmapDisabled() const { + return m_bmpDisabled; + } + + // Creates a "disabled" bitmap by dithering it with the background colour + wxBitmap CreateBitmapDisabled(const wxBitmap &bitmap) const; + + // set/get the margins (in pixels) around the label and bitmap + // if fit = TRUE then resize the button to fit + void SetMargins(const wxSize &margin, bool fit = FALSE); + + // set/get the margins around the text label + // the inter bitmap/label margin is the max of either margin, not the sum + void SetLabelMargin(const wxSize &margin, bool fit = FALSE); + wxSize GetLabelMargin() const { + return m_labelMargin; + } + // set/get the margins around the bitmap + // the inter bitmap/label margin is the max of either margin, not the sum + void SetBitmapMargin(const wxSize &margin, bool fit = FALSE); + wxSize GetBitmapMargin() const { + return m_bitmapMargin; + } + + // can be used to activate the focused behavior (see MenuButton) + void SetFocused(bool focused) { + m_focused = focused; + Refresh(FALSE); + } + bool GetFocused() const { + return m_focused; + } + +protected: + void OnPaint(wxPaintEvent &event); + void Redraw(); + virtual void Paint( wxDC &dc ); + + virtual wxSize DoGetBestSize() const; + + virtual void SendEvent(); + + void OnMouseEvents(wxMouseEvent &event); + + void OnSize( wxSizeEvent &event ); + + virtual void CalcLayout(bool refresh); + + long m_down; // toggle state if m_down%2 then depressed + bool m_focused; // mouse in window + long m_button_style; + + // the bitmaps for various states + wxBitmap m_bmpLabel, + m_bmpSelected, + m_bmpFocus, + m_bmpDisabled; + + // the margins around the label/bitmap + wxSize m_labelMargin, + m_bitmapMargin; + + wxPoint m_bitmapPos, + m_labelPos; + + wxTimer *m_timer; + + wxEventType m_eventType; // store the mouse event type + +private: + void Init(); + DECLARE_DYNAMIC_CLASS(wxCustomButton) + DECLARE_EVENT_TABLE() +}; + +//----------------------------------------------------------------------------- +// wxMenuButton styles +//----------------------------------------------------------------------------- + +#define wxMENUBUTTON_DROP_WIDTH 10 +#define wxMENUBUTTON_DROP_HEIGHT 22 + +enum wxMenuButton_Styles +{ + wxMENUBUT_FLAT = wxCUSTBUT_FLAT +}; + +//----------------------------------------------------------------------------- +// wxMenuButton +//----------------------------------------------------------------------------- + +class wxMenuButton : public wxControl +{ +public: + + wxMenuButton() : wxControl() { + Init(); + } + + // Use this constructor if you need one compatible with a wxBitmapButton + // setup the button later with AssignMenu + wxMenuButton( wxWindow* parent, wxWindowID id, + const wxBitmap &bitmap, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxT("wxMenuButton")) + : wxControl() + { + Init(); + Create(parent,id,wxEmptyString,bitmap,pos,size,style,val,name); + } + + virtual ~wxMenuButton(); + + bool Create( wxWindow* parent, + wxWindowID id, + const wxString &label, + const wxBitmap &bitmap, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxNO_BORDER, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxT("wxMenuButton")); + + // Gets the id of the first selected radio item or wxNOT_FOUND (-1) if none + int GetSelection() const; + + // This menu will be displayed when the dropdown button is pressed. + // if static_menu is FALSE it will be deleted when the buttton is destroyed. + void AssignMenu(wxMenu *menu, bool static_menu = FALSE); + + wxMenu *GetMenu() const { + return m_menu; + } + + // get a pointer to the label button, for turning it into a toggle perhaps + wxCustomButton *GetLabelButton() const { + return m_labelButton; + } + wxCustomButton *GetDropDownButton() const { + return m_dropdownButton; + } + + void SetToolTip(const wxString &tip); + void SetToolTip(wxToolTip *tip); + +protected: + void OnButton(wxCommandEvent &event); + + virtual void DoSetSize(int x, int y, int width, int height, + int sizeFlags = wxSIZE_AUTO); + + virtual wxSize DoGetBestSize(); + +// FIXME! - in MSW the radio items don't check themselves +#ifdef __WXMSW__ + void OnMenu( wxCommandEvent &event ); +#endif + + wxCustomButton *m_labelButton; + wxCustomButton *m_dropdownButton; + + wxMenu *m_menu; + bool m_menu_static; + long m_style; + +private: + void Init(); + DECLARE_DYNAMIC_CLASS(wxMenuButton) + DECLARE_EVENT_TABLE() +}; + +//----------------------------------------------------------------------------- +// wxMenuButtonEvents +// +// EVT_MENUBUTTON_OPEN(id, fn) - menu is about to be opened, (dis)(en)able items +// or call Veto() to stop menu from popping up +// this is a wxNotifyEvent +//----------------------------------------------------------------------------- + +BEGIN_DECLARE_EVENT_TYPES() +DECLARE_LOCAL_EVENT_TYPE( wxEVT_MENUBUTTON_OPEN, 0 ) +END_DECLARE_EVENT_TYPES() + +#define EVT_MENUBUTTON_OPEN(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_MENUBUTTON_OPEN, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) & fn, (wxObject *) NULL ), + +#endif // _WX_MENUBTN_H_ diff --git a/applications/deprecated/old_arch/osmo4_wx/osmo4.ico b/applications/deprecated/old_arch/osmo4_wx/osmo4.ico new file mode 100644 index 0000000000000000000000000000000000000000..36ff66711771065305f263aee09bda915091c6b0 GIT binary patch literal 15086 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 Ih+0ATC&$&)D*ylh literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmo4_wx/osmo4.xpm b/applications/deprecated/old_arch/osmo4_wx/osmo4.xpm new file mode 100644 index 0000000..bec8e6a --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/osmo4.xpm @@ -0,0 +1,301 @@ +/* XPM */ +static const char * osmo4[] = { +"32 32 266 2", +" c None", +". c #990909", +"+ c #A10505", +"@ c #AB0404", +"# c #AF0202", +"$ c #B10303", +"% c #AE0202", +"& c #A90505", +"* c #A10606", +"= c #990E0E", +"- c #990D0D", +"; c #A80303", +"> c #BD0000", +", c #D40000", +"' c #DE0000", +") c #E20000", +"! c #E10000", +"~ c #DC0000", +"{ c #CD0000", +"] c #B80101", +"^ c #A40909", +"/ c #A20505", +"( c #BD0101", +"_ c #E00000", +": c #CB0000", +"< c #A80000", +"[ c #7E0101", +"} c #6B0202", +"| c #670202", +"1 c #720202", +"2 c #920000", +"3 c #B70000", +"4 c #D70000", +"5 c #B80303", +"6 c #9D0B0B", +"7 c #980909", +"8 c #B00202", +"9 c #DB0000", +"0 c #B50909", +"a c #8A1313", +"b c #1C0505", +"c c #070505", +"d c #080808", +"e c #0A0A0A", +"f c #090909", +"g c #070707", +"h c #0C0404", +"i c #5B1414", +"j c #A70F0F", +"k c #CC0303", +"l c #CC0000", +"m c #AB0505", +"n c #950D0D", +"o c #B60101", +"p c #DD0000", +"q c #CF0202", +"r c #9C1414", +"s c #141414", +"t c #0C0C0C", +"u c #0F0F0F", +"v c #111111", +"w c #101010", +"x c #0E0E0E", +"y c #B70707", +"z c #DF0000", +"A c #D50000", +"B c #A90606", +"C c #970E0E", +"D c #B30202", +"E c #C50505", +"F c #812121", +"G c #191919", +"H c #161616", +"I c #181818", +"J c #171717", +"K c #151515", +"L c #AF0A0A", +"M c #D70101", +"N c #D60000", +"O c #AD0606", +"P c #AA0303", +"Q c #DA0000", +"R c #C80505", +"S c #8E1E1E", +"T c #1D1D1D", +"U c #1F1F1F", +"V c #202020", +"W c #B00909", +"X c #CE0000", +"Y c #9F0A0A", +"Z c #9B0808", +"` c #D20000", +" . c #D80101", +".. c #8B1B1B", +"+. c #2D2D2D", +"@. c #272727", +"#. c #262626", +"$. c #252525", +"%. c #BB0606", +"&. c #BB0303", +"*. c #AF0303", +"=. c #AF0B0B", +"-. c #303030", +";. c #2B2B2B", +">. c #323232", +",. c #CD0202", +"'. c #A60A0A", +"). c #9E0909", +"!. c #CF0000", +"~. c #CE0404", +"{. c #292929", +"]. c #B10808", +"^. c #A70303", +"/. c #B60A0A", +"(. c #961010", +"_. c #B90000", +":. c #9C1212", +"<. c #1A1A1A", +"[. c #222222", +"}. c #1C1C1C", +"|. c #C20202", +"1. c #A30606", +"2. c #C60000", +"3. c #2A2A2A", +"4. c #3B3B3B", +"5. c #444444", +"6. c #434343", +"7. c #3A3A3A", +"8. c #1E1E1E", +"9. c #131313", +"0. c #BB0A0A", +"a. c #AD0707", +"b. c #9A1515", +"c. c #D30000", +"d. c #353535", +"e. c #484848", +"f. c #5F5F5F", +"g. c #6C6C6C", +"h. c #646464", +"i. c #565656", +"j. c #343434", +"k. c #212121", +"l. c #121212", +"m. c #B30505", +"n. c #B10404", +"o. c #9A1111", +"p. c #424242", +"q. c #555555", +"r. c #6B6B6B", +"s. c #757575", +"t. c #6E6E6E", +"u. c #606060", +"v. c #4E4E4E", +"w. c #3F3F3F", +"x. c #2C2C2C", +"y. c #B10909", +"z. c #B60707", +"A. c #9B1515", +"B. c #D00000", +"C. c #494949", +"D. c #595959", +"E. c #676767", +"F. c #696969", +"G. c #616161", +"H. c #525252", +"I. c #454545", +"J. c #B20707", +"K. c #363636", +"L. c #626262", +"M. c #5B5B5B", +"N. c #505050", +"O. c #282828", +"P. c #B80B0B", +"Q. c #AC0707", +"R. c #AA1111", +"S. c #0D0D0D", +"T. c #585858", +"U. c #545454", +"V. c #4B4B4B", +"W. c #BF0303", +"X. c #9F0B0B", +"Y. c #B90707", +"Z. c #242424", +"`. c #313131", +" + c #3E3E3E", +".+ c #474747", +"++ c #4D4D4D", +"@+ c #4F4F4F", +"#+ c #4C4C4C", +"$+ c #3D3D3D", +"%+ c #D90000", +"&+ c #8E1010", +"*+ c #A00808", +"=+ c #D00303", +"-+ c #3C3C3C", +";+ c #0B0B0B", +">+ c #AE0808", +",+ c #C10101", +"'+ c #BB0202", +")+ c #BA0A0A", +"!+ c #1B1B1B", +"~+ c #2F2F2F", +"{+ c #C10303", +"]+ c #A10A0A", +"^+ c #9F0707", +"/+ c #D80000", +"(+ c #BE0303", +"_+ c #821C1C", +":+ c #C20404", +"<+ c #232323", +"[+ c #A90C0C", +"}+ c #970C0C", +"|+ c #960E0E", +"1+ c #BE0101", +"2+ c #C60505", +"3+ c #131212", +"4+ c #B00B0B", +"5+ c #CE0101", +"6+ c #A80707", +"7+ c #990B0B", +"8+ c #C40404", +"9+ c #AD0909", +"0+ c #D00101", +"a+ c #B00505", +"b+ c #7B1C1C", +"c+ c #960C0C", +"d+ c #BC0202", +"e+ c #BC0808", +"f+ c #962525", +"g+ c #482E2E", +"h+ c #1E1616", +"i+ c #141010", +"j+ c #2F2020", +"k+ c #703636", +"l+ c #A81212", +"m+ c #A90707", +"n+ c #8E1313", +"o+ c #D30606", +"p+ c #B91E1E", +"q+ c #901919", +"r+ c #661010", +"s+ c #540F0F", +"t+ c #4F0D0D", +"u+ c #5A0F0F", +"v+ c #7A1515", +"w+ c #A21E1E", +"x+ c #C51212", +"y+ c #D60101", +"z+ c #980D0D", +"A+ c #930C0C", +"B+ c #B30404", +"C+ c #C60202", +"D+ c #7B1919", +"E+ c #8C1515", +"F+ c #9F0909", +"G+ c #B20303", +"H+ c #C30000", +"I+ c #CA0000", +"J+ c #C90000", +"K+ c #BC0101", +"L+ c #AA0505", +"M+ c #8F1111", +"N+ c #7F1E1E", +"O+ c #732626", +"P+ c #762A2A", +"Q+ c #6E2828", +" ", +" . + @ # $ % & * = ", +" - ; > , ' ) ) ! ) ! ~ { ] ^ ", +" / ( ' _ : < [ } | 1 2 3 4 ) , 5 6 ", +" 7 8 9 ' 0 a b c d e e f g h i j k ) l m ", +" n o p q r s t u v v w t x y z A B ", +" C D ) E F G H I G J K L M N O ", +" P Q R S T U U T V W ' X Y ", +" Z ` ... +.@.#.$. %.! &. ", +" *.) =. -.;.>. ,.4 '. ", +" ).!.~. {. ].) ( ", +" ^.z /. $. A ` (. ", +" _.! :. K K <.V [.}.K K |.z 1. ", +" 2.9 v <.3.4.5.6.7.;.8.9.J 0.) a. ", +" b.!.c. w }.d.e.f.g.h.i.5.j.k.l. m._ n. ", +" o.` !. u J 3.p.q.r.s.t.u.v.w.x.T w y._ z. ", +" A.B.` u k.j.C.D.E.g.F.G.H.I.j.$.9.l. m._ J. ", +" : 4 s v #.K.C.q.u.h.L.M.N.I.K.O.J x P.) Q. ", +" > z R. S.9.#.d.5.v.i.D.T.U.V.p.j.{.G t W._ X. ", +" % ) Y. l.9.Z.`. +.+++N.@+#+I.$+>.@.I t { %+&+ ", +" *+, =+ x w V ;.K.$+6.I.I.p.-+K.;.[.H ;+ >+z ,+ ", +" '+_ )+ x S.!+Z.~+d.7.-+-+7.d.~+#.8.9.;+ {+_ ]+ ", +" ^+/+, e s }.$.;.~+`.`.-.;.#.U J S.w z.' (+_+ ", +" ] ) :+ t S.K T [.@.O.O.@.<+U I v ;+ [+` ~ }+ ", +" |+1+) 2+ e t 9.I }.T 8.}.G K u e 3+ 4+5+' 6+ ", +" 7+l ) 8+ e ;+u 9.K K 9.v S.f w 9+0+) a+b+ ", +" c+d+) N e+f+g+h+;+f e f i+j+k+l+|.~ /+m+ ", +" n+D N ! o+p+q+r+s+t+u+v+w+x+y+! X z+ ", +" A+B+X _ ! ~ /+N %+' ) ~ C+Y D+ ", +" E+F+G+H+I+l J+K+L+M+N+ ", +" O+P+Q+ ", +" "}; diff --git a/applications/deprecated/old_arch/osmo4_wx/playlist.xpm b/applications/deprecated/old_arch/osmo4_wx/playlist.xpm new file mode 100644 index 0000000..cfad2dc --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/playlist.xpm @@ -0,0 +1,158 @@ +/* XPM */ +static const char* pl_open[] = { +"16 16 5 1", +" c #000000", +"! c #808000", +"# c #C0C0C0", +"$ c #FFFF00", +"% c #FFFFFF", +"################", +"################", +"######### ####", +"######## ### # #", +"############# #", +"# ######## #", +" %$% #####", +" $%$%$%$%$ #####", +" %$%$%$%$% #####", +" $%$% #", +" %$% !!!!!!!!! #", +" $% !!!!!!!!! ##", +" % !!!!!!!!! ###", +" !!!!!!!!! ####", +" #####", +"################"}; + +/* XPM */ +static const char* pl_save[] = { +"16 16 3 1", +" c #000000", +"! c #808000", +"# c #C0C0C0", +"################", +"# #", +"# ! ######## # #", +"# ! ######## #", +"# ! ######## ! #", +"# ! ######## ! #", +"# ! ######## ! #", +"# ! ######## ! #", +"# !! !! #", +"# !!!!!!!!!!!! #", +"# !! ! #", +"# !! ## ! #", +"# !! ## ! #", +"# !! ## ! #", +"## #", +"################"}; + +/* XPM */ +static const char* pl_add[] = { +"16 16 2 1", +" c #000000", +"! c #C0C0C0", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!! !!!", +"!! !!!", +"!! !!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* pl_rem[] = { +"16 16 2 1", +" c #000000", +"! c #C0C0C0", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!! !!!", +"!! !!!", +"!! !!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* pl_up[] = { +"16 16 2 1", +" c #000000", +"! c #C0C0C0", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!! !!!!!!!!", +"!!!!!! !!!!!!!", +"!!!!! !!!!!!", +"!!!! !!!!!", +"!!! !!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* pl_down[] = { +"16 16 2 1", +" c #000000", +"! c #C0C0C0", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!!!!! !!!!!!!", +"!!! !!!!", +"!!!! !!!!!", +"!!!!! !!!!!!", +"!!!!!! !!!!!!!", +"!!!!!!! !!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* pl_sort[] = { +"16 16 2 1", +" c #000000", +"! c #C0C0C0", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!! !!!!! !!!!!", +"!!!! !!!! !!!!", +"!!!! !!! !!!", +"!!!! !!!!! !!!!!", +"!!!! !!!!! !!!!!", +"!!!! !!!!! !!!!!", +"!!!! !!!!! !!!!!", +"!! !!! !!!!!", +"!!! !!!! !!!!!", +"!!!! !!!!! !!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + diff --git a/applications/deprecated/old_arch/osmo4_wx/resource.h b/applications/deprecated/old_arch/osmo4_wx/resource.h new file mode 100644 index 0000000..94a1520 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by wxOsmo4.rc +// +#define IDI_OSMO_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 104 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/applications/deprecated/old_arch/osmo4_wx/toolbar.xpm b/applications/deprecated/old_arch/osmo4_wx/toolbar.xpm new file mode 100644 index 0000000..887d59e --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/toolbar.xpm @@ -0,0 +1,254 @@ +/* XPM */ +static const char* tool_open_file[] = { +"16 16 2 1", +" c #000000", +"! c none", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!! !!!!!!!", +"!!!!!! !!!!!!", +"!!!!! !!!!!", +"!!!! !!!!", +"!!! !!!", +"!! !!", +"!! !!", +"!!!!!!!!!!!!!!!!", +"!! !!", +"!! !!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* tool_prev[] = { +"16 16 3 1", +" c #000000", +"! c none", +"# c #FF0000", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!! !!", +"!!!!!!!!!! !!", +"!!!!!!!! ## !!", +"!!!!!! #### !!", +"!!!! ###### !!", +"!!! ######## !!", +"!!!! ##### !!", +"!!!!!! ### !!", +"!!!!!!!! # !!", +"!!!!!!!!!! !!", +"!!!!!!!!!!!! !!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* tool_next[] = { +"16 16 3 1", +" c #000000", +"! c none", +"# c #FF0000", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!! !!!!!!!!!!!!", +"!! !!!!!!!!!!", +"!! ## !!!!!!!!", +"!! #### !!!!!!", +"!! ###### !!!!", +"!! ######## !!!", +"!! ###### !!!!", +"!! #### !!!!!!", +"!! ## !!!!!!!!", +"!! !!!!!!!!!!", +"!! !!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* tool_play[] = { +"16 16 2 1", +" c #000000", +"! c none", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!! !!!!!!!!!!!!", +"!! !!!!!!!!!!", +"!! !!!!!!!!", +"!! !!!!!!", +"!! !!!!", +"!! !!", +"!! !!!!", +"!! !!!!!!", +"!! !!!!!!!!", +"!! !!!!!!!!!!", +"!! !!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* tool_pause[] = { +"16 16 3 1", +" c #000000", +"! c #808080", +"# c none", +"################", +"################", +"################", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"### !##! ###", +"################", +"################"}; + + +/* XPM */ +static const char* tool_step[] = { +"16 16 2 1", +" c #000000", +"! c none", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!! !!!!!!!!!!!", +"!! !!!!!!!!!", +"!! !!!!!!!", +"!!!! !!!!!", +"!!!!!! !!!", +"!!!!!!!! !!", +"!!!!!! !!!", +"!!!! !!!!!", +"!! !!!!!!!", +"!! !!!!!!!!!", +"!! !!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + + +/* XPM */ +static const char* tool_stop[] = { +"16 16 2 1", +" c #000000", +"! c none", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!! !!", +"!!!!!!!!!!!!!!!!", +"!!!!!!!!!!!!!!!!"}; + +/* XPM */ +static const char* tool_info[] = { +"16 16 3 1", +" c #000000", +"! c none", +"# c #0000FF", +"!!!!!!!!!!!!!!!!", +"!!!!! !!!!!", +"!!! !!!", +"!! ###### !!", +"! ####!!#### !", +"! ####!!#### !", +" ############ ", +" #####!!##### ", +" ######!!##### ", +" #####!!##### ", +" #####!!##### ", +"! ####!!#### !", +"! #####!!### !", +"!! ###### !!", +"!!! !!!", +"!!!!! !!!!!"}; + + +/* XPM */ +static const char* tool_config[] = { +"16 16 3 1", +" c #000000", +"! c #808080", +"# c none", +"################", +"################", +"## ## ######", +"## ## # ## # ##", +"## ## #", +"## #!# ####### #", +"## # #!# ## ## #", +"## #!# #!# ! # #", +"## # #!# ## ## #", +"## #!# #!##### #", +"## # #!# ## ## #", +"## #!# #!# ! # #", +"## # #!# ## ## #", +"## #", +"################", +"################"}; + +/* XPM */ +static const char* tool_sw_2d[] = { +"16 16 4 1", +" c #FF0000", +". c #C0C0C0", +"+ c #0000FF", +"@ c #000000", +" .............. ", +". ..++..++++.. .", +".. +..+..+..+ ..", +"... ..+..+.. ...", +".... +...+. +...", +"...+. +..+ .+...", +"...+++ .+ ++....", +"....... .......", +"....@@ @@ @.....", +"...@. .@.@ .....", +"...@ ....@. ....", +"... ..@@.@.. ...", +".. @...@.@.@. ..", +". ..@@@@@@@@.. .", +" .............. ", +"................"}; + +/* XPM */ +static const char* tool_sw_3d[] = { +"16 16 4 1", +" c #FFFFFF", +". c #C0C0C0", +"+ c #0000FF", +"@ c #000000", +" ", +"................", +"....++..++++....", +"...+..+..+..+...", +"......+..+..+...", +"....++...+..+...", +"...+..+..+..+...", +"...++++.++++....", +"................", +"....@@@@@@@.....", +"...@...@.@......", +"...@.....@......", +"...@..@@.@......", +"...@...@.@.@....", +"....@@@@@@@@....", +"................"}; + diff --git a/applications/deprecated/old_arch/osmo4_wx/wxGPACControl.cpp b/applications/deprecated/old_arch/osmo4_wx/wxGPACControl.cpp new file mode 100644 index 0000000..e422e4d --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/wxGPACControl.cpp @@ -0,0 +1,1051 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 "wxOsmo4.h" +#include +#include +#include +#include +#include +#include + +#include + +#include "wxGPACControl.h" + + +#define NUM_RATES 11 +static const char *BIFSRates[11] = +{ + "5.0", + "7.5", + "10.0", + "12.5", + "15.0", + "24.0", + "25.0", + "30.0", + "50.0", + "60.0", + "100.0" +}; + +void wxGPACControl::SetYUVLabel() +{ + u32 yuv_format = gf_term_get_option(m_pApp->m_term, GF_OPT_YUV_FORMAT); + if (!yuv_format) { + m_yuvtxt->SetLabel(wxT("(No YUV used)")); + } else { + char str[100]; + sprintf(str, "(%s used)", gf_4cc_to_str(yuv_format)); + m_yuvtxt->SetLabel(wxString(str, wxConvUTF8) ); + } +} + +wxGPACControl::wxGPACControl(wxWindow *parent) + : wxDialog(parent, -1, wxString(wxT("GPAC Control Panel"))) +{ + const char *sOpt; + SetSize(320, 240); + u32 i; + wxBoxSizer *bs; + Centre(); + + m_pApp = (wxOsmo4Frame *)parent; + + s_main = new wxBoxSizer(wxVERTICAL); + + s_header = new wxBoxSizer(wxHORIZONTAL); + //s_header->Add(new wxStaticText(this, 0, wxT("Category"), wxDefaultPosition, wxSize(60, 20)), wxALIGN_CENTER); + m_select = new wxComboBox(this, ID_SELECT, wxT(""), wxDefaultPosition, wxSize(120, 30), 0, NULL, wxCB_READONLY); + s_header->Add(m_select, 2, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_header->Add( new wxButton(this, ID_APPLY, wxT("Apply"), wxDefaultPosition, +#ifdef WIN32 + wxSize(40, 20) +#else + wxSize(40, 30) +#endif + ), + 1, wxALIGN_TOP|wxALIGN_RIGHT|wxADJUST_MINSIZE); + s_main->Add(s_header, 0, wxEXPAND, 0); + + /*general section*/ + s_general = new wxBoxSizer(wxVERTICAL); + m_loop = new wxCheckBox(this, 0, wxT("Loop at End"), wxPoint(10, 40), wxSize(140, 20)); + s_general->Add(m_loop); + m_lookforsubs = new wxCheckBox(this, 0, wxT("Look for Subtitles"), wxPoint(180, 40), wxSize(140, 20)); + s_general->Add(m_lookforsubs); + m_noconsole = new wxCheckBox(this, 0, wxT("Disable console messages"), wxPoint(10, 80), wxSize(180, 20)); + s_general->Add(m_noconsole); + m_viewxmt = new wxCheckBox(this, 0, wxT("View graph in XMT-A format"), wxPoint(10, 120), wxSize(180, 20)); + s_general->Add(m_viewxmt); + s_main->Add(s_general, 0, wxEXPAND, 0); + + /*MPEG-4 systems*/ + s_mpeg4 = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Prefered Stream Language")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_lang = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_lang, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_mpeg4->Add(bs, 0, wxALL|wxEXPAND, 2); + + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Decoder Threading Mode")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_thread = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_thread, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_mpeg4->Add(bs, 0, wxALL|wxEXPAND, 2); + m_bifsalwaysdrawn = new wxCheckBox(this, 0, wxT("Always draw late BIFS frames")); + s_mpeg4->Add(m_bifsalwaysdrawn); + m_singletime = new wxCheckBox(this, 0, wxT("Force Single Timeline")); + s_mpeg4->Add(m_singletime); + s_main->Add(s_mpeg4, 0, wxEXPAND, 0); + + /*media decoders*/ + s_mdec = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Prefered Audio Output")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_decaudio = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_decaudio, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_mdec->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Prefered Video Output")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_decvideo = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_decvideo, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_mdec->Add(bs, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_mdec, 0, wxEXPAND, 0); + + /*Rendering*/ + s_rend = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Target Frame Rate")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_fps = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_fps, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Anti-Aliasing")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_aa = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_aa, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Graphics Driver")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_graph = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_graph, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + m_draw_bounds = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(new wxStaticText(this, 0, wxT("Bounds")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + bs->Add(m_draw_bounds, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); + m_fast = new wxCheckBox(this, 0, wxT("Fast Rendering")); + m_force_size = new wxCheckBox(this, 0, wxT("Force Scene Size")); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(m_fast, wxALIGN_CENTER | wxADJUST_MINSIZE); + bs->Add(m_force_size, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rend->Add(bs, 0, wxALL|wxEXPAND, 2); + m_use3D = new wxCheckBox(this, 0, wxT("Use 3D Renderer")); + s_rend->Add(m_use3D, 0, wxALL|wxEXPAND, 2); + m_bWas3D = m_use3D->GetValue(); + s_main->Add(s_rend, 0, wxEXPAND, 0); + + /*Render 2D*/ + s_rend2d = new wxBoxSizer(wxVERTICAL); + m_direct = new wxCheckBox(this, 0, wxT("Direct Rendering")); + s_rend2d->Add(m_direct, 0, wxALL|wxEXPAND, 2); + m_scalable = new wxCheckBox(this, 0, wxT("Scalable Zoom")); + s_rend2d->Add(m_scalable, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + m_noyuv = new wxCheckBox(this, 0, wxT("Disable YUV hardware")); + bs->Add(m_noyuv, wxALIGN_CENTER | wxADJUST_MINSIZE); + m_yuvtxt = new wxStaticText(this, 0, wxT("(No YUV used)"), wxDefaultPosition, wxSize(60, 20), wxALIGN_LEFT); + bs->Add(m_yuvtxt, wxALIGN_CENTER|wxADJUST_MINSIZE); + s_rend2d->Add(bs, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_rend2d, 0, wxEXPAND, 0); + + /*Render 3D*/ + s_rend3d = new wxBoxSizer(wxVERTICAL); + m_raster_outlines = new wxCheckBox(this, 0, wxT("Use OpenGL Raster outlines")); + s_rend3d->Add(m_raster_outlines, 0, wxALL|wxEXPAND, 2); + m_polyaa = new wxCheckBox(this, 0, wxT("Enable polygon anti-aliasing")); + s_rend3d->Add(m_polyaa, 0, wxALL|wxEXPAND, 2); + m_nobackcull = new wxCheckBox(this, 0, wxT("Disable backface culling")); + s_rend3d->Add(m_nobackcull, 0, wxALL|wxEXPAND, 2); + + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Wireframe mode")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_wire = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_wire, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rend3d->Add(bs, 0, wxALL|wxEXPAND, 2); + + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Draw Normals")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_normals = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_normals, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rend3d->Add(bs, 0, wxALL|wxEXPAND, 2); + + m_emulpow2 = new wxCheckBox(this, 0, wxT("Emulate power-of-two textures for video")); + s_rend3d->Add(m_emulpow2, 0, wxALL|wxEXPAND, 2); + m_norectext = new wxCheckBox(this, 0, wxT("Disable rectangular texture extensions")); + s_rend3d->Add(m_norectext, 0, wxALL|wxEXPAND, 2); + m_copypixels = new wxCheckBox(this, 0, wxT("Bitmap node uses direct pixel copy")); + s_rend3d->Add(m_copypixels, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_rend3d, 0, wxEXPAND, 0); + + /*video*/ + s_video = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Video Driver")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + m_video = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_video , wxALIGN_CENTER | wxADJUST_MINSIZE); + s_video->Add(bs, 0, wxALL|wxEXPAND, 2); + m_switchres = new wxCheckBox(this, 0, wxT("Change video resolution in fullscreen")); + s_video->Add(m_switchres, 0, wxALL|wxEXPAND, 2); + m_usehwmem = new wxCheckBox(this, 0, wxT("Use hardware memory in 2D mode")); + s_video->Add(m_usehwmem, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_video, 0, wxEXPAND, 0); + + + /*audio*/ + s_audio = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Audio Driver")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_audio = new wxComboBox(this, ID_AUDIO_DRIVER, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_audio, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_audio->Add(bs, 0, wxALL|wxEXPAND, 2); + m_forcecfg = new wxCheckBox(this, ID_FORCE_AUDIO, wxT("Force Audio Config")); + m_forcecfg->SetValue(1); + s_audio->Add(m_forcecfg, 0, wxALL|wxEXPAND, 2); + + + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Number of buffers")), wxALIGN_CENTER|wxADJUST_MINSIZE); + m_nbbuf = new wxSpinCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(20, 20), wxSP_WRAP | wxSP_ARROW_KEYS, 1, 30, 15); + m_nbbuf->SetValue(8); + bs->Add(m_nbbuf, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_audio->Add(bs, 0, wxALL|wxEXPAND, 2); + + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Total length in ms")), wxALIGN_CENTER | wxADJUST_MINSIZE); + m_buflen = new wxSpinCtrl(this, -1, wxT(""), wxDefaultPosition, wxSize(20, 20), wxSP_WRAP | wxSP_ARROW_KEYS, 1, 1000); + m_buflen->SetValue(400); + bs->Add(m_buflen, wxALIGN_CENTER | wxADJUST_MINSIZE|wxLEFT,10); + s_audio->Add(bs, 0, wxALL|wxEXPAND, 2); + + m_noresync = new wxCheckBox(this, -1, wxT("Disable Resynchronization")); + s_audio->Add(m_noresync); + m_nomulitch = new wxCheckBox(this, -1, wxT("Disable Multichannel")); + s_audio->Add(m_nomulitch); +#ifdef WIN32 + m_notifs = new wxCheckBox(this, -1, wxT("Disable DirectSound Notifications")); + s_audio->Add(m_notifs); +#endif + s_main->Add(s_audio, 0, wxEXPAND, 0); + + /*font*/ + s_font = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Font Engine")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + m_font = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_font, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_font->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("System Font Directory")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + m_fontdir = new wxButton(this, ID_FONT_DIR, wxT("..."), wxDefaultPosition, wxDefaultSize); + bs->Add(m_fontdir, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_font->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Text Texturing Mode")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + m_texturemode = new wxComboBox(this, 0, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); + bs->Add(m_texturemode, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_font->Add(bs, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_font, 0, wxEXPAND, 0); + + /*download*/ + s_dnld = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Cache Directory")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + m_cachedir = new wxButton(this, ID_CACHE_DIR, wxT("...")); + bs->Add(m_cachedir, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_dnld->Add(bs, 0, wxALL|wxEXPAND, 2); + m_cleancache = new wxCheckBox(this, -1, wxT("Remove temp files on exit")); + s_dnld->Add(m_cleancache); + m_restartcache = new wxCheckBox(this, -1, wxT("Always redownload incomplete cached files")); + s_dnld->Add(m_restartcache); + bs = new wxBoxSizer(wxHORIZONTAL); + m_progressive = new wxCheckBox(this, ID_PROGRESSIVE, wxT("XML progressive load")); + bs->Add(m_progressive, wxALIGN_CENTER | wxADJUST_MINSIZE); + m_sax_duration = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 120), wxSize(60, 20)); + bs->Add(m_sax_duration, wxALIGN_CENTER | wxADJUST_MINSIZE); + bs->Add(new wxStaticText(this, 0, wxT("max load slice (ms)")), wxADJUST_MINSIZE | wxALIGN_CENTER); + s_dnld->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + m_use_proxy = new wxCheckBox(this, ID_USE_PROXY, wxT("Use proxy")); + bs->Add(m_use_proxy, wxALIGN_CENTER | wxADJUST_MINSIZE); + m_proxy_name = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 120), wxSize(60, 20)); + bs->Add(m_proxy_name, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_dnld->Add(bs, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_dnld, 0, wxEXPAND, 0); + + /*streaming*/ + s_stream = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Default RTSP port")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + m_port = new wxComboBox(this, ID_RTSP_PORT, wxT(""), wxPoint(160, 40), wxSize(140, 30), 0, NULL, wxCB_READONLY); + bs->Add(m_port, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); + m_rtsp = new wxCheckBox(this, ID_RTP_OVER_RTSP, wxT("RTP over RTSP"), wxPoint(10, 80), wxSize(140, 20)); + m_reorder = new wxCheckBox(this, -1, wxT("use RTP reordering"), wxPoint(160, 80), wxSize(130, 20)); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(m_rtsp, wxALIGN_CENTER | wxADJUST_MINSIZE); + bs->Add(m_reorder, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + m_timeout = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 120), wxSize(60, 20)); + bs->Add(new wxStaticText(this, 0, wxT("Control Timeout (ms): ")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + bs->Add(m_timeout, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + m_buffer = new wxTextCtrl(this, 0, wxT(""), wxPoint(10, 150), wxSize(60, 20)); + bs->Add(new wxStaticText(this, 0, wxT("Media Buffering (ms): ")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + bs->Add(m_buffer, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); + bs = new wxBoxSizer(wxHORIZONTAL); + m_dorebuffer = new wxCheckBox(this, ID_RTSP_REBUFFER, wxT("Rebuffer if below")); + bs->Add(m_dorebuffer, wxALIGN_CENTER | wxADJUST_MINSIZE); + m_rebuffer = new wxTextCtrl(this, 0, wxT(""), wxPoint(200, 180), wxSize(60, 20)); + bs->Add(m_rebuffer, wxALIGN_CENTER | wxADJUST_MINSIZE); + m_rebuffer->Disable(); + s_stream->Add(bs, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_stream, 0, wxEXPAND, 0); + + /*streaming cache*/ + s_rec = new wxBoxSizer(wxVERTICAL); + bs = new wxBoxSizer(wxHORIZONTAL); + bs->Add(new wxStaticText(this, 0, wxT("Record To: ")), wxALIGN_CENTER | wxADJUST_MINSIZE | wxALIGN_RIGHT); + m_recdir = new wxButton(this, ID_RECORD_DIR, wxT("...")); + bs->Add(m_recdir, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rec->Add(bs, 0, wxALL|wxEXPAND, 2); + m_overwrite = new wxCheckBox(this, -1, wxT("Overwrite existing files")); + s_rec->Add(m_overwrite); + bs = new wxBoxSizer(wxHORIZONTAL); + m_usename = new wxCheckBox(this, ID_USE_FILENAME, wxT("Use filename")); + m_recfile = new wxTextCtrl(this, 0, wxT("")); + bs->Add(m_usename, wxALIGN_CENTER | wxADJUST_MINSIZE); + bs->Add(m_recfile, wxALIGN_CENTER | wxADJUST_MINSIZE); + s_rec->Add(bs, 0, wxALL|wxEXPAND, 2); + s_main->Add(s_rec, 0, wxEXPAND, 0); + + /*load options*/ + GF_Config *cfg = m_pApp->m_user.config; + /*general*/ + sOpt = gf_cfg_get_key(cfg, "General", "Loop"); + m_loop->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "General", "LookForSubtitles"); + m_lookforsubs->SetValue((sOpt && !stricmp(sOpt, "no")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "General", "ConsoleOff"); + m_noconsole->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "General", "ViewXMT"); + m_viewxmt->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + /*lang config*/ + u32 count = gf_lang_get_count(); + for (i=0; iAppend(wxString(gf_lang_get_name(i), wxConvUTF8) ); + } + + sOpt = gf_cfg_get_key(cfg, "Systems", "Language3CC"); + if (!sOpt) sOpt = "eng"; + s32 select = gf_lang_find(sOpt); + if (select<0) select = 0; + m_lang->SetSelection(select); + + /*systems config*/ + sOpt = gf_cfg_get_key(cfg, "Systems", "ThreadingPolicy"); + select = 0; + m_thread->Append(wxT("Single Thread")); + m_thread->Append(wxT("Mutli Thread")); + if (sOpt && !stricmp(sOpt, "Multi")) select = 1; + m_thread->Append(wxT("Free")); + if (sOpt && !stricmp(sOpt, "Free")) select = 2; + m_thread->SetSelection(select); + sOpt = gf_cfg_get_key(cfg, "Systems", "ForceSingleClock"); + m_singletime->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Systems", "AlwaysDrawBIFS"); + m_bifsalwaysdrawn->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + + /*audio dec enum*/ + sOpt = gf_cfg_get_key(cfg, "Systems", "DefAudioDec"); + u32 count = gf_modules_get_count(m_pApp->m_user.modules); + GF_BaseDecoder *ifc_d; + select = 0; + s32 to_sel = 0; + for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); + if (!ifc_d) continue; + if (ifc_d->CanHandleStream(ifc_d, GF_STREAM_AUDIO, NULL, 0)) { + if (sOpt && !stricmp(ifc_d->module_name, sOpt)) select = to_sel; + m_decaudio->Append(wxString(ifc_d->module_name, wxConvUTF8) ); + to_sel++; + } + gf_modules_close_interface((GF_BaseInterface *) ifc_d); + } + m_decaudio->SetSelection(select); + + /*video dec enum*/ + sOpt = gf_cfg_get_key(cfg, "Systems", "DefVideoDec"); + select = to_sel = 0; + for (i=0; im_user.modules, i, GF_MEDIA_DECODER_INTERFACE); + if (!ifc_d) continue; + if (ifc_d->CanHandleStream(ifc_d, GF_STREAM_VISUAL, NULL, 0)) { + if (sOpt && !stricmp(ifc_d->module_name, sOpt)) select = to_sel; + m_decvideo->Append(wxString(ifc_d->module_name, wxConvUTF8) ); + to_sel++; + } + gf_modules_close_interface((GF_BaseInterface *) ifc_d); + } + m_decvideo->SetSelection(select); + + /*rendering FIXME*/ + m_bWas3D = 0; + m_use3D->SetValue(m_bWas3D ? 1 : 0); + + sOpt = gf_cfg_get_key(cfg, "Compositor", "ForceSceneSize"); + m_force_size->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(cfg, "Compositor", "FrameRate"); + if (!sOpt) sOpt = "30.0"; + select = 0; + for (i = 0; iAppend(wxString(BIFSRates[i], wxConvUTF8) ); + if (sOpt && !stricmp(sOpt, BIFSRates[i]) ) select = i; + } + m_fps->SetSelection(select); + + sOpt = gf_cfg_get_key(cfg, "Compositor", "HighSpeed"); + m_fast->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + sOpt = gf_cfg_get_key(cfg, "Compositor", "AntiAlias"); + m_aa->Append(wxT("None")); + m_aa->Append(wxT("Text only")); + m_aa->Append(wxT("Complete")); + select = 2; + if (sOpt && !stricmp(sOpt, "Text")) select = 1; + else if (sOpt && !stricmp(sOpt, "None")) select = 0; + m_aa->SetSelection(select); + + sOpt = gf_cfg_get_key(cfg, "Compositor", "BoundingVolume"); + m_draw_bounds->Append(wxT("None")); + m_draw_bounds->Append(wxT("Box/Rect")); + m_draw_bounds->Append(wxT("AABB Tree")); + select = 0; + if (sOpt && !stricmp(sOpt, "Box")) select = 1; + else if (sOpt && !stricmp(sOpt, "AABB")) select = 2; + m_draw_bounds->SetSelection(select); + + /*render2d*/ + sOpt = gf_cfg_get_key(cfg, "Compositor", "DirectDraw"); + m_direct->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Compositor", "ScalableZoom"); + m_scalable->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Compositor", "DisableYUV"); + m_noyuv->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + SetYUVLabel(); + + /*graphics driver enum*/ + sOpt = gf_cfg_get_key(cfg, "core", "raster2d"); + GF_BaseInterface *ifce; + select = to_sel = 0; + for (i=0; im_user.modules, i, GF_RASTER_2D_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + m_graph->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); + gf_modules_close_interface(ifce); + to_sel++; + } + m_graph->SetSelection(select); + + /*render3d*/ + sOpt = gf_cfg_get_key(cfg, "Compositor", "RasterOutlines"); + m_raster_outlines->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Compositor", "EmulatePOW2"); + m_emulpow2->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Compositor", "PolygonAA"); + m_polyaa->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Compositor", "BackFaceCulling"); + m_nobackcull->SetValue((sOpt && !stricmp(sOpt, "Off")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Compositor", "Wireframe"); + sOpt = gf_cfg_get_key(cfg, "Compositor", "BitmapCopyPixels"); + m_copypixels->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Compositor", "DisableRectExt"); + m_norectext->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + m_wire->Append(wxT("No Wireframe")); + m_wire->Append(wxT("Wireframe Only")); + m_wire->Append(wxT("Solid and Wireframe")); + sOpt = gf_cfg_get_key(cfg, "Compositor", "Wireframe"); + if (sOpt && !stricmp(sOpt, "WireOnly")) m_wire->SetSelection(1); + else if (sOpt && !stricmp(sOpt, "WireOnSolid")) m_wire->SetSelection(2); + else m_wire->SetSelection(0); + m_normals->Append(wxT("Never")); + m_normals->Append(wxT("Per Face")); + m_normals->Append(wxT("Per Vertex")); + sOpt = gf_cfg_get_key(cfg, "Compositor", "DrawNormals"); + if (sOpt && !stricmp(sOpt, "PerFace")) m_normals->SetSelection(1); + else if (sOpt && !stricmp(sOpt, "PerVertex")) m_normals->SetSelection(2); + else m_normals->SetSelection(0); + + /*video*/ + m_switchres->SetValue( gf_cfg_get_bool(cfg, "core", "switch-vres") ); + sOpt = gf_cfg_get_key(cfg, "core", "hwvmem"); + m_usehwmem->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "core", "video-output"); + select = to_sel = 0; + for (i=0; im_user.modules, i, GF_VIDEO_OUTPUT_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + m_video->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); + gf_modules_close_interface(ifce); + to_sel++; + } + m_video->SetSelection(select); + + /*audio*/ + sOpt = gf_cfg_get_key(cfg, "Audio", "ForceConfig"); + m_forcecfg->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Audio", "NumBuffers"); + m_nbbuf->SetValue( sOpt ? wxString(sOpt, wxConvUTF8) : wxT("2")); + sOpt = gf_cfg_get_key(cfg, "Audio", "TotalDuration"); + m_buflen->SetValue( sOpt ? wxString(sOpt, wxConvUTF8) : wxT("120")); + wxCommandEvent event; + ForceAudio(event); + sOpt = gf_cfg_get_key(cfg, "Audio", "NoResync"); + m_noresync->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Audio", "DisableMultiChannel"); + m_nomulitch->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + + /*driver enum*/ + sOpt = gf_cfg_get_key(cfg, "core", "audio-output"); + select = to_sel = 0; + for (i=0; im_user.modules, i, GF_AUDIO_OUTPUT_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + m_audio->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); + gf_modules_close_interface(ifce); + to_sel++; + } + m_audio->SetSelection(select); +#ifdef WIN32 + sOpt = gf_cfg_get_key(cfg, "Audio", "DisableNotification"); + m_notifs->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + wxCommandEvent audevt; + OnSetAudioDriver(audevt); +#endif + + /*font*/ + sOpt = gf_cfg_get_key(cfg, "FontCache", "FontReader"); + to_sel = select = 0; + for (i=0; im_user.modules, i, GF_FONT_READER_INTERFACE); + if (!ifce) continue; + if (sOpt && !stricmp(((GF_BaseInterface *)ifce)->module_name, sOpt)) select = to_sel; + m_font->Append(wxString(((GF_BaseInterface *)ifce)->module_name, wxConvUTF8) ); + gf_modules_close_interface(ifce); + to_sel++; + } + m_font->SetSelection(select); + sOpt = gf_cfg_get_key(cfg, "FontCache", "FontDirectory"); + if (sOpt) m_fontdir->SetLabel(wxString(sOpt, wxConvUTF8) ); + sOpt = gf_cfg_get_key(cfg, "Compositor", "TextureTextMode"); + m_texturemode->Append(wxT("Default")); + m_texturemode->Append(wxT("Never")); + m_texturemode->Append(wxT("Always")); + if (sOpt && !stricmp(sOpt, "Always")) m_texturemode->SetSelection(2); + else if (sOpt && !stricmp(sOpt, "3D")) m_texturemode->SetSelection(1); + else m_texturemode->SetSelection(0); + + /*downloader*/ + sOpt = gf_cfg_get_key(cfg, "Core", "CacheDirectory"); + if (sOpt) m_cachedir->SetLabel(wxString(sOpt, wxConvUTF8) ); + sOpt = gf_cfg_get_key(cfg, "Core", "CleanCache"); + m_cleancache->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "Core", "RestartFiles"); + m_restartcache->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "SAXLoader", "Progressive"); + m_progressive->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(cfg, "SAXLoader", "MaxDuration"); + m_sax_duration->SetValue(sOpt ? wxString(sOpt, wxConvUTF8) : wxT("30")); + if (! m_progressive->GetValue()) m_sax_duration->Enable(0); + + sOpt = gf_cfg_get_key(cfg, "Core", "HTTPProxyEnabled"); + m_use_proxy->SetValue( (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + char szProxy[GF_MAX_PATH]; + strcpy(szProxy, ""); + sOpt = gf_cfg_get_key(cfg, "Core", "HTTPProxyName"); + if (sOpt) { + strcat(szProxy, sOpt); + sOpt = gf_cfg_get_key(cfg, "Core", "HTTPProxyPort"); + if (sOpt) { + strcat(szProxy, ":"); + strcat(szProxy, sOpt); + } + } else { + m_use_proxy->SetValue(0); + } + m_proxy_name->SetValue( wxString((char *)szProxy, wxConvUTF8) ); + if (! m_use_proxy->GetValue()) m_proxy_name->Enable(0); + + /*streaming*/ + m_port->Append(wxT("554 (RTSP standard)")); + m_port->Append(wxT("7070 (RTSP ext)")); + m_port->Append(wxT("80 (RTSP / HTTP tunnel)")); + m_port->Append(wxT("8080 (RTSP / HTTP tunnel)")); + sOpt = gf_cfg_get_key(cfg, "Streaming", "DefaultPort"); + u32 port = 554; + Bool force_rtsp = 0; + if (sOpt) port = atoi(sOpt); + switch (port) { + case 8080: + m_port->SetSelection(3); + force_rtsp = 1; + break; + case 80: + m_port->SetSelection(2); + force_rtsp = 1; + break; + case 7070: + m_port->SetSelection(1); + break; + default: + m_port->SetSelection(0); + break; + } + + Bool use_rtsp = 0; + sOpt = gf_cfg_get_key(cfg, "Streaming", "RTPoverRTSP"); + if (sOpt && !stricmp(sOpt, "yes")) use_rtsp = 1; + + if (force_rtsp) { + m_rtsp->SetValue(1); + m_rtsp->Enable(0); + m_reorder->SetValue(0); + m_reorder->Enable(0); + } else { + m_rtsp->SetValue(use_rtsp ? 1 : 0); + m_rtsp->Enable(1); + m_reorder->Enable(1); + sOpt = gf_cfg_get_key(cfg, "Streaming", "ReorderSize"); + m_reorder->SetValue( (sOpt && !stricmp(sOpt, "0")) ? 1 : 0); + } + sOpt = gf_cfg_get_key(cfg, "Streaming", "RTSPTimeout"); + m_timeout->SetValue(sOpt ? wxString(sOpt, wxConvUTF8) : wxT("30000")); + sOpt = gf_cfg_get_key(cfg, "Network", "BufferLength"); + m_buffer->SetValue(sOpt ? wxString(sOpt, wxConvUTF8) : wxT("3000")); + sOpt = gf_cfg_get_key(cfg, "Network", "RebufferLength"); + u32 buf_len = 0; + if (sOpt) buf_len = atoi(sOpt); + if (buf_len) { + m_dorebuffer->SetValue(1); + m_rebuffer->SetValue(wxString(sOpt, wxConvUTF8)); + m_rebuffer->Enable(1); + } else { + m_dorebuffer->SetValue(0); + m_rebuffer->SetValue(wxT("0")); + m_rebuffer->Enable(0); + } + + RTPoverRTSP(event); + + sOpt = gf_cfg_get_key(cfg, "StreamingCache", "RecordDirectory"); + if (!sOpt) sOpt = gf_cfg_get_key(cfg, "Core", "CacheDirectory"); + if (sOpt) m_recdir->SetLabel(wxString(sOpt, wxConvUTF8)); + sOpt = gf_cfg_get_key(cfg, "StreamingCache", "KeepExistingFiles"); + m_overwrite->SetValue((sOpt && !stricmp(sOpt, "yes")) ? 0 : 1); + + sOpt = gf_cfg_get_key(cfg, "StreamingCache", "BaseFileName"); + if (sOpt) { + m_usename->SetValue(1); + m_recfile->Enable(1); + m_recfile->SetValue(wxString(sOpt, wxConvUTF8)); + } else { + m_usename->SetValue(0); + m_recfile->Enable(0); + m_recfile->SetValue(wxT("uses service URL")); + } + + m_select->Append(wxT("General")); + m_select->Append(wxT("MPEG-4 Systems")); + m_select->Append(wxT("Media Decoders")); + m_select->Append(wxT("Compositor")); + m_select->Append(wxT("Renderer 2D")); + m_select->Append(wxT("Renderer 3D")); + m_select->Append(wxT("Video Output")); + m_select->Append(wxT("Audio Output")); + m_select->Append(wxT("Text Engine")); + m_select->Append(wxT("File Download")); + m_select->Append(wxT("Real-Time Streaming")); + m_select->Append(wxT("Streaming Cache")); + + sOpt = gf_cfg_get_key(cfg, "General", "ConfigPanel"); + m_sel = sOpt ? atoi(sOpt) : 0; + if (m_sel>11) m_sel=11; + m_select->SetSelection(m_sel); + + DoSelect(); +} + +BEGIN_EVENT_TABLE(wxGPACControl, wxDialog) + EVT_BUTTON(ID_APPLY, wxGPACControl::Apply) + EVT_COMBOBOX(ID_SELECT, wxGPACControl::OnSetSelection) + EVT_CHECKBOX(ID_FORCE_AUDIO, wxGPACControl::ForceAudio) + EVT_COMBOBOX(ID_AUDIO_DRIVER, wxGPACControl::OnSetAudioDriver) + EVT_BUTTON(ID_FONT_DIR, wxGPACControl::FontDir) + EVT_BUTTON(ID_CACHE_DIR, wxGPACControl::CacheDir) + EVT_CHECKBOX(ID_PROGRESSIVE, wxGPACControl::OnProgressive) + EVT_CHECKBOX(ID_USE_PROXY, wxGPACControl::OnUseProxy) + EVT_CHECKBOX(ID_RTP_OVER_RTSP, wxGPACControl::RTPoverRTSP) + EVT_CHECKBOX(ID_RTSP_REBUFFER, wxGPACControl::Rebuffer) + EVT_COMBOBOX(ID_RTSP_PORT, wxGPACControl::OnSetRTSPPort) + EVT_CHECKBOX(ID_USE_FILENAME, wxGPACControl::OnUseFileName) + EVT_BUTTON(ID_RECORD_DIR, wxGPACControl::OnRecDir) +END_EVENT_TABLE() + + +wxGPACControl::~wxGPACControl() +{ + char str[20]; + sprintf(str, "%d", m_sel); + gf_cfg_set_key(m_pApp->m_user.config, "General", "ConfigPanel", str); +} + + +void wxGPACControl::DoSelect() +{ + + /*hide everything*/ + s_main->Show(s_general, false); + s_main->Show(s_mpeg4, false); + s_main->Show(s_mdec, false); + s_main->Show(s_rend, false); + s_main->Show(s_rend2d, false); + s_main->Show(s_rend3d, false); + s_main->Show(s_video, false); + s_main->Show(s_audio, false); + s_main->Show(s_font, false); + s_main->Show(s_dnld, false); + s_main->Show(s_stream, false); + s_main->Show(s_rec, false); + switch (m_sel) { + case 0: + s_main->Show(s_general, true); + break; + case 1: + s_main->Show(s_mpeg4, true); + break; + case 2: + s_main->Show(s_mdec, true); + break; + case 3: + s_main->Show(s_rend, true); + break; + case 4: + s_main->Show(s_rend2d, true); + break; + case 5: + s_main->Show(s_rend3d, true); + break; + case 6: + s_main->Show(s_video, true); + break; + case 7: + s_main->Show(s_audio, true); + break; + case 8: + s_main->Show(s_font, true); + break; + case 9: + s_main->Show(s_dnld, true); + break; + case 10: + s_main->Show(s_stream, true); + break; + case 11: + s_main->Show(s_rec, true); + break; + } + SetSizer(s_main); + s_main->Fit(this); + //s_main->Layout(); + return; + +} + +void wxGPACControl::OnSetSelection(wxCommandEvent &WXUNUSED(event)) +{ + m_sel = m_select->GetSelection(); + DoSelect(); +} + +void wxGPACControl::FontDir(wxCommandEvent &WXUNUSED(event)) +{ + wxDirDialog dlg(this); + dlg.SetPath(m_fontdir->GetLabel()); + if (dlg.ShowModal() == wxID_OK) { + m_fontdir->SetLabel(dlg.GetPath()); + } +} +void wxGPACControl::CacheDir(wxCommandEvent &WXUNUSED(event)) +{ + wxDirDialog dlg(this); + dlg.SetPath(m_cachedir->GetLabel()); + if (dlg.ShowModal() == wxID_OK) { + m_cachedir->SetLabel(dlg.GetPath()); + } +} + +void wxGPACControl::OnProgressive(wxCommandEvent &WXUNUSED(event)) +{ + m_sax_duration->Enable(m_progressive->GetValue() ? 1 : 0); +} + +void wxGPACControl::OnUseProxy(wxCommandEvent &WXUNUSED(event)) +{ + m_proxy_name->Enable(m_use_proxy->GetValue() ? 1 : 0); +} + +void wxGPACControl::RTPoverRTSP(wxCommandEvent &WXUNUSED(event)) +{ + m_reorder->Enable(m_rtsp->GetValue() ? 0 : 1); +} + +void wxGPACControl::Rebuffer(wxCommandEvent &WXUNUSED(event)) +{ + if (m_dorebuffer->GetValue()) { + m_rebuffer->Enable(); + } else { + m_rebuffer->Disable(); + } +} + +void wxGPACControl::OnSetRTSPPort(wxCommandEvent &WXUNUSED(event)) +{ + if (m_port->GetSelection() > 1) { + m_rtsp->Enable(0); + m_reorder->Enable(0); + } else { + m_rtsp->Enable(1); + m_reorder->Enable(1); + } +} + +void wxGPACControl::OnRecDir(wxCommandEvent &WXUNUSED(event)) +{ + wxDirDialog dlg(this); + dlg.SetPath(m_recdir->GetLabel()); + if (dlg.ShowModal() == wxID_OK) { + m_recdir->SetLabel(dlg.GetPath()); + } +} + +void wxGPACControl::OnUseFileName(wxCommandEvent &WXUNUSED(event)) +{ + if (m_usename->GetValue()) { + m_recfile->Enable(); + m_recfile->SetValue(wxT("record")); + } else { + m_recfile->Disable(); + m_recfile->SetValue(wxT("uses service URL")); + } +} + +void wxGPACControl::ForceAudio(wxCommandEvent &WXUNUSED(event)) +{ + if (m_forcecfg->GetValue()) { + m_nbbuf->Enable(); + m_buflen->Enable(); + } else { + m_nbbuf->Disable(); + m_buflen->Disable(); + } +} + +void wxGPACControl::OnSetAudioDriver(wxCommandEvent &WXUNUSED(event)) +{ +#ifdef WIN32 + if (strstr(m_audio->GetStringSelection().mb_str(wxConvUTF8), "DirectSound")) { + m_notifs->Enable(1); + } else { + m_notifs->Enable(0); + } +#endif +} + + + +void wxGPACControl::Apply(wxCommandEvent &WXUNUSED(event)) +{ + /*save options*/ + GF_Config *cfg = m_pApp->m_user.config; + + m_pApp->m_loop = m_loop->GetValue() ? 1 : 0; + gf_cfg_set_key(cfg, "General", "Loop", m_loop->GetValue() ? "yes" : "no"); + m_pApp->m_lookforsubs = m_lookforsubs->GetValue() ? 1 : 0; + gf_cfg_set_key(cfg, "General", "LookForSubtitles", m_lookforsubs->GetValue() ? "yes" : "no"); + m_pApp->m_console_off = m_noconsole->GetValue() ? 1 : 0; + gf_cfg_set_key(cfg, "General", "ConsoleOff", m_noconsole->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "General", "ViewXMT", m_viewxmt->GetValue() ? "yes" : "no"); + + s32 sel = m_lang->GetSelection(); + gf_cfg_set_key(cfg, "Systems", "LanguageName", gf_lang_get_name(sel) ); + gf_cfg_set_key(cfg, "Systems", "Language3CC", gf_lang_get_3cc(sel) ); + gf_cfg_set_key(cfg, "Systems", "Language2CC", gf_lang_get_2cc(sel) ); + + + sel = m_thread->GetSelection(); + gf_cfg_set_key(cfg, "Systems", "ThreadingPolicy", (sel==0) ? "Single" : ( (sel==1) ? "Multi" : "Free")); + gf_cfg_set_key(cfg, "Systems", "ForceSingleClock", m_singletime->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Systems", "AlwaysDrawBIFS", m_bifsalwaysdrawn->GetValue() ? "yes" : "no"); + + gf_cfg_set_key(cfg, "Systems", "DefAudioDec", m_decaudio->GetStringSelection().mb_str(wxConvUTF8)); + gf_cfg_set_key(cfg, "Systems", "DefVideoDec", m_decvideo->GetStringSelection().mb_str(wxConvUTF8)); + + + gf_cfg_set_key(cfg, "Compositor", "HighSpeed", m_fast->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "ForceSceneSize", m_force_size->GetValue() ? "yes" : "no"); + + gf_cfg_set_key(cfg, "Compositor", "FrameRate", BIFSRates[m_fps->GetSelection()]); + sel = m_aa->GetSelection(); + gf_cfg_set_key(cfg, "Compositor", "AntiAlias", (sel==0) ? "None" : ( (sel==1) ? "Text" : "All")); + sel = m_draw_bounds->GetSelection(); + gf_cfg_set_key(cfg, "Compositor", "BoundingVolume", (sel==2) ? "AABB" : (sel==1) ? "Box" : "None"); + + Bool is_3D = m_use3D->GetValue() ? 1 : 0; + if (m_bWas3D != is_3D) { + /*FIXME*/ + } + gf_cfg_set_key(cfg, "core", "raster2d", m_graph->GetStringSelection().mb_str(wxConvUTF8)); + + gf_cfg_set_key(cfg, "Compositor", "DirectDraw", m_direct->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", m_scalable->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "DisableYUV", m_noyuv->GetValue() ? "yes" : "no"); + + gf_cfg_set_key(cfg, "Compositor", "RasterOutlines", m_raster_outlines->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "EmulatePOW2", m_emulpow2->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "PolygonAA", m_polyaa->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "DisableRectExt", m_norectext->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "BitmapCopyPixels", m_copypixels->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Compositor", "BackFaceCulling", m_nobackcull->GetValue() ? "Off" : "On"); + + sel = m_wire->GetSelection(); + gf_cfg_set_key(cfg, "Compositor", "Wireframe", (sel==2) ? "WireOnSolid" : ( (sel==1) ? "WireOnly" : "WireNone" ) ); + sel = m_normals->GetSelection(); + gf_cfg_set_key(cfg, "Compositor", "DrawNormals", (sel==2) ? "PerVertex" : ( (sel==1) ? "PerFace" : "Never" ) ); + + gf_cfg_set_key(cfg, "core", "switch-vres", m_switchres->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "core", "hwvmem", m_usehwmem->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "core", "video-output", m_video->GetStringSelection().mb_str(wxConvUTF8)); + + + gf_cfg_set_key(cfg, "Audio", "ForceConfig", m_forcecfg->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Audio", "NoResync", m_noresync->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Audio", "DisableMultiChannel", m_nomulitch->GetValue() ? "yes" : "no"); + + gf_cfg_set_key(cfg, "Audio", "NumBuffers", wxString::Format(wxT("%d"), m_nbbuf->GetValue()).mb_str(wxConvUTF8) ); + gf_cfg_set_key(cfg, "Audio", "TotalDuration", wxString::Format(wxT("%d"), m_buflen->GetValue()).mb_str(wxConvUTF8) ); + gf_cfg_set_key(cfg, "core", "audio-output", m_audio->GetStringSelection().mb_str(wxConvUTF8)); +#ifdef WIN32 + if (m_notifs->IsEnabled()) + gf_cfg_set_key(cfg, "Audio", "DisableNotification", m_notifs->GetValue() ? "yes" : "no"); +#endif + + gf_cfg_set_key(cfg, "FontCache", "FontReader", m_font->GetStringSelection().mb_str(wxConvUTF8)); + gf_cfg_set_key(cfg, "FontCache", "FontDirectory", m_fontdir->GetLabel().mb_str(wxConvUTF8)); + switch (m_texturemode->GetSelection()) { + case 2: + gf_cfg_set_key(cfg, "Compositor", "TextureTextMode", "Always"); + break; + case 1: + gf_cfg_set_key(cfg, "Compositor", "TextureTextMode", "Never"); + break; + default: + gf_cfg_set_key(cfg, "Compositor", "TextureTextMode", "Default"); + break; + } + + gf_cfg_set_key(cfg, "Core", "CleanCache", m_cleancache->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "Core", "RestartFiles", m_restartcache->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "SAXLoader", "Progressive", m_progressive->GetValue() ? "yes" : "no"); + gf_cfg_set_key(cfg, "SAXLoader", "MaxDuration", m_sax_duration->GetLabel().mb_str(wxConvUTF8)); + gf_cfg_set_key(cfg, "Core", "CacheDirectory", m_cachedir->GetLabel().mb_str(wxConvUTF8)); + + + Bool force_rtsp = 0; + switch (m_port->GetSelection()) { + case 3: + gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "8080"); + force_rtsp = 1; + break; + case 2: + gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "80"); + force_rtsp = 1; + break; + case 1: + gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "7070"); + break; + default: + gf_cfg_set_key(cfg, "Streaming", "DefaultPort", "554"); + break; + } + + if (force_rtsp) { + gf_cfg_set_key(cfg, "Streaming", "RTPoverRTSP", "yes"); + } else { + gf_cfg_set_key(cfg, "Streaming", "RTPoverRTSP", m_rtsp->GetValue() ? "yes" : "no"); + if (!m_rtsp->GetValue()) gf_cfg_set_key(cfg, "Streaming", "ReorderSize", m_dorebuffer->GetValue() ? "30" : "0"); + } + + gf_cfg_set_key(cfg, "Streaming", "RTSPTimeout", m_timeout->GetValue().mb_str(wxConvUTF8)); + gf_cfg_set_key(cfg, "Network", "BufferLength", m_buffer->GetValue().mb_str(wxConvUTF8)); + if (m_dorebuffer->GetValue()) { + gf_cfg_set_key(cfg, "Network", "RebufferLength", m_rebuffer->GetValue().mb_str(wxConvUTF8)); + } else { + gf_cfg_set_key(cfg, "Network", "RebufferLength", "0"); + } + + gf_cfg_set_key(cfg, "StreamingCache", "KeepExistingFiles", m_overwrite->GetValue() ? "no" : "yes"); + if (m_usename->GetValue()) { + gf_cfg_set_key(cfg, "StreamingCache", "BaseFileName", m_recfile->GetValue().mb_str(wxConvUTF8)); + } else { + gf_cfg_set_key(cfg, "StreamingCache", "BaseFileName", NULL); + } + gf_cfg_set_key(cfg, "StreamingCache", "RecordDirectory", m_recdir->GetLabel().mb_str(wxConvUTF8)); + + + gf_term_set_option(m_pApp->m_term, GF_OPT_RELOAD_CONFIG, 1); +} + diff --git a/applications/deprecated/old_arch/osmo4_wx/wxGPACControl.h b/applications/deprecated/old_arch/osmo4_wx/wxGPACControl.h new file mode 100644 index 0000000..eb4226d --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/wxGPACControl.h @@ -0,0 +1,138 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 _OPTIONS_H +#define _OPTIONS_H + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include +#include + +enum +{ + ID_SELECT = 1000, + ID_APPLY, + + ID_MAKE_DEF, + ID_FORCE_AUDIO, + ID_AUDIO_DRIVER, + ID_FONT_DIR, + ID_CACHE_DIR, + ID_PROGRESSIVE, + ID_RTSP_PORT, + ID_RTP_OVER_RTSP, + ID_RTSP_REBUFFER, + ID_RECORD_DIR, + ID_USE_FILENAME, + ID_USE_PROXY, +}; + +class wxOsmo4Frame; +class wxGPACControl : public wxDialog +{ +public: + wxGPACControl(wxWindow *parent); + virtual ~wxGPACControl(); + +private: + DECLARE_EVENT_TABLE() + + wxOsmo4Frame *m_pApp; + + wxComboBox *m_select; + Bool m_bWas3D; + + void Apply(wxCommandEvent &event); + void OnSetSelection(wxCommandEvent &event); + void ForceAudio(wxCommandEvent &event); + void OnSetAudioDriver(wxCommandEvent &event); + void FontDir(wxCommandEvent &event); + void CacheDir(wxCommandEvent &event); + void OnProgressive(wxCommandEvent &event); + void OnUseProxy(wxCommandEvent &event); + void RTPoverRTSP(wxCommandEvent &event); + void Rebuffer(wxCommandEvent &event); + void OnSetRTSPPort(wxCommandEvent &event); + void OnUseFileName(wxCommandEvent &event); + void OnRecDir(wxCommandEvent &event); + void DoSelect(); + s32 m_sel; + void SetYUVLabel(); + + wxBoxSizer *s_header, *s_main, *s_general, *s_mpeg4, *s_mdec, *s_rend, *s_rend2d, *s_rend3d, *s_audio, *s_video, *s_font, *s_dnld, *s_stream, *s_rec; + + /*general section*/ + wxCheckBox *m_loop, *m_lookforsubs, *m_noconsole, *m_viewxmt; + /*MPEG-4 systems*/ + wxCheckBox *m_bifsalwaysdrawn, *m_singletime; + wxComboBox *m_lang, *m_thread; + /*media decoders*/ + wxComboBox *m_decaudio, *m_decvideo; + /*Rendering*/ + wxComboBox *m_fps, *m_aa, *m_draw_bounds; + wxCheckBox *m_use3D, *m_fast, *m_force_size; + /*Renderer 2D*/ + wxComboBox *m_graph; + wxCheckBox *m_noyuv, *m_direct, *m_scalable; + wxStaticText *m_yuvtxt; + /*Renderer 3D*/ + wxCheckBox *m_raster_outlines, *m_polyaa, *m_nobackcull, *m_emulpow2, *m_norectext, *m_copypixels; + wxComboBox *m_wire, *m_normals; + /*video*/ + wxComboBox *m_video; + wxCheckBox *m_switchres, *m_usehwmem; + /*audio*/ + wxSpinCtrl *m_nbbuf, *m_buflen; + wxComboBox *m_audio; + wxCheckBox *m_forcecfg, *m_noresync, *m_nomulitch; +#ifdef WIN32 + wxCheckBox *m_notifs; +#endif + /*font*/ + wxComboBox *m_font; + wxButton *m_fontdir; + wxComboBox *m_texturemode; + /*file download*/ + wxButton *m_cachedir; + wxCheckBox *m_cleancache, *m_restartcache, *m_progressive, *m_use_proxy; + wxTextCtrl *m_sax_duration, *m_proxy_name; + /*streaming*/ + wxComboBox *m_port; + wxCheckBox *m_rtsp, *m_reorder, *m_dorebuffer; + wxTextCtrl *m_timeout, *m_buffer, *m_rebuffer; + /*file recorder*/ + wxButton *m_recdir; + wxCheckBox *m_overwrite, *m_usename; + wxTextCtrl *m_recfile; +}; + +#endif + diff --git a/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.cpp b/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.cpp new file mode 100644 index 0000000..5d851bf --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.cpp @@ -0,0 +1,2392 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 "wxOsmo4.h" +#include "wxGPACControl.h" +#include "fileprops.h" +#include +#include +#include +#include +#include + + +IMPLEMENT_APP(wxOsmo4App) + +#include "osmo4.xpm" + +#include + + + + + +#include +#include + +#include "toolbar.xpm" + +#include "Playlist.h" + +#ifdef WIN32 +#define FRAME_H 140 +#else +#define FRAME_H 110 +#endif + + +wxString get_pref_browser(GF_Config *cfg) +{ + const char *sOpt = gf_cfg_get_key(cfg, "General", "Browser"); + if (sOpt) return wxString(sOpt, wxConvUTF8); + return wxEmptyString; + /* + #ifdef __WXMAC__ + return wxT("safari"); + #else + #ifdef WIN32 + return wxT("explorer.exe"); + #else + return wxT("mozilla"); + #endif + #endif*/ +} + + +IMPLEMENT_DYNAMIC_CLASS(wxGPACEvent, wxEvent ) + +wxGPACEvent::wxGPACEvent(wxWindow* win) +{ + SetEventType(GPAC_EVENT); + SetEventObject(win); + gpac_evt.type = 0; + to_url = wxT(""); +} +wxEvent *wxGPACEvent::Clone() const +{ + wxGPACEvent *evt = new wxGPACEvent((wxWindow *) m_eventObject); + evt->to_url = to_url; + evt->gpac_evt = gpac_evt; + return evt; +} + +#include + +/*open file dlg*/ +BEGIN_EVENT_TABLE(OpenURLDlg, wxDialog) + EVT_BUTTON(ID_URL_GO, OpenURLDlg::OnGo) +END_EVENT_TABLE() + +OpenURLDlg::OpenURLDlg(wxWindow *parent, GF_Config *cfg) + : wxDialog(parent, -1, wxString(wxT("Enter remote presentation location"))) +{ +#ifndef WIN32 + SetSize(430, 35); +#else + SetSize(430, 55); +#endif + Centre(); + m_url = new wxComboBox(this, -1, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN); + m_url->SetSize(0, 2, 340, 18, wxSIZE_AUTO); + m_go = new wxButton(this, ID_URL_GO, wxT("Go !")); +#ifndef WIN32 + m_go->SetSize(344, 2, 20, 18, wxSIZE_AUTO); +#else + m_go->SetSize(364, 2, 30, 18, wxSIZE_AUTO); +#endif + m_urlVal = wxT(""); + + m_cfg = cfg; + + const char *sOpt; + u32 i=0; + + while (1) { + sOpt = gf_cfg_get_key_name(m_cfg, "RecentFiles", i); + if (!sOpt) break; + m_url->Append(wxString(sOpt, wxConvUTF8) ); + i++; + } +} + +#define MAX_LAST_FILES 20 +void UpdateLastFiles(GF_Config *cfg, const char *URL) +{ + u32 nb_entries; + gf_cfg_set_key(cfg, "RecentFiles", URL, NULL); + gf_cfg_insert_key(cfg, "RecentFiles", URL, "", 0); + /*remove last entry if needed*/ + nb_entries = gf_cfg_get_key_count(cfg, "RecentFiles"); + if (nb_entries>MAX_LAST_FILES) { + gf_cfg_set_key(cfg, "RecentFiles", gf_cfg_get_key_name(cfg, "RecentFiles", nb_entries-1), NULL); + } +} + +void OpenURLDlg::OnGo(wxCommandEvent& event) +{ + m_urlVal = m_url->GetValue(); + UpdateLastFiles(m_cfg, m_urlVal.mb_str(wxConvUTF8)); + EndModal(wxID_OK); +} +/*end open file dlg*/ + +#ifdef WIN32 +u32 get_sys_col(int idx) +{ + u32 res; + DWORD val = GetSysColor(idx); + res = (val)&0xFF; + res<<=8; + res |= (val>>8)&0xFF; + res<<=8; + res |= (val>>16)&0xFF; + return res; +} +#endif + +static void wxOsmo4_progress_cbk(const void *usr, const char *title, u64 done, u64 total) +{ + if (!total) return; + wxOsmo4Frame *app = (wxOsmo4Frame *)usr; + s32 prog = (s32) ( (100 * (u64)done) / total); + if (app->m_last_prog < prog) { + app->m_last_prog = prog; + + if (prog<100) { + /*appears to crash wxWidgets / X11 when refreshing the text too often*/ + if (app->m_LastStatusTime + 200 > gf_sys_clock()) return; + char msg[1024]; + sprintf(msg, "%s %02d %%)", title, prog); + //app->SetStatus(wxString(msg, wxConvUTF8)); + } else { + app->SetStatus(wxT("Ready")); + app->m_last_prog = -1; + } + } +} + +Bool GPAC_EventProc(void *ptr, GF_Event *evt) +{ + wxCommandEvent event; + wxOsmo4Frame *app = (wxOsmo4Frame *)ptr; + + switch (evt->type) { + case GF_EVENT_DURATION: + app->m_duration = (u32) (evt->duration.duration*1000); + app->m_can_seek = evt->duration.can_seek; + if (app->m_duration<1100) app->m_can_seek = 0; + app->m_pProg->Enable(app->m_can_seek ? 1 : 0); + app->m_pPlayList->SetDuration((u32) evt->duration.duration); + break; + case GF_EVENT_MESSAGE: + { + const char *servName; + if (!evt->message.service || !strcmp(evt->message.service, app->m_pPlayList->GetURL().mb_str(wxConvUTF8))) { + servName = "main service"; + } else { + servName = evt->message.service; + } + if (!evt->message.message) return 0; + + if (evt->message.error) { + app->SetStatus(wxString(evt->message.message, wxConvUTF8) + wxT(" (") + wxString(servName, wxConvUTF8) + wxT(")") ); + if (!app->m_connected) app->m_pPlayList->SetDead(); + } + else if (!app->m_console_off) { + if (strstr(evt->message.message, "100 %")) { + app->SetStatus(wxT("")); + } else { + app->SetStatus(wxString(evt->message.message, wxConvUTF8) ); + } + } + +#if 0 + /*log*/ + 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: + { + const char *sTitle; + 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; + case GF_EVENT_KEYDOWN: + if (app->m_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(app->m_term) - 5*app->m_duration/100; + if (res<0) res=0; + gf_term_play_from_time(app->m_term, res, 0); + break; + case GF_KEY_RIGHT: + res = gf_term_get_time_in_ms(app->m_term) + 5*app->m_duration/100; + if ((u32) res>=app->m_duration) res = 0; + gf_term_play_from_time(app->m_term, res, 0); + break; + case GF_KEY_DOWN: + res = gf_term_get_time_in_ms(app->m_term) - 60000; + if (res<0) res=0; + gf_term_play_from_time(app->m_term, res, 0); + break; + case GF_KEY_UP: + res = gf_term_get_time_in_ms(app->m_term) + 60000; + if ((u32) res>=app->m_duration) res = 0; + gf_term_play_from_time(app->m_term, res, 0); + break; + } + } else if (evt->key.flags & GF_KEY_MOD_CTRL) { + switch (evt->key.key_code) { + case GF_KEY_LEFT: + app->m_pPlayList->PlayPrev(); + break; + case GF_KEY_RIGHT: + app->m_pPlayList->PlayNext(); + break; + } + } else { + switch (evt->key.key_code) { + case GF_KEY_HOME: + 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)) + gf_term_set_option(app->m_term, GF_OPT_FULLSCREEN, 0); + break; + default: + { + wxGPACEvent wxevt(app); + wxevt.gpac_evt = *evt; + app->AddPendingEvent(wxevt); + } + break; + } + } + break; + + case GF_EVENT_CONNECT: + { + wxGPACEvent wxevt(app); + wxevt.gpac_evt.type = GF_EVENT_CONNECT; + wxevt.gpac_evt.connect.is_connected = evt->connect.is_connected; + if (!evt->connect.is_connected) app->m_duration = 0; + app->AddPendingEvent(wxevt); + } + break; + case GF_EVENT_NAVIGATE: + { + wxGPACEvent wxevt(app); + wxevt.to_url = wxString(evt->navigate.to_url, wxConvUTF8); + wxevt.gpac_evt.type = evt->type; + app->AddPendingEvent(wxevt); + } + return 1; + case GF_EVENT_SET_CAPTION: + { + wxGPACEvent wxevt(app); + wxevt.to_url = wxString(evt->caption.caption, wxConvUTF8); + wxevt.gpac_evt.type = evt->type; + app->AddPendingEvent(wxevt); + } + return 1; + + case GF_EVENT_QUIT: + case GF_EVENT_VIEWPOINTS: + case GF_EVENT_STREAMLIST: + case GF_EVENT_SCENE_SIZE: +// case GF_EVENT_SIZE: + { + wxGPACEvent wxevt(app); + wxevt.gpac_evt = *evt; + app->AddPendingEvent(wxevt); + } + break; + case GF_EVENT_DBLCLICK: + gf_term_set_option(app->m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(app->m_term, GF_OPT_FULLSCREEN)); + return 0; + case GF_EVENT_MOUSEDOWN: + if (!gf_term_get_option(app->m_term, GF_OPT_FULLSCREEN)) { +#ifdef __WXGTK__ + app->m_pVisual->SetFocus(); +#else + app->m_pView->SetFocus(); +#endif + } + break; + case GF_EVENT_AUTHORIZATION: + { + wxGPACEvent wxevt(app); + wxTextEntryDialog user_d (0, + wxT("Please set the user name for connection"), + wxString(evt->auth.site_url, wxConvUTF8), + wxString(evt->auth.user, wxConvUTF8)); + if (user_d.ShowModal() != wxID_OK) + return 0; + strncpy(evt->auth.user, user_d.GetValue().mb_str(wxConvUTF8), 50); + wxPasswordEntryDialog passwd_d(0, + wxT("Please enter password"), + wxString(evt->auth.site_url, wxConvUTF8), + wxString(evt->auth.password, wxConvUTF8)); + if (passwd_d.ShowModal() != wxID_OK) + return 0; + strncpy(evt->auth.password, passwd_d.GetValue().mb_str(wxConvUTF8), 50); + return 1; + } + case GF_EVENT_SYS_COLORS: +#ifdef WIN32 + evt->sys_cols.sys_colors[0] = get_sys_col(COLOR_ACTIVEBORDER); + evt->sys_cols.sys_colors[1] = get_sys_col(COLOR_ACTIVECAPTION); + evt->sys_cols.sys_colors[2] = get_sys_col(COLOR_APPWORKSPACE); + evt->sys_cols.sys_colors[3] = get_sys_col(COLOR_BACKGROUND); + evt->sys_cols.sys_colors[4] = get_sys_col(COLOR_BTNFACE); + evt->sys_cols.sys_colors[5] = get_sys_col(COLOR_BTNHIGHLIGHT); + evt->sys_cols.sys_colors[6] = get_sys_col(COLOR_BTNSHADOW); + evt->sys_cols.sys_colors[7] = get_sys_col(COLOR_BTNTEXT); + evt->sys_cols.sys_colors[8] = get_sys_col(COLOR_CAPTIONTEXT); + evt->sys_cols.sys_colors[9] = get_sys_col(COLOR_GRAYTEXT); + evt->sys_cols.sys_colors[10] = get_sys_col(COLOR_HIGHLIGHT); + evt->sys_cols.sys_colors[11] = get_sys_col(COLOR_HIGHLIGHTTEXT); + evt->sys_cols.sys_colors[12] = get_sys_col(COLOR_INACTIVEBORDER); + evt->sys_cols.sys_colors[13] = get_sys_col(COLOR_INACTIVECAPTION); + evt->sys_cols.sys_colors[14] = get_sys_col(COLOR_INACTIVECAPTIONTEXT); + evt->sys_cols.sys_colors[15] = get_sys_col(COLOR_INFOBK); + evt->sys_cols.sys_colors[16] = get_sys_col(COLOR_INFOTEXT); + evt->sys_cols.sys_colors[17] = get_sys_col(COLOR_MENU); + evt->sys_cols.sys_colors[18] = get_sys_col(COLOR_MENUTEXT); + evt->sys_cols.sys_colors[19] = get_sys_col(COLOR_SCROLLBAR); + evt->sys_cols.sys_colors[20] = get_sys_col(COLOR_3DDKSHADOW); + evt->sys_cols.sys_colors[21] = get_sys_col(COLOR_3DFACE); + evt->sys_cols.sys_colors[22] = get_sys_col(COLOR_3DHIGHLIGHT); + evt->sys_cols.sys_colors[23] = get_sys_col(COLOR_3DLIGHT); + evt->sys_cols.sys_colors[24] = get_sys_col(COLOR_3DSHADOW); + evt->sys_cols.sys_colors[25] = get_sys_col(COLOR_WINDOW); + evt->sys_cols.sys_colors[26] = get_sys_col(COLOR_WINDOWFRAME); + evt->sys_cols.sys_colors[27] = get_sys_col(COLOR_WINDOWTEXT); + return 1; +#else + memset(evt->sys_cols.sys_colors, 0, sizeof(u32)*28); + return 1; +#endif + } + return 0; +} + + + +bool wxOsmo4App::OnInit() +{ +#ifdef __WXGTK__ + XSynchronize((Display *) wxGetDisplay(), 1); +#endif + wxFrame *frame = new wxOsmo4Frame(); + frame->Show(TRUE); + SetTopWindow(frame); + return true; +} + + +class myDropfiles : public wxFileDropTarget +{ +public: + myDropfiles() : wxFileDropTarget() {} + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames); + wxOsmo4Frame *m_pMain; +}; + +bool myDropfiles::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames) +{ + u32 count = filenames.GetCount(); + + if (count==1) { + const char *ext = strrchr(filenames.Item(0).mb_str(wxConvUTF8) , '.'); + /*if playing and sub d&d, open sub in current presentation*/ + if (m_pMain->m_connected && ext && ( !stricmp(ext, ".srt") || !stricmp(ext, ".sub") || !stricmp(ext, ".ttxt") || !stricmp(ext, ".xml") ) ) { + m_pMain->AddSubtitle(filenames.Item(0).mb_str(wxConvUTF8) , 1); + return TRUE; + } + } + + for (u32 i=0; im_pPlayList->QueueURL(filenames.Item(i)); + + m_pMain->m_pPlayList->RefreshList(); + m_pMain->m_pPlayList->PlayNext(); + return TRUE; +} + +bool GPACLogs::OnFrameClose(wxFrame *frame) +{ + Show(FALSE); + return 0; +} + +void wxOsmo4Frame::ShowViewWindow(Bool do_show) +{ + m_pView->Show(do_show ? 1 : 0); +#ifdef __WXGTK__ + //m_pView->Show(0); +#endif +} + +#ifdef __WXGTK__ +extern "C" { +#ifdef __WXGTK20__ + int gdk_x11_drawable_get_xid( void * ); + void *gdk_x11_drawable_get_xdisplay( void * ); +#endif + void *gtk_widget_get_parent_window( void * ); +} +#endif + + +void wxOsmo4Frame::CheckVideoOut() +{ + const char *sOpt = gf_cfg_get_key(m_user.config, "core", "video-output"); + void *os_handle = NULL; + void *os_display = NULL; + /*build a child window for embed display*/ + if (sOpt && stricmp(sOpt, "SDL Video Output")) { + if (m_user.os_window_handler) return; + m_bExternalView = 0; + +#ifdef __WXGTK__ + GtkWidget* widget = m_pVisual->GetHandle(); + +#ifdef __WXGTK20__ + os_handle = (void *) gdk_x11_drawable_get_xid(gtk_widget_get_parent_window(widget)); +#else + os_handle = (void *)*(int *)( (char *)gtk_widget_get_parent_window(widget) + 2 * sizeof(void *) ); +#endif + +#elif defined (WIN32) + os_handle = m_pView->GetHandle(); +#endif + if (os_handle) { + m_user.os_window_handler = os_handle; + m_user.os_display = os_display; + ShowViewWindow(1); + m_pView->SetSize(320, 240); + SetSize(wxSize(320, 240+FRAME_H)); + SetWindowStyle(wxDEFAULT_FRAME_STYLE); + DoLayout(320, 240); + return; + } + } + /*we're using SDL, don't use SDL hack*/ + m_bExternalView = 1; + m_user.os_window_handler = 0; + m_user.os_display = NULL; + SetSize(wxSize(320,FRAME_H)); + m_pView->SetSize(0, 0); + ShowViewWindow(0); + DoLayout(); + SetWindowStyle(wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER)); +} + +static void wxOsmo4_do_log(void *cbk, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list list) +{ + wxOsmo4Frame *osmo = (wxOsmo4Frame *)cbk; + + if (osmo->m_logs) { + vfprintf(osmo->m_logs, fmt, list); + fflush(osmo->m_logs); + } else { + ::wxVLogMessage(wxString(fmt, wxConvUTF8), list); + } +} + + +Bool wxOsmo4Frame::LoadTerminal() +{ + m_term = NULL; + memset(&m_user, 0, sizeof(GF_User)); + + /*locate exec dir for cfg file*/ + wxPathList pathList; + wxString currentDir(wxGetCwd()); + wxString abs_gpac_path = wxT(""); + char *gpac_cfg, *sep; + + ::wxLogMessage(wxT("Looking for GPAC configuration file")); + + /*load config*/ + Bool first_launch = 0; + m_user.config = gf_cfg_init(NULL, &first_launch); + + if (!m_user.config) { + wxMessageDialog(NULL, wxT("Cannot open GPAC configuration file"), wxT("Init error"), wxOK); + return 0; + } + + gpac_cfg = gf_cfg_get_filename(m_user.config); + sep = strrchr(gpac_cfg, '/'); + if (!sep) sep = strrchr(gpac_cfg, '\\'); + if (sep) sep[0] = 0; + strcpy(szAppPath, gpac_cfg); + if (sep) sep[0] = '/'; + + /*check log file*/ + const char *str = gf_cfg_get_key(m_user.config, "General", "LogFile"); + if (str) m_logs = gf_fopen(str, "wt"); + gf_log_set_callback(this, wxOsmo4_do_log); + + /*set log level*/ + gf_log_set_tools_levels( gf_cfg_get_key(m_user.config, "General", "Logs") ); + + gf_sys_init(GF_MemTrackerNone); + + ::wxLogMessage(wxT("GPAC configuration file opened - looking for modules")); + + m_user.modules = gf_modules_new(str, m_user.config); + /*initial launch*/ + if (!m_user.modules || !gf_modules_get_count(m_user.modules)) { + wxMessageDialog(NULL, wxT("No modules available - system cannot work"), wxT("Fatal Error"), wxOK).ShowModal(); + if (m_user.modules) gf_modules_del(m_user.modules); + gf_cfg_del(m_user.config); + m_user.config = NULL; + return 0; + } + + if (first_launch) { + u32 i; + for (i=0; iCanHandleURL(ifce, "test.test"); + gf_modules_close_interface((GF_BaseInterface *) ifce); + } + } + } + + + + ::wxLogMessage(wxT("%d modules found:"), gf_modules_get_count(m_user.modules)); + for (u32 i=0; im_pMain = this; + SetDropTarget(droptarget); + m_pLogs = new GPACLogs(this); + m_bGrabbed = 0; + + /*new menu bar*/ + wxMenuBar *b = new wxMenuBar(); + /*file*/ + wxMenu *menu = new wxMenu(); + 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); + wxMenu *smenu = new wxMenu(); + smenu->Append(ID_MCACHE_ENABLE, wxT("&Enable"), wxT("Turns Recorder On/Off")); + smenu->Append(ID_MCACHE_STOP, wxT("&Stop"), wxT("Stops recording and saves")); + smenu->Append(ID_MCACHE_ABORT, wxT("&Abort"), wxT("Stops recording and discards")); + menu->Append(0, wxT("&Streaming Cache"), smenu); + menu->AppendSeparator(); + menu->Append(FILE_COPY, wxT("&Copy\tCtrl+C"), wxT("Copy selected text")); + menu->Append(FILE_PASTE, wxT("&Paste\tCtrl+V"), wxT("Copy selected text")); + menu->AppendSeparator(); + menu->Append(FILE_QUIT, wxT("E&xit"), wxT("Quit the application")); + b->Append(menu, wxT("&File")); + /*view*/ + menu = new wxMenu(); + vp_list = new wxMenu(); + menu->Append(0, wxT("&Viewpoint"), vp_list); + smenu = new wxMenu(); + smenu->Append(ID_HEADLIGHT, wxT("Headlight"), wxT("Turns headlight on/off"), wxITEM_CHECK); + smenu->AppendSeparator(); + smenu->Append(ID_NAVIGATE_NONE, wxT("None"), wxT("Disables Navigation"), wxITEM_CHECK); + smenu->Append(ID_NAVIGATE_WALK, wxT("Walk"), wxT("Walk Navigation"), wxITEM_CHECK); + smenu->Append(ID_NAVIGATE_FLY, wxT("Fly"), wxT("Fly Navigation"), wxITEM_CHECK); + smenu->Append(ID_NAVIGATE_EXAMINE, wxT("Examine"), wxT("Examine Navigation"), wxITEM_CHECK); + smenu->Append(ID_NAVIGATE_PAN, wxT("Pan"), wxT("Pan Navigation"), wxITEM_CHECK); + smenu->Append(ID_NAVIGATE_SLIDE, wxT("Slide"), wxT("Slide Navigation"), wxITEM_CHECK); + smenu->Append(ID_NAVIGATE_ORBIT, wxT("Orbit"), wxT("Orbit Navigation"), wxITEM_CHECK); + smenu->Append(ID_NAVIGATE_GAME, wxT("Game"), wxT("Game Navigation"), wxITEM_CHECK); + smenu->AppendSeparator(); + wxMenu *ssmenu = new wxMenu(); + ssmenu->Append(ID_COLLIDE_NONE, wxT("None"), wxT("No Collision detection"), wxITEM_CHECK); + ssmenu->Append(ID_COLLIDE_REG, wxT("Regular"), wxT("Regular Collision detection"), wxITEM_CHECK); + ssmenu->Append(ID_COLLIDE_DISP, wxT("Displacement"), wxT("Collision detecion with camera displacement"), wxITEM_CHECK); + smenu->Append(0, wxT("&Collision"), ssmenu); + smenu->Append(ID_GRAVITY, wxT("Gravity"), wxT("Turns gravity on/off"), wxITEM_CHECK); + smenu->AppendSeparator(); + smenu->Append(ID_NAVIGATE_RESET, wxT("Reset"), wxT("Reset Navigation")); + + menu->Append(0, wxT("&Navigation"), smenu); + menu->AppendSeparator(); + menu->Append(VIEW_FULLSCREEN, wxT("&Fullscreen"), wxT("Toggles Fullscreen"), wxITEM_CHECK); + menu->Append(VIEW_ORIGINAL, wxT("&Original Size"), wxT("Restore original size")); + smenu = new wxMenu(); + smenu->Append(VIEW_AR_KEEP, wxT("Keep Original\tCtrl+1"), wxT("Keep original aspect ratio"), wxITEM_CHECK); + smenu->Append(VIEW_AR_FILL, wxT("Fill Screen\tCtrl+2"), wxT("Stretch presentation to fill screen"), wxITEM_CHECK); + smenu->Append(VIEW_AR_43, wxT("Ratio 4/3\tCtrl+3"), wxT("Force aspect ratio to 4/3"), wxITEM_CHECK); + smenu->Append(VIEW_AR_169, wxT("Ratio 16/9\tCtrl+4"), wxT("Force aspect ratio to 16/9"), wxITEM_CHECK); + menu->Append(0, wxT("&Aspect Ratio"), smenu); + smenu->Check(VIEW_AR_KEEP, 1); + menu->AppendSeparator(); + menu->Append(VIEW_OPTIONS, wxT("&Options"), wxT("View Options")); + menu->AppendSeparator(); + menu->Append(VIEW_RTI, wxT("&Resource Usage"), wxT("View Resource Usage"), wxITEM_CHECK); + menu->Append(VIEW_LOGS, wxT("&Logs"), wxT("View GPAC logs")); + b->Append(menu, wxT("&View")); + + /*play*/ + menu = new wxMenu(); + sel_menu = new wxMenu(); + sel_menu->Append(0, wxT("&Audio"), new wxMenu()); + sel_menu->Append(0, wxT("&Video"), new wxMenu()); + sel_menu->Append(0, wxT("&Subtitles"), new wxMenu()); + sel_menu->AppendSeparator(); + sel_menu->Append(ID_ADD_SUB, wxT("&Add Subtitle"), wxT("Adds subtitle")); + menu->Append(ID_STREAM_MENU, wxT("&Streams Selection"), sel_menu); + chap_menu = new wxMenu(); + menu->Append(ID_CHAPTER_MENU, wxT("&Chapters"), chap_menu); + + menu->AppendSeparator(); + menu->Append(VIEW_PLAYLIST, wxT("&Playlist\tCtrl+L"), wxT("Show navigation history as playlist"), wxITEM_CHECK); + menu->Append(ID_CLEAR_NAV, wxT("&Clear History"), wxT("Clear navigation history")); + menu->AppendSeparator(); + menu->Append(FILE_PLAY, wxT("&Play/Pause\tCtrl+P"), wxT("Play/Pause/Resume Presentation")); + menu->Append(FILE_STEP, wxT("&Step-by-Step\tCtrl+S"), wxT("Play/Pause/Resume Presentation")); + menu->Append(FILE_STOP, wxT("&Stop"), wxT("Stop Presentation")); + menu->AppendSeparator(); + menu->Append(FILE_RELOAD_CONFIG, wxT("&Reload Config\tCtrl+R"), wxT("Reload Configuration File")); + menu->Append(FILE_RELOAD, wxT("&Reload File\tCtrl+R"), wxT("Reload Presentation")); + b->Append(menu, wxT("&Play")); + + menu = new wxMenu(); + menu->Append(APP_SHORTCUTS, wxT("&Shortcuts"), wxT("Show keyboard shortcuts")); + menu->Append(APP_NAV_KEYS, wxT("&Navigation Keys"), wxT("Show navigation keys")); + menu->AppendSeparator(); + menu->Append(APP_ABOUT, wxT("&About"), wxT("Display information and copyright")); + b->Append(menu, wxT("&?")); + + SetMenuBar(b); + + m_pStatusbar = CreateStatusBar(1, 0, -1, wxT("statusBar")); + ws[0] = 60; + ws[1] = 70; + ws[2] = -1; + m_pStatusbar->SetFieldsCount(3, ws); + + SetStatusBarPane(2); + wxColour foreCol = m_pStatusbar->GetBackgroundColour(); + SetBackgroundColour(foreCol); + + + m_pTimer = new wxTimer(); + m_pTimer->SetOwner(this, ID_CTRL_TIMER); + m_bGrabbed = 0; + + /*create toolbar*/ + m_pToolBar = CreateToolBar(wxTB_FLAT|wxTB_HORIZONTAL); + m_pOpenFile = new wxBitmap(tool_open_file); + m_pPrev = new wxBitmap(tool_prev); + m_pNext = new wxBitmap(tool_next); + m_pPlay = new wxBitmap(tool_play); + m_pPause = new wxBitmap(tool_pause); + m_pStep = new wxBitmap(tool_step); + m_pStop = new wxBitmap(tool_stop); + m_pInfo = new wxBitmap(tool_info); + m_pConfig = new wxBitmap(tool_config); + m_pSW2D = new wxBitmap(tool_sw_2d); + m_pSW3D = new wxBitmap(tool_sw_3d); + + 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")); + m_pToolBar->AddControl(m_pPrevBut); + m_pNextBut = new wxMenuButton(m_pToolBar, FILE_NEXT, *m_pNext); + m_pNextBut->SetToolTip(wxT("Next Location")); + m_pToolBar->AddControl(m_pNextBut); + + m_pToolBar->AddSeparator(); + m_pToolBar->AddTool(FILE_PLAY, wxT(""), *m_pPlay, wxT("Play/Pause File")); + m_pToolBar->AddTool(FILE_STEP, wxT(""), *m_pStep, wxT("Step-by-Step Mode")); + m_pToolBar->AddTool(FILE_STOP, wxT(""), *m_pStop, wxT("Stop File")); + m_pToolBar->AddSeparator(); + m_pToolBar->AddTool(FILE_PROPERTIES, wxT(""), *m_pInfo, wxT("Show File Information")); + m_pToolBar->AddSeparator(); + m_pToolBar->AddTool(VIEW_OPTIONS, wxT(""), *m_pConfig, wxT("GPAC Configuration")); + m_pToolBar->AddTool(SWITCH_RENDER, wxT(""), *m_pSW3D, wxT("Switch 2D/3D Renderers")); + + m_pToolBar->Realize(); + + m_Address = new wxMyComboBox(this, ID_ADDRESS, wxT(""), wxPoint(50, 0), wxSize(80, 20)); + wxStaticText *add_text = new wxStaticText(this, -1, wxT("URL"), wxPoint(0, 0), wxSize(40, 20)); + add_text->SetBackgroundColour(foreCol); + + m_pAddBar = new wxBoxSizer(wxHORIZONTAL); + m_pAddBar->Add(add_text, 0, wxALIGN_TOP); + m_pAddBar->Add(m_Address, 2, wxALIGN_CENTER|wxEXPAND|wxADJUST_MINSIZE); + m_pAddBar->SetMinSize(80, 32); + m_pAddBar->Layout(); + + m_pProg = new wxSlider(this, ID_SLIDER, 0, 0, 1000, wxPoint(0, 22), wxSize(80, 22), wxSL_HORIZONTAL|wxSUNKEN_BORDER); + m_pProg->Enable(0); + m_pProg->Show(); + m_pProg->SetBackgroundColour(foreCol); + + m_pView = new wxWindow(this, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); + m_pView->SetBackgroundColour(wxColour(wxT("BLACK"))); +#ifdef __WXGTK__ + m_pVisual = new wxWindow(m_pView, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); + m_pVisual->SetBackgroundColour(wxColour(wxT("BLACK"))); +#endif + + m_pPlayList = new wxPlaylist(this); + m_pPlayList->SetIcon(wxIcon(osmo4)); + m_pPlayList->Hide(); + Raise(); + Show(); + + m_connected = 0; + if (!LoadTerminal()) { + Close(TRUE); + return; + } + + + + if (m_bExternalView) SetWindowStyle(wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER)); + DoLayout(320, 240); + UpdateRenderSwitch(); + + const char *sOpt = gf_cfg_get_key(m_user.config, "General", "ConsoleOff"); + m_console_off = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; + sOpt = gf_cfg_get_key(m_user.config, "General", "Loop"); + m_loop = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; + 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); + m_LastStatusTime = 0; + + m_pPrevBut->Refresh(); + m_pNextBut->Refresh(); + + wxOsmo4App &app = wxGetApp(); + if (app.argc>1) { + m_pPlayList->QueueURL(wxString(app.argv[1])); + m_pPlayList->RefreshList(); + m_pPlayList->PlayNext(); + } else { + char sPL[GF_MAX_PATH]; + strcpy((char *) sPL, szAppPath); +#ifdef WIN32 + strcat(sPL, "gpac_pl.m3u"); +#else + strcat(sPL, ".gpac_pl.m3u"); +#endif + m_pPlayList->OpenPlaylist(wxString(sPL, wxConvUTF8) ); + const char *sOpt = gf_cfg_get_key(m_user.config, "General", "PLEntry"); + if (sOpt) { + m_pPlayList->m_cur_entry = atoi(sOpt); + if (m_pPlayList->m_cur_entry>=(s32)gf_list_count(m_pPlayList->m_entries)) + m_pPlayList->m_cur_entry = -1; + } + + sOpt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + if (sOpt) { + gf_term_connect(m_term, sOpt); + m_bStartupFile = 1; + } + } + + sOpt = gf_cfg_get_key(m_user.config, "core", "audio-output"); + + if (!strcmp(sOpt, "No Audio Output Available")) { + ::wxLogMessage(wxT("WARNING: no audio output availble - make sure no other program is locking the sound card")); + SetStatus(wxT("No audio ouput available")); + + } else { + SetStatus(wxT("Ready")); + } +} + +wxOsmo4Frame::~wxOsmo4Frame() +{ + vp_list = NULL; + sel_menu = NULL; + + if (m_user.modules) gf_modules_del(m_user.modules); + gf_sys_close(); + if (m_user.config) gf_cfg_del(m_user.config); + + if (m_chapters_start) gf_free(m_chapters_start); + if (m_pView) delete m_pView; + + //m_pToolBar->RemoveTool(FILE_PREV); + //m_pToolBar->RemoveTool(FILE_NEXT); + + delete m_pPrevBut; + delete m_pNextBut; + delete m_pPlayList; + delete m_pTimer; + delete m_pOpenFile; + delete m_pPrev; + delete m_pNext; + delete m_pPlay; + delete m_pPause; + delete m_pStep; + delete m_pStop; + delete m_pInfo; + delete m_pConfig; + delete m_pSW2D; + delete m_pSW3D; +} + + +BEGIN_EVENT_TABLE(wxOsmo4Frame, wxFrame) + EVT_CLOSE(wxOsmo4Frame::OnCloseApp) + 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) + EVT_MENU(FILE_QUIT, wxOsmo4Frame::OnFileQuit) + EVT_MENU(VIEW_FULLSCREEN, wxOsmo4Frame::OnFullScreen) + EVT_MENU(VIEW_OPTIONS, wxOsmo4Frame::OnOptions) + EVT_MENU(VIEW_AR_KEEP, wxOsmo4Frame::OnViewARKeep) + EVT_MENU(VIEW_AR_FILL, wxOsmo4Frame::OnViewARFill) + EVT_MENU(VIEW_AR_169, wxOsmo4Frame::OnViewAR169) + EVT_MENU(VIEW_AR_43, wxOsmo4Frame::OnViewAR43) + EVT_MENU(VIEW_ORIGINAL, wxOsmo4Frame::OnViewOriginal) + EVT_MENU(VIEW_PLAYLIST, wxOsmo4Frame::OnPlaylist) + EVT_UPDATE_UI(VIEW_PLAYLIST, wxOsmo4Frame::OnUpdatePlayList) + EVT_MENU(FILE_COPY, wxOsmo4Frame::OnFileCopy) + EVT_UPDATE_UI(FILE_COPY, wxOsmo4Frame::OnUpdateFileCopy) + EVT_MENU(FILE_PASTE, wxOsmo4Frame::OnFilePaste) + EVT_UPDATE_UI(FILE_PASTE, wxOsmo4Frame::OnUpdateFilePaste) + + EVT_MENU(ID_CLEAR_NAV, wxOsmo4Frame::OnClearNav) + EVT_UPDATE_UI(ID_STREAM_MENU, wxOsmo4Frame::OnUpdateStreamMenu) + EVT_UPDATE_UI(ID_CHAPTER_MENU, wxOsmo4Frame::OnUpdateChapterMenu) + EVT_MENU(ID_ADD_SUB, wxOsmo4Frame::OnAddSub) + + EVT_MENU(ID_MCACHE_ENABLE, wxOsmo4Frame::OnCacheEnable) + EVT_UPDATE_UI(ID_MCACHE_ENABLE, wxOsmo4Frame::OnUpdateCacheEnable) + EVT_MENU(ID_MCACHE_STOP, wxOsmo4Frame::OnCacheStop) + 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) + EVT_MENU(APP_ABOUT, wxOsmo4Frame::OnAbout) + EVT_GPACEVENT(wxOsmo4Frame::OnGPACEvent) + EVT_TIMER(ID_CTRL_TIMER, wxOsmo4Frame::OnTimer) + EVT_COMMAND_SCROLL(ID_SLIDER, wxOsmo4Frame::OnSlide) + EVT_MENU(VIEW_LOGS, wxOsmo4Frame::OnLogs) + EVT_MENU(VIEW_RTI, wxOsmo4Frame::OnRTI) + + EVT_MENUBUTTON_OPEN(FILE_PREV, wxOsmo4Frame::OnFilePrevOpen) + EVT_MENUBUTTON_OPEN(FILE_NEXT, wxOsmo4Frame::OnFileNextOpen) + EVT_MENU(FILE_PREV, wxOsmo4Frame::OnNavPrev) + EVT_UPDATE_UI(FILE_PREV, wxOsmo4Frame::OnUpdateNavPrev) + EVT_MENU_RANGE(ID_NAV_PREV_0, ID_NAV_PREV_9, wxOsmo4Frame::OnNavPrevMenu) + EVT_MENU(FILE_NEXT, wxOsmo4Frame::OnNavNext) + EVT_UPDATE_UI(FILE_NEXT, wxOsmo4Frame::OnUpdateNavNext) + EVT_MENU_RANGE(ID_NAV_NEXT_0, ID_NAV_NEXT_9, wxOsmo4Frame::OnNavNextMenu) + + EVT_TOOL(FILE_PLAY, wxOsmo4Frame::OnFilePlay) + EVT_TOOL(FILE_STEP, wxOsmo4Frame::OnFileStep) + EVT_TOOL(FILE_STOP, wxOsmo4Frame::OnFileStop) + EVT_TOOL(SWITCH_RENDER, wxOsmo4Frame::OnRenderSwitch) + + 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_MENU_RANGE(ID_SETCHAP_FIRST, ID_SETCHAP_LAST, wxOsmo4Frame::OnChapterSel) + 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_MENU_RANGE(ID_NAVIGATE_NONE, ID_NAVIGATE_GAME, wxOsmo4Frame::OnNavigate) + 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_MENU(ID_HEADLIGHT, wxOsmo4Frame::OnHeadlight) + EVT_UPDATE_UI(ID_HEADLIGHT, wxOsmo4Frame::OnUpdateHeadlight) + EVT_MENU(ID_GRAVITY, wxOsmo4Frame::OnGravity) + 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(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) +END_EVENT_TABLE() + +void wxOsmo4Frame::DoLayout(u32 v_width, u32 v_height) +{ + wxPoint pos; + if (!m_Address || !m_pProg) return; + + int t_h = m_pToolBar->GetSize().y; + int a_h = m_pAddBar->GetSize().y; + int p_h = m_pProg->GetSize().y; + + if (m_bExternalView) { + if (v_width && v_height) { + m_orig_width = v_width; + m_orig_height = v_height; + } + SetClientSize(320, a_h+p_h+t_h); + m_pAddBar->SetDimension(0,0, 320, a_h); + m_pProg->SetSize(0, t_h+a_h, 320, p_h, 0); + return; + } + + if (v_width && v_height) { + m_orig_width = v_width; + m_orig_height = v_height; + v_height += a_h + p_h + t_h; + SetClientSize(v_width, v_height); + m_pView->SetSize(0, a_h+t_h, v_width, v_height, 0); + m_pAddBar->SetDimension(0, t_h, v_width, a_h); + m_pProg->SetSize(0, v_height - p_h, v_width, p_h, 0); + } + wxSize s = GetClientSize(); + s.y -= a_h + p_h + t_h; + if (m_pView) { + m_pView->SetSize(0, a_h+t_h, s.x, s.y, 0); + m_pAddBar->SetDimension(0, 0, s.x, a_h); + m_pAddBar->SetDimension(0, 0, s.x, a_h); + m_pAddBar->Layout(); + m_pProg->SetSize(0, s.y+t_h+a_h, s.x, p_h, 0); + if (m_term) gf_term_set_size(m_term, s.x, s.y); + } +} + +void wxOsmo4Frame::OnSize(wxSizeEvent &event) +{ + DoLayout(); +} + +void wxOsmo4Frame::OnCloseApp(wxCloseEvent &WXUNUSED(event)) +{ + if (m_term) gf_term_del(m_term); + m_term = NULL; + Destroy(); +} + + +wxString wxOsmo4Frame::GetFileFilter() +{ + u32 keyCount, i; + wxString sFiles, sSupportedFiles, sExts; + + /*force MP4 and 3GP files at beginning to make sure they are selected (Win32 bug with too large filters)*/ + sSupportedFiles = wxT("All Known Files|*.m3u;*.pls;*.mp4;*.3gp;*.3g2"); + sExts = wxT(""); + sFiles = wxT(""); + keyCount = gf_cfg_get_key_count(m_user.config, "MimeTypes"); + for (i=0; i=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); + sFiles += wxT("|"); + + wxString sOpt = wxString(szKeyList, wxConvUTF8); + while (1) { + wxString ext = sOpt.BeforeFirst(' '); + if (ext.Find('.')<0) { + if (first) first = 0; + else sFiles += wxT(";"); + sFiles += wxT("*."); + sFiles += ext; + wxString sext = ext; + sext += wxT(";"); + if (sSupportedFiles.Find(sext)<0) { + sSupportedFiles += wxT(";*."); + sSupportedFiles += ext; + } + } + if (sOpt==ext) break; + wxString rem = ext + wxT(" "); + sOpt.Replace(rem, wxT(""), TRUE); + } + sFiles += wxT("|"); + } + sSupportedFiles += wxT("|"); + sSupportedFiles += sFiles; + sSupportedFiles += wxT("M3U Playlists|*.m3u|ShoutCast Playlists|*.pls|All Files|*.*||"); + return sSupportedFiles; +} + +void wxOsmo4Frame::OnFileOpen(wxCommandEvent & WXUNUSED(event)) +{ + wxFileDialog dlg(this, wxT("Select file(s)"), wxT(""), wxT(""), GetFileFilter(), wxOPEN | wxMULTIPLE | wxCHANGE_DIR /*| wxHIDE_READONLY*/); + + if (dlg.ShowModal() != wxID_OK) return; + + wxArrayString stra; + dlg.GetPaths(stra); + if (stra.GetCount() == 1) { + m_pPlayList->Truncate(); + } else { + m_pPlayList->Clear(); + } + for (u32 i=0; iQueueURL(stra[i]); + + m_pPlayList->RefreshList(); + m_pPlayList->PlayNext(); +} + +void wxOsmo4Frame::OnFileOpenURL(wxCommandEvent & WXUNUSED(event)) +{ + OpenURLDlg dlg(this, m_user.config); + if (dlg.ShowModal()==wxID_OK) { + m_pPlayList->Truncate(); + m_pPlayList->QueueURL(dlg.m_urlVal); + m_pPlayList->RefreshList(); + m_pPlayList->PlayNext(); + } +} + +void wxOsmo4Frame::OnFileProperties(wxCommandEvent & WXUNUSED(event)) +{ + wxFileProps dlg(this); + dlg.SetIcon(wxIcon(osmo4)); + dlg.ShowModal(); +} + +void wxOsmo4Frame::OnFileReload(wxCommandEvent & WXUNUSED(event)) +{ + gf_term_disconnect(m_term); + m_connected = 0; + DoConnect(); +} + +void wxOsmo4Frame::OnFileReloadConfig(wxCommandEvent & WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_RELOAD_CONFIG, 1); +} + +void wxOsmo4Frame::OnFileQuit(wxCommandEvent & WXUNUSED(event)) +{ + Close(FALSE); +} + +void wxOsmo4Frame::OnViewOriginal(wxCommandEvent & WXUNUSED(event)) +{ + if (!m_bExternalView) { + DoLayout(m_orig_width, m_orig_height); + } else { + gf_term_set_option(m_term, GF_OPT_ORIGINAL_VIEW, 1); + } +} + +void wxOsmo4Frame::OnOptions(wxCommandEvent & WXUNUSED(event)) +{ + wxGPACControl dlg(this); + dlg.SetIcon(wxIcon(osmo4)); + dlg.ShowModal(); +} + +void wxOsmo4Frame::DoConnect() +{ + //if (m_connected) { gf_term_disconnect(m_term); m_connected = 0; } + + wxString url = m_pPlayList->GetURL(); + m_Address->SetValue(url); +#ifdef __WXGTK__ + m_pVisual->SetFocus(); +#else + m_pView->SetFocus(); +#endif + wxString txt = wxT("Osmo4 - "); + txt += m_pPlayList->GetDisplayName(); + SetTitle(txt); + m_bStartupFile = 0; + gf_term_connect(m_term, url.mb_str(wxConvUTF8)); +} + +void wxOsmo4Frame::OnLogs(wxCommandEvent & WXUNUSED(event)) +{ + m_pLogs->Show(); +} + +void wxOsmo4Frame::OnUpdateNeedsConnect(wxUpdateUIEvent &event) +{ + event.Enable(m_connected ? 1 : 0); +} + +void wxOsmo4Frame::OnUpdatePlay(wxUpdateUIEvent &event) +{ + event.Enable( (m_connected || m_pPlayList->HasValidEntries()) ? 1 : 0); +} + +void wxOsmo4Frame::OnUpdateFullScreen(wxUpdateUIEvent &event) +{ + if (m_connected) { + event.Enable(1); + event.Check(gf_term_get_option(m_term, GF_OPT_FULLSCREEN) ? 1 : 0); + } else { + event.Enable(0); + } +} + +void wxOsmo4Frame::OnFullScreen(wxCommandEvent & WXUNUSED(event)) +{ + Bool isFS = gf_term_get_option(m_term, GF_OPT_FULLSCREEN) ? 1 : 0; + gf_term_set_option(m_term, GF_OPT_FULLSCREEN, isFS ? 0 : 1); +} + +void wxOsmo4Frame::OnViewARKeep(wxCommandEvent & WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); +} +void wxOsmo4Frame::OnViewARFill(wxCommandEvent & WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); +} +void wxOsmo4Frame::OnViewAR169(wxCommandEvent & WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); +} +void wxOsmo4Frame::OnViewAR43(wxCommandEvent & WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); +} + +void wxOsmo4Frame::OnUpdateAR(wxUpdateUIEvent &event) +{ + if (!m_connected) { + event.Enable(0); + return; + } + event.Enable(1); + 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)) + event.Check(1); + 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)) + event.Check(1); + else event.Check(0); +} + +void wxOsmo4Frame::OnShortcuts(wxCommandEvent & WXUNUSED(event)) +{ + wxMessageDialog dlg(this, + wxT("Shortcuts with focus on main frame:\n") + wxT("Open File: Ctrl + O\n") + wxT("Show File Information: Ctrl + I\n") + wxT("Reload File: Ctrl + R\n") + wxT("Pause/Resume File: Ctrl + P\n") + wxT("Step by Step: Ctrl + S\n") + wxT("Fullscreen On/Off: Alt + Return\n") + wxT("View Playlist: Ctrl + L\n") + wxT("Aspect Ratio Normal: Ctrl + 1\n") + wxT("Aspect Ratio Fill: Ctrl + 2\n") + wxT("Aspect Ratio 4/3: Ctrl + 3\n") + wxT("Aspect Ratio 16/9: Ctrl + 4\n") + 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 +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); + + dlg.ShowModal(); +} + +void wxOsmo4Frame::OnNavInfo(wxCommandEvent & WXUNUSED(event)) +{ + wxMessageDialog dlg(this, + wxT("* Walk & Fly modes:\n") + wxT("\tH move: H pan - V move: Z-translate - V move+CTRL or Wheel: V pan - Right Click (Walk only): Jump\n") + wxT("\tleft/right: H pan - left/right+CTRL: H translate - up/down: Z-translate - up/down+CTRL: V pan\n") + wxT("* Pan mode:\n") + wxT("\tH move: H pan - V move: V pan - V move+CTRL or Wheel: Z-translate\n") + wxT("\tleft/right: H pan - left/right+CTRL: H translate - up/down: V pan - up/down+CTRL: Z-translate\n") + wxT("* Slide mode:\n") + wxT("\tH move: H translate - V move: V translate - V move+CTRL or Wheel: Z-translate\n") + wxT("\tleft/right: H translate - left/right+CTRL: H pan - up/down: V translate - up/down+CTRL: Z-translate\n") + wxT("* Examine & Orbit mode:\n") + wxT("\tH move: Y-Axis rotate - H move+CTRL: No move - V move: X-Axis rotate - V move+CTRL or Wheel: Z-translate\n") + wxT("\tleft/right: Y-Axis rotate - left/right+CTRL: H translate - up/down: X-Axis rotate - up/down+CTRL: Y-translate\n") + wxT("* VR mode:\n") + wxT("\tH move: H pan - V move: V pan - V move+CTRL or Wheel: Camera Zoom\n") + wxT("\tleft/right: H pan - up/down: V pan - up/down+CTRL: Camera Zoom\n") + wxT("* Game mode (press END to escape):\n") + wxT("\tH move: H pan - V move: V pan\n") + wxT("\tleft/right: H translate - up/down: Z-translate\n") + wxT("\n") + wxT("* All 3D modes: CTRL+PGUP/PGDOWN will zoom in/out camera (field of view) \n") + wxT("\n") + wxT("*Slide Mode in 2D:\n") + wxT("\tH move: H translate - V move: V translate - V move+CTRL: zoom\n") + wxT("\tleft/right: H translate - up/down: V translate - up/down+CTRL: zoom\n") + wxT("*Examine Mode in 2D (3D renderer only):\n") + wxT("\tH move: Y-Axis rotate - V move: X-Axis rotate\n") + wxT("\tleft/right: Y-Axis rotate - up/down: X-Axis rotate\n") + wxT("\n") + wxT("HOME: reset navigation to last viewpoint (2D or 3D navigation)\n") + wxT("SHIFT key in all modes: fast movement\n") + + , wxT("3D navigation keys (\'H\'orizontal and \'V\'ertical) used in GPAC") + , wxOK ); + dlg.ShowModal(); +} + + +/*open file dlg*/ +class AboutDlg : public wxDialog { +public: + AboutDlg(wxWindow *parent); + +private: + wxStaticText *m_info; + wxButton *m_close; + void OnClose(wxCommandEvent& event); + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(AboutDlg, wxDialog) + EVT_BUTTON(ID_ABOUT_CLOSE, AboutDlg::OnClose) +END_EVENT_TABLE() + +AboutDlg::AboutDlg(wxWindow *parent) + : wxDialog(parent, -1, wxString(wxT("GPAC/Osmo4 V ")wxT(GPAC_FULL_VERSION))) +{ + SetSize(220, 320); + Centre(); + wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); + + m_info = new wxStaticText(this, -1, wxT("http://gpac.io"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE); + sizer->Add(m_info, 1, wxEXPAND|wxADJUST_MINSIZE, 0); + m_close = new wxButton(this, ID_ABOUT_CLOSE, wxT("Close"), wxDefaultPosition, wxSize(120, 20)); + sizer->Add(m_close, 0, wxEXPAND, 0); + + SetIcon(wxIcon(osmo4)); + m_info->SetLabel( + wxT("Osmo4 Player\n") + wxT("GPAC Multimedia Framework\n") + wxT("\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") + wxT("Authors: Jean Le Feuvre\n") + wxT("(c) Telecom ParisTech 2005-2012\n") + wxT("All Rights Reserved\n") + wxT("http://gpac.io\n") + wxT("\n") + wxT(" ** With Many Thanks To ** \n\n") + wxT("Mozilla SpiderMonkey (JavaScript)\n") + wxT("The FreeType Project\n") + wxT("The PNG Group, The I.J.G.\n") + wxT("FFMPEG, FAAD, XVID, MAD\n") + ); + + SetSizer(sizer); + sizer->Fit(this); +} +void AboutDlg::OnClose(wxCommandEvent& WXUNUSED(event)) +{ + Close(FALSE); +} + +void wxOsmo4Frame::OnAbout(wxCommandEvent & WXUNUSED(event)) +{ + AboutDlg dlg(this); + dlg.ShowModal(); +} + + +void wxOsmo4Frame::OnGPACEvent(wxGPACEvent &event) +{ + wxString cmd; + wxCommandEvent evt; + if (!m_term) return; + + switch (event.gpac_evt.type) { + case GF_EVENT_NAVIGATE: + if (gf_term_is_supported_url(m_term, event.to_url.mb_str(wxConvUTF8), 1, 0)) { + char *str = gf_url_concatenate(m_pPlayList->GetURL().mb_str(wxConvUTF8), event.to_url.mb_str(wxConvUTF8)); + if (str) { + m_pPlayList->Truncate(); + m_pPlayList->QueueURL(wxString(str, wxConvUTF8)); + m_pPlayList->RefreshList(); + gf_free(str); + m_pPlayList->PlayNext(); + } + return; + } + cmd = get_pref_browser(m_user.config); + if (cmd.IsEmpty()) { + cmd += wxT(" "); + cmd += event.to_url; + wxExecute(cmd); + } else { +#ifdef wxLaunchDefaultBrowser + wxLaunchDefaultBrowser(event.to_url); +#endif + } + break; + case GF_EVENT_QUIT: + Close(TRUE); + break; + case GF_EVENT_SET_CAPTION: + SetTitle(event.to_url); + break; + case GF_EVENT_CONNECT: + BuildStreamList(0); + ConnectAcknowledged(event.gpac_evt.connect.is_connected); + break; + case GF_EVENT_KEYDOWN: + if (!(event.gpac_evt.key.flags & GF_KEY_MOD_CTRL)) return; + switch (event.gpac_evt.key.key_code) { + case GF_KEY_R: + gf_term_set_option(m_term, GF_OPT_REFRESH, 1); + break; + case GF_KEY_P: + OnFilePlay(evt); + break; + case GF_KEY_S: + OnFileStep(evt); + break; + } + break; + case GF_EVENT_SCENE_SIZE: + m_orig_width = event.gpac_evt.size.width; + m_orig_height = event.gpac_evt.size.height; + case GF_EVENT_SIZE: + if (! gf_term_get_option(m_term, GF_OPT_FULLSCREEN)) { + DoLayout(event.gpac_evt.size.width, event.gpac_evt.size.height); + } + break; + case GF_EVENT_VIEWPOINTS: + BuildViewList(); + break; + case GF_EVENT_STREAMLIST: + BuildStreamList(0); + break; + } +} + + +static wxString format_time(u32 duration, u32 timescale) +{ + u32 h, m, s; + Float time = duration; + time /= timescale; + time *= 1000; + h = (u32) (time / 1000 / 3600); + m = (u32) (time / 1000 / 60 - h*60); + s = (u32) (time / 1000 - h*3600 - m*60); + return wxString::Format(wxT("%02d:%02d:%02d"), h, m, s); +} + +void wxOsmo4Frame::SetStatus(wxString str) +{ + //m_pStatusbar->SetStatusText(str, 2); + m_LastStatusTime = gf_sys_clock(); +} + +#define RTI_REFRESH_MS 500 +void wxOsmo4Frame::OnRTI(wxCommandEvent & event) +{ + m_bViewRTI = event.IsChecked(); + if (m_bViewRTI) { + 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_pTimer->Stop(); + } +} + +void wxOsmo4Frame::OnTimer(wxTimerEvent& WXUNUSED(event)) +{ + wxString str; + u32 now; + if (m_LastStatusTime) { + now = gf_sys_clock(); + if (now > 1000+m_LastStatusTime) { + m_LastStatusTime = 0; + m_pStatusbar->SetStatusText(wxT("Ready"), 2); + } + } + + if (m_bViewRTI) { + GF_SystemRTInfo rti; + 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" ), + rti.total_cpu_usage, rti.process_cpu_usage, rti.gpac_memory/1024); + + m_pStatusbar->SetStatusText(str, 2); + } + if (!m_connected) return; + + now = gf_term_get_time_in_ms(m_term); + if (!now) return; + + if (!m_duration) { + str = format_time(now, 1000); + m_pStatusbar->SetStatusText(str); + str = wxString::Format(wxT("FPS %.2f"), gf_term_get_framerate(m_term, 0)); + m_pStatusbar->SetStatusText(str, 1); + return; + } +#ifdef __WXGTK__ + if (m_bGrabbed) { + u32 now = gf_sys_clock() - m_last_grab_time; + if (now>200) { + m_bGrabbed = 0; + Double res = (Double) m_last_grab_pos; + res /= 1000; + res *= m_duration; + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + m_bToReset = 0; + } + gf_term_play_from_time(m_term, (u32) res, 0); + return; + } + } +#endif + + if (!m_bGrabbed) { + if ((now >= m_duration + 500) && gf_term_get_option(m_term, GF_OPT_IS_FINISHED)) { + m_pPlayList->PlayNext(); + } else { + Double val = now * 1000; + val /= m_duration; + m_pProg->SetValue((val<=1000) ? (u32) val : 1000); + + if (0) { + str = format_time(m_duration-now, 1000); + } else { + str = format_time(now, 1000); + } + m_pStatusbar->SetStatusText(str); + str = wxString::Format(wxT("FPS %.2f"), gf_term_get_framerate(m_term, 0)); + m_pStatusbar->SetStatusText(str, 1); + } + } +} + +void wxOsmo4Frame::ConnectAcknowledged(Bool bOk) +{ + if (bOk) { + m_pTimer->Start(RTI_REFRESH_MS, 0); + m_connected = 1; + m_bToReset = 0; + UpdatePlay(); + BuildChapterList(0); + } else { + BuildChapterList(1); + if (!m_connected) { + UpdatePlay(); + m_pTimer->Stop(); + //m_pProg->Enable(0); + } + } +} + +void wxOsmo4Frame::OnFilePlay(wxCommandEvent & WXUNUSED(event)) +{ + wxCommandEvent evt; + if (m_connected) { + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + if (m_bToReset) { + m_pTimer->Start(100, 0); + gf_term_play_from_time(m_term, 0, 0); + } + m_bToReset = 0; + UpdatePlay(); + } else { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + UpdatePlay(); + } + } else { + m_pPlayList->Play(); + } +} + +void wxOsmo4Frame::OnFileStep(wxCommandEvent & WXUNUSED(event)) +{ + wxCommandEvent evt; + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); + UpdatePlay(); +} + +void wxOsmo4Frame::OnFileStop(wxCommandEvent &WXUNUSED(event)) +{ + Stop(); +} + +void wxOsmo4Frame::Stop() +{ + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + } + m_bToReset = 1; + m_pTimer->Stop(); + m_pProg->SetValue(0); + UpdatePlay(); +} + +void wxOsmo4Frame::OnSlide(wxScrollEvent &event) +{ + if (!m_duration) return; + + /*wxSlider on GTK is buggy, so track a release timeout*/ +#ifdef __WXGTK__ + m_last_grab_time = gf_sys_clock(); + m_bGrabbed = 1; + m_last_grab_pos = event.GetPosition(); + Double now = (Double) m_last_grab_pos; + now /= 1000; + now *= m_duration; + wxString str = format_time((u32) (now), 1000); + m_pStatusbar->SetStatusText(str); + if (!m_pTimer->IsRunning()) m_pTimer->Start(100, 0); +#else + s32 type = event.GetEventType(); + if (type == wxEVT_SCROLL_THUMBTRACK) { + m_bGrabbed = 1; + Double now = (Double) event.GetPosition(); + now /= 1000; + 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(); + res /= 1000; + res *= m_duration; + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { + gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + m_bToReset = 0; + if (!m_pTimer->IsRunning()) m_pTimer->Start(100, 0); + } + gf_term_play_from_time(m_term, (u32) res, 0); + } +#endif +} + + +void wxOsmo4Frame::BuildViewList() +{ + if (!vp_list || !m_connected) return; + + while (vp_list->GetMenuItemCount()) { + wxMenuItem* it = vp_list->FindItemByPosition(0); + vp_list->Delete(it); + } + + s32 id = ID_VIEWPOINT_FIRST; + nb_viewpoints = 0; + while (1) { + const char *szName; + Bool bound; + GF_Err e = gf_term_get_viewpoint(m_term, nb_viewpoints+1, &szName, &bound); + if (e) break; + if (szName) { + vp_list->AppendCheckItem(id+nb_viewpoints, wxString(szName, wxConvUTF8) ); + } else { + vp_list->AppendCheckItem(id+nb_viewpoints, wxString::Format(wxT("Viewpoint #%d"), nb_viewpoints+1) ); + } + nb_viewpoints++; + } +} + +void wxOsmo4Frame::OnViewport(wxCommandEvent & event) +{ + u32 ID = event.GetId() - ID_VIEWPOINT_FIRST; + gf_term_set_viewpoint(m_term, ID+1, NULL); +} + +void wxOsmo4Frame::OnUpdateViewport(wxUpdateUIEvent & event) +{ + u32 ID = event.GetId() - ID_VIEWPOINT_FIRST; + const char *szName; + Bool bound; + gf_term_get_viewpoint(m_term, ID+1, &szName, &bound); + event.Enable(1); + if (bound) event.Check(1); +} + +void wxOsmo4Frame::OnNavigate(wxCommandEvent & event) +{ + switch (event.GetId()) { + case ID_NAVIGATE_NONE: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_NONE); + break; + case ID_NAVIGATE_WALK: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_WALK); + break; + case ID_NAVIGATE_FLY: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_FLY); + break; + case ID_NAVIGATE_EXAMINE: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_EXAMINE); + break; + case ID_NAVIGATE_PAN: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_PAN); + break; + case ID_NAVIGATE_SLIDE: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_SLIDE); + break; + case ID_NAVIGATE_ORBIT: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_ORBIT); + break; + case ID_NAVIGATE_GAME: + gf_term_set_option(m_term, GF_OPT_NAVIGATION, GF_NAVIGATE_GAME); + break; + } +} +void wxOsmo4Frame::OnNavigateReset(wxCommandEvent & WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_NAVIGATION_TYPE, 0); +} +void wxOsmo4Frame::OnUpdateNavigation(wxUpdateUIEvent & event) +{ + u32 ID = event.GetId(); + event.Enable(0); + if (!m_connected) return; + u32 type = gf_term_get_option(m_term, GF_OPT_NAVIGATION_TYPE); + bool enable = type ? 1 : 0; + + u32 mode = gf_term_get_option(m_term, GF_OPT_NAVIGATION); + /*common 2D/3D modes*/ + if (ID==ID_NAVIGATE_NONE) { + event.Enable(enable); + event.Check(mode ? 0 : 1); + } + else if (ID==ID_NAVIGATE_EXAMINE) { + event.Enable(enable); + event.Check((mode==GF_NAVIGATE_EXAMINE) ? 1 : 0); + } + 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); + 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); + else if (ID==ID_NAVIGATE_ORBIT) event.Check((mode==GF_NAVIGATE_ORBIT) ? 1 : 0); + else if (ID==ID_NAVIGATE_GAME) event.Check((mode==GF_NAVIGATE_GAME) ? 1 : 0); +} + +void wxOsmo4Frame::OnRenderSwitch(wxCommandEvent &WXUNUSED(event)) +{ + const char *opt = gf_cfg_get_key(m_user.config, "Compositor", "ForceOpenGL"); + Bool use_gl = (opt && !stricmp(opt, "yes")) ? 1 : 0; + gf_cfg_set_key(m_user.config, "Compositor", "ForceOpenGL", use_gl ? "no" : "yes"); + + gf_term_set_option(m_term, GF_OPT_USE_OPENGL, !use_gl); + + UpdateRenderSwitch(); +} + +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")) + 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")); + +#ifdef WIN32 + /*there's a display bug with the menubtn, remove and reinsert*/ + m_pToolBar->RemoveTool(FILE_PREV); + m_pToolBar->RemoveTool(FILE_NEXT); + m_pToolBar->InsertControl(2, m_pPrevBut); + m_pToolBar->InsertControl(3, m_pNextBut); +#endif + m_pToolBar->Realize(); +} + +void wxOsmo4Frame::UpdatePlay() +{ + m_pToolBar->RemoveTool(FILE_PLAY); + if (m_connected) { + if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) + m_pToolBar->InsertTool(5, FILE_PLAY, *m_pPlay, wxNullBitmap, FALSE, NULL, wxT("Pause File")); + else + m_pToolBar->InsertTool(5, FILE_PLAY, *m_pPause, wxNullBitmap, FALSE, NULL, wxT("Play File")); + } else { + m_pToolBar->InsertTool(5, FILE_PLAY, *m_pPlay, wxNullBitmap, FALSE, NULL, wxT("Pause File")); + } + +#ifdef WIN32 + /*there's a display bug with the menubtn, remove and reinsert*/ + m_pToolBar->RemoveTool(FILE_PREV); + m_pToolBar->RemoveTool(FILE_NEXT); + m_pToolBar->InsertControl(2, m_pPrevBut); + m_pToolBar->InsertControl(3, m_pNextBut); +#endif + m_pToolBar->Realize(); +} + +void wxOsmo4Frame::OnCollide(wxCommandEvent & event) +{ + u32 ID = event.GetId(); + if (ID==ID_COLLIDE_NONE) gf_term_set_option(m_term, GF_OPT_COLLISION, GF_COLLISION_NONE); + else if (ID==ID_COLLIDE_REG) gf_term_set_option(m_term, GF_OPT_COLLISION, GF_COLLISION_NORMAL); + else if (ID==ID_COLLIDE_DISP) gf_term_set_option(m_term, GF_OPT_COLLISION, GF_COLLISION_DISPLACEMENT); +} +void wxOsmo4Frame::OnUpdateCollide(wxUpdateUIEvent & event) +{ + u32 ID = event.GetId(); + event.Enable(0); + if (!m_connected) return; + event.Enable(1); + u32 mode = gf_term_get_option(m_term, GF_OPT_COLLISION); + if (ID==ID_COLLIDE_NONE) { + event.Check((mode==GF_COLLISION_NONE) ? 1 : 0); + } + else if (ID==ID_COLLIDE_REG) { + event.Check((mode==GF_COLLISION_NORMAL) ? 1 : 0); + } + else if (ID==ID_COLLIDE_DISP) { + event.Check((mode==GF_COLLISION_DISPLACEMENT) ? 1 : 0); + } +} + +void wxOsmo4Frame::OnHeadlight(wxCommandEvent &WXUNUSED(event)) +{ + Bool val = !gf_term_get_option(m_term, GF_OPT_HEADLIGHT); + gf_term_set_option(m_term, GF_OPT_HEADLIGHT, val); +} +void wxOsmo4Frame::OnUpdateHeadlight(wxUpdateUIEvent & event) +{ + event.Enable(0); + if (!m_connected) return; + u32 type = gf_term_get_option(m_term, GF_OPT_NAVIGATION_TYPE); + if (type!=GF_NAVIGATE_TYPE_3D) return; + + event.Enable(1); + event.Check(gf_term_get_option(m_term, GF_OPT_HEADLIGHT) ? 1 : 0); +} +void wxOsmo4Frame::OnGravity(wxCommandEvent & WXUNUSED(event)) +{ + Bool val = gf_term_get_option(m_term, GF_OPT_GRAVITY) ? 0 : 1; + gf_term_set_option(m_term, GF_OPT_GRAVITY, val); +} +void wxOsmo4Frame::OnUpdateGravity(wxUpdateUIEvent & event) +{ + event.Enable(0); + if (!m_connected) return; + u32 type = gf_term_get_option(m_term, GF_OPT_NAVIGATION_TYPE); + if (type!=GF_NAVIGATE_TYPE_3D) return; + type = gf_term_get_option(m_term, GF_OPT_NAVIGATION); + if (type != GF_NAVIGATE_WALK) return; + event.Enable(1); + event.Check(gf_term_get_option(m_term, GF_OPT_GRAVITY) ? 1 : 0); +} + + +BEGIN_EVENT_TABLE(wxMyComboBox, wxComboBox) + EVT_KEY_UP(wxMyComboBox::OnKeyUp) +END_EVENT_TABLE() + +void wxMyComboBox::OnKeyUp(wxKeyEvent &event) +{ + if (event.GetKeyCode()==WXK_RETURN) { + event.Skip(); + wxCommandEvent evt; + evt.SetEventType(wxEVT_COMMAND_COMBOBOX_SELECTED); + evt.SetEventObject(this); + evt.SetId(GetId()); + GetParent()->AddPendingEvent(evt); + } +} + + +void wxOsmo4Frame::ReloadURLs() +{ + const char *sOpt; + u32 i=0; + + m_Address->Clear(); + while (1) { + sOpt = gf_cfg_get_key_name(m_user.config, "RecentFiles", i); + if (!sOpt) break; + m_Address->Append(wxString(sOpt, wxConvUTF8) ); + i++; + } +} + +void wxOsmo4Frame::SelectionReady() +{ + wxString urlVal = m_Address->GetValue(); + if (urlVal.Find(wxT("://"))>0) { + UpdateLastFiles(m_user.config, urlVal.mb_str(wxConvUTF8)); + ReloadURLs(); + } + m_pPlayList->Truncate(); + m_pPlayList->QueueURL(urlVal); + m_pPlayList->RefreshList(); + m_pPlayList->PlayNext(); +} + +void wxOsmo4Frame::OnURLSelect(wxCommandEvent &WXUNUSED(event)) +{ + SelectionReady(); +} + +void wxOsmo4Frame::OnPlaylist(wxCommandEvent &WXUNUSED(event)) +{ + assert(m_pPlayList); + m_pPlayList->Show(m_pPlayList->IsShown() ? 0 : 1); +} + +void wxOsmo4Frame::OnUpdatePlayList(wxUpdateUIEvent & event) +{ + event.Enable(1); + event.Check(m_pPlayList->IsShown() ? 1 : 0); +} + +void wxOsmo4Frame::OnFilePrevOpen(wxNotifyEvent & event) +{ + u32 count = gf_list_count(m_pPlayList->m_entries); + u32 start = m_pPlayList->m_cur_entry - 1; + wxMenu *popup = new wxMenu(); + + for (u32 i=0; i<10; i++) { + if (i > start) break; + if (start - i >= count) break; + PLEntry *ple = (PLEntry *) gf_list_get(m_pPlayList->m_entries, start - i); + popup->Append(ID_NAV_PREV_0 + i, wxString(ple->m_disp_name, wxConvUTF8) ); + } + m_pPrevBut->AssignMenu(popup); +} + +void wxOsmo4Frame::OnFileNextOpen(wxNotifyEvent & event) +{ + u32 count = gf_list_count(m_pPlayList->m_entries); + wxMenu *popup = new wxMenu(); + u32 start = m_pPlayList->m_cur_entry + 1; + for (u32 i=0; i<10; i++) { + if (start + i >= count) break; + PLEntry *ple = (PLEntry *) gf_list_get(m_pPlayList->m_entries, start + i); + popup->Append(ID_NAV_NEXT_0 + i, wxString(ple->m_disp_name, wxConvUTF8) ); + } + m_pNextBut->AssignMenu(popup); +} + +void wxOsmo4Frame::OnNavPrev(wxCommandEvent &WXUNUSED(event)) +{ + if (m_pPlayList->m_cur_entry<=0) return; + m_pPlayList->PlayPrev(); +} +void wxOsmo4Frame::OnUpdateNavPrev(wxUpdateUIEvent & event) +{ + if (m_pPlayList->m_cur_entry<=0) event.Enable(0); + else event.Enable(TRUE); +} +void wxOsmo4Frame::OnNavPrevMenu(wxCommandEvent &event) +{ + u32 ID = event.GetId() - ID_NAV_PREV_0; + s32 prev = m_pPlayList->m_cur_entry - ID; + if (prev>=0) { + m_pPlayList->m_cur_entry = prev; + m_pPlayList->PlayPrev(); + } +} +void wxOsmo4Frame::OnNavNext(wxCommandEvent &WXUNUSED(event)) +{ + /*don't play if last could trigger playlist loop*/ + if ((m_pPlayList->m_cur_entry<0) || (gf_list_count(m_pPlayList->m_entries) == 1 + (u32) m_pPlayList->m_cur_entry)) return; + m_pPlayList->PlayNext(); +} +void wxOsmo4Frame::OnUpdateNavNext(wxUpdateUIEvent & event) +{ + if (m_pPlayList->m_cur_entry<0) event.Enable(0); + else if ((u32) m_pPlayList->m_cur_entry + 1 == gf_list_count(m_pPlayList->m_entries) ) event.Enable(0); + else event.Enable(1); +} + +void wxOsmo4Frame::OnNavNextMenu(wxCommandEvent &event) +{ + u32 ID = event.GetId() - ID_NAV_NEXT_0; + s32 next = m_pPlayList->m_cur_entry + ID; + if (next < (s32) gf_list_count(m_pPlayList->m_entries) ) { + m_pPlayList->m_cur_entry = next; + m_pPlayList->PlayNext(); + } +} + +void wxOsmo4Frame::OnClearNav(wxCommandEvent &WXUNUSED(event)) +{ + m_pPlayList->ClearButPlaying(); +} + + +void wxOsmo4Frame::BuildStreamList(Bool reset_only) +{ + u32 nb_subs; + wxMenu *pMenu; + + pMenu = sel_menu->FindItemByPosition(0)->GetSubMenu(); + while (pMenu->GetMenuItemCount()) { + wxMenuItem* it = pMenu->FindItemByPosition(0); + pMenu->Delete(it); + } + pMenu = sel_menu->FindItemByPosition(1)->GetSubMenu(); + while (pMenu->GetMenuItemCount()) { + wxMenuItem* it = pMenu->FindItemByPosition(0); + pMenu->Delete(it); + } + pMenu = sel_menu->FindItemByPosition(2)->GetSubMenu(); + while (pMenu->GetMenuItemCount()) { + wxMenuItem* it = pMenu->FindItemByPosition(0); + pMenu->Delete(it); + } + + if (reset_only) { + m_bFirstStreamListBuild = 1; + return; + } + + if (!gf_term_get_option(m_term, GF_OPT_CAN_SELECT_STREAMS)) return; + + nb_subs = 0; + GF_ObjectManager *root_od = gf_term_get_root_object(m_term); + if (!root_od) return; + u32 count = gf_term_get_object_count(m_term, root_od); + + for (u32 i=0; iFindItemByPosition(0)->GetSubMenu(); + if (!info.owns_service) sprintf(szLabel, "Audio #"LLU, (u64)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 #"LLU, (u64)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 #"LLU, (u64)pMenu->GetMenuItemCount() + 1); + pMenu->AppendCheckItem(ID_SELSTREAM_0 +i, wxString(szLabel, wxConvUTF8)); + break; + } + } + if (m_bFirstStreamListBuild) { + m_bFirstStreamListBuild = 0; + if (!nb_subs && m_lookforsubs) LookForSubtitles(); + } +} + +void wxOsmo4Frame::OnStreamSel(wxCommandEvent & event) +{ + GF_ObjectManager *root_od = gf_term_get_root_object(m_term); + if (!root_od) return; + u32 ID = event.GetId() - ID_SELSTREAM_0; + GF_ObjectManager *odm = gf_term_get_object(m_term, root_od, ID); + gf_term_select_object(m_term, odm); +} + +void wxOsmo4Frame::OnUpdateStreamSel(wxUpdateUIEvent & event) +{ + GF_ObjectManager *root_od = gf_term_get_root_object(m_term); + if (!root_od) return; + u32 ID = event.GetId() - ID_SELSTREAM_0; + + GF_ObjectManager *odm = gf_term_get_object(m_term, root_od, ID); + if (!odm) return; + + GF_MediaInfo info; + gf_term_get_object_info(m_term, odm, &info); + event.Enable(1); + event.Check(info.status ? 1 : 0); +} + +void wxOsmo4Frame::OnUpdateStreamMenu(wxUpdateUIEvent & event) +{ + if (!m_connected || !gf_term_get_option(m_term, GF_OPT_CAN_SELECT_STREAMS)) { + event.Enable(0); + } else { + event.Enable(1); + } +} + +void wxOsmo4Frame::OnAddSub(wxCommandEvent &WXUNUSED(event)) +{ + wxFileDialog dlg(this, wxT("Add Subtitle"), wxT(""), wxT(""), wxT("All Subtitles|*.srt;*.ttxt|SRT Subtitles|*.srt|3GPP TimedText|*.ttxt|"), wxOPEN | wxCHANGE_DIR /* | wxHIDE_READONLY*/); + + if (dlg.ShowModal() == wxID_OK) { + AddSubtitle(dlg.GetPath().mb_str(wxConvUTF8), 1); + } + +} + +void wxOsmo4Frame::AddSubtitle(const char *fileName, Bool auto_play) +{ + gf_term_add_object(m_term, fileName, auto_play); +} + +static Bool subs_enum_dir_item(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) +{ + wxOsmo4Frame *_this = (wxOsmo4Frame*)cbck; + _this->AddSubtitle(item_path, 0); + return 0; +} + +void wxOsmo4Frame::LookForSubtitles() +{ + char dir[GF_MAX_PATH]; + const char *url = m_pPlayList->GetURL().mb_str(wxConvUTF8); + strcpy(dir, url); + char *sep = strrchr(dir, '\\'); + if (!sep) strcpy(dir, ::wxGetCwd().mb_str(wxConvUTF8)); + else sep[0] = 0; + + gf_enum_directory(dir, 0, subs_enum_dir_item, this, "ttxt;srt"); +} + +void wxOsmo4Frame::OnCacheEnable(wxCommandEvent &WXUNUSED(event)) +{ + u32 state = gf_term_get_option(m_term, GF_OPT_MEDIA_CACHE); + if (state==GF_MEDIA_CACHE_DISABLED) { + gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_ENABLED); + } else if (state==GF_MEDIA_CACHE_DISABLED) { + gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); + } +} + +void wxOsmo4Frame::OnCacheStop(wxCommandEvent &WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); +} + +void wxOsmo4Frame::OnCacheAbort(wxCommandEvent &WXUNUSED(event)) +{ + gf_term_set_option(m_term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISCARD); +} + +void wxOsmo4Frame::OnUpdateCacheEnable(wxUpdateUIEvent & event) +{ + u32 state = gf_term_get_option(m_term, GF_OPT_MEDIA_CACHE); + switch (state) { + case GF_MEDIA_CACHE_ENABLED: + event.Enable(1); + event.SetText(wxT("Enabled")); + break; + case GF_MEDIA_CACHE_RUNNING: + event.SetText(wxT("Running")); + event.Enable(0); + break; + case GF_MEDIA_CACHE_DISABLED: + event.SetText(wxT("Disabled")); + break; + } +} + +void wxOsmo4Frame::OnUpdateCacheAbort(wxUpdateUIEvent & event) +{ + u32 state = gf_term_get_option(m_term, GF_OPT_MEDIA_CACHE); + event.Enable( (state==GF_MEDIA_CACHE_RUNNING) ? 1 : 0); +} + + + +void wxOsmo4Frame::BuildChapterList(Bool reset_only) +{ + GF_MediaInfo odi; + + while (chap_menu->GetMenuItemCount()) { + wxMenuItem* it = chap_menu->FindItemByPosition(0); + chap_menu->Delete(it); + } + if (m_chapters_start) gf_free(m_chapters_start); + m_chapters_start = NULL; + m_num_chapters = 0; + if (reset_only) return; + + GF_ObjectManager *root_od = gf_term_get_root_object(m_term); + if (!root_od) return; + if (gf_term_get_object_info(m_term, root_od, &odi) != GF_OK) return; + + u32 count = gf_list_count(odi.od->OCIDescriptors); + m_num_chapters = 0; + for (u32 i=0; iOCIDescriptors, i); + if (seg->tag != GF_ODF_SEGMENT_TAG) continue; + + if (seg->SegmentName && strlen((const char *)seg->SegmentName)) { + strcpy(szLabel, (const char *) seg->SegmentName); + } else { + sprintf(szLabel, "Chapter %02d", m_num_chapters+1); + } + chap_menu->AppendCheckItem(ID_SETCHAP_FIRST + m_num_chapters, wxString(szLabel, wxConvUTF8)); + + 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++; + } + + /*get any service info*/ + NetInfoCommand com; + if (!m_bStartupFile && gf_term_get_service_info(m_term, root_od, &com) == GF_OK) { + wxString title = wxT(""); + if (com.track_info) { + title.Format(wxT("%02d "), (u32) (com.track_info>>16) ); + } + 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); + } + +} + +void wxOsmo4Frame::OnChapterSel(wxCommandEvent & event) +{ + GF_ObjectManager *root_od = gf_term_get_root_object(m_term); + if (!root_od) return; + u32 ID = event.GetId() - ID_SETCHAP_FIRST; + gf_term_play_from_time(m_term, (u32) (1000*m_chapters_start[ID]), 0); +} + +void wxOsmo4Frame::OnUpdateChapterSel(wxUpdateUIEvent & event) +{ + Double now; + Bool is_current; + u32 ID = event.GetId() - ID_SETCHAP_FIRST; + + now = gf_term_get_time_in_ms(m_term); + now /= 1000; + + is_current = 0; + if (m_chapters_start[ID]<=now) { + if (ID+1now) is_current = 1; + } else { + is_current = 1; + } + } + event.Enable(1); + event.Check(is_current ? 1 : 0); +} + +void wxOsmo4Frame::OnUpdateChapterMenu(wxUpdateUIEvent & event) +{ + if (!m_connected || !m_num_chapters) { + event.Enable(0); + } else { + event.Enable(1); + } +} + +void wxOsmo4Frame::OnFileCopy(wxCommandEvent &event) +{ + const char *text = gf_term_get_text_selection(m_term, 0); + if (!text) return; + if (!wxTheClipboard->Open()) return; + + wxTheClipboard->SetData( new wxTextDataObject( wxString(text, wxConvUTF8)) ); + wxTheClipboard->Close(); +} + +void wxOsmo4Frame::OnUpdateFileCopy(wxUpdateUIEvent &event) +{ + if (gf_term_get_text_selection(m_term, 1)!=NULL) { + event.Enable(1); + } else { + event.Enable(0); + } +} + +void wxOsmo4Frame::OnFilePaste(wxCommandEvent &event) +{ + if (!wxTheClipboard->Open()) return; + if (wxTheClipboard->IsSupported( wxDF_TEXT )) { + wxTextDataObject data; + wxTheClipboard->GetData(data); + gf_term_paste_text(m_term, data.GetText().mb_str(wxConvUTF8), 0); + } + wxTheClipboard->Close(); +} + +void wxOsmo4Frame::OnUpdateFilePaste(wxUpdateUIEvent &event) +{ + Bool ok = 0; + if (wxTheClipboard->Open()) { + if (wxTheClipboard->IsSupported( wxDF_TEXT )) { + if (gf_term_paste_text(m_term, NULL, 1)==GF_OK) { + ok = 1; + } + } + wxTheClipboard->Close(); + } + event.Enable(ok ? 1 : 0); +} + diff --git a/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.h b/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.h new file mode 100644 index 0000000..ae19a6c --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.h @@ -0,0 +1,391 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / Osmo4 wxWidgets GUI + * + * 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 _WXOSMO4_H +#define _WXOSMO4_H + +/* +we need to force X to work in sync mode when we use embedded view... +include first to avoid Bool type redef between X11 and gpac +*/ +#ifdef __WXGTK__ +#include +#endif + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include +#include +#include +#include "menubtn.h" + +/*include gpac AFTER wx in case we override malloc/realloc/free for mem tracking*/ +#include +#include + +class wxOsmo4App : public wxApp +{ +public: + virtual bool OnInit(); +}; + +DECLARE_APP(wxOsmo4App) + +class wxOsmo4Frame; +class wxPlaylist; + +class GPACLogs : public wxLogWindow { +public: + GPACLogs(wxFrame *parent) : wxLogWindow(parent, wxT("GPAC Logs"), FALSE, FALSE) { + m_pMain = (wxOsmo4Frame *) parent; + } + virtual bool OnFrameClose(wxFrame *frame); + +private: + wxOsmo4Frame *m_pMain; +}; + +#define MAX_VIEWPOINTS 50 + +// Menu commands +enum +{ + GWX_FILE_OPEN = wxID_HIGHEST, + GWX_FILE_OPEN_URL, + FILE_RELOAD, + FILE_RELOAD_CONFIG, + FILE_PLAY, + FILE_STEP, + FILE_STOP, + FILE_PREV, + FILE_NEXT, + FILE_PROPERTIES, + FILE_COPY, + FILE_PASTE, + TERM_RELOAD, + FILE_QUIT, + VIEW_FULLSCREEN, + VIEW_ORIGINAL, + VIEW_AR_KEEP, + VIEW_AR_FILL, + VIEW_AR_43, + VIEW_AR_169, + VIEW_OPTIONS, + VIEW_LOGS, + VIEW_RTI, + VIEW_PLAYLIST, + SWITCH_RENDER, + APP_SHORTCUTS, + APP_NAV_KEYS, + APP_ABOUT, + ID_ADDRESS, + ID_URL_GO, + ID_ABOUT_CLOSE, + ID_CLEAR_NAV, + ID_STREAM_MENU, + ID_CHAPTER_MENU, + ID_ADD_SUB, + + ID_MCACHE_ENABLE, + ID_MCACHE_STOP, + ID_MCACHE_ABORT, + + ID_CTRL_TIMER, + ID_SLIDER, + + ID_TREE_VIEW, + ID_OD_TIMER, + ID_VIEW_SG, + ID_VIEW_WI, + ID_VIEW_SEL, + + + ID_HEADLIGHT, + ID_NAVIGATE_NONE, + ID_NAVIGATE_WALK, + ID_NAVIGATE_FLY, + ID_NAVIGATE_EXAMINE, + ID_NAVIGATE_SLIDE, + ID_NAVIGATE_PAN, + ID_NAVIGATE_ORBIT, + ID_NAVIGATE_GAME, + ID_NAVIGATE_RESET, + + ID_COLLIDE_NONE, + ID_COLLIDE_REG, + ID_COLLIDE_DISP, + ID_GRAVITY, + + ID_PL_OPEN, + ID_PL_SAVE, + ID_PL_ADD_FILE, + ID_PL_ADD_URL, + ID_PL_ADD_DIR, + ID_PL_ADD_DIR_REC, + ID_PL_REM_FILE, + ID_PL_REM_ALL, + ID_PL_REM_DEAD, + ID_PL_UP, + ID_PL_DOWN, + ID_PL_RANDOMIZE, + ID_PL_REVERSE, + ID_PL_SEL_REV, + ID_PL_SORT_TITLE, + ID_PL_SORT_FILE, + ID_PL_SORT_DUR, + ID_PL_PLAY, + + + /*reserve IDs for viewpoint menu*/ + ID_VIEWPOINT_FIRST, + ID_VIEWPOINT_LAST = ID_VIEWPOINT_FIRST + MAX_VIEWPOINTS, + + /*reserve IDs for navigation menus*/ + ID_NAV_PREV_0, + ID_NAV_PREV_9 = ID_NAV_PREV_0 + 10, + ID_NAV_NEXT_0, + ID_NAV_NEXT_9 = ID_NAV_NEXT_0 + 10, + /*reserve IDs for stream selection menus*/ + ID_SELSTREAM_0, + ID_SELSTREAM_9 = ID_SELSTREAM_0 + 10, + + /*reserve IDs for chapter selection menus*/ + ID_SETCHAP_FIRST, + ID_SETCHAP_LAST = ID_SELSTREAM_0 + 200, +}; + +wxString get_pref_browser(GF_Config *cfg); + +class wxGPACEvent : public wxEvent +{ +public: + wxGPACEvent( wxWindow* win = (wxWindow*) NULL ); + void CopyObject( wxObject& obj ) const; + virtual wxEvent *Clone() const; + + wxString to_url; + GF_Event gpac_evt; + + DECLARE_DYNAMIC_CLASS(wxGPACEvent) +}; +typedef void (wxEvtHandler::*GPACEventFunction)(wxGPACEvent&); +DEFINE_EVENT_TYPE(GPAC_EVENT) + +#define EVT_GPACEVENT(func) DECLARE_EVENT_TABLE_ENTRY(GPAC_EVENT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (GPACEventFunction) & func, (wxObject*) NULL), + +class OpenURLDlg : public wxDialog { +public: + OpenURLDlg(wxWindow *parent, GF_Config *cfg); + wxString m_urlVal; +private: + wxButton *m_go; + wxComboBox *m_url; + GF_Config *m_cfg; + void OnGo(wxCommandEvent& event); + DECLARE_EVENT_TABLE() +}; + +class wxMyComboBox : public wxComboBox +{ +public: + wxMyComboBox(wxWindow* parent, wxWindowID id, const wxString& value = wxT(""), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize) + : wxComboBox(parent, id, value, pos, size, 0, NULL, wxCB_DROPDOWN) + {} + +private: + DECLARE_EVENT_TABLE() + + void OnKeyUp(wxKeyEvent &event); +}; + +class wxOsmo4Frame : public wxFrame { +public: + wxOsmo4Frame(); + virtual ~wxOsmo4Frame(); + + char szAppPath[GF_MAX_PATH]; + + u32 m_duration; + wxString the_next_url; + 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 SetStatus(wxString str); + + void OnFilePlay(wxCommandEvent &event); + void OnFileStep(wxCommandEvent &event); + void OnFileStop(wxCommandEvent &event); + wxString GetFileFilter(); + + void BuildViewList(); + void BuildStreamList(Bool reset_only); + void BuildChapterList(Bool reset_only); + + void AddSubtitle(const char *fileName, Bool auto_play); + + wxWindow *m_pView; + +#ifdef __WXGTK__ + u32 m_last_grab_time, m_last_grab_pos; + wxWindow *m_pVisual; +#endif + wxSlider *m_pProg; + wxPlaylist *m_pPlayList; + + void DoLayout(u32 v_width = 0, u32 v_height = 0); + s32 m_last_prog; + + FILE *m_logs; + u32 m_log_level, m_log_tools; + u32 m_LastStatusTime; + +protected: + +private: + DECLARE_EVENT_TABLE() + + void OnCloseApp(wxCloseEvent &event); + void OnSize(wxSizeEvent &event); + + void OnFileOpen(wxCommandEvent &event); + void OnFileOpenURL(wxCommandEvent &event); + void OnFileReload(wxCommandEvent &event); + void OnFileReloadConfig(wxCommandEvent & event); + void OnFileProperties(wxCommandEvent &event); + void OnFileQuit(wxCommandEvent &event); + void OnFullScreen(wxCommandEvent &event); + void OnOptions(wxCommandEvent &event); + void OnViewARKeep(wxCommandEvent &event); + void OnViewARFill(wxCommandEvent &event); + void OnViewAR169(wxCommandEvent &event); + void OnViewAR43(wxCommandEvent &event); + void OnViewOriginal(wxCommandEvent &event); + void OnPlaylist(wxCommandEvent &event); + void OnShortcuts(wxCommandEvent &event); + void OnNavInfo(wxCommandEvent &event); + void OnAddSub(wxCommandEvent &event); + void OnAbout(wxCommandEvent &event); + Bool LoadTerminal(); + void OnGPACEvent(wxGPACEvent &event); + void OnTimer(wxTimerEvent& event); + void OnSlide(wxScrollEvent &event); + void OnRelease(wxScrollEvent &event); + void OnLogs(wxCommandEvent & event); + void OnRTI(wxCommandEvent & event); + void OnUpdatePlay(wxUpdateUIEvent &event); + void OnUpdateNeedsConnect(wxUpdateUIEvent &event); + void OnUpdateFullScreen(wxUpdateUIEvent &event); + void OnUpdateAR(wxUpdateUIEvent &event); + void OnViewport(wxCommandEvent & event); + void OnUpdateViewport(wxUpdateUIEvent & event); + void OnNavigate(wxCommandEvent & event); + void OnNavigateReset(wxCommandEvent & event); + void OnUpdateNavigation(wxUpdateUIEvent & event); + void OnRenderSwitch(wxCommandEvent &event); + void OnCollide(wxCommandEvent & event); + void OnUpdateCollide(wxUpdateUIEvent & event); + void OnHeadlight(wxCommandEvent & event); + void OnUpdateHeadlight(wxUpdateUIEvent & event); + void OnGravity(wxCommandEvent & event); + void OnUpdateGravity(wxUpdateUIEvent & event); + void OnURLSelect(wxCommandEvent &event); + void OnUpdatePlayList(wxUpdateUIEvent & event); + void OnFilePrevOpen(wxNotifyEvent & event); + void OnFileNextOpen(wxNotifyEvent & event); + void OnNavPrev(wxCommandEvent &event); + void OnUpdateNavPrev(wxUpdateUIEvent & event); + void OnNavPrevMenu(wxCommandEvent &event); + void OnNavNext(wxCommandEvent &event); + void OnUpdateNavNext(wxUpdateUIEvent & event); + void OnNavNextMenu(wxCommandEvent &event); + void OnClearNav(wxCommandEvent &event); + void OnStreamSel(wxCommandEvent &event); + void OnUpdateStreamSel(wxUpdateUIEvent & event); + void OnUpdateStreamMenu(wxUpdateUIEvent & event); + void OnChapterSel(wxCommandEvent &event); + void OnUpdateChapterSel(wxUpdateUIEvent & event); + void OnUpdateChapterMenu(wxUpdateUIEvent & event); + + void SelectionReady(); + void ReloadURLs(); + void LookForSubtitles(); + + void OnCacheEnable(wxCommandEvent &event); + void OnCacheStop(wxCommandEvent &event); + void OnCacheAbort(wxCommandEvent &event); + void OnUpdateCacheEnable(wxUpdateUIEvent & event); + void OnUpdateCacheAbort(wxUpdateUIEvent & event); + + void OnFileCopy(wxCommandEvent &event); + void OnUpdateFileCopy(wxUpdateUIEvent &event); + void OnFilePaste(wxCommandEvent &event); + void OnUpdateFilePaste(wxUpdateUIEvent &event); + + + void CheckVideoOut(); + + wxMenuBar* m_pMenubar; + wxStatusBar* m_pStatusbar; + wxTimer *m_pTimer; + GPACLogs *m_pLogs; + wxBoxSizer *m_pAddBar; + + Bool m_bGrabbed, m_bToReset, m_bFirstStreamListBuild; + wxBitmap *m_pOpenFile, *m_pPrev, *m_pNext, *m_pPlay, *m_pPause, *m_pStep, *m_pStop, *m_pInfo, *m_pConfig, *m_pSW2D, *m_pSW3D; + wxMenuButton *m_pPrevBut, *m_pNextBut; + wxToolBar *m_pToolBar; + wxMyComboBox *m_Address; + + wxMenu *vp_list; + wxMenu *sel_menu; + wxMenu *chap_menu; + void Stop(); + + s32 nb_viewpoints; + + void UpdateRenderSwitch(); + void UpdatePlay(); + + u32 m_orig_width, m_orig_height; + + u32 m_num_chapters; + Double *m_chapters_start; + Bool m_bExternalView, m_bViewRTI, m_bStartupFile; + + void ShowViewWindow(Bool do_show); +}; + + +#endif //_WXOSMO4_H + diff --git a/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.rc b/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.rc new file mode 100644 index 0000000..3e839b8 --- /dev/null +++ b/applications/deprecated/old_arch/osmo4_wx/wxOsmo4.rc @@ -0,0 +1,72 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// French (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 +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_OSMO_ICON ICON DISCARDABLE "../../doc/osmo4.ico" +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/applications/deprecated/old_arch/osmophone/Osmo4.ico b/applications/deprecated/old_arch/osmophone/Osmo4.ico new file mode 100644 index 0000000000000000000000000000000000000000..d544ffce61cc278ca5f2b433f70dc50a3c3435b4 GIT binary patch literal 1078 zcma)5J8s)R5Pd5f;IOfFJ8oqH0Rmkim3*WCIe>>yA*xB1od^WTRVXM2p}LeR9Y8Si zW=W@V;gM!`-u(ANz+r{D_AvUh0zPx~e#RRIJlp{r+G_F>+2NiNP{zJbN+&(4^Fm1# z!!U3)$CUq=Cez6LnaPAvYeGz9YRi`N-yqTiQl(48p@}7sT*#%NU4)|_uF3%tN@sfs z=yE{gGo&F|z#*WT+emb(LODZ7(=(v!=Yyb8Vh|0TE`Dfa#n>6-c-(H&sYGikZL7qt z_Yyrdj&E4XO8Nyefx*N!RNf!hyE^ttPmUMEj3=J!wT4-b8N#I5A3YV2Z1$4 +#include +/*for initial setup*/ +#include + +#include +#include + +#include +#include +#include + +#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 +#define GPAC_TIMER_ID 21 +#define GPAC_TIMER_DUR 33 + + +Bool gf_file_dialog(HINSTANCE inst, HWND parent, char *url, const char *ext_list, GF_Config *cfg); +void set_backlight_state(Bool disable); +void refresh_recent_files(); +void do_layout(Bool notif_size); + +static HWND g_hwnd = NULL; +static HWND g_hwnd_disp = NULL; +static HWND g_hwnd_menu = NULL; +static HWND g_hwnd_status = NULL; +static HINSTANCE g_hinst = NULL; +static Bool is_ppc = GF_FALSE; + +static Bool is_connected = GF_FALSE; +static Bool navigation_on = GF_FALSE; +static Bool playlist_navigation_on = GF_TRUE; + +static u32 log_level = GF_LOG_ERROR; + +static u32 Duration; +static Bool CanSeek = GF_FALSE; +static u32 Volume=100; +static char the_url[GF_MAX_PATH] = ""; +static Bool NavigateTo = GF_FALSE; +static char the_next_url[GF_MAX_PATH]; +static GF_Terminal *term; +static GF_User user; +static u32 disp_w = 0; +static u32 disp_h = 0; +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 = GF_FALSE; +static u32 prev_batt_bl, prev_ac_bl; +static Bool show_status = GF_TRUE; +static Bool reset_status = GF_TRUE; +static u32 last_state_time = 0; +static Bool loop = GF_FALSE; +static Bool full_screen = GF_FALSE; +static Bool force_2d_gl = GF_FALSE; +static Bool ctrl_mod_down = GF_FALSE; +static Bool view_cpu = GF_TRUE; +static Bool use_low_fps = GF_FALSE; +static Bool use_svg_prog = GF_FALSE; + +static Bool log_rti = GF_FALSE; +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(); + } +} + +void update_state_info() +{ + TCHAR wstate[1024]; + Double FPS; + u32 time, m, s; + if (!show_status) return; + if (last_state_time) { + if (GetTickCount() > last_state_time + 200) { + last_state_time = 0; + reset_status = GF_TRUE; + } + else return; + } + if (!term) return; + if (!is_connected && reset_status) { + SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) TEXT("Ready") ); + reset_status = GF_FALSE; + return; + } + + FPS = gf_term_get_framerate(term, GF_FALSE); + time = gf_term_get_time_in_ms(term) / 1000; + m = time/60; + s = time - m*60; + if (view_cpu) { + GF_SystemRTInfo rti; + if (!gf_sys_get_rti(STATE_TIMER_DUR, &rti, 0)) return; + wsprintf(wstate, TEXT("T %02d:%02d : FPS %02.2f : CPU %02d"), m, s, FPS, rti.total_cpu_usage); + } else { + wsprintf(wstate, TEXT("T %02d:%02d : FPS %02.2f"), m, s, FPS); + } + SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) wstate); +} + + +static u64 prev_pos = 0; +void cbk_on_progress(void *_title, u64 done, u64 total) +{ +#if 0 + char szMsg[1024]; + u32 pos = (u32) ((u64) done * 100)/total; + if (pos=GF_LOG_INFO)) { + vfprintf(log_file, fmt, list); + } +} +static void on_gpac_log(void *cbk, GF_LOG_Level ll, GF_LOG_Tool lm, const char *fmt, va_list list) +{ + if (fmt && log_file) vfprintf(log_file, fmt, list); +} + + +static void setup_logs() +{ + if (log_file) gf_fclose(log_file); + log_file = NULL; + + gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_ERROR); + gf_log_set_callback(NULL, NULL); + + if (log_rti) { + const char *filename = gf_cfg_get_key(user.config, "General", "LogFile"); + if (!filename) { + gf_cfg_set_key(user.config, "General", "LogFile", "\\gpac_logs.txt"); + filename = "\\gpac_logs.txt"; + } + log_file = gf_fopen(filename, "a+t"); + + 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_tool_level(GF_LOG_ALL, GF_LOG_ERROR); + gf_log_set_tool_level(GF_LOG_RTI, GF_LOG_DEBUG); + 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 { + const char *filename = gf_cfg_get_key(user.config, "General", "LogFile"); + if (!filename) { + gf_cfg_set_key(user.config, "General", "LogFile", "\\gpac_logs.txt"); + filename = "\\gpac_logs.txt"; + } + const char *logs = gf_cfg_get_key(user.config, "General", "Logs"); + if (logs) { + if (gf_log_set_tools_levels( logs ) != GF_OK) { + } else { + if (log_file = gf_fopen(filename, "a+t")) { + gf_log_set_callback(log_file, on_gpac_log); + } + } + } + } +} + +void do_open_file() +{ + gf_cfg_set_key(user.config, "RecentFiles", the_url, NULL); + gf_cfg_insert_key(user.config, "RecentFiles", the_url, "", 0); + u32 count = gf_cfg_get_key_count(user.config, "RecentFiles"); + if (count > 10) gf_cfg_set_key(user.config, "RecentFiles", gf_cfg_get_key_name(user.config, "RecentFiles", count-1), NULL); + + setup_logs(); + + gf_term_connect(term, the_url); +} + +void switch_playlist(Bool play_prev) +{ + char szPLE[20]; + u32 idx = 0; + u32 count; + const char *ple = gf_cfg_get_key(user.config, "General", "PLEntry"); + if (ple) idx = atoi(ple); + + count = gf_cfg_get_key_count(user.config, "Playlist"); + if (!count) return; + /*not the first launch*/ + if (strlen(the_url)) { + if (!idx && play_prev) return; + if (play_prev) idx--; + else idx++; + if (idx>=count) return; + } else { + if (idx>=count) idx=0; + } + + ple = gf_cfg_get_key_name(user.config, "Playlist", idx); + if (!ple) return; + + sprintf(szPLE, "%d", idx); + gf_cfg_set_key(user.config, "General", "PLEntry", szPLE); + + strcpy(the_url, ple); + do_open_file(); +} + + +Bool GPAC_EventProc(void *ptr, GF_Event *evt) +{ + switch (evt->type) { + case GF_EVENT_DURATION: + Duration = (u32) (evt->duration.duration*1000); + CanSeek = evt->duration.can_seek; + break; + case GF_EVENT_MESSAGE: + { + if (!evt->message.message) return GF_FALSE; + GF_LOG(GF_LOG_ERROR, GF_LOG_CONSOLE, ("%s: %s\n", evt->message.message, gf_error_to_string(evt->message.error))); + //set_status((char *) evt->message.message); + } + break; + case GF_EVENT_PROGRESS: + { + 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 "; + cbk_on_progress(szTitle, evt->progress.done, evt->progress.total); + } + break; + + case GF_EVENT_SIZE: + break; + case GF_EVENT_RESOLUTION: + recompute_res(evt->size.width, evt->size.height); + do_layout(GF_TRUE); + break; + + case GF_EVENT_SCENE_SIZE: + do_layout(GF_TRUE); + break; + case GF_EVENT_DBLCLICK: + set_full_screen(); + return GF_FALSE; + case GF_EVENT_CONNECT: + if (evt->connect.is_connected) { + is_connected = GF_TRUE; + if (!backlight_off) set_backlight_state(GF_TRUE); + refresh_recent_files(); + navigation_on = (gf_term_get_option(term, GF_OPT_NAVIGATION)==GF_NAVIGATE_NONE) ? GF_FALSE : GF_TRUE; + } else { + navigation_on = GF_FALSE; + is_connected = GF_FALSE; + 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) { + case GF_KEY_ENTER: + if (full_screen) set_full_screen(); + break; + case GF_KEY_1: + ctrl_mod_down = (Bool)!ctrl_mod_down; + evt->key.key_code = GF_KEY_CONTROL; + evt->type = ctrl_mod_down ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; + gf_term_user_event(term, evt); + break; + case GF_KEY_MEDIAPREVIOUSTRACK: + playlist_act = 2; + break; + case GF_KEY_MEDIANEXTTRACK: + playlist_act = 1; + break; + } + break; + case GF_EVENT_NAVIGATE: + if (gf_term_is_supported_url(term, evt->navigate.to_url, GF_TRUE, GF_TRUE)) { + gf_term_navigate_to(term, evt->navigate.to_url); + return GF_TRUE; + } else { +#ifdef _WIN32_WCE + u16 dst[1024]; +#endif + SHELLEXECUTEINFO info; + + /* + if (full_screen) gf_term_set_option(term, GF_OPT_FULLSCREEN, 0); + full_screen = 0; + */ + memset(&info, 0, sizeof(SHELLEXECUTEINFO)); + info.cbSize = sizeof(SHELLEXECUTEINFO); + info.lpVerb = _T("open"); + info.fMask = SEE_MASK_NOCLOSEPROCESS; + 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); + } + return GF_TRUE; + } + return GF_FALSE; +} + +//#define TERM_NOT_THREADED + +Bool LoadTerminal() +{ + /*by default use current dir*/ + strcpy(the_url, "."); + + setup_logs(); + + g_hwnd_disp = CreateWindow(TEXT("STATIC"), NULL, WS_CHILD | WS_VISIBLE , 0, 0, disp_w, disp_h, g_hwnd, NULL, g_hinst, NULL); + + user.EventProc = GPAC_EventProc; + /*dummy in this case (global vars) but MUST be non-NULL*/ + user.opaque = user.modules; + user.os_window_handler = g_hwnd_disp; +#ifdef TERM_NOT_THREADED + user.init_flags = GF_TERM_NO_REGULATION; + user.threads = 0; +#endif + + term = gf_term_new(&user); + if (!term) { + gf_modules_del(user.modules); + gf_cfg_del(user.config); + memset(&user, 0, sizeof(GF_User)); + return GF_FALSE; + } + +#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 + + const char *str = gf_cfg_get_key(user.config, "General", "StartupFile"); + if (str) { + do_layout(GF_TRUE); + strcpy(the_url, str); + gf_term_connect(term, str); + } + return GF_TRUE; +} + +void do_layout(Bool notif_size) +{ + u32 w, h; + if (full_screen) { + w = screen_w; + h = screen_h; + ::ShowWindow(g_hwnd_status, 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 { +#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*ratio_h; + } else { + ::ShowWindow(g_hwnd_status, SW_HIDE); +// ::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; + } + } + if (notif_size && term) gf_term_set_size(term, w, h); +} + + +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) { + dwSize = 4; + RegQueryValueEx(hKey, _T("BatteryTimeout"), NULL, NULL,(unsigned char*) &prev_batt_bl, &dwSize); + dwSize = 4; + RegQueryValueEx(hKey, _T("ACTimeout"), NULL, NULL, (unsigned char*) &prev_ac_bl,&dwSize); + dwSize = 4; + dwValue = 0xefff ; + RegSetValueEx(hKey, _T("BatteryTimeout"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize); + dwSize = 4; + dwValue = 0xefff ; + RegSetValueEx( hKey, _T("ACTimeout"), NULL, REG_DWORD, (unsigned char *)&dwValue, dwSize); + backlight_off = GF_TRUE; + } else { + if (prev_batt_bl) { + dwSize = 4; + RegSetValueEx(hKey, _T("BatteryTimeout"), NULL, REG_DWORD, (unsigned char *)&prev_batt_bl, dwSize); + } + if (prev_ac_bl) { + dwSize = 4; + RegSetValueEx(hKey, _T("ACTimeout"), NULL, REG_DWORD,(unsigned char *)&prev_ac_bl, dwSize); + } + backlight_off = GF_FALSE; + } + RegCloseKey(hKey); + hBL = CreateEvent(NULL, FALSE, FALSE, _T("BackLightChangeEvent")); + if (hBL) { + SetEvent(hBL); + CloseHandle(hBL); + } +#endif +} + +static Bool do_resume = GF_FALSE; +static Bool prev_backlight_state; +void gf_freeze_display(Bool do_gf_freeze) +{ + if (do_gf_freeze) { + prev_backlight_state = backlight_off; + do_resume = GF_FALSE; + if (0 && is_connected && gf_term_get_option(term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { + do_resume= GF_TRUE; + gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + } + /*gf_freeze display*/ + gf_term_set_option(term, GF_OPT_FREEZE_DISPLAY, 1); + + set_backlight_state(GF_FALSE); + gf_sleep(100); + } else { + if (prev_backlight_state) set_backlight_state(GF_TRUE); + gf_term_set_option(term, GF_OPT_FREEZE_DISPLAY, 0); + + if (do_resume) { + gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + set_backlight_state(GF_TRUE); + } + } +} + +static void show_taskbar(Bool show_it) +{ +#ifdef _WIN32_WCE + HWND wnd; + if (!is_ppc) return; + + wnd = GetForegroundWindow(); + wnd = g_hwnd; + if (show_it) { + SHFullScreen(wnd, SHFS_SHOWSTARTICON | SHFS_SHOWTASKBAR| SHFS_SHOWSIPBUTTON); + ::ShowWindow(::FindWindow(_T("HHTaskbar"),NULL), SW_SHOWNA); + } else { + ::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_menu, SHCMBM_GETSUBMENU, 0, ID_MENU_FILE); + /*pos is hardcoded*/ + hMenu = GetSubMenu(hMenu, 2); + + while (RemoveMenu(hMenu, 0, MF_BYPOSITION)) {} + + for (u32 i=0; iCanHandleURL(ifce, "test.test"); + gf_modules_close_interface((GF_BaseInterface *)ifce); + } + } + MessageBox(NULL, _T("Thank you for installing GPAC"), _T("Initial setup done"), MB_OK); + } + + str = gf_cfg_get_key(user.config, "General", "Loop"); + loop = (!str || !stricmp(str, "yes")) ? GF_TRUE : GF_FALSE; + + str = gf_cfg_get_key(user.config, "SAXLoader", "Progressive"); + use_svg_prog = (str && !strcmp(str, "yes")) ? GF_TRUE : GF_FALSE; + + str = gf_cfg_get_key(user.config, "General", "RTIRefreshPeriod"); + if (str) { + rti_update_time_ms = atoi(str); + } else { + gf_cfg_set_key(user.config, "General", "RTIRefreshPeriod", "200"); + } + + str = gf_cfg_get_key(user.config, "General", "ShowStatusBar"); + show_status = (str && !strcmp(str, "yes")) ? GF_TRUE : GF_FALSE; + + +#ifdef _WIN32_WCE + if (is_ppc) GXOpenInput(); +#endif + + if (InitInstance(nShowCmd)) { + SetForegroundWindow(g_hwnd); + show_taskbar(GF_FALSE); + + force_2d_gl = (Bool)gf_term_get_option(term, GF_OPT_USE_OPENGL); + + while (GetMessage(&msg, NULL, 0,0) == TRUE) { + TranslateMessage (&msg); + DispatchMessage (&msg); + + if (playlist_act) { + switch_playlist((Bool)(playlist_act-1)); + playlist_act = 0; + } + } + show_taskbar(GF_TRUE); + } +#ifdef _WIN32_WCE + if (is_ppc) GXCloseInput(); +#endif + + /*and destroy*/ + if (term) gf_term_del(term); + if (user.modules) gf_modules_del(user.modules); + if (user.config) gf_cfg_del(user.config); + + if (backlight_off) set_backlight_state(GF_FALSE); + + gf_sys_close(); + if (log_file) gf_fclose(log_file); + return 0; +} diff --git a/applications/deprecated/old_arch/osmophone/newres.h b/applications/deprecated/old_arch/osmophone/newres.h new file mode 100644 index 0000000..523557a --- /dev/null +++ b/applications/deprecated/old_arch/osmophone/newres.h @@ -0,0 +1,41 @@ +#ifndef __NEWRES_H__ +#define __NEWRES_H__ + +#if defined(_WIN32_WCE) && !defined(UNDER_CE) +#define UNDER_CE _WIN32_WCE +#endif + +#if defined(_WIN32_WCE) +#if !defined(WCEOLE_ENABLE_DIALOGEX) +#define DIALOGEX DIALOG DISCARDABLE +#endif +#include +#define SHMENUBAR RCDATA +#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300) +#include +#define AFXCE_IDR_SCRATCH_SHMENU 28700 +#else +#define I_IMAGENONE (-2) +#define NOMENU 0xFFFF +#define IDS_SHNEW 1 + +#define IDM_SHAREDNEW 10 +#define IDM_SHAREDNEWDEFAULT 11 +#endif // _WIN32_WCE_PSPC +#define AFXCE_IDD_SAVEMODIFIEDDLG 28701 +#endif // _WIN32_WCE + +#ifdef RC_INVOKED +#ifndef _INC_WINDOWS +#define _INC_WINDOWS +#include "winuser.h" // extract from windows header +#include "winver.h" +#endif +#endif + +#ifdef IDC_STATIC +#undef IDC_STATIC +#endif +#define IDC_STATIC (-1) + +#endif //__NEWRES_H__ diff --git a/applications/deprecated/old_arch/osmophone/openfile.cpp b/applications/deprecated/old_arch/osmophone/openfile.cpp new file mode 100644 index 0000000..55ea606 --- /dev/null +++ b/applications/deprecated/old_arch/osmophone/openfile.cpp @@ -0,0 +1,405 @@ +#include + +#ifdef _WIN32_WCE + +#include + +#include +#include "resource.h" + +static HINSTANCE g_hInst = NULL; +static HMENU g_hMenuView; +static HWND g_hWndMenuBar; +static HWND hDirTxt; +static HWND the_wnd; +static HWND hList; +static TCHAR w_current_dir[GF_MAX_PATH] = _T("\\"); +static u8 current_dir[GF_MAX_PATH] = "\\"; +static const char *extension_list = NULL; +static char *out_url = NULL; +Bool bViewUnknownTypes = GF_FALSE; +Bool playlist_mode = GF_FALSE; +GF_Config *cfg; + + +static void refresh_menu_states() +{ + if (playlist_mode) { + EnableMenuItem(g_hMenuView, IDM_OF_PL_UP, MF_BYCOMMAND|MF_ENABLED); + EnableMenuItem(g_hMenuView, IDM_OF_PL_DOWN, MF_BYCOMMAND|MF_ENABLED ); + } else { + EnableMenuItem(g_hMenuView, IDM_OF_VIEW_ALL, MF_BYCOMMAND| (extension_list ? MF_ENABLED : MF_GRAYED) ); + CheckMenuItem(g_hMenuView, IDM_OF_VIEW_ALL, MF_BYCOMMAND| (bViewUnknownTypes ? MF_CHECKED : MF_UNCHECKED) ); + } + CheckMenuItem(g_hMenuView, IDM_OF_PLAYLIST, MF_BYCOMMAND| (playlist_mode ? MF_CHECKED : MF_UNCHECKED) ); +} + +static void switch_menu_pl() +{ + DeleteMenu(g_hMenuView, IDM_OF_VIEW_ALL, MF_BYCOMMAND); + DeleteMenu(g_hMenuView, IDM_OF_PL_UP, MF_BYCOMMAND); + DeleteMenu(g_hMenuView, IDM_OF_PL_DOWN, MF_BYCOMMAND); + DeleteMenu(g_hMenuView, IDM_OF_PL_CLEAR, MF_BYCOMMAND); + + if (playlist_mode) { + InsertMenu(g_hMenuView, 0, MF_BYPOSITION, IDM_OF_PL_CLEAR, _T("Clear")); + InsertMenu(g_hMenuView, 0, MF_BYPOSITION, IDM_OF_PL_DOWN, _T("Move Down") ); + InsertMenu(g_hMenuView, 0, MF_BYPOSITION, IDM_OF_PL_UP, _T("Move Up") ); + } else { + InsertMenu(g_hMenuView, 0, MF_BYPOSITION, IDM_OF_VIEW_ALL, _T("All Unknown Files") ); + } + TBBUTTONINFO tbbi; + tbbi.cbSize = sizeof(tbbi); + tbbi.dwMask = TBIF_TEXT; + tbbi.pszText = playlist_mode ? _T("Remove") : _T("Add"); + SendMessage(g_hWndMenuBar, TB_SETBUTTONINFO, IDM_OF_PL_ACT, (LPARAM)&tbbi); + refresh_menu_states(); +} + + +Bool enum_dirs(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info) +{ + TCHAR w_name[GF_MAX_PATH], w_str_name[GF_MAX_PATH]; + + CE_CharToWide(name, (u16 *) w_name); + wcscpy(w_str_name, _T("+ ")); + wcscat(w_str_name, w_name); + int iRes = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) w_str_name); + SendMessage(hList, LB_SETITEMDATA, iRes, (LPARAM) 1); + return GF_FALSE; +} + +Bool enum_files(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info) +{ + TCHAR w_name[GF_MAX_PATH]; + + if (!bViewUnknownTypes && extension_list) { + char *ext = strrchr(name, '.'); + if (!ext || !strstr(extension_list, ext+1)) return GF_FALSE; + } + CE_CharToWide(name, (u16 *) w_name); + SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) w_name); + return GF_FALSE; +} + + +void set_directory(TCHAR *dir) +{ + SendMessage(hList, LB_RESETCONTENT, 0, 0); + + CE_WideToChar((u16 *) dir, (char *) current_dir); + wcscpy(w_current_dir, dir); + SetWindowText(hDirTxt, w_current_dir); + + if (strcmp((const char *) current_dir, "\\")) { + int iRes = SendMessage(hList, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) _T("+ ..") ); + SendMessage(hList, LB_SETITEMDATA, iRes, (LPARAM) 1); + } + + /*enum directories*/ + gf_enum_directory((const char *) current_dir, GF_TRUE, enum_dirs, NULL, NULL); + /*enum files*/ + gf_enum_directory((char *) current_dir, GF_FALSE, enum_files, NULL, NULL); + SendMessage(hList, LB_SETCURSEL, 0, 0); + SetFocus(hList); +} + + + +void refresh_playlist() +{ + TCHAR w_name[GF_MAX_PATH]; + u32 count, i; + + SetWindowText(hDirTxt, _T("Playlist")); + SendMessage(hList, LB_RESETCONTENT, 0, 0); + + count = gf_cfg_get_key_count(cfg, "Playlist"); + for (i=0; i=count) i=0; + SendMessage(hList, LB_SETCURSEL, i, 0); + SetFocus(hList); +} + +void playlist_act(u32 act_type) +{ + u32 idx, count; + char entry[MAX_PATH]; + const char *url; + + /*reset all*/ + if (act_type == 3) { + count = gf_cfg_get_key_count(cfg, "Playlist"); + while (count) { + url = gf_cfg_get_key_name(cfg, "Playlist", 0); + gf_cfg_set_key(cfg, "Playlist", url, NULL); + count--; + } + refresh_playlist(); + return; + } + count = SendMessage(hList, LB_GETSELCOUNT, 0, 0); + if (!count) return; + idx = SendMessage(hList, LB_GETCURSEL, 0, 0); + + if ((act_type==1) && !idx) return; + else if ((act_type==2) && (idx+1==count)) return; + + url = gf_cfg_get_key_name(cfg, "Playlist", idx); + if (!url) return; + strcpy(entry, url); + /*remove from playlist*/ + gf_cfg_set_key(cfg, "Playlist", url, NULL); + switch (act_type) { + /*remove*/ + case 0: + if (idx+1==count) idx--; + break; + /*up*/ + case 1: + gf_cfg_insert_key(cfg, "Playlist", entry, "", idx-1); + idx--; + break; + /*down*/ + case 2: + gf_cfg_insert_key(cfg, "Playlist", entry, "", idx+1); + idx++; + break; + } + refresh_playlist(); + SendMessage(hList, LB_SETCURSEL, idx, 0); + SetFocus(hList); +} + +Bool add_files(void *cbk, char *name, char *path, GF_FileEnumInfo *file_info) +{ + if (!bViewUnknownTypes && extension_list) { + char *ext = strrchr(name, '.'); + if (!ext || !strstr(extension_list, ext+1)) return GF_FALSE; + } + gf_cfg_set_key(cfg, "Playlist", path, ""); + return GF_FALSE; +} + +void process_list_change(HWND hWnd, Bool add_to_pl) +{ + TCHAR sTxt[GF_MAX_PATH]; + if (!SendMessage(hList, LB_GETSELCOUNT, 0, 0)) return; + + u32 idx = SendMessage(hList, LB_GETCURSEL, 0, 0); + SendMessage(hList, LB_GETTEXT, idx, (LPARAM)(LPCTSTR) sTxt); + + DWORD param = SendMessage(hList, LB_GETITEMDATA, idx, 0); + if (param==1) { + if (!wcscmp(sTxt, _T("+ ..") ) ) { + if (add_to_pl) return; + current_dir[strlen((const char *) current_dir)-1] = 0; + char *b = strrchr((const char *) current_dir, '\\'); + if (b) b[1] = 0; + else b[0] = '\\'; + CE_CharToWide((char *) current_dir, (u16 *) w_current_dir); + set_directory(w_current_dir); + } else { + if (add_to_pl) { + char dir[MAX_PATH]; + TCHAR wdir[MAX_PATH]; + wcscpy(wdir, w_current_dir); + wcscat(wdir, sTxt+2); + wcscat(wdir, _T("\\")); + CE_WideToChar((u16 *) wdir, (char *) dir); + gf_enum_directory(dir, GF_FALSE, add_files, NULL, NULL); + } else { + wcscat(w_current_dir, sTxt+2); + wcscat(w_current_dir, _T("\\")); + CE_WideToChar((u16 *) w_current_dir, (char *) current_dir); + set_directory(w_current_dir); + } + } + } else { + char szTxt[1024]; + CE_WideToChar((u16 *) sTxt, (char *) szTxt); + strcpy((char *) out_url, (const char *) current_dir); + strcat(out_url, szTxt); + if (add_to_pl) { + gf_cfg_set_key(cfg, "Playlist", out_url, ""); + strcpy(out_url, ""); + } else { + if (playlist_mode) { + const char *file; + char szPLE[20]; + sprintf(szPLE, "%d", idx); + gf_cfg_set_key(cfg, "General", "PLEntry", szPLE); + file = gf_cfg_get_key_name(cfg, "Playlist", idx); + strcpy(out_url, file); + } + gf_cfg_set_key(cfg, "General", "LastWorkingDir", (const char *) current_dir); + EndDialog(hWnd, 1); + } + } +} + +BOOL InitFileDialog(const HWND hWnd) +{ + TCHAR psz[80]; + ZeroMemory(psz, sizeof(psz)); + SHINITDLGINFO sid; + ZeroMemory(&sid, sizeof(sid)); + sid.dwMask = SHIDIM_FLAGS; + sid.dwFlags = SHIDIF_SIZEDLGFULLSCREEN; + sid.hDlg = hWnd; + + if (FALSE == SHInitDialog(&sid)) + return FALSE; + + SHMENUBARINFO mbi; + ZeroMemory(&mbi, sizeof(SHMENUBARINFO)); + mbi.cbSize = sizeof(SHMENUBARINFO); + mbi.hwndParent = hWnd; + mbi.nToolBarId = IDR_MENU_OPEN; + mbi.hInstRes = g_hInst; + + if (FALSE == SHCreateMenuBar(&mbi)) + { + return FALSE; + } + g_hWndMenuBar = mbi.hwndMB; + + ShowWindow(g_hWndMenuBar, SW_SHOW); + + the_wnd = hWnd; + + hDirTxt = GetDlgItem(hWnd, IDC_DIRNAME); + hList = GetDlgItem(hWnd, IDC_FILELIST); + g_hMenuView = (HMENU)SendMessage(g_hWndMenuBar, SHCMBM_GETSUBMENU, 0, ID_OF_VIEW); + + RECT rc; + GetClientRect(hWnd, &rc); + u32 caption_h = GetSystemMetrics(SM_CYCAPTION) - 3; + MoveWindow(hDirTxt, 0, 0, rc.right - rc.left, caption_h, 1); + MoveWindow(hList, 0, caption_h, rc.right - rc.left, rc.bottom - rc.top - caption_h, 1); + + if (playlist_mode) { + refresh_playlist(); + } else { + if (!strcmp((const char *) current_dir, "\\")) { + char *opt = (char *) gf_cfg_get_key(cfg, "General", "LastWorkingDir"); + if (opt) CE_CharToWide(opt, (u16 *) w_current_dir); + } + set_directory(w_current_dir); + } + switch_menu_pl(); + return TRUE; +} + +BOOL CALLBACK FileDialogProc(const HWND hWnd, const UINT Msg, const WPARAM wParam, const LPARAM lParam) +{ + BOOL bProcessedMsg = TRUE; + + switch (Msg) { + case WM_INITDIALOG: + if (FALSE == InitFileDialog(hWnd)) + EndDialog(hWnd, -1); + break; + + case WM_ACTIVATE: + if (WA_INACTIVE != LOWORD(wParam)) SetFocus(hWnd); + break; + + case WM_CLOSE: + EndDialog(hWnd, 0); + break; + + case WM_COMMAND: + if (LOWORD(wParam) == IDC_FILELIST) { + if (HIWORD(wParam) == LBN_DBLCLK) { + process_list_change(hWnd, GF_FALSE); + } else { + bProcessedMsg = FALSE; + } + } else { + switch (LOWORD(wParam)) { + case IDOK: + process_list_change(hWnd, GF_FALSE); + break; + case IDCANCEL: + EndDialog(hWnd, 0); + break; + case IDM_OF_VIEW_ALL: + bViewUnknownTypes = (Bool) !bViewUnknownTypes; + refresh_menu_states(); + set_directory(w_current_dir); + break; + case IDM_OF_PLAYLIST: + playlist_mode = (Bool) !playlist_mode; + if (playlist_mode) refresh_playlist(); + else set_directory(w_current_dir); + switch_menu_pl(); + break; + case IDM_OF_PL_ACT: + if (playlist_mode) { + playlist_act(0); + } else { + process_list_change(hWnd, GF_TRUE); + } + break; + case IDM_OF_PL_UP: + playlist_act(1); + break; + case IDM_OF_PL_DOWN: + playlist_act(2); + break; + case IDM_OF_PL_CLEAR: + playlist_act(3); + break; + default: + bProcessedMsg = FALSE; + break; + } + } + break; + case WM_KEYDOWN: + switch (wParam) { + case VK_LEFT: + case '1': + playlist_act(1); + break; + case VK_RIGHT: + case '2': + playlist_act(2); + break; + default: + bProcessedMsg = FALSE; + break; + } + break; + + default: + bProcessedMsg = FALSE; + } + + return bProcessedMsg; +} + +Bool gf_file_dialog(HINSTANCE inst, HWND parent, char *url, const char *ext_list, GF_Config *gpac_cfg) +{ + extension_list = ext_list; + out_url = url; + g_hInst = inst; + cfg = gpac_cfg; + int iResult = DialogBox(inst, MAKEINTRESOURCE(IDD_FILEDIALOG), parent,(DLGPROC)FileDialogProc); + if (iResult>0) return GF_TRUE; + return GF_FALSE; +} + + +#endif + diff --git a/applications/deprecated/old_arch/osmophone/osmophone.rc b/applications/deprecated/old_arch/osmophone/osmophone.rc new file mode 100644 index 0000000..a947092 --- /dev/null +++ b/applications/deprecated/old_arch/osmophone/osmophone.rc @@ -0,0 +1,425 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "newres.h" + +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Anglais (États-Unis) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON ICON "../../doc/osmo4.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""newres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// RCDATA +// + +IDM_MAIN_MENU1 RCDATA +BEGIN + 0x0066, 0x0002, 0xfffe, 0x9c53, 0x0004, 0x0018, 0x9c55, 0x0000, 0x0000, + 0xfffe, 0x9c58, 0x0004, 0x0018, 0x9c59, 0x0000, 0x0001 +END + +IDR_ABOUT_MENU RCDATA +BEGIN + 0x006b, 0x0001, 0xfffe, 0x9c77, 0x0004, 0x0010, 0x9c6c, 0x0000, 0xffff + +END + +IDM_MAIN_MENU2 RCDATA +BEGIN + 0x006c, 0x0002, 0xfffe, 0x9c83, 0x0004, 0x0018, 0x9c85, 0x0000, 0x0000, + 0xfffe, 0x9c87, 0x0004, 0x0018, 0x9c89, 0x0000, 0x0001 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDM_MAIN_MENU MENU +BEGIN + POPUP "File" + BEGIN + MENUITEM "Open", IDM_FILE_OPEN + MENUITEM "Open URL", IDM_FILE_OPEN_URL + POPUP "Recent" + BEGIN + MENUITEM "FILE 1", IDM_OPEN_FILE1 + MENUITEM "FILE 2", IDM_OPEN_FILE2 + MENUITEM "FILE 3", IDM_OPEN_FILE3 + MENUITEM "FILE 4", IDM_OPEN_FILE4 + MENUITEM "FILE 5", IDM_OPEN_FILE5 + MENUITEM "FILE 6", IDM_OPEN_FILE6 + MENUITEM "FILE 7", IDM_OPEN_FILE7 + MENUITEM "FILE 8 ", IDM_OPEN_FILE8 + MENUITEM "FILE 9", IDM_OPEN_FILE9 + END + MENUITEM SEPARATOR + 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" + BEGIN + POPUP "Navigate" + BEGIN + MENUITEM "Reset", IDM_NAV_RESET + MENUITEM SEPARATOR + MENUITEM "None", IDM_NAV_NONE + MENUITEM "Slide", IDM_NAV_SLIDE + MENUITEM "Walk", IDM_NAV_WALK + MENUITEM "Fly", IDM_NAV_FLY + MENUITEM "Examine", IDM_NAV_EXAMINE + MENUITEM SEPARATOR + MENUITEM "Headlight", IDM_NAV_HEADLIGHT + MENUITEM "Gravity", IDM_NAV_GRAVITY + POPUP "Collision" + BEGIN + MENUITEM "Disabled", IDM_NAV_COL_NONE + MENUITEM "Regular", IDM_NAV_COL_REG + MENUITEM "Displacement", IDM_NAV_COL_DISP + END + END + MENUITEM SEPARATOR + MENUITEM "Fullscreen", IDM_VIEW_FS + POPUP "Info" + BEGIN + MENUITEM "Status Bar", IDM_VIEW_STATUS + MENUITEM "CPU usage", IDM_VIEW_CPU + END + MENUITEM SEPARATOR + 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 +BEGIN + MENUITEM "OK", IDM_ABOUT_OK +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_CLASSNAME "Osmophone" + IDS_WINDOWNAME "Osmo4" + IDS_APPNAME "Osmophone.exe" +END + +STRINGTABLE +BEGIN + IDS_CAP_QUIT "Exit" + IDS_CAP_FILE "File" + IDS_CAP_EXIT "View" + IDS_CAP_VIEW "View" +END + +STRINGTABLE +BEGIN + IDS_CAP_OK "OK" +END + +STRINGTABLE +BEGIN + IDS_CAP_NAVIGATE "Navigate" +END + +STRINGTABLE +BEGIN + IDS_CAP_OPTION "Options" + IDS_CAP_MENUITEM40072 "?" +END + +STRINGTABLE +BEGIN + IDS_CAP_DISABLE_PLAYLIST "Copy/Paste" +END + +#endif // Anglais (États-Unis) 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 + +///////////////////////////////////////////////////////////////////////////// +// +// RCDATA +// + +IDR_MENU_OPEN RCDATA +BEGIN + 0x006a, 0x0002, 0xfffe, 0x9c9b, 0x0004, 0x0010, 0x9c9f, 0x0000, 0xffff, + 0xfffe, 0x9c9a, 0x0004, 0x0018, 0x9c59, 0x0000, 0x0001 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU_OPEN MENU +BEGIN + MENUITEM "Add", IDM_OF_PL_ACT + POPUP "View" + BEGIN + MENUITEM "All Unknown Files", IDM_OF_VIEW_ALL + MENUITEM "Move Up", IDM_OF_PL_UP + MENUITEM "Move Down", IDM_OF_PL_DOWN + MENUITEM "Clear", IDM_OF_PL_CLEAR + MENUITEM SEPARATOR + MENUITEM "Playlist Mode", IDM_OF_PLAYLIST + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_APPABOUT, DIALOG + BEGIN + LEFTMARGIN, 1 + RIGHTMARGIN, 113 + BOTTOMMARGIN, 74 + END + + IDD_FILEDIALOG, DIALOG + BEGIN + RIGHTMARGIN, 103 + BOTTOMMARGIN, 85 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +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,1,0,16,16 + CTEXT "Osmo4/GPAC\n"GPAC_VERSION" ",IDC_NAMECTRL,23,1,65,17 + CTEXT "Copyright (c) 2007 Telecom ParisTech\nAll Rights Reserved\nLicensed under LGPL",IDC_STATIC,2,44,111,33 +END + +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 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "CompanyName", "Telecom ParisTech" + VALUE "FileDescription", "osmophone" + VALUE "FileVersion", GPAC_VERSION + VALUE "InternalName", "osmophone" + VALUE "LegalCopyright", "Copyright © Telecom ParisTech 2008" + VALUE "OriginalFilename", "osmophone.exe" + VALUE "ProductName", "Osmo4-GPAC" + VALUE "ProductVersion", GPAC_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x40c, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_CAP_FILE "+" + IDS_CAP_VIEW "View" +END + +STRINGTABLE +BEGIN + IDS_CAP_OK "OK" +END + +STRINGTABLE +BEGIN + IDS_CAP_SELECT "File" +END + +STRINGTABLE +BEGIN + IDS_CAP_MENUITEM40092 "Add" + IDS_CAP_ADD "Add" +END + +#endif // Français (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/applications/deprecated/old_arch/osmophone/osmophone.vcxproj b/applications/deprecated/old_arch/osmophone/osmophone.vcxproj new file mode 100644 index 0000000..90f552c --- /dev/null +++ b/applications/deprecated/old_arch/osmophone/osmophone.vcxproj @@ -0,0 +1,343 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717} + osmophone + + + + Application + false + Unicode + + + Application + false + Unicode + + + Application + false + Unicode + + + Application + false + Unicode + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + true + true + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(Platform)\$(Configuration)/osmophone.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE + MultiThreadedDebugDLL + + + $(IntDir)$(ProjectName).pch + .\obj\$(Platform)\$(Configuration)\osmophone/ + .\obj\$(Platform)\$(Configuration)\osmophone/ + .\obj\$(Platform)\$(Configuration)\osmophone/ + true + Level3 + true + ProgramDatabase + + + /r %(AdditionalOptions) + UNDER_CE=$(CEVER);_WIN32_WCE=$(CEVER);DEBUG;UNICODE;_UNICODE;$(CePlatform);ARM;_ARM_;ARMV4;%(PreprocessorDefinitions) + 0x0409 + ../../include + + + ../../bin/$(Platform)\$(Configuration)/osmophone.exe + true + ../../extra_lib/lib/$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + + + true + .\obj\$(Platform)\$(Configuration)\osmophone/osmophone.pdb + Windows + 65536 + 4096 + WinMainCRTStartup + 0x00010000 + MachineX86 + + + true + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + $(Platform)\$(Configuration)/osmophone.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE + MultiThreadedDebugDLL + + + $(IntDir)$(ProjectName).pch + .\obj\$(Platform)\$(Configuration)\osmophone/ + .\obj\$(Platform)\$(Configuration)\osmophone/ + .\obj\$(Platform)\$(Configuration)\osmophone/ + true + Level3 + true + ProgramDatabase + + + /r %(AdditionalOptions) + UNDER_CE=$(CEVER);_WIN32_WCE=$(CEVER);DEBUG;UNICODE;_UNICODE;$(CePlatform);ARM;_ARM_;ARMV4;%(PreprocessorDefinitions) + 0x0409 + ../../include + + + ../../bin/$(Platform)\$(Configuration)/osmophone.exe + true + ../../extra_lib/lib/$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + + + true + .\obj\$(Platform)\$(Configuration)\osmophone/osmophone.pdb + Windows + 65536 + 4096 + WinMainCRTStartup + 0x00010000 + + + true + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + $(Platform)\$(Configuration)/osmophone.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE + MultiThreadedDLL + + + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + /r %(AdditionalOptions) + UNDER_CE=$(CEVER);_WIN32_WCE=$(CEVER);NDEBUG;UNICODE;_UNICODE;$(CePlatform);ARM;_ARM_;ARMV4;%(PreprocessorDefinitions) + 0x0409 + + + ../../bin/$(Platform)/$(Configuration)/$(ProjectName).exe + true + ../../extra_lib/lib/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) + + + .\obj\$(Platform)\$(Configuration)\osmophone/osmophone.pdb + Windows + 65536 + 4096 + WinMainCRTStartup + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + $(Platform)\$(Configuration)/osmophone.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE + MultiThreadedDLL + + + $(IntDir)$(ProjectName).pch + $(IntDir) + $(IntDir) + $(IntDir) + Level3 + true + + + /r %(AdditionalOptions) + UNDER_CE=$(CEVER);_WIN32_WCE=$(CEVER);NDEBUG;UNICODE;_UNICODE;$(CePlatform);ARM;_ARM_;ARMV4;%(PreprocessorDefinitions) + 0x0409 + + + ../../bin/$(Platform)/$(Configuration)/$(ProjectName).exe + true + ../../extra_lib/lib/$(Platform)/$(Configuration);%(AdditionalLibraryDirectories) + + + .\obj\$(Platform)\$(Configuration)\osmophone/osmophone.pdb + Windows + 65536 + 4096 + WinMainCRTStartup + + + true + $(IntDir)$(ProjectName).bsc + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + + + + + true + true + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + + + + + + + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + + + + + true + true + %(AdditionalIncludeDirectories) + %(AdditionalIncludeDirectories) + + + + + + + + + true + true + DEBUG;_AFXDLL + DEBUG;_AFXDLL + 0x0809 + 0x0809 + ../../doc;%(AdditionalIncludeDirectories) + ../../doc;%(AdditionalIncludeDirectories) + true + true + DEBUG;_AFXDLL + DEBUG;_AFXDLL + 0x0809 + 0x0809 + ../../doc;%(AdditionalIncludeDirectories) + ../../doc;%(AdditionalIncludeDirectories) + + + + + + + + + + + + {d3540754-e0cf-4604-ac11-82de9bd4d814} + false + + + + + + \ No newline at end of file diff --git a/applications/deprecated/old_arch/osmophone/resource.h b/applications/deprecated/old_arch/osmophone/resource.h new file mode 100644 index 0000000..5a966d1 --- /dev/null +++ b/applications/deprecated/old_arch/osmophone/resource.h @@ -0,0 +1,169 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by osmophone.rc +// +#define IDS_CLASSNAME 1 +#define IDS_WINDOWNAME 4 +#define IDS_APPNAME 5 +#define IDI_ICON 101 +#define IDM_MENU 102 +#define IDM_MAIN_MENU 102 +#define IDM_MAIN_MENU1 102 +#define IDD_ABOUTBOX 103 +#define IDD_APPABOUT 104 +#define IDD_OPENFILE 105 +#define IDD_FILEDIALOG 105 +#define IDR_MENU_OPEN 106 +#define IDR_ABOUT_MENU 107 +#define IDM_MAIN_MENU2 108 +#define IDM_MAIN_MENUITEM1 401 +#define IDM_MAIN_MENUITEM2 402 +#define IDS_MAIN_MENUITEM1 410 +#define IDS_MAIN_MENUITEM2 412 +#define IDC_EDIT1 1001 +#define IDC_DIRNAME 1001 +#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 +#define IDM_RELEASE 40005 +#define ID_FILE_SHOW_WMKEYDOWN 40006 +#define ID_FILE_SHOW_WMKEYUP 40007 +#define ID_FILE_SHOW_WMCHAR 40008 +#define ID_FILE_SHOW_WMMOUSEMOVE 40009 +#define ID_FILE_SHOW_WMLBUTTONDOWN 40010 +#define ID_FILE_SHOW_WMLBUTTONDBLCLK 40011 +#define ID_FILE_SHOW_WMLBUTTONUP 40012 +#define ID_FILE_SHOW_WMRBUTTONDOWN 40013 +#define ID_FILE_SHOW_WMRBUTTONUP 40014 +#define ID_FILE_SHOW_WMRBUTTONDBLCLK 40015 +#define IDM_ITEM_QUIT 40016 +#define IDS_CAP_QUIT 40018 +#define ID_MENU_FILE 40019 +#define IDS_CAP_FILE 40021 +#define IDM_FILE_OPEN 40022 +#define IDS_CAP_EXIT 40023 +#define IDM_MENU_VIEW 40024 +#define IDS_CAP_VIEW 40025 +#define IDM_FILE_OPEN_URL 40026 +#define IDM_OPEN_FILE1 40030 +#define IDM_OPEN_FILE2 40031 +#define IDM_OPEN_FILE3 40032 +#define IDM_OPEN_FILE4 40033 +#define IDM_OPEN_FILE5 40034 +#define IDM_OPEN_FILE6 40035 +#define IDM_OPEN_FILE7 40036 +#define IDM_OPEN_FILE8 40037 +#define IDM_OPEN_FILE9 40038 +#define IDM_OPEN_FILE10 40039 +#define ID_VIEW 40040 +#define IDM_OF_VIEW_ALL 40041 +#define IDS_CAP_OK 40044 +#define IDS_CAP_MENUITEM40045 40046 +#define ID_SELECT 40047 +#define IDS_CAP_SELECT 40049 +#define IDM_OF_PL_ADD 40050 +#define IDM_OF_PLAYLIST 40051 +#define IDM_OF_PL_REM 40052 +#define IDM_VIEW_FS 40053 +#define IDM_VIEW_ABOUT 40054 +#define IDM_ABOUT_OK 40055 +#define IDM_VIEW_STATUS 40057 +#define IDM_VIEW_FORCEGL 40058 +#define ID_NAVIGATE 40059 +#define IDS_CAP_NAVIGATE 40061 +#define IDM_NAV_NONE 40062 +#define IDM_NAV_SLIDE 40063 +#define IDM_SELECT 40064 +#define IDM_NAV_RESET 40065 +#define IDM_MENU_SWITCH 40066 +#define ID_OPTION 40067 +#define IDS_CAP_OPTION 40069 +#define ID_MENUITEM40071 40071 +#define IDS_CAP_MENUITEM40072 40073 +#define IDM_NAV_WALK 40074 +#define IDM_NAV_FLY 40075 +#define IDM_NAV_EXAMINE 40076 +#define IDM_NAV_HEADLIGHT 40077 +#define IDM_NAV_GRAVITY 40078 +#define IDM_NAV_COL_NONE 40079 +#define IDM_NAV_COL_REG 40080 +#define IDM_NAV_COL_DISP 40081 +#define IDM_VIEW_AR_NONE 40082 +#define IDM_VIEW_AR_FILL 40083 +#define IDM_VIEW_AR_4_3 40084 +#define IDM_VIEW_AR_16_9 40085 +#define IDM_OF_PL_UP 40088 +#define IDM_OF_PL_DOWN 40089 +#define ID_OF_VIEW 40090 +#define IDM_OF_PL_ACT 40091 +#define IDS_CAP_MENUITEM40092 40093 +#define IDS_CAP_ADD 40095 +#define IDM_OF_PL_CLEAR 40096 +#define IDM_FILE_LOG_RTI 40097 +#define IDM_VIEW_CPU 40098 +#define IDM_FILE_PAUSE 40099 +#define IDM_VIEW_LOW_RATE 40100 +#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 40152 +#define _APS_NEXT_CONTROL_VALUE 1005 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/applications/deprecated/old_arch/osmozilla/Makefile b/applications/deprecated/old_arch/osmozilla/Makefile new file mode 100644 index 0000000..694701e --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/Makefile @@ -0,0 +1,109 @@ +include ../../config.mak + +vpath %.cpp $(SRC_PATH)/applications/osmozilla + +ifeq ($(CONFIG_WIN32),yes) +USER_NAME=root +else +USER_NAME=$(shell whoami) +ifeq ($(USER_NAME),root) +else +MOZILLA_DIR=local +endif +endif + +CFLAGS=$(CXXFLAGS) $(XUL_CFLAGS) -I"$(SRC_PATH)/include" + +ifeq ($(DEBUGBUILD),yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD),yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +ifeq ($(CONFIG_WIN32),yes) +CFLAGS+=-DXP_WIN +else +ifeq ($(CONFIG_DARWIN),yes) +CFLAGS+=-DXP_MAC +else +CFLAGS+=-DXP_UNIX -DMOZ_X11 +endif +endif + +CFLAGS+=-DNPBASIC_EXPORTS -DMOZILLA_STRICT_API -DXPCOM_GLUE + + +LINKLIBS=-L../../bin/gcc -lgpac + +OBJS=osmozilla.o osmo_npapi.o + +SRCS := $(OBJS:.o=.cpp) + + +LIB=nposmozilla$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +LINKLIBS+=-lwinmm -lgdi32 +LDFLAGS+=--export-all-symbols +endif + +all: $(LIB) + +$(LIB): $(OBJS) +ifeq ($(CONFIG_WIN32),yes) + windres osmozilla.rc osmoz.o + $(CXX) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) osmoz.o $(LINKLIBS) $(LDFLAGS) + cp "$(SRC_PATH)/applications/osmozilla/nsIOsmozilla.xpt_w32" ../../bin/gcc/nposmozilla.xpt + chmod +w ../../bin/gcc/nposmozilla.xpt +else + $(CXX) $(SHFLAGS) $(OBJS) $(LINKLIBS) -o ../../bin/gcc/$@ $(LDFLAGS) + cp "$(SRC_PATH)/applications/osmozilla/nsIOsmozilla.xpt_linux" ../../bin/gcc/nposmozilla.xpt + chmod +w ../../bin/gcc/nposmozilla.xpt +endif + @echo $(USER_ROOT) + +clean: + rm -f $(OBJS) ../../bin/gcc/$(LIB) ../../bin/gcc/nposmozilla.xpt +ifeq ($(CONFIG_WIN32),yes) + rm -f osmoz.o +endif + +install: +ifeq ($(MOZILLA_DIR),local) +ifeq ($(USER_NAME),root) + @echo "*** Root cannot install local mozilla plugins! ***" + @echo "*** Exit root mode and reinstall mozilla plugin! ***" +else + $(MAKE) $(LIB) + $(INSTALL) -D -m 755 ../../bin/gcc/$(LIB) "$(HOME)/.mozilla/plugins/$(LIB)" + $(INSTALL) -D -m 755 ../../bin/gcc/nposmozilla.xpt "$(HOME)/.mozilla/components/nposmozilla.xpt" +endif +else + $(INSTALL) -D -m 755 ../../bin/gcc/$(LIB) "$(MOZILLA_DIR)/components/$(LIB)" + $(INSTALL) -D -m 755 ../../bin/gcc/nposmozilla.xpt "$(MOZILLA_DIR)/components/nposmozilla.xpt" +endif + +uninstall: +ifeq ($(MOZILLA_DIR),local) +ifeq ($(USER_NAME),root) +else + rm -rf "$(HOME)/.mozilla/plugins/$(LIB)" + rm -rf "$(HOME)/.mozilla/components/nposmozilla.xpt" +endif +else + rm -rf "$(MOZILLA_DIR)/components/$(LIB)" + rm -rf "$(MOZILLA_DIR)/components/nposmozilla.xpt" +endif + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + diff --git a/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.h b/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.h new file mode 100644 index 0000000..e52276d --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.h @@ -0,0 +1,148 @@ +/* +* DO NOT EDIT. THIS FILE IS GENERATED FROM nsIOsmozilla.idl +*/ + +#ifndef __gen_nsIOsmozilla_h__ +#define __gen_nsIOsmozilla_h__ + +#include "osmo_npapi.h" + +#ifdef GECKO_XPCOM + +#ifndef __gen_nsISupports_h__ +#include "nsISupports.h" +#endif + +/* For IDL files that don't want to include root IDL files. */ +#ifndef NS_NO_VTABLE +#define NS_NO_VTABLE +#endif + +/* starting interface: nsIOsmozilla */ +#define NS_IOSMOZILLA_IID_STR "d2d536a0-b6fc-11d5-9d10-0060b0fbd80b" + +#define NS_IOSMOZILLA_IID \ + {0xd2d536a0, 0xb6fc, 0x11d5, \ + { 0x9d, 0x10, 0x00, 0x60, 0xb0, 0xfb, 0xd8, 0x0b }} + +class NS_NO_VTABLE nsIOsmozilla : public nsISupports { +public: + + NS_DEFINE_STATIC_IID_ACCESSOR(NS_IOSMOZILLA_IID) + + /* void Pause (); */ + NS_IMETHOD Pause(void) = 0; + + /* void Play (); */ + NS_IMETHOD Play(void) = 0; + + /* void Stop (); */ + NS_IMETHOD Stop(void) = 0; + + /* void Update (in string type, in string commands); */ + NS_IMETHOD Update(const char *type, const char *commands) = 0; + + /* void QualitySwitch (in int switch_up); */ + NS_IMETHOD QualitySwitch(int switch_up) = 0; + + /* void SetURL (in string url); */ + NS_IMETHOD SetURL(const char *url) = 0; +}; + +/* Use this macro when declaring classes that implement this interface. */ +#define NS_DECL_NSIOSMOZILLA \ + NS_IMETHOD Pause(void); \ + NS_IMETHOD Play(void); \ + NS_IMETHOD Stop(void); \ + NS_IMETHOD Update(const char *type, const char *commands); \ + NS_IMETHOD QualitySwitch(int switch_up); \ + NS_IMETHOD SetURL(const char *type); + +/* Use this macro to declare functions that forward the behavior of this interface to another object. */ +#define NS_FORWARD_NSIOSMOZILLA(_to) \ + NS_IMETHOD Pause(void) { return _to Pause(); } \ + NS_IMETHOD Play(void) { return _to Play(); } \ + NS_IMETHOD Stop(void) { return _to Stop(); } \ + NS_IMETHOD Update(const char *type, const char *commands) { return _to Update(type, commands); } \ + NS_IMETHOD QualitySwitch(int switch_up) { return _to QualitySwitch( switch_up ); } \ + NS_IMETHOD SetURL(const char *url) { return _to SetURL(url); } + +/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */ +#define NS_FORWARD_SAFE_NSIOSMOZILLA(_to) \ + NS_IMETHOD Pause(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Pause(); } \ + NS_IMETHOD Play(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Play(); } \ + NS_IMETHOD Stop(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Stop(); } \ + NS_IMETHOD Update(const char *type, const char *commands) { return !_to ? NS_ERROR_NULL_POINTER : _to->Update(type, commands); } \ + NS_IMETHOD QualitySwitch(int switch_up) { return !_to ? NS_ERROR_NULL_POINTER : _to->QualitySwitch(switch_up); } \ + NS_IMETHOD SetURL(const char *url) { return !_to ? NS_ERROR_NULL_POINTER : _to->Update(url); } \ + +#if 0 +/* Use the code below as a template for the implementation class for this interface. */ + +/* Header file */ +class nsOsmozilla : public nsIOsmozilla +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOSMOZILLA + + nsOsmozilla(); + virtual ~nsOsmozilla(); + /* additional members */ +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS1(nsOsmozilla, nsIOsmozilla) + +nsOsmozilla::nsOsmozilla() +{ + /* member initializers and constructor code */ +} + +nsOsmozilla::~nsOsmozilla() +{ + /* destructor code */ +} + +/* void Pause (); */ +NS_IMETHODIMP nsOsmozilla::Pause() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void Play (); */ +NS_IMETHODIMP nsOsmozilla::Play() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void Stop (); */ +NS_IMETHODIMP nsOsmozilla::Stop() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void Update (in string type, in string commands); */ +NS_IMETHODIMP nsOsmozilla::Update(const char *type, const char *commands) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void QualitySwitch (in int switch_up); */ +NS_IMETHODIMP nsOsmozilla::QualitySwitch(int switch_up) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void SetURL (in string url); */ +NS_IMETHODIMP nsOsmozilla::SetURL(const char *type) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* End of implementation class template. */ +#endif + +#endif //GECKO_XPCOM + +#endif /* __gen_nsIOsmozilla_h__ */ diff --git a/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.idl b/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.idl new file mode 100644 index 0000000..ba44e77 --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.idl @@ -0,0 +1,10 @@ +#include "nsISupports.idl" + +[scriptable, uuid(ce32e3ff-36f8-425f-94be-d85b26e634ee)] +interface nsIOsmozilla : nsISupports { + void Pause(); + void Play(); + void Stop(); + void Update(in string type, in string commands); + void QualitySwitch(in long switch_up); +}; diff --git a/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.xpt_linux b/applications/deprecated/old_arch/osmozilla/nsIOsmozilla.xpt_linux new file mode 100644 index 0000000000000000000000000000000000000000..1c96fbb3cbf5e69ed61129a611f127121875f92a GIT binary patch literal 180 zcmazDaQ64*3aKne^~p@)<&t7#VqjumVAul0N-XaA`q7eo;v=1CZ@soSR>jnUj+U(#`@>-XaA`q7eo;v=1CZ@soSR>jnUj+U(#`@> +#include +#endif + +NPNetscapeFuncs *sBrowserFunctions = NULL; + +NPError Osmozilla_GetURL(NPP instance, const char *url, const char *target) +{ + if (!sBrowserFunctions) return NPERR_INVALID_FUNCTABLE_ERROR; + return sBrowserFunctions->geturl(instance, url, target); +} + +void Osmozilla_SetStatus(NPP instance, const char *message) +{ + if (!sBrowserFunctions) return; + sBrowserFunctions->status(instance, message); +} + +#ifndef GECKO_XPCOM +void Osmozilla_InitScripting(Osmozilla *osmo); +#endif + +NPError NPOsmozilla_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved) +{ + Osmozilla *osmo; + NPError rv = NPERR_NO_ERROR; + if (instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + osmo = (Osmozilla *) malloc(sizeof(Osmozilla)); + memset(osmo, 0, sizeof(Osmozilla)); + + osmo->np_instance = instance; + // associate the plugin instance object with NPP instance + instance->pdata = (void *)osmo; + + osmo->supports_xembed = 0; + sBrowserFunctions->getvalue(NULL, NPNVSupportsXEmbedBool, (void *)&osmo->supports_xembed); + + Osmozilla_Initialize(osmo, argc, argn, argv); + +#ifndef GECKO_XPCOM + Osmozilla_InitScripting(osmo); +#endif + + return rv; +} + +// here is the place to clean up and destroy the nsPluginInstance object +NPError NPOsmozilla_Destroy (NPP instance, NPSavedData** save) +{ + NPError rv = NPERR_NO_ERROR; + Osmozilla *osmozilla; + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + osmozilla = (Osmozilla*)instance->pdata; + if (osmozilla != NULL) { + Osmozilla_Shutdown(osmozilla); +#ifdef GECKO_XPCOM + NPOsmozilla_ShutdownScript(osmozilla); +#else + if (osmozilla->script_obj) sBrowserFunctions->releaseobject(osmozilla->script_obj); + osmozilla->script_obj = NULL; +#endif + + free(osmozilla); + } + instance->pdata = NULL; + return rv; +} + +// during this call we know when the plugin window is ready or +// is about to be destroyed so we can do some gui specific +// initialization and shutdown +NPError NPOsmozilla_SetWindow (NPP instance, NPWindow* pNPWindow) +{ + Osmozilla *osmozilla; + void *os_wnd_handle, *os_wnd_display; + NPError rv = NPERR_NO_ERROR; + + if (!instance || !instance->pdata) return NPERR_INVALID_INSTANCE_ERROR; + if (pNPWindow == NULL) return NPERR_GENERIC_ERROR; + osmozilla = (Osmozilla *)instance->pdata; + + // window just created + if (!osmozilla->window_set) { + if (pNPWindow->window == NULL) return NPERR_GENERIC_ERROR; + +#ifdef XP_WIN + os_wnd_handle = pNPWindow->window; + os_wnd_display = NULL; +#elif defined(XP_MAXOS) + os_wnd_handle = pNPWindow->window; + os_wnd_display = NULL; +#elif defined(XP_UNIX) + os_wnd_handle = pNPWindow->window; + /*HACK - although we don't use the display in the X11 plugin, this is used to signal that + the user is mozilla and prevent some X11 calls crashing the browser in file playing mode + (eg, "firefox myfile.mp4" )*/ + os_wnd_display =((NPSetWindowCallbackStruct *)pNPWindow->ws_info)->display; +#endif + + if (! Osmozilla_SetWindow(osmozilla, os_wnd_handle, os_wnd_display, pNPWindow->width, pNPWindow->height) ) { + return NPERR_MODULE_LOAD_FAILED_ERROR; + } + + } + +#if 0 + // window goes away + if((pNPWindow->window == NULL) && plugin->isInitialized()) + return plugin->SetWindow(pNPWindow); + + // window resized? + if(plugin->isInitialized() && (pNPWindow->window != NULL)) + return plugin->SetWindow(pNPWindow); + + // this should not happen, nothing to do + if((pNPWindow->window == NULL) && !plugin->isInitialized()) + return plugin->SetWindow(pNPWindow); +#endif + + return rv; +} + +NPError NPOsmozilla_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t *stype) +{ + Osmozilla *osmozilla; + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + osmozilla = (Osmozilla *)instance->pdata; + if(osmozilla== NULL) + return NPERR_GENERIC_ERROR; + + Osmozilla_ConnectTo(osmozilla, stream->url); + *stype = NP_SEEK; + return NPERR_NO_ERROR; +} + +NPINT32 NPOsmozilla_WriteReady (NPP instance, NPStream *stream) +{ + return 0x0fffffff; +} + +NPINT32 NPOsmozilla_Write (NPP instance, NPStream *stream, NPINT32 offset, NPINT32 len, void *buffer) +{ + return len; +} + +NPError NPOsmozilla_DestroyStream (NPP instance, NPStream *stream, NPError reason) +{ + return NPERR_NO_ERROR; +} + +void NPOsmozilla_StreamAsFile (NPP instance, NPStream* stream, const char* fname) +{ +} + +void NPOsmozilla_Print (NPP instance, NPPrint* printInfo) +{ + Osmozilla *osmozilla; + if(instance == NULL) + return; + + osmozilla = (Osmozilla *)instance->pdata; + if(osmozilla== NULL) + return; + + Osmozilla_Print(osmozilla, (printInfo->mode == NP_EMBED) ? 1 : 0, printInfo->print.embedPrint.platformPrint, + printInfo->print.embedPrint.window.x, printInfo->print.embedPrint.window.y, + printInfo->print.embedPrint.window.width, printInfo->print.embedPrint.window.height); +} + +void NPOsmozilla_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) +{ + return; +} + +NPError NPOsmozilla_GetValue(NPP instance, NPPVariable variable, void *value) +{ + NPError rv = NPERR_NO_ERROR; + Osmozilla *osmozilla; + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + osmozilla = (Osmozilla *)instance->pdata; + if(osmozilla== NULL) return NPERR_GENERIC_ERROR; + + switch (variable) { +#ifdef GECKO_XPCOM + case NPPVpluginScriptableInstance: + rv = NPOsmozilla_GetPeer(osmozilla, value); + break; + + case NPPVpluginScriptableIID: + rv = NPOsmozilla_GetPeerIID(osmozilla, value); + break; +#else + + case NPPVpluginScriptableNPObject: + sBrowserFunctions->retainobject(osmozilla->script_obj); + * (void **)value = osmozilla->script_obj; + break; + +#endif + case NPPVpluginNeedsXEmbed: + *((int *)value) = 1; + break; + case NPPVpluginNameString : + *(const char**)value = "Osmozilla/GPAC plugin for NPAPI"; + break; + default: + break; + } + + return rv; +} + + + +NPError NPOsmozilla_SetValue(NPP instance, NPNVariable variable, void *value) +{ + return NPERR_NO_ERROR; +} + +int16_t NPOsmozilla_HandleEvent(NPP instance, void* event) +{ + /*we hacked the proc*/ + return 0; +} + + +NPError OSCALL NP_Shutdown() +{ +#ifdef GECKO_XPCOM + NPOsmozilla_ReleaseServiceManager(); +#endif + return NPERR_NO_ERROR; +} + +static NPError fillPluginFunctionTable(NPPluginFuncs* aNPPFuncs) +{ + if(aNPPFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + // Set up the plugin function table that Netscape will use to + // call us. Netscape needs to know about our version and size + // and have a UniversalProcPointer for every function we implement. + + aNPPFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + aNPPFuncs->newp = NPOsmozilla_New; + aNPPFuncs->destroy = NPOsmozilla_Destroy; + aNPPFuncs->setwindow = NPOsmozilla_SetWindow; + aNPPFuncs->newstream = NPOsmozilla_NewStream; + aNPPFuncs->destroystream = NPOsmozilla_DestroyStream; + aNPPFuncs->asfile = NPOsmozilla_StreamAsFile; + aNPPFuncs->writeready = NPOsmozilla_WriteReady; + aNPPFuncs->write = NPOsmozilla_Write; + aNPPFuncs->print = NPOsmozilla_Print; + aNPPFuncs->event = NPOsmozilla_HandleEvent; + aNPPFuncs->urlnotify = NPOsmozilla_URLNotify; + aNPPFuncs->getvalue = NPOsmozilla_GetValue; + aNPPFuncs->setvalue = NPOsmozilla_SetValue; + return NPERR_NO_ERROR; +} + + +static NPError NS_PluginInitialize() +{ +#ifdef GECKO_XPCOM + NPOsmozilla_GetServiceManager(); +#endif + return NPERR_NO_ERROR; +} + +// get values per plugin +NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue) +{ + NPError err = NPERR_NO_ERROR; + switch (aVariable) { + case NPPVpluginNameString: + *((char **)aValue) = (char *) "Osmozilla"; + break; + case NPPVpluginDescriptionString: + *((char **)aValue) = Osmozilla_GetVersion(); + break; + default: + err = NPERR_INVALID_PARAM; + break; + } + return err; +} + + + + +#define GPAC_PLUGIN_MIMETYPES \ + "audio/mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \ + "audio/x-mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \ + "audio/amr:amr,awb:AMR Audio;" \ + "audio/mp4:mp4,mpg4,mpeg4,m4a:MPEG-4 Audio;" \ + "audio/aac:aac:MPEG-4 AAC Music;" \ + "audio/aacp:aac:MPEG-4 AACPlus Music;" \ + "audio/basic:snd,au:Basic Audio;" \ + "audio/x-wav:wav:WAV Audio;" \ + "audio/3gpp:3gp,3gpp:3GPP/MMS Music;" \ + "audio/3gpp2:3g2,3gp2:3GPP2/MMS Music;" \ + "video/mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \ + "video/x-mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \ + "video/mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \ + "video/x-mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \ + "video/avi:avi:AVI Video;" \ + "video/quicktime:mov,qt:QuickTime Movies;" \ + "video/x-ms-asf:asf,asx:Windows Media Video;" \ + "video/x-ms-wmv:wmv:Windows Media;" \ + "video/mp4:mp4,mpg4:MPEG-4 Video;" \ + "video/3gpp:3gp,3gpp:3GPP/MMS Video;" \ + "video/3gpp2:3g2,3gp2:3GPP2/MMS Video;" \ + "image/jpeg:jpeg,jpg:JPEG Images;" \ + "image/png:png:PNG Images;" \ + "image/bmp:bmp:MS Bitmap Images;" \ + "image/svg+xml:svg,svg.gz,svgz:SVG Document;" \ + "image/x-svgm:svgm:SVGM Document;" \ + "x-subtitle/srt:srt:SRT SubTitles;" \ + "x-subtitle/sub:sub:SUB SubTitles;" \ + "x-subtitle/ttxt:ttxt:GPAC 3GPP TimedText;" \ + "model/vrml:wrl,wrl.gz:VRML World;" \ + "model/x3d+vrml:x3dv,x3dv.gz,x3dvz:X3D/VRML World;" \ + "model/x3d+xml:x3d,x3d.gz,x3dz:X3D/XML World;" \ + "application/ogg:ogg:Ogg Media;" \ + "application/x-ogg:ogg:Ogg Media;" \ + "application/x-bt:bt,bt.gz,btz:MPEG-4 Text (BT);" \ + "application/x-xmt:xmt,xmt.gz,xmtz:MPEG-4 Text (XMT);" \ + "application/mp4:mp4,mpg4:MPEG-4 Movies;" \ + "application/sdp:sdp:Streaming Media Session;" \ + /* explicit plugin call */ \ + "application/x-gpac::GPAC plugin;" \ + +char * NP_GetMIMEDescription(void) +{ + return (char *) GPAC_PLUGIN_MIMETYPES; +} + + +NPError NP_GetValue(void *future, NPPVariable aVariable, void *aValue) +{ + return NS_PluginGetValue(aVariable, aValue); +} + + +#if defined(XP_WIN) || defined(XP_MACOS) + +NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs) +{ + sBrowserFunctions = aNPNFuncs; + + return NS_PluginInitialize(); +} + +NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* aNPPFuncs) +{ + return fillPluginFunctionTable(aNPPFuncs); +} + + +#elif defined(XP_UNIX) + +NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs, NPPluginFuncs* aNPPFuncs) +{ + NPError rv; + sBrowserFunctions = aNPNFuncs; + rv = fillPluginFunctionTable(aNPPFuncs); + if(rv != NPERR_NO_ERROR) + return rv; + + return NS_PluginInitialize(); +} +#endif + + +#ifdef GECKO_XPCOM + + +#include +#include +#include +#include +#include + +#include "nsIOsmozilla.h" + +#include "osmozilla.h" + + +nsIServiceManager *gServiceManager = NULL; + + +// We must implement nsIClassInfo because it signals the +// Mozilla Security Manager to allow calls from JavaScript. +// helper class to implement all necessary nsIClassInfo method stubs +// and to set flags used by the security system + +class nsClassInfoMixin : public nsIClassInfo +{ + // These flags are used by the DOM and security systems to signal that + // JavaScript callers are allowed to call this object's scritable methods. + NS_IMETHOD GetFlags(PRUint32 *aFlags) + { *aFlags = nsIClassInfo::PLUGIN_OBJECT | nsIClassInfo::DOM_OBJECT; + return NS_OK; + } + + NS_IMETHOD GetImplementationLanguage(PRUint32 *aImplementationLanguage) + { *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK; + } + + // The rest of the methods can safely return error codes... + NS_IMETHOD GetInterfaces(PRUint32 *count, nsIID ***array) + { + return NS_ERROR_NOT_IMPLEMENTED; + } + NS_IMETHOD GetHelperForLanguage(PRUint32 language, nsISupports **_retval) + { + return NS_ERROR_NOT_IMPLEMENTED; + } + NS_IMETHOD GetContractID(char **aContractID) + { + return NS_ERROR_NOT_IMPLEMENTED; + } + NS_IMETHOD GetClassDescription(char **aClassDescription) + { + return NS_ERROR_NOT_IMPLEMENTED; + } + NS_IMETHOD GetClassID(nsCID **aClassID) + { + return NS_ERROR_NOT_IMPLEMENTED; + } + NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) + { + return NS_ERROR_NOT_IMPLEMENTED; + } +}; + + +class nsOsmozillaPeer : public nsIOsmozilla , public nsClassInfoMixin +{ +public: + nsOsmozillaPeer(Osmozilla *osmo); + virtual ~nsOsmozillaPeer(); + + // methods from nsISupports + NS_IMETHOD QueryInterface(const nsIID & aIID, void **aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(); + NS_IMETHOD_(nsrefcnt) Release(); + +public: + NS_DECL_NSIOSMOZILLA + void SetInstance(Osmozilla *osmo); + +protected: + nsrefcnt mRefCnt; + Osmozilla *mPlugin; +}; + + +static NS_DEFINE_IID(kIZillaPluginIID, NS_IOSMOZILLA_IID); +static NS_DEFINE_IID(kIClassInfoIID, NS_ICLASSINFO_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +nsOsmozillaPeer::nsOsmozillaPeer(Osmozilla *osmo) +{ + mPlugin=osmo; + mRefCnt = 0; +} + +nsOsmozillaPeer::~nsOsmozillaPeer() +{ +} +// Notice that we expose our claim to implement nsIClassInfo. +//NS_IMPL_ISUPPORTS2(nsOsmozillaPeer, nsITestPlugin, nsIClassInfo) + +// the following method will be callable from JavaScript +NS_IMETHODIMP nsOsmozillaPeer::Pause() { + Osmozilla_Pause(mPlugin); + return NS_OK; +} +NS_IMETHODIMP nsOsmozillaPeer::Play() { + Osmozilla_Play(mPlugin); + return NS_OK; +} +NS_IMETHODIMP nsOsmozillaPeer::Stop() { + Osmozilla_Stop(mPlugin); + return NS_OK; +} + +NS_IMETHODIMP nsOsmozillaPeer::Update(const char *type, const char *commands) +{ + Osmozilla_Update(mPlugin, type, commands); + return NS_OK; +} + +NS_IMETHODIMP nsOsmozillaPeer::QualitySwitch(int switch_up) +{ + Osmozilla_QualitySwitch(mPlugin, switch_up); + return NS_OK; +} + +NS_IMETHODIMP nsOsmozillaPeer::SetURL(const char *url) +{ + Osmozilla_SetURL(mPlugin, url); + return NS_OK; +} + +void nsOsmozillaPeer::SetInstance(Osmozilla *osmo) +{ + mPlugin = osmo; +} + +NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::AddRef() +{ + ++mRefCnt; + return mRefCnt; +} + +NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::Release() +{ + --mRefCnt; + if (mRefCnt == 0) { + delete this; + return 0; + } + return mRefCnt; +} + +// here nsOsmozillaPeer should return three interfaces it can be asked for by their iid's +// static casts are necessary to ensure that correct pointer is returned +NS_IMETHODIMP nsOsmozillaPeer::QueryInterface(const nsIID & aIID, + void **aInstancePtr) +{ + if (!aInstancePtr) + return NS_ERROR_NULL_POINTER; + + if (aIID.Equals(kIZillaPluginIID)) { + *aInstancePtr = NS_STATIC_CAST(nsIOsmozilla *, this); + AddRef(); + return NS_OK; + } + + if (aIID.Equals(kIClassInfoIID)) { + *aInstancePtr = NS_STATIC_CAST(nsIClassInfo *, this); + AddRef(); + return NS_OK; + } + + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = NS_STATIC_CAST(nsISupports *, (NS_STATIC_CAST (nsIOsmozilla *, this))); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + +extern NPNetscapeFuncs *sBrowserFunctions; + +void NPOsmozilla_GetServiceManager() +{ + // this is probably a good place to get the service manager + // note that Mozilla will add reference, so do not forget to release + nsISupports *sm = NULL; + + if (!sBrowserFunctions) return; + sBrowserFunctions->getvalue(NULL, NPNVserviceManager, &sm); + + // Mozilla returns nsIServiceManager so we can use it directly; doing QI on + // nsISupports here can still be more appropriate in case something is changed + // in the future so we don't need to do casting of any sort. + if (sm) { + sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void **) &gServiceManager); + NS_RELEASE(sm); + } +} + +void NPOsmozilla_ReleaseServiceManager() +{ +#ifdef GECKO_XPCOM + // we should release the service manager + NS_IF_RELEASE(gServiceManager); + gServiceManager = NULL; +#endif +} + +void NPOsmozilla_ShutdownScript(Osmozilla *osmo) +{ + nsOsmozillaPeer *peer = (nsOsmozillaPeer *) osmo->scriptable_peer; + if (peer != NULL) { + peer->SetInstance(NULL); + NS_IF_RELEASE(peer); + } +} + + +NPError NPOsmozilla_GetPeer(Osmozilla *osmo, void *value) +{ + if (!osmo->scriptable_peer) { + osmo->scriptable_peer = new nsOsmozillaPeer(osmo); + if (!osmo->scriptable_peer) return NPERR_OUT_OF_MEMORY_ERROR; + NS_ADDREF( (nsOsmozillaPeer *) osmo->scriptable_peer); + } + + NS_ADDREF( (nsOsmozillaPeer *)osmo->scriptable_peer); + *(nsISupports **) value = (nsISupports *) osmo->scriptable_peer; + return NPERR_NO_ERROR; +} + +NPError NPOsmozilla_GetPeerIID(Osmozilla *osmo, void *value) +{ + static nsIID scriptableIID = NS_IOSMOZILLA_IID; + if (!sBrowserFunctions) return NPERR_OUT_OF_MEMORY_ERROR; + + nsIID *ptr = (nsIID *) sBrowserFunctions->memalloc( sizeof(nsIID) ); + if (! ptr) return NPERR_OUT_OF_MEMORY_ERROR; + + *ptr = scriptableIID; + *(nsIID **) value = ptr; + return NPERR_NO_ERROR; +} + +#else + +enum +{ + kOSMOZILLA_ID_METHOD_PLAY = 0, + kOSMOZILLA_ID_METHOD_PAUSE, + kOSMOZILLA_ID_METHOD_STOP, + kOSMOZILLA_ID_METHOD_UPDATE, + kOSMOZILLA_ID_METHOD_QUALITY_SWITCH, + kOSMOZILLA_ID_METHOD_SET_URL, + + kOSMOZILLA_NUM_METHODS +}; + +NPIdentifier v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_NUM_METHODS]; +const NPUTF8 * v_OSMOZILLA_MethodNames[kOSMOZILLA_NUM_METHODS] = { + "Play", + "Pause", + "Stop", + "Update", + "QualitySwitch", + "SetURL", +}; + +NPClass osmozilla_script_class; + +typedef struct { + NPClass *_class; + uint32_t referenceCount; + Osmozilla *osmo; +} OsmozillaObject; + +NPObject *OSMOZILLA_Allocate(NPP npp, NPClass *theClass) +{ + OsmozillaObject *obj = NULL; + + sBrowserFunctions->getstringidentifiers(v_OSMOZILLA_MethodNames, kOSMOZILLA_NUM_METHODS, v_OSMOZILLA_MethodIdentifiers); + obj = (OsmozillaObject *)malloc(sizeof(OsmozillaObject)); + obj->osmo = (Osmozilla *) npp->pdata; + return (NPObject *)obj; +} + +void OSMOZILLA_Deallocate(NPObject* obj) +{ + free(obj); + return; +} + +void OSMOZILLA_Invalidate(NPObject* obj) +{ + return; +} + +bool OSMOZILLA_HasMethod(NPObject* obj, NPIdentifier name) +{ + int i = 0; + while (i < kOSMOZILLA_NUM_METHODS) { + if ( name == v_OSMOZILLA_MethodIdentifiers[i] ) { + return 1; + } + i++; + } + return 0; +} + +bool OSMOZILLA_Invoke(NPObject* obj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) +{ + OsmozillaObject *npo = (OsmozillaObject *)obj; + if (!npo->osmo) return 0; + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_PLAY]) { + Osmozilla_Play(npo->osmo); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_PAUSE]) { + Osmozilla_Pause(npo->osmo); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_STOP]) { + Osmozilla_Stop(npo->osmo); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_UPDATE]) { + const char *mime = NULL; + const char *update = NULL; + if (argCount==2) { + mime = (args[0].type==NPVariantType_String) ? args[0].value.stringValue.UTF8Characters : NULL; + update = (args[1].type==NPVariantType_String) ? args[1].value.stringValue.UTF8Characters : NULL; + } + if (!update) return 0; + Osmozilla_Update(npo->osmo, mime, update); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_QUALITY_SWITCH]) { + int up = 1; + if (argCount==1) { + if (args[0].type==NPVariantType_Bool) up = args[0].value.boolValue ? 1 : 0; + else if (args[0].type==NPVariantType_Int32) up = args[0].value.intValue ? 1 : 0; + } + Osmozilla_QualitySwitch(npo->osmo, up); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_SET_URL]) { + const char *url = ""; + if (argCount>=1) { + if (args[0].type==NPVariantType_String) + url = args[0].value.stringValue.UTF8Characters; + } + Osmozilla_SetURL(npo->osmo, url); + return 1; + } + return 0; +} + +bool OSMOZILLA_InvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + return 1; +} + +bool OSMOZILLA_HasProperty(NPObject* obj, NPIdentifier name) +{ + bool result = 0; + if ( sBrowserFunctions->identifierisstring(name) ) + { + NPUTF8 *val = sBrowserFunctions->utf8fromidentifier(name); + + if ( !strcmp(val, "DownloadProgress") ) + { + result = 1; + } + + sBrowserFunctions->memfree(val); + } + /*nothing exposed yet*/ + return result; +} + +bool OSMOZILLA_GetProperty(NPObject* obj, NPIdentifier name, NPVariant* result) +{ + OsmozillaObject *npo = (OsmozillaObject *)obj; + if (!npo->osmo) return 0; + if ( sBrowserFunctions->identifierisstring(name) ) + { + NPUTF8 *val = sBrowserFunctions->utf8fromidentifier(name); + + if ( !strcmp(val, "DownloadProgress") ) + { + int val = Osmozilla_GetDownloadProgress(npo->osmo); + INT32_TO_NPVARIANT(val, *result); + } + + sBrowserFunctions->memfree(val); + } + return 1; +} + +bool OSMOZILLA_SetProperty(NPObject *obj, NPIdentifier name, const NPVariant *value) +{ + return 1; +} + +bool OSMOZILLA_RemoveProperty(NPObject *npobj, NPIdentifier name) +{ + return 1; +} + +bool OSMOZILLA_Enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) +{ + return 1; +} + +void Osmozilla_InitScripting(Osmozilla *osmo) +{ + osmozilla_script_class.allocate = OSMOZILLA_Allocate; + osmozilla_script_class.deallocate = OSMOZILLA_Deallocate; + osmozilla_script_class.invalidate = OSMOZILLA_Invalidate; + osmozilla_script_class.hasMethod = OSMOZILLA_HasMethod; + osmozilla_script_class.invoke = OSMOZILLA_Invoke; + osmozilla_script_class.invokeDefault = OSMOZILLA_InvokeDefault; + osmozilla_script_class.hasProperty = OSMOZILLA_HasProperty; + osmozilla_script_class.getProperty = OSMOZILLA_GetProperty; + osmozilla_script_class.setProperty = OSMOZILLA_SetProperty; + osmozilla_script_class.removeProperty = OSMOZILLA_RemoveProperty; + osmozilla_script_class.enumerate = OSMOZILLA_Enumerate; + + /*create script object*/ + osmo->script_obj = sBrowserFunctions->createobject(osmo->np_instance, &osmozilla_script_class); + +} + +#endif //GECKO_XPCOM + diff --git a/applications/deprecated/old_arch/osmozilla/osmo_npapi.h b/applications/deprecated/old_arch/osmozilla/osmo_npapi.h new file mode 100644 index 0000000..a7a83ae --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/osmo_npapi.h @@ -0,0 +1,136 @@ +/* +* GPAC - Multimedia Framework C SDK +* + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 +* All rights reserved +* +* This file is part of GPAC / Osmozilla NPAPI plugin +* +* 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 _OSMO_NPAPI_H_ +#define _OSMO_NPAPI_H_ + + +#ifdef WIN32 +#include +#ifndef __cplusplus +typedef BOOL bool; +#endif //__cplusplus +#endif + +#include "npapi.h" + +/*check this with gecko 1.9.2*/ +#if (NP_VERSION_MINOR < 20) +#define GECKO_XPCOM +#endif + +#ifdef GECKO_XPCOM +#include "npupp.h" + +#ifndef uint16_t +typedef uint16 uint16_t; +#endif + +#ifndef int16_t +typedef int16 int16_t; +#endif + +#define NPINT32 int32 + +#else + +#include "npfunctions.h" + +#define NPINT32 int32_t + +#endif + +#ifdef XP_UNIX +#include +#endif //XP_UNIX + + +#ifndef HIBYTE +#define HIBYTE(i) (i >> 8) +#endif + +#ifndef LOBYTE +#define LOBYTE(i) (i & 0xff) +#endif + +/*functions callbacks to browser*/ +NPError Osmozilla_GetURL(NPP instance, const char *url, const char *target); +void Osmozilla_SetStatus(NPP instance, const char *message); + + +/* +Plugins functions exposed to browser +*/ +NPError NPOsmozilla_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved); +NPError NPOsmozilla_Destroy(NPP instance, NPSavedData** save); +NPError NPOsmozilla_SetWindow(NPP instance, NPWindow* window); +NPError NPOsmozilla_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype); +NPError NPOsmozilla_DestroyStream(NPP instance, NPStream* stream, NPError reason); +NPINT32 NPOsmozilla_WriteReady(NPP instance, NPStream* stream); +NPINT32 NPOsmozilla_Write(NPP instance, NPStream* stream, NPINT32 offset, NPINT32 len, void* buffer); +void NPOsmozilla_StreamAsFile(NPP instance, NPStream* stream, const char* fname); +void NPOsmozilla_Print(NPP instance, NPPrint* platformPrint); +int16_t NPOsmozilla_HandleEvent(NPP instance, void* event); +void NPOsmozilla_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData); +NPError NPOsmozilla_GetValue(NPP instance, NPPVariable variable, void *result); +NPError NPOsmozilla_SetValue(NPP instance, NPNVariable variable, void *value); + + +/* +Functions called by browser +*/ + +typedef struct __tag_osmozilla Osmozilla; + +/*base functions*/ +int Osmozilla_Initialize(Osmozilla *osmo, signed short argc, char* argn[], char* argv[]); +void Osmozilla_Shutdown(Osmozilla *osmo); +int Osmozilla_SetWindow(Osmozilla *osmozilla, void *os_wnd_handle, void *os_wnd_display, unsigned int width, unsigned int height); +void Osmozilla_ConnectTo(Osmozilla *osmozilla, const char *url); +void Osmozilla_Print(Osmozilla *osmozilla, unsigned int is_embed, void *os_print_dc, unsigned int target_x, unsigned int target_y, unsigned int target_width, unsigned int target_height); +char *Osmozilla_GetVersion(); + + +/*scripting functions*/ +void Osmozilla_Play(Osmozilla *osmo); +void Osmozilla_Pause(Osmozilla *osmo); +void Osmozilla_Stop(Osmozilla *osmo); +void Osmozilla_Update(Osmozilla *osmo, const char *type, const char *commands); +void Osmozilla_QualitySwitch(Osmozilla *osmo, int switch_up); +void Osmozilla_SetURL(Osmozilla *osmo, const char *url); +int Osmozilla_GetDownloadProgress(Osmozilla *osmo); + + +#ifdef GECKO_XPCOM + +void NPOsmozilla_GetServiceManager(); +void NPOsmozilla_ReleaseServiceManager(); +void NPOsmozilla_ShutdownScript(Osmozilla *osmo); +NPError NPOsmozilla_GetPeer(Osmozilla *osmo, void *value); +NPError NPOsmozilla_GetPeerIID(Osmozilla *osmo, void *value); + +#endif //GECKO_XPCOM + +#endif //_NPPLAT_H_ diff --git a/applications/deprecated/old_arch/osmozilla/osmozilla.cpp b/applications/deprecated/old_arch/osmozilla/osmozilla.cpp new file mode 100644 index 0000000..2f0b26e --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/osmozilla.cpp @@ -0,0 +1,531 @@ +/* +* GPAC - Multimedia Framework C SDK +* + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 +* All rights reserved +* +* This file is part of GPAC / Osmozilla NPAPI plugin +* +* 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 "osmozilla.h" + +#ifdef XP_WIN +#include +#endif + +#include +#include +#include + + +short Osmozilla_GetURL(NPP instance, const char *url, const char *target); +void Osmozilla_SetStatus(NPP instance, const char *message); + + +void Osmozilla_Shutdown(Osmozilla *osmo) +{ + if (osmo->url) gf_free(osmo->url); + osmo->url = NULL; + if (osmo->term) { + GF_Terminal *a_term = osmo->term; + osmo->term = NULL; + gf_term_del(a_term); + } + if (osmo->user) { + if (osmo->user->modules) gf_modules_del(osmo->user->modules); + if (osmo->user->config) gf_cfg_del(osmo->user->config); + gf_free(osmo->user); + osmo->user = NULL; + } +} + +static void osmozilla_do_log(void *cbk, GF_LOG_Level level, GF_LOG_Tool tool, const char *fmt, va_list list) +{ + FILE *logs = (FILE *) cbk; + vfprintf(logs, fmt, list); + fflush(logs); +} + + +Bool Osmozilla_EventProc(void *opaque, GF_Event *evt) +{ + char msg[1024]; + Osmozilla *osmo = (Osmozilla *)opaque; + if (!osmo->term) return GF_FALSE; + + switch (evt->type) { + case GF_EVENT_MESSAGE: + if (!evt->message.message) return GF_FALSE; + if (evt->message.error) + sprintf((char *)msg, "GPAC: %s (%s)", evt->message.message, gf_error_to_string(evt->message.error)); + else + sprintf((char *)msg, "GPAC: %s", evt->message.message); + + Osmozilla_SetStatus(osmo->np_instance, msg); + break; + case GF_EVENT_PROGRESS: + if (evt->progress.done == evt->progress.total) { + Osmozilla_SetStatus(osmo->np_instance, ""); + osmo->download_progress = 100; + } else { + char *szTitle = (char *)""; + if (evt->progress.progress_type==0) szTitle = (char *)"Buffer "; + else if (evt->progress.progress_type==1) + { + szTitle = (char *)"Download "; + osmo->download_progress = (int) (100.0*evt->progress.done) / evt->progress.total; + } + 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); + Osmozilla_SetStatus(osmo->np_instance, msg); + } + break; + + /*IGNORE any scene size, just work with the size allocated in the parent doc*/ + case GF_EVENT_SCENE_SIZE: + gf_term_set_size(osmo->term, osmo->width, osmo->height); + break; + /*window has been resized (full-screen plugin), resize*/ + case GF_EVENT_SIZE: + osmo->width = evt->size.width; + osmo->height = evt->size.height; + gf_term_set_size(osmo->term, osmo->width, osmo->height); + break; + case GF_EVENT_CONNECT: + osmo->is_connected = evt->connect.is_connected; + break; + case GF_EVENT_DURATION: + osmo->can_seek = evt->duration.can_seek; + osmo->duration = evt->duration.duration; + break; + case GF_EVENT_DBLCLICK: + gf_term_set_option(osmo->term, GF_OPT_FULLSCREEN, !gf_term_get_option(osmo->term, GF_OPT_FULLSCREEN)); + break; + case GF_EVENT_NAVIGATE_INFO: + strcpy(msg, evt->navigate.to_url); + Osmozilla_SetStatus(osmo->np_instance, msg); + break; + case GF_EVENT_NAVIGATE: + if (gf_term_is_supported_url(osmo->term, evt->navigate.to_url, GF_TRUE, osmo->disable_mime ? GF_TRUE : GF_FALSE)) { + gf_term_navigate_to(osmo->term, evt->navigate.to_url); + return GF_TRUE; + } else { + u32 i; + char *target = (char *)"_self"; + + for (i=0; inavigate.param_count; i++) { + 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; + } + Osmozilla_GetURL(osmo->np_instance, evt->navigate.to_url, target); + return GF_TRUE; + } + break; + } + return GF_FALSE; +} + +int Osmozilla_Initialize(Osmozilla *osmo, signed short argc, char* argn[], char* argv[]) +{ + const char *str; + int i; + osmo->auto_start = 1; + osmo->use_gui = 0; + + /*options sent from plugin*/ + for(i=0; iauto_start = 0; + + else if (!stricmp(argn[i],"src") ) { + if (osmo->url) gf_free(osmo->url); + osmo->url = gf_strdup(argv[i]); + } + else if (!stricmp(argn[i],"use3d") && (!stricmp(argv[i], "true") || !stricmp(argv[i], "yes") ) ) { + osmo->use_3d = 1; + } + else if (!stricmp(argn[i],"loop") && (!stricmp(argv[i], "true") || !stricmp(argv[i], "yes") ) ) { + osmo->loop = 1; + } + else if (!stricmp(argn[i],"aspectratio")) { + osmo->aspect_ratio = GF_ASPECT_RATIO_KEEP; + if (!stricmp(argv[i], "keep")) osmo->aspect_ratio = GF_ASPECT_RATIO_KEEP; + else if (!stricmp(argv[i], "16:9")) osmo->aspect_ratio = GF_ASPECT_RATIO_16_9; + else if (!stricmp(argv[i], "4:3")) osmo->aspect_ratio = GF_ASPECT_RATIO_4_3; + else if (!stricmp(argv[i], "fill")) osmo->aspect_ratio = GF_ASPECT_RATIO_FILL_SCREEN; + } + else if (!stricmp(argn[i],"gui") && (!stricmp(argv[i], "true") || !stricmp(argv[i], "yes") ) ) + osmo->use_gui = 1; + } + + /*URL is not absolute, request new stream to mozilla - we don't pass absolute URLs since some may not be + handled by gecko */ + if (osmo->url) { + Bool absolute_url = GF_FALSE; + if (strstr(osmo->url, "://")) absolute_url = GF_TRUE; + else if (osmo->url[0] == '/') { + FILE *test = gf_fopen(osmo->url, "rb"); + if (test) { + absolute_url = GF_TRUE; + gf_fclose(test); + } + } + else if ((osmo->url[1] == ':') && ((osmo->url[2] == '\\') || (osmo->url[2] == '/'))) absolute_url = GF_TRUE; + + if (!absolute_url) { + char *url = osmo->url; + osmo->url = NULL; + Osmozilla_GetURL(osmo->np_instance, url, NULL); + gf_free(url); + } + } + + GF_SAFEALLOC(osmo->user, GF_User); + osmo->user->config = gf_cfg_init(NULL, NULL); + /*need to have a valid cfg file for now*/ + if (!osmo->user->config) { + gf_free(osmo->user); + osmo->user = NULL; +#ifdef WIN32 + MessageBox(NULL, "GPAC CONFIGURATION FILE NOT FOUND OR INVALID", "OSMOZILLA FATAL ERROR", MB_OK); +#else + fprintf(stdout, "OSMOZILLA FATAL ERROR\nGPAC CONFIGURATION FILE NOT FOUND OR INVALID\n"); +#endif + return 0; + } + + osmo->user->modules = gf_modules_new(NULL, osmo->user->config); + if (!gf_modules_get_count(osmo->user->modules)) { + if (osmo->user->modules) gf_modules_del(osmo->user->modules); + gf_free(osmo->user); + osmo->user = NULL; +#ifdef WIN32 + MessageBox(NULL, "GPAC MODULES NOT FOUND", "OSMOZILLA FATAL ERROR", MB_OK); +#else + fprintf(stdout, "OSMOZILLA FATAL ERROR\nGPAC MODULES NOT FOUND\n"); +#endif + return 0; + } + + osmo->user->opaque = osmo; + osmo->user->EventProc = Osmozilla_EventProc; + + /*always fetch mime ? Check with anchor examples*/ + osmo->disable_mime = 0; + str = gf_cfg_get_key(osmo->user->config, "General", "NoMIMETypeFetch"); + if (str && !strcmp(str, "yes")) osmo->disable_mime = 0; + /*check log file*/ + str = gf_cfg_get_key(osmo->user->config, "General", "LogFile"); + if (str) { + osmo->logs = gf_fopen(str, "wt"); + if (osmo->logs) gf_log_set_callback(osmo->logs, osmozilla_do_log); + } + + /*setup logs*/ + if (gf_log_set_tools_levels(gf_cfg_get_key(osmo->user->config, "General", "Logs")) != GF_OK) + fprintf(stdout, "Osmozilla: invalid log level specified\n"); + + fprintf(stdout, "Osmozilla initialized\n"); + return 1; +} + +int Osmozilla_SetWindow(Osmozilla *osmo, void *os_wnd_handle, void *os_wnd_display, unsigned int width, unsigned int height) +{ + const char *gui; + + if (!osmo->user) return 0; + + if (osmo->window_set) { + osmo->width = width; + osmo->height = height; + if (osmo->is_connected) gf_term_set_size(osmo->term, osmo->width, osmo->height); + return 1; + } + if (!os_wnd_handle) return 0; + + osmo->width = width; + osmo->height = height; + + osmo->user->os_window_handler = os_wnd_handle; + osmo->user->os_display = os_wnd_display; + + /*Everything is now setup, create the terminal*/ + fprintf(stdout, "Creating Osmozilla terminal\n"); + osmo->term = gf_term_new(osmo->user); + if (!osmo->term) return 0; + fprintf(stdout, "Osmozilla terminal created\n"); + + gf_term_set_option(osmo->term, GF_OPT_ASPECT_RATIO, osmo->aspect_ratio); + osmo->window_set = 1; + +#ifdef XP_WIN + SetFocus((HWND)os_wnd_handle); +#endif + + /*stream not ready*/ + if (!osmo->url || !osmo->auto_start) { + fprintf(stdout, "Osmozilla ready - not connecting to %s yet\n", osmo->url); + return 1; + } + + /*connect from 0 and pause if not autoplay*/ + gui = gf_cfg_get_key(osmo->user->config, "General", "StartupFile"); + if (gui && osmo->use_gui) { + gf_cfg_set_key(osmo->user->config, "Temp", "BrowserMode", "yes"); + gf_cfg_set_key(osmo->user->config, "Temp", "GUIStartupFile", osmo->url); + gf_term_connect(osmo->term, gui); + } else { + gf_term_connect(osmo->term, osmo->url); + } + fprintf(stdout, "Osmozilla connected to %s\n", osmo->url); + return 1; +} + +char *Osmozilla_GetVersion() +{ + return (char *) "GPAC Plugin " GPAC_FULL_VERSION " for NPAPI compatible Web Browsers. For more information go to GPAC website"; +} + +void Osmozilla_ConnectTo(Osmozilla *osmo, const char *url) +{ + if (!osmo->user) return; + + if ( osmo->url && !strcmp(url, osmo->url)) + return; + + fprintf(stdout, "Osmozilla connecting to %s\n", url); + + if (osmo->url) gf_free(osmo->url); + osmo->url = gf_strdup(url); + + /*connect from 0 and pause if not autoplay*/ + if (osmo->auto_start) { + const char *gui = gf_cfg_get_key(osmo->user->config, "General", "StartupFile"); + if (gui && osmo->use_gui) { + gf_cfg_set_key(osmo->user->config, "Temp", "BrowserMode", "yes"); + gf_cfg_set_key(osmo->user->config, "Temp", "GUIStartupFile", url); + gf_term_connect(osmo->term, gui); + } else { + gf_term_connect(osmo->term, url); + } + } + fprintf(stdout, "Osmozilla connected to %s\n", url); +} + +void Osmozilla_Pause(Osmozilla *osmo) +{ + if (osmo->term) { + if (gf_term_get_option(osmo->term, GF_OPT_PLAY_STATE) == GF_STATE_PAUSED) { + gf_term_set_option(osmo->term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + } else { + gf_term_set_option(osmo->term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + } + } +} + +void Osmozilla_Play(Osmozilla *osmo) +{ + if (!osmo->is_connected) { + if (osmo->url) gf_term_connect(osmo->term, (const char *) osmo->url); + } else { + gf_term_set_option(osmo->term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + } +} + +void Osmozilla_Stop(Osmozilla *osmo) +{ + if (osmo->term) gf_term_disconnect(osmo->term); +} + +#ifdef XP_WIN +PBITMAPINFO CreateBitmapInfoStruct(GF_VideoSurface *pfb) +{ + PBITMAPINFO pbmi; + WORD cClrBits; + + cClrBits = 32; + + pbmi = (PBITMAPINFO) LocalAlloc(LPTR, + sizeof(BITMAPINFOHEADER)); + + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pfb->width; + pbmi->bmiHeader.biHeight = 1; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = cClrBits; + + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 + * pbmi->bmiHeader.biHeight; + pbmi->bmiHeader.biClrImportant = 0; + return pbmi; +} +#endif + +void Osmozilla_Print(Osmozilla *osmo, unsigned int is_embed, void *os_print_dc, unsigned int target_x, unsigned int target_y, unsigned int target_width, unsigned int target_height) +{ + if (is_embed) { +#ifdef XP_MACOS + /* + os_print_dc contains a THPrint reference on MacOS + */ + } +#endif // XP_MACOS +#ifdef XP_UNIX + /* + os_print_dc contains a NPPrintCallbackStruct on Unix and + the plug-in location and size in the NPWindow are in page coordinates (720/ inch), but the printer requires point coordinates (72/inch) + */ +#endif // XP_UNIX +#ifdef XP_WIN + /* + The coordinates for the window rectangle are in TWIPS format. + This means that you need to convert the x-y coordinates using the Windows API call DPtoLP when you output text + */ + GF_VideoSurface fb; + u32 xsrc, ysrc; + u16 src_16; + char *src; + float deltay; + int ysuiv = 0; + char *ligne; + BITMAPINFO *infoSrc; + HDC pDC = (HDC)os_print_dc; + /*lock the source buffer */ + gf_term_get_screen_buffer(osmo->term, &fb); + infoSrc = CreateBitmapInfoStruct(&fb); + deltay = (float)target_height/(float)fb.height; + ligne = (char *) LocalAlloc(GMEM_FIXED, fb.width*4); + for (ysrc=0; ysrc> 8) & 0xf8; + dst[2] += dst[2]>>5; + dst[1] = (src_16 >> 3) & 0xfc; + dst[1] += dst[1]>>6; + dst[0] = (src_16 << 3) & 0xf8; + dst[0] += dst[0]>>5; + src+=2; + break; + case GF_PIXEL_RGB_555: + src_16 = * (u16 *)src; + dst[2] = (src_16 >> 7) & 0xf8; + dst[2] += dst[2]>>5; + dst[1] = (src_16 >> 2) & 0xf8; + dst[1] += dst[1]>>5; + dst[0] = (src_16 << 3) & 0xf8; + dst[0] += dst[0]>>5; + src+=2; + break; + } + dst += 4; + } + ycrt = ysuiv; + ysuiv = (u32) ( ((float)ysrc+1.0)*deltay); + delta = ysuiv-ycrt; + StretchDIBits( + pDC, target_x, target_y, target_width, + delta, + 0, 0, fb.width, 1, + ligne, infoSrc, DIB_RGB_COLORS, SRCCOPY); + } + + /*unlock GPAC frame buffer */ + gf_term_release_screen_buffer(osmo->term, &fb); + /* gf_free temporary objects */ + GlobalFree(ligne); + LocalFree(infoSrc); +#endif // XP_WIN + + return; +} + +/*TODO - this is full print, present the print dialog and manage the print*/ +} + +void Osmozilla_Update(Osmozilla *osmo, const char *type, const char *commands) +{ + if (osmo->term) { + GF_Err e = gf_term_scene_update(osmo->term, (char *) type, (char *) commands); + if (e) { + char szMsg[1024]; + sprintf((char *)szMsg, "GPAC: Error applying update (%s)", gf_error_to_string(e) ); + Osmozilla_SetStatus(osmo->np_instance, szMsg); + } + } +} + +void Osmozilla_QualitySwitch(Osmozilla *osmo, int switch_up) +{ + if (osmo->term) + gf_term_switch_quality(osmo->term, switch_up ? GF_TRUE : GF_FALSE); +} + +void Osmozilla_SetURL(Osmozilla *osmo, const char *url) +{ + if (osmo->term) { + if (osmo->url) gf_free(osmo->url); + osmo->url = gf_strdup(url); + gf_term_connect(osmo->term, osmo->url); + } +} + +int Osmozilla_GetDownloadProgress(Osmozilla *osmo) +{ + if (osmo->term) + return osmo->download_progress; + return 0; +} diff --git a/applications/deprecated/old_arch/osmozilla/osmozilla.def b/applications/deprecated/old_arch/osmozilla/osmozilla.def new file mode 100644 index 0000000..5d5bbb1 --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/osmozilla.def @@ -0,0 +1,6 @@ +LIBRARY nposmozilla + +EXPORTS + NP_GetEntryPoints @1 + NP_Initialize @2 + NP_Shutdown @3 diff --git a/applications/deprecated/old_arch/osmozilla/osmozilla.h b/applications/deprecated/old_arch/osmozilla/osmozilla.h new file mode 100644 index 0000000..9556ac4 --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/osmozilla.h @@ -0,0 +1,75 @@ +/* +* GPAC - Multimedia Framework C SDK +* + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 +* All rights reserved +* +* This file is part of GPAC / Osmozilla NPAPI plugin +* +* 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 __OSMOZILLA_H__ +#define __OSMOZILLA_H__ + + +/*DO NOT INCLUDE ANY GPAC FILE IN THIS HEADER, IT CAUSES TYPE REDEFINITION CONFLICT ON OSX*/ +typedef struct _tag_terminal GF_Terminal; +typedef struct _tag_user GF_User; + +#include + + +typedef struct _NPP *NPP; + +typedef struct __tag_osmozilla +{ + /*plugiun & window info*/ + NPP np_instance; + int window_set; + unsigned int height, width; + + int supports_xembed; + /*GPAC term*/ + GF_User *user; + GF_Terminal *term; + + /*general options*/ + unsigned int loop, auto_start, is_connected, use_3d, disable_mime; + unsigned int aspect_ratio; + + /*the URL we are connected to*/ + char *url; + /*timing info of current url*/ + double duration; + char can_seek; + int use_gui; + int download_progress; + + /*log file if any*/ + FILE *logs; + +#ifdef GECKO_XPCOM + void *scriptable_peer; +#else + struct NPObject *script_obj; +#endif + +} Osmozilla; + + +#endif // __OSMOZILLA_H__ diff --git a/applications/deprecated/old_arch/osmozilla/osmozilla.png b/applications/deprecated/old_arch/osmozilla/osmozilla.png new file mode 100644 index 0000000000000000000000000000000000000000..6f66a17b1edda041995dfdee6d4baae64b040a71 GIT binary patch literal 121239 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 Gxb=Tf0re~Z literal 0 HcmV?d00001 diff --git a/applications/deprecated/old_arch/osmozilla/osmozilla.rc b/applications/deprecated/old_arch/osmozilla/osmozilla.rc new file mode 100644 index 0000000..39c14a0 --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/osmozilla.rc @@ -0,0 +1,128 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winresrc.h" + +/*do not include setup.h*/ +#define _GF_SETUP_H_ +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,1,0 + PRODUCTVERSION 1,0,1,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "Osmozilla allows playback of many media and rich media files. For more information, visit gpac.io\0" + VALUE "FileExtents", "*|aac|wrl,wrl.gz|x3dv,x3dv.gz,x3dvz|x3d,x3d.gz,x3dz|svg,svg.gz,svgz|mpg,mpeg,mp2,mpa,mpe,mpv2|asf,wma,wmv,asx,asr|avi|mp4,mpg4|mp4|m4a|3gp,3gpp|3gp,3gpp|3g2,3gp2|3g2,3gp2|mp2,mp3,mpga,mpega|ogg|sdp\0" + VALUE "FileOpenName", "GPAC Plugin|AAC Music|VRML World|X3D/VRML World|X3D/XML World|SVG Document|MPEG Video|WindowsMedia Movies|AVI Movies|MPEG-4 Videos|MPEG-4 Movies|MPEG-4 Music|3GPP Movies|3GPP Music|3GPP2 Movies|3GPP2 Music|MP3 Music|OGG Movies|SDP Session\0" + VALUE "FileVersion", GPAC_VERSION"-rev"GPAC_GIT_REVISION"\0" + VALUE "InternalName", "nposmozilla\0" + VALUE "LegalCopyright", "Copyright � Telecom ParisTech 2005-2007\0" + VALUE "LegalTrademarks", "\0" + VALUE "MIMEType", "application/x-gpac|audio/aac|model/vrml|model/x3d+vrml|model/x3d+xml|image/svg+xml|video/mpeg|video/x-ms-asf|video/avi|video/mp4|application/mp4|audio/mp4|video/3gpp|audio/3gpp|video/3gpp2|audio/3gpp2|audio/mpeg|application/ogg|application/sdp\0" + VALUE "OriginalFilename", "nposmozilla.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Osmozilla - GPAC Plugin for Mozilla\0" + VALUE "ProductVersion", GPAC_VERSION"-rev"GPAC_GIT_REVISION"\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // !_MAC + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""winresrc.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/applications/deprecated/old_arch/osmozilla/osmozilla.vcxproj b/applications/deprecated/old_arch/osmozilla/osmozilla.vcxproj new file mode 100644 index 0000000..9170bba --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/osmozilla.vcxproj @@ -0,0 +1,304 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {A0288B75-0D95-4106-A3A7-779A891E8FEF} + osmozilla + + + + DynamicLibrary + false + MultiByte + v140 + + + DynamicLibrary + false + MultiByte + v140 + + + DynamicLibrary + false + MultiByte + v140 + + + DynamicLibrary + false + MultiByte + v140 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + true + true + true + true + true + true + ../../bin/$(Platform)\$(Configuration)/ + ../../bin/$(Platform)\$(Configuration)/ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + .\obj\$(Platform)\$(Configuration)\$(ProjectName)\ + false + false + nposmozilla + nposmozilla + nposmozilla + nposmozilla + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\obj/osmozilla_deb/osmozilla.tlb + + + + + Disabled + ..\..\extra_lib\include\xulrunner-sdk\include;..\..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;XP_WIN32;XP_WIN;_X86_;_WINDOWS;_USRDLL;NPBASIC_EXPORTS;MOZILLA_STRICT_API;XPCOM_GLUE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + .\obj/osmozilla_deb/osmozilla.pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + EditAndContinue + Cdecl + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + advapi32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\applications\osmozilla\osmozilla.def + true + $(IntDir)$(ProjectName).pdb + .\obj/osmozilla_deb/nposmozilla.lib + MachineX86 + + + true + .\obj/osmozilla_deb/osmozilla.bsc + + + copy ..\..\applications\osmozilla\nsIOsmozilla.xpt_w32 ..\..\bin\$(Platform)\$(Configuration)\nposmozilla.xpt + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\obj/osmozilla_deb/osmozilla.tlb + + + + + Disabled + ..\..\extra_lib\include\xulrunner-sdk\include;..\..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;XP_WIN32;XP_WIN;_X86_;_WINDOWS;_USRDLL;NPBASIC_EXPORTS;MOZILLA_STRICT_API;XPCOM_GLUE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + .\obj/osmozilla_deb/osmozilla.pch + $(IntDir) + $(IntDir) + $(IntDir) + true + Level3 + true + ProgramDatabase + Cdecl + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + advapi32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\applications\osmozilla\osmozilla.def + true + $(IntDir)$(ProjectName).pdb + .\obj/osmozilla_deb/nposmozilla.lib + + + true + .\obj/osmozilla_deb/osmozilla.bsc + + + copy ..\..\applications\osmozilla\nsIOsmozilla.xpt_w32 ..\..\bin\$(Platform)\$(Configuration)\nposmozilla.xpt + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\obj/osmozilla_rel/osmozilla.tlb + + + + + MaxSpeed + OnlyExplicitInline + ..\..\extra_lib\include\xulrunner-sdk\include;..\..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_WINDOWS;_USRDLL;NPBASIC_EXPORTS;MOZILLA_STRICT_API;XP_WIN;_X86_;XPCOM_GLUE;WINVER=0x0400;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + .\obj/osmozilla_rel/osmozilla.pch + .\obj/osmozilla_rel/ + .\obj/osmozilla_rel/ + .\obj/osmozilla_rel/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + advapi32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\applications\osmozilla\osmozilla.def + .\obj/osmozilla_rel/nposmozilla.pdb + .\obj/osmozilla_rel/nposmozilla.lib + MachineX86 + + + true + $(IntDir)$(ProjectName).bsc + + + copy ..\..\applications\osmozilla\nsIOsmozilla.xpt_w32 ..\..\bin\$(Platform)\$(Configuration)\nposmozilla.xpt + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\obj/osmozilla_rel/osmozilla.tlb + + + + + Disabled + Default + ..\..\extra_lib\include\xulrunner-sdk\include;..\..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_WINDOWS;_USRDLL;NPBASIC_EXPORTS;MOZILLA_STRICT_API;XP_WIN;_WIN64;XPCOM_GLUE;WINVER=0x0400;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + .\obj/osmozilla_rel/osmozilla.pch + .\obj/osmozilla_rel/ + .\obj/osmozilla_rel/ + .\obj/osmozilla_rel/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + advapi32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + ..\..\applications\osmozilla\osmozilla.def + .\obj/osmozilla_rel/nposmozilla.pdb + .\obj/osmozilla_rel/nposmozilla.lib + + + true + $(IntDir)$(ProjectName).bsc + + + copy ..\..\applications\osmozilla\nsIOsmozilla.xpt_w32 ..\..\bin\$(Platform)\$(Configuration)\nposmozilla.xpt + + + + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + ../../include;%(AdditionalIncludeDirectories) + ../../include;%(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + ../../include;%(AdditionalIncludeDirectories) + ../../include;%(AdditionalIncludeDirectories) + + + + + + + + + + {d3540754-e0cf-4604-ac11-82de9bd4d814} + false + + + + + + \ No newline at end of file diff --git a/applications/deprecated/old_arch/osmozilla/readme.txt b/applications/deprecated/old_arch/osmozilla/readme.txt new file mode 100644 index 0000000..7a61b5c --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/readme.txt @@ -0,0 +1,8 @@ +to regenerate plugin interface from IDL: + +xpidl -m header -I path_to\gecko-sdk\xpcom\idl nsIOsmozilla.idl +xpidl -m typelib -I path_to\gecko-sdk\xpcom\idl nsIOsmozilla.idl +xpt_link nposmozilla.xpt nsIOsmozilla.xpt + +This MUST be done for win32 and linux OSs independently, an .xpt file generated on one OS is not compatible with another OS... +Please keep the w32 file "nsIOsmozilla.xpt_w32" and the linux one "nsIOsmozilla.xpt_linux" to bear with makefiles... \ No newline at end of file diff --git a/applications/deprecated/old_arch/osmozilla/resource.h b/applications/deprecated/old_arch/osmozilla/resource.h new file mode 100644 index 0000000..1179a5e --- /dev/null +++ b/applications/deprecated/old_arch/osmozilla/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by osmozilla.rc +// +#define IDD_MAIN 101 +#define IDC_BUTTON_GO 1002 +#define IDC_STATIC_UA 1003 +#define IDC_BUTTON1 1005 +#define IDC_BUTTON_DONT 1005 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1006 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/applications/generators/MPEG4/Makefile b/applications/generators/MPEG4/Makefile index e739047..b3f0391 100644 --- a/applications/generators/MPEG4/Makefile +++ b/applications/generators/MPEG4/Makefile @@ -4,12 +4,12 @@ vpath %.c $(SRC_PATH)/applications/generators/MPEG4 CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif diff --git a/applications/generators/MPEG4/main.c b/applications/generators/MPEG4/main.c index e4a143b..ef7ab5f 100644 --- a/applications/generators/MPEG4/main.c +++ b/applications/generators/MPEG4/main.c @@ -182,9 +182,8 @@ BNode *BlankNode() u8 IsNDT(GF_List *NDTs, char *famName) { u32 i; - char *ndtName; for (i=0; iNDT); i++) { - ndt = gf_list_get(node->NDT, i); + char *ndt = gf_list_get(node->NDT, i); if (!strcmp(ndt, NDTName)) return 1; } return 0; @@ -422,7 +419,6 @@ u32 GetBitsCount(u32 MaxVal) u32 GetNDTCount(char *NDTName, GF_List *BNodes, u32 Version) { u32 i, nodeCount; - BNode *n; //V1 begins at 0 if (Version == 1) { @@ -437,7 +433,7 @@ u32 GetNDTCount(char *NDTName, GF_List *BNodes, u32 Version) nodeCount = 1; } for (i=0; iversion != Version) continue; if (!IsNodeInTable(n, NDTName)) continue; nodeCount++; @@ -449,7 +445,6 @@ u32 GetNDTCount(char *NDTName, GF_List *BNodes, u32 Version) void WriteNDT_H(FILE *f, GF_List *BNodes, GF_List *NDTs, u32 Version) { u32 i, j, first, count; - char *NDTName; BNode *n; @@ -457,7 +452,7 @@ void WriteNDT_H(FILE *f, GF_List *BNodes, GF_List *NDTs, u32 Version) //for all NDTs for (i=0; iname); for (i=0; iFields) ; i++ ) { - bf = gf_list_get(n->Fields, i); + BField *bf = gf_list_get(n->Fields, i); if (!bf->hasAnim && !bf->hasQuant) continue; fprintf(f, "\tcase %d:\n", i); @@ -1038,7 +1031,7 @@ void WriteNodeCode(GF_List *BNodes) } //SFString else if (!strcmp(bf->familly, "SFString")) { - fprintf(f, "\tp->%s.buffer = (char*)gf_malloc(sizeof(char) * %d);\n", bf->name, strlen(bf->def)+1); + fprintf(f, "\tp->%s.buffer = (char*)gf_malloc(sizeof(char) * %u);\n", bf->name, (u32) strlen(bf->def)+1); fprintf(f, "\tstrcpy(p->%s.buffer, \"%s\");\n", bf->name, bf->def); } @@ -1209,7 +1202,7 @@ void WriteNodeCode(GF_List *BNodes) store = CurrentLine; CurrentLine = token; GetNextToken(tok, " \""); - fprintf(f, "\tp->%s.vals[%d] = (char*)gf_malloc(sizeof(char) * %d);\n", bf->name, j, strlen(tok)+1); + fprintf(f, "\tp->%s.vals[%d] = (char*)gf_malloc(sizeof(char) * %u);\n", bf->name, j, (u32) strlen(tok)+1); fprintf(f, "\tstrcpy(p->%s.vals[%d], \"%s\");\n", bf->name, j, tok); j+=1; CurrentLine = store; @@ -1378,10 +1371,6 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs, u32 version) //get its name GetNextToken(n->name, " \t["); - if (!strcmp(n->name, "TimeSensor")) { - n = n; - } - //extract the NDTs GetNextToken(token, "\t[ %#="); if (strcmp(token, "NDT")) { @@ -1474,9 +1463,9 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs, u32 version) } } else if (!strcmp(f->familly, "SFInt32")) { if (!strcmp(f->def, "+I") || !strcmp(f->def, "I")) { - strcpy(f->def, "1 << 31"); + strcpy(f->def, "0x80000000"); } else if (!strcmp(f->def, "-I")) { - strcpy(f->def, "- (1 << 31)"); + strcpy(f->def, "GF_INT_MIN"); } } } @@ -1527,12 +1516,11 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs, u32 version) void WriteNodeDump(FILE *f, BNode *n) { - BField *bf; u32 i; fprintf(f, "static const char *%s_FieldName[] = {\n", n->name); for (i=0; iFields); i++) { - bf = gf_list_get(n->Fields, i); + BField *bf = gf_list_get(n->Fields, i); if (!i) { fprintf(f, " \"%s\"", bf->name); } else { @@ -1634,7 +1622,7 @@ void generate_ndts(GF_List *NDTs, GF_List *nodes, u32 nbVersion) "\n"\ "\n"\ "Node Coding Tables for BIFS Version %d group\n" - ,GPAC_FULL_VERSION, i+1, i+1); + ,gf_gpac_version(), i+1, i+1); for (j=0; jnode->doc == NULL ) { /* if one XPaths a node from a fragment, libxml2 will - refuse the lookup. this is not very usefull for XML + refuse the lookup. this is not very useful for XML scripters. thus we need to create a temporary document to make libxml2 do it's job correctly. */ @@ -461,8 +461,6 @@ void setAttributeType(SVGGenAttribute *att) strcpy(att->impl_type, "SVG_PointerEvents"); } else if (!strcmp(att->svg_name, "vector-effect")) { strcpy(att->impl_type, "SVG_VectorEffect"); - } else if (!strcmp(att->svg_name, "vector-effect")) { - strcpy(att->impl_type, "SVG_VectorEffect"); } else if (!strcmp(att->svg_name, "display-align")) { strcpy(att->impl_type, "SVG_DisplayAlign"); } else if (!strcmp(att->svg_name, "text-align")) { @@ -631,7 +629,7 @@ SVGGenAttrGrp *getOneGlobalAttrGrp(xmlDocPtr doc, xmlXPathContextPtr xpathCtx, x /* attributes group already resolved */ for (j = 0; j < gf_list_count(globalAttrGrp); j++) { - SVGGenAttrGrp *attgrp = gf_list_get(globalAttrGrp, j); + attgrp = gf_list_get(globalAttrGrp, j); if (!strcmp(attgrp->name, name)) { return attgrp; } diff --git a/applications/generators/SVG/v2.c b/applications/generators/SVG/v2.c index f0359aa..957fd48 100644 --- a/applications/generators/SVG/v2.c +++ b/applications/generators/SVG/v2.c @@ -194,9 +194,6 @@ void generateNodeImpl2(FILE *output, SVGGenElement* svg_elt) } else if (!strcmp("solid-opacity", att->svg_name)) { fprintf(output, "\tp->solid_opacity.type = SVG_NUMBER_VALUE;\n"); fprintf(output, "\tp->solid_opacity.value = FIX_ONE;\n"); - } else if (!strcmp("solid-color", att->svg_name)) { - fprintf(output, "\tp->stop_color.type = SVG_PAINT_COLOR;\n"); - fprintf(output, "\tp->stop_color.color.type = SVG_COLOR_RGBCOLOR;\n"); } else if (!strcmp("stop-opacity", att->svg_name)) { fprintf(output, "\tp->stop_opacity.type = SVG_NUMBER_VALUE;\n"); fprintf(output, "\tp->stop_opacity.value = FIX_ONE;\n"); diff --git a/applications/generators/WebGLGen/Makefile b/applications/generators/WebGLGen/Makefile new file mode 100644 index 0000000..6a3d7e2 --- /dev/null +++ b/applications/generators/WebGLGen/Makefile @@ -0,0 +1,52 @@ +include ../../../config.mak + +vpath %.c $(SRC_PATH)/applications/generators/WebGLGen + +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 + +ifeq ($(CONFIG_WIN32),yes) +EXE=.exe +PROG=WGLGen$(EXE) +else +EXT= +PROG=WGLGen +endif + +SRCS := $(OBJS:.o=.c) + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) -o $@ $(OBJS) $(EXTRALIBS) -L../../../bin/gcc -L../../../extra_lib/lib/gcc -lgpac $(LDFLAGS) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) $(PROG) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + +-include .depend diff --git a/applications/generators/WebGLGen/WGLGen b/applications/generators/WebGLGen/WGLGen new file mode 100755 index 0000000000000000000000000000000000000000..394bb6e3e953da11531c60e6094e4d0c3399073d GIT binary patch literal 27288 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 +#include + +static void start_ctx(char *ctx_name, FILE **ifce_c, FILE **fun_c) +{ + char szFile[GF_MAX_PATH]; + sprintf(szFile, "../../../src/jsmods/%s.c", ctx_name); + FILE *res = gf_fopen(szFile, "wt"); + *ifce_c = res; + *fun_c = gf_file_temp(NULL); + + fprintf(res, "/* !! AUTOGENERATED FILE - DO NOT MODIFY !! \n"); + fprintf(res, "\n%s implementation for QJS\n*/\n\n", ctx_name); +} + + +static void end_ctx(FILE *ifce_c, FILE *func_c, char *ctx_name) +{ + + fprintf(ifce_c, "static const JSCFunctionListEntry %s_funcs[] =\n\{\n", ctx_name); + gf_fseek(func_c, 0, SEEK_SET); + while (!feof(func_c)) { + char szLine[4001]; + szLine[0] = 0; + gf_fgets(szLine, 4000, func_c); + gf_fputs(szLine, ifce_c); + } + gf_fclose(func_c); + fprintf(ifce_c, "};\n"); + gf_fclose(ifce_c); + gf_free(ctx_name); + +} + +static void put_const(FILE *fun_defs, char *c_name, char *c_val) +{ + fprintf(fun_defs, "\tJS_PROP_INT32_DEF(\"%s\", %s, JS_PROP_CONFIGURABLE),\n", c_name, c_val); +} +static void put_fun(FILE *fun_defs, char *f_name) +{ + fprintf(fun_defs, "\tJS_CFUNC_DEF(\"%s\", 0, wgl_%s),\n", f_name, f_name); +} +static void put_prop(FILE *fun_defs, char *ctx_name, char *pname, Bool is_readonly) +{ + if (is_readonly) { + fprintf(fun_defs, "\tJS_CGETSET_MAGIC_DEF(\"%s\", %s_getProperty, NULL, %s_PROP_%s),\n", pname, ctx_name, ctx_name, pname); + } else { + fprintf(fun_defs, "\tJS_CGETSET_MAGIC_DEF(\"%s\", %s_getProperty, %s_setProperty, %s_PROP_%s),\n", pname, ctx_name, ctx_name, ctx_name, pname); + } +} + +static const char *get_arg_type(char *arg_type, Bool *is_array) +{ + *is_array = GF_FALSE; + if (!strcmp(arg_type, "GLenum")) return "u32"; + if (!strcmp(arg_type, "DOMString")) return "const char *"; + if (!strcmp(arg_type, "DOMString?")) return "const char *"; + if (!strcmp(arg_type, "GLuint")) return "u32"; + if (!strcmp(arg_type, "GLint")) return "s32"; + if (!strcmp(arg_type, "GLuint")) return "u32"; + if (!strcmp(arg_type, "GLclampf")) return "Float"; + if (!strcmp(arg_type, "GLfloat")) return "Float"; + if (!strcmp(arg_type, "GLboolean")) return "Bool"; + if (!strcmp(arg_type, "boolean")) return "Bool"; + if (!strcmp(arg_type, "GLsizei")) return "u32"; + if (!strcmp(arg_type, "GLbitfield")) return "u32"; + if (!strcmp(arg_type, "GLshort")) return "s16"; + if (!strcmp(arg_type, "GLushort")) return "u16"; + if (!strcmp(arg_type, "GLsizeiptr")) return "u64"; + if (!strcmp(arg_type, "GLintptr")) return "u64"; + if (!strcmp(arg_type, "GLbyte")) return "s8"; + if (!strcmp(arg_type, "GLubyte")) return "u8"; + if (!strcmp(arg_type, "WebGLProgram?")) return "WebGLProgram"; + if (!strcmp(arg_type, "WebGLShader?")) return "WebGLShader"; + if (!strcmp(arg_type, "WebGLBuffer?")) return "WebGLBuffer"; + if (!strcmp(arg_type, "WebGLFramebuffer?")) return "WebGLFramebuffer"; + if (!strcmp(arg_type, "WebGLRenderbuffer?")) return "WebGLRenderbuffer"; + if (!strcmp(arg_type, "WebGLTexture?")) return "WebGLTexture"; + if (!strcmp(arg_type, "WebGLUniformLocation?")) return "WebGLUniformLocation"; + if (!strcmp(arg_type, "TexImageSource?")) return "TexImageSource"; + if (!strcmp(arg_type, "WebGLContextAttributes?")) return "WebGLContextAttributes"; + if (!strcmp(arg_type, "boolean?")) return "Bool"; + if (!strcmp(arg_type, "WebGLActiveInfo?")) return "JSValue"; + + if (!strcmp(arg_type, "Float32Array")) { + *is_array = GF_TRUE; + return "Float *"; + } + if (!strcmp(arg_type, "Int32Array")) { + *is_array = GF_TRUE; + return "s32 *"; + } + if (!strcmp(arg_type, "sequence?")) { + return "JSValue"; + } + if (!strcmp(arg_type, "sequence?")) { + return "JSValue"; + } + if (!strcmp(arg_type, "ArrayBufferView") + || !strcmp(arg_type, "ArrayBufferView?") + || !strcmp(arg_type, "BufferDataSource?") + ) { + *is_array = GF_TRUE; + return "u8 *"; + } + + if (!strcmp(arg_type, "object?") + || !strcmp(arg_type, "WebGLShaderPrecisionFormat?") + || !strcmp(arg_type, "any") + ) { + return NULL; + } + + fprintf(stderr, "arg type %s not supported\n", arg_type); + return "JSValue"; +} + +static void put_arg_get(FILE *ifce_c, char *fname, int idx, char *arg_type, char *arg_name) +{ + Bool is_array; + const char *native_type = get_arg_type(arg_type, &is_array); + if (!native_type) return; + + if (!strcmp(native_type, "Bool")) { + fprintf(ifce_c, "\tWGL_GET_BOOL(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "s32")) { + fprintf(ifce_c, "\tWGL_GET_S32(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "u32")) { + fprintf(ifce_c, "\tWGL_GET_U32(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "u64")) { + fprintf(ifce_c, "\tWGL_GET_U64(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "s64")) { + fprintf(ifce_c, "\tWGL_GET_S64(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "s16")) { + fprintf(ifce_c, "\tWGL_GET_S16(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "u16")) { + fprintf(ifce_c, "\tWGL_GET_U16(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(arg_type, "GLclampf")) { + fprintf(ifce_c, "\tWGL_GET_FLOAT_CLAMP(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "Float")) { + fprintf(ifce_c, "\tWGL_GET_FLOAT(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "const char *")) { + fprintf(ifce_c, "\tWGL_GET_STRING(%s, argv[%d]);\n", arg_name, idx); + } + else if (!strcmp(native_type, "WebGLProgram") + || !strcmp(native_type, "WebGLShader") + || !strcmp(native_type, "WebGLBuffer") + || !strcmp(native_type, "WebGLFramebuffer") + || !strcmp(native_type, "WebGLRenderbuffer") + || !strcmp(native_type, "WebGLTexture") + || !strcmp(native_type, "WebGLUniformLocation") + ) { + fprintf(ifce_c, "\tWGL_GET_GLID(%s, argv[%d], %s_class_id);\n", arg_name, idx, native_type); + } + + else if (!strcmp(arg_type, "BufferDataSource?")) { + fprintf(ifce_c, "\tif(!JS_IsObject(argv[%d])) {\n", idx); + fprintf(ifce_c, "\t\tWGL_GET_U32(%s_size, argv[%d]);\n", arg_name, idx); + fprintf(ifce_c, "\t} else {\n"); + fprintf(ifce_c, "\t\t%s = wgl_GetArrayBuffer(ctx, &%s_size, argv[%d]);\n", arg_name, arg_name, idx); + fprintf(ifce_c, "\t}\n"); + } + else if (is_array && !strcmp(native_type, "u8 *")) { + fprintf(ifce_c, "\tif(!JS_IsArray(ctx, argv[%d])) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", idx); + fprintf(ifce_c, "\t%s = wgl_GetArrayBuffer(ctx, &%s_size, argv[%d]);\n", arg_name, arg_name, idx); + } + else if (is_array && (!strcmp(native_type, "Float *") || !strcmp(native_type, "s32 *")) ) { + u32 vlen = 1; + if (strstr(fname, "2fv")) vlen = 2; + else if (strstr(fname, "3fv")) vlen = 3; + else if (strstr(fname, "4fv")) vlen = 4; + + if (!strcmp(native_type, "s32 *")) + fprintf(ifce_c, "\tif (!WGL_LOAD_INT32_VEC(ctx, argv[%d], (s32 **) &%s, &%s_size, %d)) return js_throw_err(ctx, WGL_INVALID_VALUE);;\n", idx, arg_name, arg_name, vlen); + else { + Bool is_matrix = GF_FALSE; + if (strstr(fname, "Matrix")) is_matrix = GF_TRUE; + if (strstr(fname, "vertexAttrib")) { + fprintf(ifce_c, "\tif (!WGL_LOAD_FLOAT_VEC(ctx, argv[%d], (Float **) &%s, NULL, %d, %d)) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", idx, arg_name, vlen, is_matrix); + } else { + fprintf(ifce_c, "\tif (!WGL_LOAD_FLOAT_VEC(ctx, argv[%d], (Float **) &%s, &%s_size, %d, %d)) return js_throw_err(ctx, WGL_INVALID_VALUE);\n", idx, arg_name, arg_name, vlen, is_matrix); + } + } + } + else { + fprintf(stderr, "arg type %s not supported\n", arg_type); + } + +} + +static void put_arg_decl(FILE *ifce_c, char *fname, char *arg_type, char *arg_name) +{ + Bool is_array = GF_FALSE; + const char *native_type = get_arg_type(arg_type, &is_array); + if (!native_type) + return; + + if (is_array) { + if (strstr(fname, "vertexAttrib1fv")) { + fprintf(ifce_c, "\tFloat %s[1];\n", arg_name); + } else if (strstr(fname, "vertexAttrib2fv")) { + fprintf(ifce_c, "\tFloat %s[2];\n", arg_name); + } else if (strstr(fname, "vertexAttrib3fv")) { + fprintf(ifce_c, "\tFloat %s[3];\n", arg_name); + } else if (strstr(fname, "vertexAttrib4fv")) { + fprintf(ifce_c, "\tFloat %s[4];\n", arg_name); + } else { + fprintf(ifce_c, "\t%s %s = NULL;\n", native_type, arg_name); + fprintf(ifce_c, "\tu32 %s_size = 0;\n", arg_name); + } + } else { + if (strstr(arg_name, " *")) + fprintf(ifce_c, "\t%s %s = NULL;\n", native_type, arg_name); + else if (!strcmp(native_type, "JSValue")) + fprintf(ifce_c, "\t%s %s = JS_UNDEFINED;\n", native_type, arg_name); + else if (!strncmp(native_type, "WebGL", 5)) + fprintf(ifce_c, "\tGLuint %s = 0;\n", arg_name); + else + fprintf(ifce_c, "\t%s %s = 0;\n", native_type, arg_name); + } +} +/*all functions that cannot be mapped directly due to to heavy syntax pacthing or our own hacking*/ +static const char *not_autogen_funcs = "getContextAttributes,isContextLost,getSupportedExtensions,getExtension,getBufferParameter,getParameter,getFramebufferAttachmentParameter,getProgramParameter,getRenderbufferParameter,getShaderParameter,getShaderPrecisionFormat,getProgramInfoLog,getShaderParameter,getShaderInfoLog,getShaderSource,getTexParameter,getUniform,getVertexAttrib,getVertexAttribOffset,readPixels,shaderSource,texImage2D,texSubImage2D,useProgram,activeTexture,bindTexture,getUniformLocation,createTexture,bindFramebuffer"; + +static void wrap_func(FILE *ifce_c, char *fname, char *fun_def) +{ + char *sep, *nsep; + u32 len, i, nb_args; + u32 first_char; + u32 ret_type=0; + Bool is_create=GF_FALSE; + Bool is_delete_fun=GF_FALSE; + char *ret_val=NULL, *exc_value=NULL, *arg_type[50], *arg_name[50]; + + if (strstr(not_autogen_funcs, fname)) { + fprintf(ifce_c, "\nstatic JSValue wgl_%s(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);\n", fname); + return; + } + + fprintf(ifce_c, "\nstatic JSValue wgl_%s(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)\n{\n", fname); + + nb_args = 0; + memset(arg_type, 0, sizeof(char *)*50); + memset(arg_name, 0, sizeof(char *)*50); + + sep = fun_def; + while (sep[0]==' ') sep++; + /*parse exception*/ + if (sep[0]=='[') { + nsep = strchr(sep, ']'); + assert(nsep); + nsep[0]=0; + exc_value = gf_strdup(sep); + nsep[0]=']'; + sep = nsep+1; + while (sep[0]==' ') sep++; + } + /*parse return value*/ + nsep = strchr(sep, ' '); + assert(nsep); + nsep[0] = 0; + ret_val = strdup(sep); + sep = nsep+1; + len = strlen(fname); + assert(!strncmp(sep, fname, len) ); + sep += len+1; + while (sep) { + char *next_arg; + nsep = strchr(sep, ','); + if (!nsep) { + nsep = strchr(sep, ')'); + if (!nsep) break; + } + nsep[0]=0; + next_arg = nsep+1; + + if (nb_args>=50) { + assert(0); + } + nsep = strchr(sep, ' '); + if (!nsep) + break; + assert(nsep); + nsep[0] = 0; + arg_type[nb_args] = gf_strdup(sep); + arg_name[nb_args] = gf_strdup(nsep+1); + nb_args++; + sep = next_arg; + while (sep[0]==' ') sep++; + } + + fprintf(ifce_c, "\tJSValue ret_val_js = JS_UNDEFINED;\n"); + + for (i=0; i 'Z')) { + first_char += 'A' - 'a'; + } + + if (is_create) { + fprintf(ifce_c, "\tGF_SAFEALLOC(wglo, GF_WebGLObject);\n"); + fprintf(ifce_c, "\tif (!wglo) return js_throw_err(ctx, WGL_OUT_OF_MEMORY);\n"); + fprintf(ifce_c, "\twglo->par_ctx = JS_GetOpaque(this_val, WebGLRenderingContextBase_class_id);\n"); + fprintf(ifce_c, "\tglGen%ss(1, &wglo->gl_id", fname+6); + } else { + if (!strcmp(fname, "deleteShader") || !strcmp(fname, "deleteProgram")) { + is_delete_fun=GF_TRUE; + } + if (!strcmp(fname, "deleteBuffer") || !strcmp(fname, "deleteTexture") || !strcmp(fname, "deleteFramebuffer") || !strcmp(fname, "deleteRenderbuffer")) { + fprintf(ifce_c, "\tgl%c%ss(1, &", first_char, fname+1); + is_delete_fun=GF_TRUE; + } + else if (!strcmp(fname, "createProgram") || !strcmp(fname, "createShader")) { + fprintf(ifce_c, "\tGF_SAFEALLOC(wglo, GF_WebGLObject);\n"); + fprintf(ifce_c, "\tif (!wglo) return js_throw_err(ctx, WGL_OUT_OF_MEMORY);\n"); + fprintf(ifce_c, "\twglo->par_ctx = JS_GetOpaque(this_val, WebGLRenderingContextBase_class_id);\n"); + fprintf(ifce_c, "\twglo->gl_id = gl%c%s(", first_char, fname+1); + } else if (!strcmp(fname, "clearDepth") || !strcmp(fname, "depthRange")) { + fprintf(ifce_c, "#if defined(GPAC_USE_GLES2)\n"); + fprintf(ifce_c, "\tgl%c%sf(\n", first_char, fname+1); + fprintf(ifce_c, "#else\n"); + fprintf(ifce_c, "\tgl%c%s(\n", first_char, fname+1); + fprintf(ifce_c, "#endif\n\t\t"); + } else { + fprintf(ifce_c, "\t"); + if (ret_type==1) { + fprintf(ifce_c, "ret_val = "); + } + if (!strncmp(fname, "uniform", 7)) { + + fprintf(ifce_c, "/*hack for GPAC textures, we create uniforms with loc -2 for such textures*/\n\tif ((s32) location>=0)\n\t\t"); + } + fprintf(ifce_c, "gl%c%s(", first_char, fname+1); + } + } + + Bool prev_is_transpose = GF_FALSE; + for (i=0; igl_id=0;\n", nat_type); + fprintf(ifce_c, "\tJS_FreeValue(ctx, glo->obj);\n\tglo->obj = JS_UNDEFINED;\n\tgf_list_del_item(glo->par_ctx->all_objects, glo);\n"); + fprintf(ifce_c, "\t}\n\t}\n"); + } + + if (ret_type==1) { + + if (!strcmp(ret_val, "GLenum") || !strcmp(ret_val, "GLint")) { + fprintf(ifce_c, "\tret_val_js = JS_NewInt32(ctx, ret_val);\n"); + } else if (!strcmp(ret_val, "GLboolean") ) { + fprintf(ifce_c, "\tret_val_js = JS_NewBool(ctx, ret_val);\n"); + } else if (!strcmp(ret_val, "WebGLProgram") ) { + fprintf(ifce_c, "\tret_val_js = JS_NewObjectClass(ctx, WebGLProgram_class_id);\n"); + fprintf(ifce_c, "\tJS_SetOpaque(ret_val_js, wglo);\n"); + } else { + fprintf(stderr, "retval %s not supported in %s\n", ret_val, fname); + } + } else if (ret_type==2) { + Bool is_array; + const char *native_type = get_arg_type(ret_val, &is_array); + fprintf(ifce_c, "\tret_val_js = JS_NewObjectClass(ctx, %s_class_id);\n", native_type); + fprintf(ifce_c, "\tJS_SetOpaque(ret_val_js, wglo);\n"); + fprintf(ifce_c, "\twglo->obj = JS_DupValue(ctx, ret_val_js);\n"); + fprintf(ifce_c, "\twglo->class_id = %s_class_id;\n", native_type); + fprintf(ifce_c, "\tgf_list_add(wglo->par_ctx->all_objects, wglo);\n"); + } + + for (i=0; i1) { + gf_free(arg_type[nb_args-1]); + gf_free(arg_name[nb_args-1]); + nb_args--; + } + gf_free(ret_val); + fprintf(ifce_c, "}\n"); +} + + +static void load_idl(const char *file) +{ + Bool in_ctxbase = GF_FALSE; + char szLine[4001], *sep; + char *curCtx = NULL; + u32 len; + FILE * idl = gf_fopen(file, "rt"); + FILE *ifce_c=NULL; + FILE *fun_defs=NULL; + + while (!feof(idl)) { + gf_fgets(szLine, 4000, idl); + if (strstr(szLine, "implements")) + continue; + len = strlen(szLine); + while (len && strchr(" \n", szLine[len])) { + szLine[len] = 0; + len--; + } + if (!len) continue; + + if (!in_ctxbase) { + if (!strstr(szLine, "RenderingContextBase")) + continue; + in_ctxbase = GF_TRUE; + sep = strchr(szLine, ' '); + assert(sep); + curCtx = gf_strdup(sep+1); + start_ctx(curCtx, &ifce_c, &fun_defs); + continue; + } else { + if (strstr(szLine, "};")){ + in_ctxbase = GF_FALSE; + end_ctx(ifce_c, fun_defs, curCtx); + ifce_c = NULL; + continue; + } + } + + if (strstr(szLine, "/*")) continue; + sep = strstr(szLine, "const "); + if (sep) { + char *cname, *nsep; + sep = strchr(sep+7, ' '); + assert(sep); + sep++; + nsep = strchr(sep, ' '); + assert(nsep); + nsep[0] = 0; + cname = gf_strdup(sep); + sep = strchr(nsep+1, '='); + assert(sep); + sep++; + while (sep[0]==' ') sep++; + nsep = strchr(sep, ';'); + assert(nsep); + nsep[0]=0; + put_const(fun_defs, cname, sep); + gf_free(cname); + continue; + } + sep = strstr(szLine, "typedef"); + if (sep) continue; + + sep = strstr(szLine, "attribute"); + if (sep) { + char *nsep; + Bool is_readonly = GF_FALSE; + sep = szLine; + while (sep[0]==' ') sep++; + if (!strncmp(sep, "readonly", 8)) { + is_readonly = GF_TRUE; + sep+=9; + } + sep += 10; + sep = strchr(sep, ' '); + assert(sep); + sep+=1; + nsep = strchr(sep, ';'); + assert(nsep); + nsep[0] = 0; + put_prop(fun_defs, curCtx, sep, is_readonly); + continue; + } + /*double type declaration for glXXXifv*/ + if (strstr(szLine, ", sequence<")) + continue; + /*double type declaration for bufferData*/ + if (strstr(szLine, ", GLsizeiptr size")) + continue; + /*double type declaration for texImage2D and texSubImage2D*/ + if (strstr(szLine, ", TexImageSource")) + continue; + + sep = strstr(szLine, "("); + /*this is a function*/ + if (sep) { + char *nsep, *fname; + sep = strchr(szLine, ']'); + if (sep) sep+=1; + else sep = szLine; + while (sep[0] == ' ') sep++; + sep = strchr(sep, ' '); + assert(sep); + sep++; + nsep = strchr(sep, '('); + assert(nsep); + nsep[0] = 0; + fname = gf_strdup(sep); + put_fun(fun_defs, sep); + nsep[0] = '('; + + wrap_func(ifce_c, fname, szLine); + gf_free(fname); + continue; + } + fprintf(stderr, "instruction %s not handled\n", szLine); + } + + + gf_fclose(idl); +} + +int main(int argc, char **argv) +{ + u32 i=0; + for (i=1; i? getSupportedExtensions(); + object? getExtension(DOMString name); + + void activeTexture(GLenum texture); + void attachShader(WebGLProgram? program, WebGLShader? shader); + void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name); + void bindBuffer(GLenum target, WebGLBuffer? buffer); + void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer); + void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer); + void bindTexture(GLenum target, WebGLTexture? texture); + void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void blendEquation(GLenum mode); + void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); + void blendFunc(GLenum sfactor, GLenum dfactor); + void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + + typedef (ArrayBuffer or ArrayBufferView) BufferDataSource; + void bufferData(GLenum target, GLsizeiptr size, GLenum usage); + void bufferData(GLenum target, BufferDataSource? data, GLenum usage); + void bufferSubData(GLenum target, GLintptr offset, BufferDataSource? data); + + [WebGLHandlesContextLoss] GLenum checkFramebufferStatus(GLenum target); + void clear(GLbitfield mask); + void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void clearDepth(GLclampf depth); + void clearStencil(GLint s); + void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void compileShader(WebGLShader? shader); + + void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView data); + void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView data); + + void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + WebGLBuffer? createBuffer(); + WebGLFramebuffer? createFramebuffer(); + WebGLProgram? createProgram(); + WebGLRenderbuffer? createRenderbuffer(); + WebGLShader? createShader(GLenum type); + WebGLTexture? createTexture(); + + void cullFace(GLenum mode); + + void deleteBuffer(WebGLBuffer? buffer); + void deleteFramebuffer(WebGLFramebuffer? framebuffer); + void deleteProgram(WebGLProgram? program); + void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer); + void deleteShader(WebGLShader? shader); + void deleteTexture(WebGLTexture? texture); + + void depthFunc(GLenum func); + void depthMask(GLboolean flag); + void depthRange(GLclampf zNear, GLclampf zFar); + void detachShader(WebGLProgram? program, WebGLShader? shader); + void disable(GLenum cap); + void disableVertexAttribArray(GLuint index); + void drawArrays(GLenum mode, GLint first, GLsizei count); + void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset); + + void enable(GLenum cap); + void enableVertexAttribArray(GLuint index); + void finish(); + void flush(); + void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer? renderbuffer); + void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture? texture, GLint level); + void frontFace(GLenum mode); + + void generateMipmap(GLenum target); + + WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, GLuint index); + WebGLActiveInfo? getActiveUniform(WebGLProgram? program, GLuint index); + sequence? getAttachedShaders(WebGLProgram? program); + + [WebGLHandlesContextLoss] GLint getAttribLocation(WebGLProgram? program, DOMString name); + + any getBufferParameter(GLenum target, GLenum pname); + any getParameter(GLenum pname); + + [WebGLHandlesContextLoss] GLenum getError(); + + any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname); + any getProgramParameter(WebGLProgram? program, GLenum pname); + DOMString? getProgramInfoLog(WebGLProgram? program); + any getRenderbufferParameter(GLenum target, GLenum pname); + any getShaderParameter(WebGLShader? shader, GLenum pname); + WebGLShaderPrecisionFormat? getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype); + DOMString? getShaderInfoLog(WebGLShader? shader); + + DOMString? getShaderSource(WebGLShader? shader); + + any getTexParameter(GLenum target, GLenum pname); + + any getUniform(WebGLProgram? program, WebGLUniformLocation? location); + + WebGLUniformLocation? getUniformLocation(WebGLProgram? program, DOMString name); + + any getVertexAttrib(GLuint index, GLenum pname); + + [WebGLHandlesContextLoss] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname); + + void hint(GLenum target, GLenum mode); + [WebGLHandlesContextLoss] GLboolean isBuffer(WebGLBuffer? buffer); + [WebGLHandlesContextLoss] GLboolean isEnabled(GLenum cap); + [WebGLHandlesContextLoss] GLboolean isFramebuffer(WebGLFramebuffer? framebuffer); + [WebGLHandlesContextLoss] GLboolean isProgram(WebGLProgram? program); + [WebGLHandlesContextLoss] GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer); + [WebGLHandlesContextLoss] GLboolean isShader(WebGLShader? shader); + [WebGLHandlesContextLoss] GLboolean isTexture(WebGLTexture? texture); + void lineWidth(GLfloat width); + void linkProgram(WebGLProgram? program); + void pixelStorei(GLenum pname, GLint param); + void polygonOffset(GLfloat factor, GLfloat units); + + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels); + + void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + void sampleCoverage(GLclampf value, GLboolean invert); + void scissor(GLint x, GLint y, GLsizei width, GLsizei height); + + void shaderSource(WebGLShader? shader, DOMString source); + + void stencilFunc(GLenum func, GLint ref, GLuint mask); + void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); + void stencilMask(GLuint mask); + void stencilMaskSeparate(GLenum face, GLuint mask); + void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); + void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); + + typedef (ImageData or HTMLImageElement or HTMLCanvasElement or HTMLVideoElement) TexImageSource; + void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels); + void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, TexImageSource? source); // May throw DOMException + + void texParameterf(GLenum target, GLenum pname, GLfloat param); + void texParameteri(GLenum target, GLenum pname, GLint param); + + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels); + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource? source); // May throw DOMException + + void uniform1f(WebGLUniformLocation? location, GLfloat x); + void uniform1fv(WebGLUniformLocation? location, Float32Array v); + void uniform1fv(WebGLUniformLocation? location, sequence v); + void uniform1i(WebGLUniformLocation? location, GLint x); + void uniform1iv(WebGLUniformLocation? location, Int32Array v); + void uniform1iv(WebGLUniformLocation? location, sequence v); + void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y); + void uniform2fv(WebGLUniformLocation? location, Float32Array v); + void uniform2fv(WebGLUniformLocation? location, sequence v); + void uniform2i(WebGLUniformLocation? location, GLint x, GLint y); + void uniform2iv(WebGLUniformLocation? location, Int32Array v); + void uniform2iv(WebGLUniformLocation? location, sequence v); + void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z); + void uniform3fv(WebGLUniformLocation? location, Float32Array v); + void uniform3fv(WebGLUniformLocation? location, sequence v); + void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z); + void uniform3iv(WebGLUniformLocation? location, Int32Array v); + void uniform3iv(WebGLUniformLocation? location, sequence v); + void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void uniform4fv(WebGLUniformLocation? location, Float32Array v); + void uniform4fv(WebGLUniformLocation? location, sequence v); + void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w); + void uniform4iv(WebGLUniformLocation? location, Int32Array v); + void uniform4iv(WebGLUniformLocation? location, sequence v); + + void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array value); + void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, sequence value); + + void useProgram(WebGLProgram? program); + void validateProgram(WebGLProgram? program); + + void vertexAttrib1f(GLuint indx, GLfloat x); + void vertexAttrib1fv(GLuint indx, Float32Array values); + void vertexAttrib1fv(GLuint indx, sequence values); + void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y); + void vertexAttrib2fv(GLuint indx, Float32Array values); + void vertexAttrib2fv(GLuint indx, sequence values); + void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z); + void vertexAttrib3fv(GLuint indx, Float32Array values); + void vertexAttrib3fv(GLuint indx, sequence values); + void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void vertexAttrib4fv(GLuint indx, Float32Array values); + void vertexAttrib4fv(GLuint indx, sequence values); + void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset); + + void viewport(GLint x, GLint y, GLsizei width, GLsizei height); +}; + +interface WebGLRenderingContext +{ +}; +WebGLRenderingContext implements WebGLRenderingContextBase; + + +[Constructor(DOMString type, optional WebGLContextEventInit eventInit)] +interface WebGLContextEvent : Event { + readonly attribute DOMString statusMessage; +}; + +// EventInit is defined in the DOM4 specification. +dictionary WebGLContextEventInit : EventInit { + DOMString statusMessage; +}; diff --git a/applications/generators/WebGLGen/webgl2.idl b/applications/generators/WebGLGen/webgl2.idl new file mode 100644 index 0000000..e5dbdc4 --- /dev/null +++ b/applications/generators/WebGLGen/webgl2.idl @@ -0,0 +1,584 @@ +// AUTOGENERATED FILE -- DO NOT EDIT -- SEE Makefile +// +// WebGL IDL definitions scraped from the Khronos specification: +// https://www.khronos.org/registry/webgl/specs/latest/ +// +// This IDL depends on the typed array specification defined at: +// https://www.khronos.org/registry/typedarray/specs/latest/typedarrays.idl + +typedef long long GLint64; +typedef unsigned long long GLuint64; + + +interface WebGLQuery : WebGLObject { +}; + +interface WebGLSampler : WebGLObject { +}; + +interface WebGLSync : WebGLObject { +}; + +interface WebGLTransformFeedback : WebGLObject { +}; + +interface WebGLVertexArrayObject : WebGLObject { +}; + +typedef (Float32Array or sequence) Float32List; +typedef (Int32Array or sequence) Int32List; +typedef (Uint32Array or sequence) Uint32List; + +[NoInterfaceObject] +interface WebGL2RenderingContextBase +{ + const GLenum READ_BUFFER = 0x0C02; + const GLenum UNPACK_ROW_LENGTH = 0x0CF2; + const GLenum UNPACK_SKIP_ROWS = 0x0CF3; + const GLenum UNPACK_SKIP_PIXELS = 0x0CF4; + const GLenum PACK_ROW_LENGTH = 0x0D02; + const GLenum PACK_SKIP_ROWS = 0x0D03; + const GLenum PACK_SKIP_PIXELS = 0x0D04; + const GLenum COLOR = 0x1800; + const GLenum DEPTH = 0x1801; + const GLenum STENCIL = 0x1802; + const GLenum RED = 0x1903; + const GLenum RGB8 = 0x8051; + const GLenum RGBA8 = 0x8058; + const GLenum RGB10_A2 = 0x8059; + const GLenum TEXTURE_BINDING_3D = 0x806A; + const GLenum UNPACK_SKIP_IMAGES = 0x806D; + const GLenum UNPACK_IMAGE_HEIGHT = 0x806E; + const GLenum TEXTURE_3D = 0x806F; + const GLenum TEXTURE_WRAP_R = 0x8072; + const GLenum MAX_3D_TEXTURE_SIZE = 0x8073; + const GLenum UNSIGNED_INT_2_10_10_10_REV = 0x8368; + const GLenum MAX_ELEMENTS_VERTICES = 0x80E8; + const GLenum MAX_ELEMENTS_INDICES = 0x80E9; + const GLenum TEXTURE_MIN_LOD = 0x813A; + const GLenum TEXTURE_MAX_LOD = 0x813B; + const GLenum TEXTURE_BASE_LEVEL = 0x813C; + const GLenum TEXTURE_MAX_LEVEL = 0x813D; + const GLenum MIN = 0x8007; + const GLenum MAX = 0x8008; + const GLenum DEPTH_COMPONENT24 = 0x81A6; + const GLenum MAX_TEXTURE_LOD_BIAS = 0x84FD; + const GLenum TEXTURE_COMPARE_MODE = 0x884C; + const GLenum TEXTURE_COMPARE_FUNC = 0x884D; + const GLenum CURRENT_QUERY = 0x8865; + const GLenum QUERY_RESULT = 0x8866; + const GLenum QUERY_RESULT_AVAILABLE = 0x8867; + const GLenum STREAM_READ = 0x88E1; + const GLenum STREAM_COPY = 0x88E2; + const GLenum STATIC_READ = 0x88E5; + const GLenum STATIC_COPY = 0x88E6; + const GLenum DYNAMIC_READ = 0x88E9; + const GLenum DYNAMIC_COPY = 0x88EA; + const GLenum MAX_DRAW_BUFFERS = 0x8824; + const GLenum DRAW_BUFFER0 = 0x8825; + const GLenum DRAW_BUFFER1 = 0x8826; + const GLenum DRAW_BUFFER2 = 0x8827; + const GLenum DRAW_BUFFER3 = 0x8828; + const GLenum DRAW_BUFFER4 = 0x8829; + const GLenum DRAW_BUFFER5 = 0x882A; + const GLenum DRAW_BUFFER6 = 0x882B; + const GLenum DRAW_BUFFER7 = 0x882C; + const GLenum DRAW_BUFFER8 = 0x882D; + const GLenum DRAW_BUFFER9 = 0x882E; + const GLenum DRAW_BUFFER10 = 0x882F; + const GLenum DRAW_BUFFER11 = 0x8830; + const GLenum DRAW_BUFFER12 = 0x8831; + const GLenum DRAW_BUFFER13 = 0x8832; + const GLenum DRAW_BUFFER14 = 0x8833; + const GLenum DRAW_BUFFER15 = 0x8834; + const GLenum MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49; + const GLenum MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A; + const GLenum SAMPLER_3D = 0x8B5F; + const GLenum SAMPLER_2D_SHADOW = 0x8B62; + const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B; + const GLenum PIXEL_PACK_BUFFER = 0x88EB; + const GLenum PIXEL_UNPACK_BUFFER = 0x88EC; + const GLenum PIXEL_PACK_BUFFER_BINDING = 0x88ED; + const GLenum PIXEL_UNPACK_BUFFER_BINDING = 0x88EF; + const GLenum FLOAT_MAT2x3 = 0x8B65; + const GLenum FLOAT_MAT2x4 = 0x8B66; + const GLenum FLOAT_MAT3x2 = 0x8B67; + const GLenum FLOAT_MAT3x4 = 0x8B68; + const GLenum FLOAT_MAT4x2 = 0x8B69; + const GLenum FLOAT_MAT4x3 = 0x8B6A; + const GLenum SRGB = 0x8C40; + const GLenum SRGB8 = 0x8C41; + const GLenum SRGB8_ALPHA8 = 0x8C43; + const GLenum COMPARE_REF_TO_TEXTURE = 0x884E; + const GLenum RGBA32F = 0x8814; + const GLenum RGB32F = 0x8815; + const GLenum RGBA16F = 0x881A; + const GLenum RGB16F = 0x881B; + const GLenum VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD; + const GLenum MAX_ARRAY_TEXTURE_LAYERS = 0x88FF; + const GLenum MIN_PROGRAM_TEXEL_OFFSET = 0x8904; + const GLenum MAX_PROGRAM_TEXEL_OFFSET = 0x8905; + const GLenum MAX_VARYING_COMPONENTS = 0x8B4B; + const GLenum TEXTURE_2D_ARRAY = 0x8C1A; + const GLenum TEXTURE_BINDING_2D_ARRAY = 0x8C1D; + const GLenum R11F_G11F_B10F = 0x8C3A; + const GLenum UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; + const GLenum RGB9_E5 = 0x8C3D; + const GLenum UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; + const GLenum TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F; + const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80; + const GLenum TRANSFORM_FEEDBACK_VARYINGS = 0x8C83; + const GLenum TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84; + const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85; + const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88; + const GLenum RASTERIZER_DISCARD = 0x8C89; + const GLenum MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A; + const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B; + const GLenum INTERLEAVED_ATTRIBS = 0x8C8C; + const GLenum SEPARATE_ATTRIBS = 0x8C8D; + const GLenum TRANSFORM_FEEDBACK_BUFFER = 0x8C8E; + const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F; + const GLenum RGBA32UI = 0x8D70; + const GLenum RGB32UI = 0x8D71; + const GLenum RGBA16UI = 0x8D76; + const GLenum RGB16UI = 0x8D77; + const GLenum RGBA8UI = 0x8D7C; + const GLenum RGB8UI = 0x8D7D; + const GLenum RGBA32I = 0x8D82; + const GLenum RGB32I = 0x8D83; + const GLenum RGBA16I = 0x8D88; + const GLenum RGB16I = 0x8D89; + const GLenum RGBA8I = 0x8D8E; + const GLenum RGB8I = 0x8D8F; + const GLenum RED_INTEGER = 0x8D94; + const GLenum RGB_INTEGER = 0x8D98; + const GLenum RGBA_INTEGER = 0x8D99; + const GLenum SAMPLER_2D_ARRAY = 0x8DC1; + const GLenum SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; + const GLenum SAMPLER_CUBE_SHADOW = 0x8DC5; + const GLenum UNSIGNED_INT_VEC2 = 0x8DC6; + const GLenum UNSIGNED_INT_VEC3 = 0x8DC7; + const GLenum UNSIGNED_INT_VEC4 = 0x8DC8; + const GLenum INT_SAMPLER_2D = 0x8DCA; + const GLenum INT_SAMPLER_3D = 0x8DCB; + const GLenum INT_SAMPLER_CUBE = 0x8DCC; + const GLenum INT_SAMPLER_2D_ARRAY = 0x8DCF; + const GLenum UNSIGNED_INT_SAMPLER_2D = 0x8DD2; + const GLenum UNSIGNED_INT_SAMPLER_3D = 0x8DD3; + const GLenum UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; + const GLenum UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; + const GLenum DEPTH_COMPONENT32F = 0x8CAC; + const GLenum DEPTH32F_STENCIL8 = 0x8CAD; + const GLenum FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; + const GLenum FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210; + const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211; + const GLenum FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212; + const GLenum FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213; + const GLenum FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214; + const GLenum FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215; + const GLenum FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216; + const GLenum FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217; + const GLenum FRAMEBUFFER_DEFAULT = 0x8218; + const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A; + const GLenum DEPTH_STENCIL = 0x84F9; + const GLenum UNSIGNED_INT_24_8 = 0x84FA; + const GLenum DEPTH24_STENCIL8 = 0x88F0; + const GLenum UNSIGNED_NORMALIZED = 0x8C17; + const GLenum DRAW_FRAMEBUFFER_BINDING = 0x8CA6; /* Same as FRAMEBUFFER_BINDING */ + const GLenum READ_FRAMEBUFFER = 0x8CA8; + const GLenum DRAW_FRAMEBUFFER = 0x8CA9; + const GLenum READ_FRAMEBUFFER_BINDING = 0x8CAA; + const GLenum RENDERBUFFER_SAMPLES = 0x8CAB; + const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4; + const GLenum MAX_COLOR_ATTACHMENTS = 0x8CDF; + const GLenum COLOR_ATTACHMENT1 = 0x8CE1; + const GLenum COLOR_ATTACHMENT2 = 0x8CE2; + const GLenum COLOR_ATTACHMENT3 = 0x8CE3; + const GLenum COLOR_ATTACHMENT4 = 0x8CE4; + const GLenum COLOR_ATTACHMENT5 = 0x8CE5; + const GLenum COLOR_ATTACHMENT6 = 0x8CE6; + const GLenum COLOR_ATTACHMENT7 = 0x8CE7; + const GLenum COLOR_ATTACHMENT8 = 0x8CE8; + const GLenum COLOR_ATTACHMENT9 = 0x8CE9; + const GLenum COLOR_ATTACHMENT10 = 0x8CEA; + const GLenum COLOR_ATTACHMENT11 = 0x8CEB; + const GLenum COLOR_ATTACHMENT12 = 0x8CEC; + const GLenum COLOR_ATTACHMENT13 = 0x8CED; + const GLenum COLOR_ATTACHMENT14 = 0x8CEE; + const GLenum COLOR_ATTACHMENT15 = 0x8CEF; + const GLenum FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56; + const GLenum MAX_SAMPLES = 0x8D57; + const GLenum HALF_FLOAT = 0x140B; + const GLenum RG = 0x8227; + const GLenum RG_INTEGER = 0x8228; + const GLenum R8 = 0x8229; + const GLenum RG8 = 0x822B; + const GLenum R16F = 0x822D; + const GLenum R32F = 0x822E; + const GLenum RG16F = 0x822F; + const GLenum RG32F = 0x8230; + const GLenum R8I = 0x8231; + const GLenum R8UI = 0x8232; + const GLenum R16I = 0x8233; + const GLenum R16UI = 0x8234; + const GLenum R32I = 0x8235; + const GLenum R32UI = 0x8236; + const GLenum RG8I = 0x8237; + const GLenum RG8UI = 0x8238; + const GLenum RG16I = 0x8239; + const GLenum RG16UI = 0x823A; + const GLenum RG32I = 0x823B; + const GLenum RG32UI = 0x823C; + const GLenum VERTEX_ARRAY_BINDING = 0x85B5; + const GLenum R8_SNORM = 0x8F94; + const GLenum RG8_SNORM = 0x8F95; + const GLenum RGB8_SNORM = 0x8F96; + const GLenum RGBA8_SNORM = 0x8F97; + const GLenum SIGNED_NORMALIZED = 0x8F9C; + const GLenum COPY_READ_BUFFER = 0x8F36; + const GLenum COPY_WRITE_BUFFER = 0x8F37; + const GLenum COPY_READ_BUFFER_BINDING = 0x8F36; /* Same as COPY_READ_BUFFER */ + const GLenum COPY_WRITE_BUFFER_BINDING = 0x8F37; /* Same as COPY_WRITE_BUFFER */ + const GLenum UNIFORM_BUFFER = 0x8A11; + const GLenum UNIFORM_BUFFER_BINDING = 0x8A28; + const GLenum UNIFORM_BUFFER_START = 0x8A29; + const GLenum UNIFORM_BUFFER_SIZE = 0x8A2A; + const GLenum MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B; + const GLenum MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D; + const GLenum MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E; + const GLenum MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F; + const GLenum MAX_UNIFORM_BLOCK_SIZE = 0x8A30; + const GLenum MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31; + const GLenum MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33; + const GLenum UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34; + const GLenum ACTIVE_UNIFORM_BLOCKS = 0x8A36; + const GLenum UNIFORM_TYPE = 0x8A37; + const GLenum UNIFORM_SIZE = 0x8A38; + const GLenum UNIFORM_BLOCK_INDEX = 0x8A3A; + const GLenum UNIFORM_OFFSET = 0x8A3B; + const GLenum UNIFORM_ARRAY_STRIDE = 0x8A3C; + const GLenum UNIFORM_MATRIX_STRIDE = 0x8A3D; + const GLenum UNIFORM_IS_ROW_MAJOR = 0x8A3E; + const GLenum UNIFORM_BLOCK_BINDING = 0x8A3F; + const GLenum UNIFORM_BLOCK_DATA_SIZE = 0x8A40; + const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42; + const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43; + const GLenum UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44; + const GLenum UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46; + const GLenum INVALID_INDEX = 0xFFFFFFFF; + const GLenum MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122; + const GLenum MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125; + const GLenum MAX_SERVER_WAIT_TIMEOUT = 0x9111; + const GLenum OBJECT_TYPE = 0x9112; + const GLenum SYNC_CONDITION = 0x9113; + const GLenum SYNC_STATUS = 0x9114; + const GLenum SYNC_FLAGS = 0x9115; + const GLenum SYNC_FENCE = 0x9116; + const GLenum SYNC_GPU_COMMANDS_COMPLETE = 0x9117; + const GLenum UNSIGNALED = 0x9118; + const GLenum SIGNALED = 0x9119; + const GLenum ALREADY_SIGNALED = 0x911A; + const GLenum TIMEOUT_EXPIRED = 0x911B; + const GLenum CONDITION_SATISFIED = 0x911C; + const GLenum WAIT_FAILED = 0x911D; + const GLenum SYNC_FLUSH_COMMANDS_BIT = 0x00000001; + const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE; + const GLenum ANY_SAMPLES_PASSED = 0x8C2F; + const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A; + const GLenum SAMPLER_BINDING = 0x8919; + const GLenum RGB10_A2UI = 0x906F; + const GLenum INT_2_10_10_10_REV = 0x8D9F; + const GLenum TRANSFORM_FEEDBACK = 0x8E22; + const GLenum TRANSFORM_FEEDBACK_PAUSED = 0x8E23; + const GLenum TRANSFORM_FEEDBACK_ACTIVE = 0x8E24; + const GLenum TRANSFORM_FEEDBACK_BINDING = 0x8E25; + const GLenum TEXTURE_IMMUTABLE_FORMAT = 0x912F; + const GLenum MAX_ELEMENT_INDEX = 0x8D6B; + const GLenum TEXTURE_IMMUTABLE_LEVELS = 0x82DF; + + const GLint64 TIMEOUT_IGNORED = -1; + + /* WebGL-specific enums */ + const GLenum MAX_CLIENT_WAIT_TIMEOUT_WEBGL = 0x9247; + + /* Buffer objects */ + // WebGL1: + void bufferData(GLenum target, GLsizeiptr size, GLenum usage); + void bufferData(GLenum target, ArrayBuffer? srcData, GLenum usage); + void bufferData(GLenum target, ArrayBufferView srcData, GLenum usage); + void bufferSubData(GLenum target, GLintptr dstByteOffset, BufferDataSource srcData); + // WebGL2: + void bufferData(GLenum target, ArrayBufferView srcData, GLenum usage, GLuint srcOffset, + optional GLuint length = 0); + void bufferSubData(GLenum target, GLintptr dstByteOffset, ArrayBufferView srcData, + GLuint srcOffset, optional GLuint length = 0); + + void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, + GLintptr writeOffset, GLsizeiptr size); + // MapBufferRange, in particular its read-only and write-only modes, + // can not be exposed safely to JavaScript. GetBufferSubData + // replaces it for the purpose of fetching data back from the GPU. + void getBufferSubData(GLenum target, GLintptr srcByteOffset, ArrayBufferView dstData, + optional GLuint dstOffset = 0, optional GLuint length = 0); + + /* Framebuffer objects */ + void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void framebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level, + GLint layer); + void invalidateFramebuffer(GLenum target, sequence attachments); + void invalidateSubFramebuffer(GLenum target, sequence attachments, + GLint x, GLint y, GLsizei width, GLsizei height); + void readBuffer(GLenum src); + + /* Renderbuffer objects */ + any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname); + void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height); + + /* Texture objects */ + void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, + GLsizei height); + void texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth); + + // WebGL1 legacy entrypoints: + void texImage2D(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, + GLenum type, ArrayBufferView? pixels); + void texImage2D(GLenum target, GLint level, GLint internalformat, + GLenum format, GLenum type, TexImageSource source); // May throw DOMException + + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, ArrayBufferView? pixels); + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLenum format, GLenum type, TexImageSource source); // May throw DOMException + + // WebGL2 entrypoints: + void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, GLintptr pboOffset); + void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + TexImageSource source); // May throw DOMException + void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, ArrayBufferView srcData, + GLuint srcOffset); + + void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, GLintptr pboOffset); + void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, + TexImageSource source); // May throw DOMException + void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView? srcData); + void texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, ArrayBufferView srcData, + GLuint srcOffset); + + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, GLintptr pboOffset); + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, + TexImageSource source); // May throw DOMException + void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, ArrayBufferView srcData, + GLuint srcOffset); + + void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + GLintptr pboOffset); + void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + TexImageSource source); // May throw DOMException + void texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, + ArrayBufferView? srcData, optional GLuint srcOffset = 0); + + void copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + + void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLintptr offset); + void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, ArrayBufferView srcData, + optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0); + + void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, GLintptr offset); + void compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, ArrayBufferView srcData, + optional GLuint srcOffset = 0, optional GLuint srcLengthOverride = 0); + + void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLintptr offset); + void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + ArrayBufferView srcData, + optional GLuint srcOffset = 0, + optional GLuint srcLengthOverride = 0); + + void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLintptr offset); + void compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, ArrayBufferView srcData, + optional GLuint srcOffset = 0, + optional GLuint srcLengthOverride = 0); + + /* Programs and shaders */ + [WebGLHandlesContextLoss] GLint getFragDataLocation(WebGLProgram program, DOMString name); + + /* Uniforms */ + void uniform1ui(WebGLUniformLocation? location, GLuint v0); + void uniform2ui(WebGLUniformLocation? location, GLuint v0, GLuint v1); + void uniform3ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2); + void uniform4ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + + void uniform1fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform2fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform3fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform4fv(WebGLUniformLocation? location, Float32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + + void uniform1iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform2iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform3iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform4iv(WebGLUniformLocation? location, Int32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + + void uniform1uiv(WebGLUniformLocation? location, Uint32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform2uiv(WebGLUniformLocation? location, Uint32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform3uiv(WebGLUniformLocation? location, Uint32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + void uniform4uiv(WebGLUniformLocation? location, Uint32List data, optional GLuint srcOffset = 0, + optional GLuint srcLength = 0); + + void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + + void uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + + void uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, + optional GLuint srcOffset = 0, optional GLuint srcLength = 0); + + /* Vertex attribs */ + void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); + void vertexAttribI4iv(GLuint index, Int32List values); + void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void vertexAttribI4uiv(GLuint index, Uint32List values); + void vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); + + /* Writing to the drawing buffer */ + void vertexAttribDivisor(GLuint index, GLuint divisor); + void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); + void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount); + void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset); + + /* Reading back pixels */ + // WebGL1: + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + ArrayBufferView? dstData); + // WebGL2: + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + GLintptr offset); + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + ArrayBufferView dstData, GLuint dstOffset); + + /* Multiple Render Targets */ + void drawBuffers(sequence buffers); + + void clearBufferfv(GLenum buffer, GLint drawbuffer, Float32List values, + optional GLuint srcOffset = 0); + void clearBufferiv(GLenum buffer, GLint drawbuffer, Int32List values, + optional GLuint srcOffset = 0); + void clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32List values, + optional GLuint srcOffset = 0); + + void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + + /* Query Objects */ + WebGLQuery? createQuery(); + void deleteQuery(WebGLQuery? query); + [WebGLHandlesContextLoss] GLboolean isQuery(WebGLQuery? query); + void beginQuery(GLenum target, WebGLQuery query); + void endQuery(GLenum target); + WebGLQuery? getQuery(GLenum target, GLenum pname); + any getQueryParameter(WebGLQuery query, GLenum pname); + + /* Sampler Objects */ + WebGLSampler? createSampler(); + void deleteSampler(WebGLSampler? sampler); + [WebGLHandlesContextLoss] GLboolean isSampler(WebGLSampler? sampler); + void bindSampler(GLuint unit, WebGLSampler? sampler); + void samplerParameteri(WebGLSampler sampler, GLenum pname, GLint param); + void samplerParameterf(WebGLSampler sampler, GLenum pname, GLfloat param); + any getSamplerParameter(WebGLSampler sampler, GLenum pname); + + /* Sync objects */ + WebGLSync? fenceSync(GLenum condition, GLbitfield flags); + [WebGLHandlesContextLoss] GLboolean isSync(WebGLSync? sync); + void deleteSync(WebGLSync? sync); + GLenum clientWaitSync(WebGLSync sync, GLbitfield flags, GLuint64 timeout); + void waitSync(WebGLSync sync, GLbitfield flags, GLint64 timeout); + any getSyncParameter(WebGLSync sync, GLenum pname); + + /* Transform Feedback */ + WebGLTransformFeedback? createTransformFeedback(); + void deleteTransformFeedback(WebGLTransformFeedback? tf); + [WebGLHandlesContextLoss] GLboolean isTransformFeedback(WebGLTransformFeedback? tf); + void bindTransformFeedback (GLenum target, WebGLTransformFeedback? tf); + void beginTransformFeedback(GLenum primitiveMode); + void endTransformFeedback(); + void transformFeedbackVaryings(WebGLProgram program, sequence varyings, GLenum bufferMode); + WebGLActiveInfo? getTransformFeedbackVarying(WebGLProgram program, GLuint index); + void pauseTransformFeedback(); + void resumeTransformFeedback(); + + /* Uniform Buffer Objects and Transform Feedback Buffers */ + void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer); + void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size); + any getIndexedParameter(GLenum target, GLuint index); + sequence? getUniformIndices(WebGLProgram program, sequence uniformNames); + any getActiveUniforms(WebGLProgram program, sequence uniformIndices, GLenum pname); + GLuint getUniformBlockIndex(WebGLProgram program, DOMString uniformBlockName); + any getActiveUniformBlockParameter(WebGLProgram program, GLuint uniformBlockIndex, GLenum pname); + DOMString? getActiveUniformBlockName(WebGLProgram program, GLuint uniformBlockIndex); + void uniformBlockBinding(WebGLProgram program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + + /* Vertex Array Objects */ + WebGLVertexArrayObject? createVertexArray(); + void deleteVertexArray(WebGLVertexArrayObject? vertexArray); + [WebGLHandlesContextLoss] GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray); + void bindVertexArray(WebGLVertexArrayObject? array); +}; +WebGL2RenderingContextBase implements WebGLRenderingContextBase; + +interface WebGL2RenderingContext +{ +}; +WebGL2RenderingContext implements WebGL2RenderingContextBase; + + diff --git a/applications/generators/X3D/Makefile b/applications/generators/X3D/Makefile index 56f2c2d..c62f2ba 100644 --- a/applications/generators/X3D/Makefile +++ b/applications/generators/X3D/Makefile @@ -4,12 +4,12 @@ vpath %.c $(SRC_PATH)/applications/generators/X3D CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif diff --git a/applications/generators/X3D/main.c b/applications/generators/X3D/main.c index 72e3670..0e788a8 100644 --- a/applications/generators/X3D/main.c +++ b/applications/generators/X3D/main.c @@ -145,9 +145,8 @@ X3DNode *BlankNode() u8 IsNDT(GF_List *NDTs, char *famName) { u32 i; - char *ndtName; for (i=0; ifamilly, "SFString")) { - fprintf(vrml_code, "\tp->%s.buffer = (char*) gf_malloc(sizeof(char) * %d);\n", bf->name, strlen(bf->def)+1); + fprintf(vrml_code, "\tp->%s.buffer = (char*) gf_malloc(sizeof(char) * %u);\n", bf->name, (u32) strlen(bf->def)+1); fprintf(vrml_code, "\tstrcpy(p->%s.buffer, \"%s\");\n", bf->name, bf->def); } @@ -809,7 +808,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) store = CurrentLine; CurrentLine = token; GetNextToken(tok, " \""); - fprintf(vrml_code, "\tp->%s.vals[%d] = (char*)gf_malloc(sizeof(char) * %d);\n", bf->name, j, strlen(tok)+1); + fprintf(vrml_code, "\tp->%s.vals[%d] = (char*)gf_malloc(sizeof(char) * %u);\n", bf->name, j, (u32) strlen(tok)+1); fprintf(vrml_code, "\tstrcpy(p->%s.vals[%d], \"%s\");\n", bf->name, j, tok); j+=1; CurrentLine = store; @@ -912,10 +911,9 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) static u32 IsNodeInTable(X3DNode *node, char *NDTName) { u32 i; - char *ndt; for (i=0; iNDT); i++) { - ndt = gf_list_get(node->NDT, i); + char *ndt = gf_list_get(node->NDT, i); if (!strcmp(ndt, NDTName)) return 1; } return 0; @@ -923,11 +921,9 @@ static u32 IsNodeInTable(X3DNode *node, char *NDTName) static u32 GetNDTCount(char *NDTName, GF_List *XNodes) { - u32 i, nodeCount; - X3DNode *n; - nodeCount = 0; + u32 i, nodeCount = 0; for (i=0; iname); for (i=0; iFields); i++) { - bf = gf_list_get(n->Fields, i); + X3DField *bf = gf_list_get(n->Fields, i); if (!i) { fprintf(f, " \"%s\"", bf->name); } else { @@ -1203,9 +1198,8 @@ void parse_profile(GF_List *nodes, FILE *prof) int main (int argc, char **argv) { - FILE *nodes, *pf; + FILE *nodes; GF_List *XNodes, *NDTs; - X3DNode *n; X3DField *bf; u32 nb_nodes, nb_imp; @@ -1222,6 +1216,7 @@ int main (int argc, char **argv) gf_fclose(nodes); if (argc>1) { + FILE *pf; pf = gf_fopen(argv[1], "rt"); if (!pf) fprintf(stdout, "Cannot open profile file %s\n", argv[1]); else { @@ -1255,7 +1250,7 @@ int main (int argc, char **argv) nb_imp = 0; //free nodes while (gf_list_count(XNodes)) { - n = gf_list_get(XNodes, 0); + X3DNode *n = gf_list_get(XNodes, 0); if (!n->skip_impl) nb_imp++; gf_list_rem(XNodes, 0); while (gf_list_count(n->NDT)) { diff --git a/applications/gpac/Info.plist b/applications/gpac/Info.plist new file mode 100644 index 0000000..45b0ed1 --- /dev/null +++ b/applications/gpac/Info.plist @@ -0,0 +1,16 @@ + + + + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleShortVersionString + 0.9.0 + CFBundleVersion + 1 + NSCameraUsageDescription + GPAC needs camera access to handle this URL + NSMicrophoneUsageDescription + GPAC needs microphone access to handle this URL + + diff --git a/applications/gpac/Makefile b/applications/gpac/Makefile new file mode 100644 index 0000000..a1bb8db --- /dev/null +++ b/applications/gpac/Makefile @@ -0,0 +1,65 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/applications/gpac + +CFLAGS=-I"$(SRC_PATH)/include" $(OPTFLAGS) + +ifeq ($(DEBUGBUILD),yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD),yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LINKFLAGS=-L../../bin/gcc +ifeq ($(CONFIG_WIN32),yes) +EXE=.exe +PROG=gpac$(EXE) +LINKFLAGS+=$(UNICODEFLAGS) +else +EXT= +PROG=gpac +endif + +ifeq ($(STATICBUILD),yes) +##include static modules and other deps for libgpac +include ../../static.mak +LINKFLAGS+=$(shell pkg-config ../../gpac.pc --libs --static | sed 's/-lgpac //' ) +LINKFLAGS+= $(GPAC_SH_FLAGS) +LINKFLAGS+=$(EXTRALIBS) +else +LINKFLAGS+=-lgpac +ifeq ($(CONFIG_DARWIN),yes) +#LINKFLAGS+= -Wl,-rpath,'@loader_path' +else +LINKFLAGS+= -Wl,-rpath,'$$ORIGIN' -Wl,-rpath-link,../../bin/gcc +endif +endif + + +#common objs - insert after ../static if any to overwrite list of objects +OBJS= main.o + +SRCS := $(OBJS:.o=.c) + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) $(LDFLAGS) + +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 .depend diff --git a/applications/gpac/main.c b/applications/gpac/main.c new file mode 100644 index 0000000..936b1b1 --- /dev/null +++ b/applications/gpac/main.c @@ -0,0 +1,4039 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2017-2020 + * All rights reserved + * + * This file is part of GPAC / gpac 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 + +static GF_SystemRTInfo rti; +static GF_FilterSession *session=NULL; +static u32 list_filters = 0; +static Bool dump_stats = GF_FALSE; +static Bool dump_graph = GF_FALSE; +static Bool print_filter_info = GF_FALSE; +static Bool print_meta_filters = GF_FALSE; +static Bool load_test_filters = GF_FALSE; +static s32 nb_loops = 0; +static s32 runfor = 0; +Bool runfor_exit = GF_FALSE; +Bool enable_prompt = GF_FALSE; +u32 enable_reports = 0; +char *report_filter = NULL; +Bool do_unit_tests = GF_FALSE; +static int alias_argc = 0; +static char **alias_argv = NULL; +static GF_List *args_used = NULL; +static GF_List *args_alloc = NULL; +static u32 gen_doc = 0; +static u32 help_flags = 0; + +//coverage for FileIO +static const char *make_fileio(const char *inargs, const char **out_arg, Bool is_input, GF_Err *e); +static void cleanup_file_io(); + +FILE *sidebar_md=NULL; +static FILE *helpout = NULL; + +static const char *auto_gen_md_warning = "\n"; + +//uncomment to check argument description matches our conventions - see filter.h +#define CHECK_DOC + +//the default set of separators +static char separator_set[7] = GF_FS_DEFAULT_SEPS; +#define SEP_LINK 5 +#define SEP_FRAG 2 +#define SEP_LIST 3 + +static Bool print_filters(int argc, char **argv, GF_FilterSession *session, GF_SysArgMode argmode); +static void dump_all_props(void); +static void dump_all_colors(void); +static void dump_all_codec(GF_FilterSession *session); +static void write_filters_options(GF_FilterSession *fsess); +static void write_core_options(); +static void write_file_extensions(); +static int gpac_make_lang(char *filename); +static Bool gpac_expand_alias(int argc, char **argv); +static u32 gpac_unit_tests(GF_MemTrackerType mem_track); + +static Bool revert_cache_file(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info); + + + +#ifndef GPAC_DISABLE_DOC +const char *gpac_doc = +"# General\n" +"Filters are configurable processing units consuming and producing data packets. These packets are carried " +"between filters through a data channel called __pid__. A PID is in charge of allocating/tracking data packets, " +"and passing the packets to the destination filter(s). A filter output PID may be connected to zero or more filters. " +"This fan-out is handled internally by GPAC (no such thing as a tee filter in GPAC).\n" +"Note: When a PID cannot be connected to any filter, a warning is thrown and all packets dispatched on " +"this PID will be destroyed. The session may however still run, unless [-full-link](CORE) is set.\n" +" \nEach output PID carries a set of properties describing the data it delivers (eg __width__, __height__, __codec__, ...). Properties " +"can be built-in (identified by a 4 character code **abcd**, see [properties (-h props)](filters_properties) ), or user-defined (identified by a string). Each PID tracks " +"its properties changes and triggers filter reconfiguration during packet processing. This allows the filter chain to be " +"reconfigured at run time, potentially reloading part of the chain (eg unload a video decoder when switching from compressed " +"to uncompressed sources).\n" +" \nEach filter exposes one or more sets of capabilities, called __capability bundle__, which are property type and values " +"that must be matched or excluded by connecting PIDs.\n" +" \nEach filter exposes a set of argument to configure itself, using property types and values described as strings formated with " +"separators. This help is given with default separator sets `:=#,@` to specify filters, properties and options. Use [-seps](GPAC) to change them.\n" +"# Property format\n" +"- boolean: formatted as `yes`|`true`|`1` or `no`|`false`|`0`\n" +"- enumeration (for filter arguments only): must use the syntax given in the argument description, otherwise value `0` (first in enum) is assumed.\n" +"- 1-dimension (numbers, floats, ints...): formatted as `value[unit]`, where `unit` can be `k`|`K` (x1000) or `m`|`M` (x1000000) or `g`|`G` (x1000000000). " +"For such properties, value `+I` means maximum possible value, `-I` minimum possible value.\n" +"- fraction: formatted as `num/den` or `num-den` or `num`, in which case the denominator is 1 if `num` is an integer, or 1000000 if `num` is a floating-point value.\n" +"- unsigned 32 bit integer: formated as number or hexadecimal using the format `0xAABBCCDD`.\n" +"- N-dimension (vectors): formatted as `DIM1xDIM2[xDIM3[xDIM4]]` values, without unit multiplier.\n" +"- string: formatted as:\n" +" - `value`: copies value to string.\n" +" - `file@FILE`: load string from local `FILE` (opened in binary mode).\n" +" - `bxml@FILE`: binarize XML from local `FILE` and set property type to data - see https://wiki.gpac.io/NHML-Format.\n" +"- data: formatted as:\n" +" - `size@address`: constant data block, not internally copied; `size` gives the size of the block, `address` the data pointer.\n" +" - `0xBYTESTRING`: data block specified in hexadecimal, internally copied.\n" +" - `file@FILE`: load data from local `FILE` (opened in binary mode).\n" +" - `bxml@FILE`: binarize XML from local `FILE` - see https://wiki.gpac.io/NHML-Format.\n" +"- pointer: are formatted as `address` giving the pointer address (32 or 64 bit depending on platforms).\n" +"- string lists: formatted as `val1,val2[,...]`. Each value can also use `file@FILE` syntax.\n" +"- integer lists: formatted as `val1,val2[,...]`\n" +"Note: The special characters in property formats (0x,/,-,+I,-I,x) cannot be configured.\n" +"# Filter declaration [__FILTER__]\n" +"## Generic declaration\n" +"Each filter is declared by its name, with optional filter arguments appended as a list of colon-separated `name=value` pairs. Additional syntax is provided for:\n" +"- boolean: `value` can be omitted, defaulting to `true` (eg `:noedit`). Using `!` before the name negates the result (eg `:!moof_first`)\n" +"- enumerations: name can be omitted (eg `:disp=pbo` is equivalent to `:pbo`), provided that filter developers pay attention to not reuse enumeration names in the same filter.\n" +"\n \n" +"When string parameters are used (eg URLs), it is recommended to escape the string using the keyword `gpac`. \n" +"EX filter:ARG=http://foo/bar?yes:gpac:opt=VAL\n" +"This will properly extract the URL.\n" +"EX filter:ARG=http://foo/bar?yes:opt=VAL\n" +"This will fail to extract it and keep `:opt=VAL` as part of the URL.\n" +"The escape mechanism is not needed for local source, for which file existence is probed during argument parsing. " +"It is also not needed for builtin procotol handlers (`avin://`, `video://`, `audio://`, `pipe://`)\n" +"For `tcp://` and `udp://` protocols, the escape is not needed if a trailing `/` is appended after the port number.\n" +"EX -i tcp://127.0.0.1:1234:OPT\n" +"This will fail to extract the URL and options.\n" +"EX -i tcp://127.0.0.1:1234/:OPT\n" +"This will extract the URL and options.\n" +"Note: one trick to avoid the escape sequence is to declare the URLs option at the end, eg `f1:opt1=foo:url=http://bar`, provided you have only one URL parameter to specify on the filter.\n" +"\n" +"It is possible to disable option parsing (for string options) by duplicating the seperator.\n" +"EX filter::opt1=UDP://IP:PORT/:someopt=VAL::opt2=VAL2\n" +"This will pass `UDP://IP:PORT/:someopt=VAL` to `opt1` without inspecting it, and `VAL2` to `opt2`.\n" +" \n" +"A filter may be assigned a name (for inspection purposes) using `:N=name` option. This name is not used in link resolution and may be changed at runtime by the filter instance.\n" +"## Source and Sink filters\n" +"Source and sink filters do not need to be addressed by the filter name, specifying `src=` or `dst=` instead is enough. " +"You can also use the syntax `-src URL` or `-i URL` for sources and `-dst URL` or `-o URL` for destination, this allows prompt completion in shells.\n" +"EX \"src=file.mp4\" or \"-src file.mp4\" or \"-i file.mp4\"\n" +"This will find a filter (for example `fin`) able to load `file.mp4`. The same result can be achieved by using `fin:src=file.mp4`.\n" +"EX \"dst=dump.yuv\" or \"-dst dump.yuv\" or \"-o dump.yuv\"\n" +"This will dump the video content in `dump.yuv`. The same result can be achieved by using `fout:dst=dump.yuv`.\n" +"\n" +"Specific source or sink filters may also be specified using `filterName:src=URL` or `filterName:dst=URL`.\n" +"\n" +"The `src=` and `dst=` syntaxes can also be used in alias for dynamic argument cloning (see `gpac -hx alias`).\n" +"## Forcing specific filters\n" +"There is a special option called `gfreg` which allows specifying preferred filters to use when handling URLs.\n" +"EX src=file.mp4:gfreg=ffdmx,ffdec\n" +"This will use __ffdmx__ to read `file.mp4` and __ffdec__ to decode it.\n" +"This can be used to test a specific filter when alternate filter chains are possible.\n" +"## Specifying encoders and decoders\n" +"By default filters chain will be resolved without any decoding/encoding if the destination accepts the desired format. " +"Otherwise, decoders/encoders will be dynamically loaded to perform the conversion, unless dynamic resolution is disabled. " +"There is a special shorcut filter name for encoders `enc` allowing to match a filter providing the desired encoding. " +"The parameters for `enc` are:\n" +"- c=NAME: identifes the desired codec. `NAME` can be the gpac codec name or the encoder instance for ffmpeg/others\n" +"- b=UINT, rate=UINT, bitrate=UINT: indicates the bitrate in bits per second\n" +"- g=UINT, gop=UINT: indicates the GOP size in frames\n" +"- pfmt=NAME: indicates the target pixel format name (see [properties (-h props)](filters_properties) ) of the source, if supported by codec\n" +"- all_intra=BOOL: indicates all frames should be intra frames, if supported by codec\n" +"\n \nOther options will be passed to the filter if it accepts generic argument parsing (as is the case for ffmpeg).\n" +"EX src=dump.yuv:size=320x240:fps=25 enc:c=avc:b=150000:g=50:cgop=true:fast=true dst=raw.264\n" +"This creates a 25 fps AVC at 175kbps with a gop duration of 2 seconds, using closed gop and fast encoding settings for ffmpeg.\n" +"\n" +"The inverse operation (forcing a decode to happen) is possible using the __reframer__ filter.\n" +"EX src=file.mp4 reframer:raw @ -o null\n" +"This will force decoding media from `file.mp4` and trash (send to `null`) the result (doing a decoder benchmark for example).\n" +"\n" +"When a filter uses an option defined as a string using the same separator character as gpac, you can either " +"modify the set of separators, or escape the seperator by duplicating it. The options enclosed by duplicated " +"separator are not parsed. This is mostly used for meta filters, such as ffmpeg, to pass options to subfilters " +"such as libx264 (cf `x264opts` parameter).\n" +"EX f:a=foo:b=bar\n" +"This will set option `a` to `foo` and option `b` to `bar` on the filter.\n" +"EX f::a=foo:b=bar\n" +"This will set option `a` to `foo:b=bar` on the filter.\n" +"EX f:a=foo::b=bar:c::d=fun\n" +"This will set option `a` to `foo`, `b` to `bar:c` and the option `d` to `fun` on the filter.\n" +"# Expliciting links between filters [__LINK__]\n" +"## Quick links\n" +"Link between filters may be manually specified. The syntax is an `@` character optionaly followed by an integer (0 if omitted). " +"This indicates which filter previously specified at prompt should be link to the next filter listed. The optional integer is a 0-based index to the previous filter declarations, 0 indicating the previous filter declaration, 1 the one before the previous delaration, ...).\n" +"Only the last link directive occuring before a filter is used to setup links for that filter.\n" +"EX fA fB @1 fC\n" +"This indicates to direct `fA` outputs to `fC`.\n" +"EX fA fB @1 @0 fC\n" +"This indicates to direct `fB` outputs to `fC`, `@1` is ignored.\n" +"\nIf no link directives are given, the links will be dynamically solved to fullfill as many connections as possible (__see below__).\n" +"Warning: This means that `fA fB fC` and `fA fB @ fC` will likely not give the same result.\n" +"\n" +"## Complex links\n" +"The link directive is just a quick shortcut to set the following arguments:\n" +"- FID=name, which assigns an identifier to the filter\n" +"- SID=name1[,name2...], which set a list of filter identifiers , or __sourceIDs__, restricting the list of possible inputs for a filter.\n" +"\n" +"EX fA fB @1 fC\n" +"This is equivalent to `fA:FID=1 fB fC:SID=1`.\n" +"Link directives specify which source a filter can accept connections from. They do not specifiy which destination a filter can connect to.\n" +"EX fA:FID=1 fB fC:SID=1\n" +"This indicates that `fC` only accpets input from `fA`, but `fB` might accept inputs from `fA`.\n" +"EX fA:FID=1 fB:FID=2 fC:SID=1 fD:SID=1,2\n" +"This indicates that `fD` only accepts input from `fA` and `fB` and `fC` only from `fA`\n" +"Note: A filter with sourceID set cannot get input from filters with no IDs.\n" +"A sourceID name can be further extended using fragment identifier (`#` by default):\n" +"- name#PIDNAME: accepts only PID(s) with name `PIDNAME`\n" +"- name#TYPE: accepts only PIDs of matching media type. TYPE can be `audio`, `video`, `scene`, `text`, `font`, `meta`\n" +"- name#TYPEN: accepts only `N`th PID of matching type from source\n" +"- name#P4CC=VAL: accepts only PIDs with property matching `VAL`.\n" +"- name#PName=VAL: same as above, using the builtin name corresponding to the property.\n" +"- name#AnyName=VAL: same as above, using the name of a non built-in property.\n" +"- name#Name=OtherPropName: compares the value with the value of another property of the PID. The matching will fail if the value to compare to is not present or different from the value to check. The property to compare with shall be a built-in property.\n" +"If the property is not defined on the PID, the property is matched. Otherwise, its value is checked against the given value.\n" +"\n" +"The following modifiers for comparisons are allowed (for both `P4CC=`, `PName=` and `AnyName=`):\n" +"- name#P4CC=!VAL: accepts only PIDs with property NOT matching `VAL`.\n" +"- name#P4CC-VAL: accepts only PIDs with property strictly less than `VAL` (only for 1-dimension number properties).\n" +"- name#P4CC+VAL: accepts only PIDs with property strictly greater than `VAL` (only for 1-dimension number properties).\n" +"\n" +"A sourceID name can also use wildcard or be empty to match a property regardless of the source filter.\n" +"EX fA fB:SID=*#ServiceID=2\n" +"EX fA fB:SID=#ServiceID=2\n" +"This indicates to match connection between `fA` and `fB` only for PIDs with a `ServiceID` property of `2`.\n" +"These extensions also work with the __LINK__ `@` shortcut.\n" +"EX fA fB @1#video fC\n" +"This indicates to direct `fA` video outputs to `fC`.\n" +"EX src=img.heif @#ItemID=200 vout\n" +"This indicates to connect to `vout` only PIDs with `ItemID` property equal to `200`.\n" +"EX src=vid.mp4 @#PID=1 vout\n" +"This indicates to connect to `vout` only PIDs with `ID` property equal to `1`.\n" +"EX src=vid.mp4 @#Width=640 vout\n" +"This indicates to connect to `vout` only PIDs with `Width` property equal to `640`.\n" +"EX src=vid.mp4 @#Width-640 vout\n" +"This indicates to connect to `vout` only PIDs with `Width` property less than `640`\n" +"EX src=vid.mp4 @#ID=ItemID#ItemNumber=1 vout\n" +"This will connect to `vout` only PID with an ID property equal to ItemID property (keep items, discard tracks) and an Item number of 1 (first item).\n" +"\n" +"Multiple fragment can be specified to check for multiple PID properties.\n" +"EX src=vid.mp4 @#Width=640#Height+380 vout\n" +"This indicates to connect to `vout` only PIDs with `Width` property equal to `640` and `Height` greater than `380`.\n" +"\n" +"Warning: If a filter PID gets connected to a loaded filter, no further dynamic link resolution will " +"be done to connect it to other filters, unless sourceIDs are set. Link directives should be carfully setup.\n" +"EX src=file.mp4 @ reframer dst=dump.mp4\n" +"This will link src `file.mp4` PID (type __file__) to dst `dump.mp4`filter (type `file`) because dst has no sourceID and therefore will " +"accept input from src. Since the PID is connected, the filter engine will not try to solve " +"a link between src and `reframer`. The result is a direct copy of the source file, `reframer` being unused.\n" +"EX src=file.mp4 reframer @ dst=dump.mp4\n" +"This will force dst to accept only from reframer, a muxer will be loaded to solve this link, and " +"src PID will be linked to `reframer` (no source ID), loading a demuxer to solve the link. The result is a complete remux of the source file.\n" +"# Arguments inheriting\n" +"Unless explicitly disabled (see [-max-chain](CORE)), the filter engine will resolve implicit or explicit (__LINK__) connections " +"between filters and will allocate any filter chain required to connect the filters. " +"In doing so, it loads new filters with arguments inherited from both the source and the destination.\n" +"EX src=file.mp4:OPT dst=file.aac dst=file.264\n" +"This will pass the `:OPT` to all filters loaded between the source and the two destinations.\n" +"EX src=file.mp4 dst=file.aac:OPT dst=file.264\n" +"This will pass the `:OPT` to all filters loaded between the source and the file.aac destination.\n" +"Note: the destination arguments inherited are the arguments placed **AFTER** the `dst=` option.\n" +"EX src=file.mp4 fout:OPTFOO:dst=file.aac:OPTBAR\n" +"This will pass the `:OPTBAR` to all filters loaded between `file.mp4` source and `file.aac` destination, but not `OPTFOO`.\n" +"Arguments inheriting can be stopped by using the keyword `gfloc`: arguments after the keyword will not be inherited.\n" +"EX src=file.mp4 dst=file.aac:OPTFOO:gfloc:OPTBAR dst=file.264\n" +"This will pass the `:OPTFOO` to all filters loaded between `file.mp4`source and `file.aac` destination, but not `OPTBAR`\n" +"Arguments are by default tracked to check if they were used by the filter chain, and a warning is thrown if this is not the case.\n" +"It may be usefull to specify arguments which may not be consumed depending on the graph resolution; the specific keyword `gfopt` indicates that arguments after the keyword will not be tracked.\n" +"EX src=file.mp4 dst=file.aac:OPTFOO:gfopt:OPTBAR dst=file.264\n" +"This will warn if `OPTFOO` is not consumed, but will not track `OPTBAR`.\n" +"# URL templating\n" +"Destination URLs can be templated using the same mechanism as MPEG-DASH, where `$KEYWORD$` is replaced in the template with the " +"resolved value and `$KEYWORD%%0Nd$` is replaced in the template with the resolved integer, padded with N zeros if needed. " +"`$$` is an escape for $\n" +"`KEYWORD` is **case sensitive**, and may be present multiple times in the string. Supported `KEYWORD` are:\n" +"- num: replaced by file number if defined, 0 otherwise\n" +"- PID: ID of the source PID\n" +"- URL: URL of source file\n" +"- File: path on disk for source file\n" +"- p4cc=ABCD: uses PID property with 4CC value `ABCD`\n" +"- pname=VAL: uses PID property with name `VAL`\n" +"- OTHER: locates property 4CC for the given name, or property name if no 4CC matches.\n" +"\n \nTemplating can be useful when encoding several qualities in one pass.\n" +"EX src=dump.yuv:size=640x360 vcrop:wnd=0x0x320x180 enc:c=avc:b=1M @2 enc:c=avc:b=750k dst=dump_$CropOrigin$x$Width$x$Height$.264:clone\n" +"This will create a croped version of the source, encoded in AVC at 1M, and a full version of the content in AVC at 750k. " +"Outputs will be `dump_0x0x320x180.264` for the croped version and `dump_0x0x640x360.264` for the non-croped one.\n" +"# Cloning filters\n" +"When a filter accepts a single connection and has a connected input, it is no longer available for dynamic resolution. " +"There may be cases where this behaviour is undesired. Take a HEIF file with N items and do:\n" +"EX src=img.heif dst=dump_$ItemID$.jpg\n" +"In this case, only one item (likely the first declared in the file) will connect to the destination.\n" +"Other items will not be connected since the destination only accepts one input PID.\n" +"There is a special option `clone` allowing destination filters (**and only them**) to be cloned with the same arguments:\n" +"EX src=img.heif dst=dump_$ItemID$.jpg:clone\n" +"In this case, the destination will be cloned for each item, and all will be exported to different JPEGs thanks to URL templating.\n" +"# Templating filter chains\n" +"There can be cases where the number of desired outputs depends on the source content, for example dumping a multiplex of N services into N files. When the destination involves multiplexing the input PIDs, the `:clone`option is not enough since the muxer will always accept the input PIDs.\n" +"To handle this, it is possible to use a PID property name in the sourceID of a filter with the value `*` or an empty value. In this case, whenever a new PID with a new value for the property is found, the filter with such sourceID will be dynamically cloned.\n" +"Warning: This feature should only be called with a single property set to `*` per source ID, results are undefined otherwise.\n" +"EX src=source.ts dst=file_$ServiceID$.mp4:SID=*#ServiceID=*\n" +"EX src=source.ts dst=file_$ServiceID$.mp4:SID=#ServiceID=\n" +"In this case, each new `ServiceID` value found when connecting PIDs to the destination will create a new destination file.\n" +"# Assigning PID properties\n" +"It is possible to define properties on output PIDs that will be declared by a filter. This allows tagging parts of the " +"graph with different properties than other parts (for example `ServiceID`). " +"The syntax is the same as filter option, and uses the fragment separator to identify properties, eg `#Name=Value`.\n" +"This sets output PIDs property (4cc, built-in name or any name) to the given value. Value can be omitted for booleans " +"(defaults to true, eg `:#Alpha`).\n" +"Non built-in properties are parsed as follows:\n" +"- `file@FOO` will be declared as string with a value set to the content of `FOO`.\n" +"- `bxml@FOO` will be declared as data with a value set to the binarized content of `FOO`.\n" +"- `FOO` will be declared as string with a value set to `FOO`.\n" +"- `TYPE@FOO` will be parsed according to `TYPE`. If the type is not recognized, the entire value is copied as string. See `gpac -h props` for defined types.\n" + +"Warning: Properties are not filtered and override the properties of the filter's output PIDs, be carefull not to break " +"the session by overriding core properties such as width/height/samplerate/... !\n" +"EX -i v1.mp4:#ServiceID=4 -i v2.mp4:#ServiceID=2 -o dump.ts\n" +"This will mux the streams in `dump.ts`, using `ServiceID` 4 for PIDs from `v1.mp4` and `ServiceID` 2 for PIDs from `v2.mp4`.\n" +"\n" +"PID properties may be conditionally assigned by checking other PID properties. The syntax uses paranthesis (not configurable) after the property assignment sign:\n" +"`#Prop=(CP=CV)VAL`\n" +"This will assign PID property `Prop` to `VAL` for PIDs with property `CP` equal to `CV`.\n" +"`#Prop=(CP=CV)VAL,(CP2=CV2)VAL2`\n" +"This will assign PID property `Prop` to `VAL` for PIDs with property `CP` equal to `CV`, and to `VAL2` for PIDs with property `CP2` equal to `CV2`.\n" +"`#Prop=(CP=CV)(CP2=CV2)VAL`\n" +"This will assign PID property `Prop` to `VAL` for PIDs with property `CP` equal to `CV` and property `CP2` equal to `CV2`.\n" +"`#Prop=(CP=CV)VAL,()DEFAULT`\n" +"This will assign PID property `Prop` to `VAL` for PIDs with property `CP` equal to `CV`, or to `DEFAULT` for other PIDs.\n" +"The condition syntax is the same as source ID fragment syntax.\n" +"Note: When set, the default value (empty condition) always matches the PID, therefore it should be placed last in the list of conditions.\n" +"EX gpac -i source.mp4:#MyProp=(audio)\"Super Audio\",(video)\"Super Video\"\n" +"This will assign property `MyProp` to `Super Audio` for audio PIDs and to `Super Video` for video PIDs.\n" +"EX gpac -i source.mp4:#MyProp=(audio1)\"Super Audio\"\n" +"This will assign property `MyProp` to `Super Audio` for first audio PID declared.\n" +"EX gpac -i source.mp4:#MyProp=(Width+1280)HD\n" +"This will assign property `MyProp` to `HD` for PIDs with property `Width` greater than 1280.\n" +"# Using option files\n" +"It is possible to use a file to define options of a filter, by specifying the target file name as an option without value, i.e. `:myopts.txt`.\n" +"Warning: Only local files are allowed.\n" +"An option file is a simple text file containing one or more options or PID properties on one or more lines.\n" +"A line begining with \"//\" is a comment and is ignored.\n" +"Options in an option file may point to other option files, with a maximum redirection level of 5.\n" +"An option file declaration (`filter:myopts.txt`) follows the same inheritance rules as regular options.\n" +"EX src=source.mp4:myopts.txt:foo=bar dst\n" +"Any filter loaded between `source.mp4` and `dst` will inherit both `myopts.txt` and `foo` options and will resolve options and PID properties given in `myopts.txt`.\n" +"# Specific filter options\n" +"Some specific keywords are replaced when processing filter options.\n" +"Warning: These keywords do not apply to PID properties. Multiple keywords cannot be defined for a single option.\n" +"Defined keywords:\n" +"- $GSHARE: replaced by system path to GPAC shared directory (e.g. /usr/share)\n" +"- $GJS: replaced by the first path specified by global config option [-js-dirs](CORE) that contains the file name following the macro, e.g. $GJS/source.js\n" +"- $GLANG: replaced by the global config language option [-lang](CORE)\n" +"- $GUA: replaced by the global config user agent option [-user-agent](CORE)\n" +"- $GINC(init_val[,inc]): replaced by `init_val` and increment `init_val` by `inc` (positive or negative number, 1 if not specified) each time a new filter using this string is created.\n" +"\n" +"The $GINC construct can be used to dynamically assign numbers in filter chains:\n" +"EX gpac -i source.ts tssplit @#ServiceID= -o dump_$GINC(10,2).ts\n" +"This will dump first service in dump_10.ts, second service in dump_12.ts, etc...\n" +"# External filters\n" +"GPAC comes with a set of built-in filters in libgpac. It may also load external filters in dynamic libraries, located in " +"folders listed in [-mod-dirs](CORE) option. The files shall be named `gf_*` and shall export" +" a single function returning a filter register - see [libgpac documentation](https://doxygen.gpac.io/) for more details.\n" +"\n"; +#endif + +static void gpac_filter_help(void) +{ + gf_sys_format_help(helpout, help_flags, +"Usage: gpac [options] FILTER [LINK] FILTER [...] \n" +#ifndef GPAC_DISABLE_DOC + "%s", gf_sys_localized("gpac", "doc", gpac_doc) +#else + "GPAC compiled without built-in doc.\n" +#endif + ); + +} + +#include +#include +#include +#include +#include + +static void gpac_modules_help(void) +{ + u32 i; + gf_sys_format_help(helpout, help_flags, "Available modules:\n"); + for (i=0; i= GF_ARGMODE_EXPERT) { + +#ifndef GPAC_DISABLE_DOC + gf_sys_format_help(helpout, help_flags, "%s", gf_sys_localized("gpac", "alias", gpac_alias) ); +#else + gf_sys_format_help(helpout, help_flags, "%s", "GPAC compiled without built-in doc.\n"); +#endif + if (argmode == GF_ARGMODE_EXPERT) { + return; + } + } + + count = gf_opts_get_key_count("gpac.alias"); + if (count) { + if (argmode < GF_ARGMODE_EXPERT) { + gf_sys_format_help(helpout, help_flags, "Available aliases (use 'gpac -hx alias' for more info on aliases):\n"); + } else { + gf_sys_format_help(helpout, help_flags, "Available aliases:\n"); + } + for (i=0; i=GF_ARGMODE_ADVANCED) + gf_sys_format_help(helpout, help_flags, " (%s)", alias_value); + + if (alias_doc) + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_OPT_DESC, ": %s", gf_sys_localized("gpac", "aliasdoc", alias_doc)); + else if (argmodeflags & GF_ARG_HINT_EXPERT)) continue; + if ((argmode==GF_ARGMODE_ADVANCED) && !(arg->flags & GF_ARG_HINT_ADVANCED)) continue; + else if ((argmode==GF_ARGMODE_BASE) && (arg->flags & (GF_ARG_HINT_ADVANCED| GF_ARG_HINT_EXPERT)) ) continue; + } + + gf_sys_print_arg(helpout, help_flags, arg, "gpac"); + } + + if (argmode>=GF_ARGMODE_ADVANCED) { + gf_sys_format_help(helpout, help_flags, "\n \nThe following libgpac core options allow customizing the filter session:\n \n" ); + gf_sys_print_core_help(helpout, help_flags, argmode, GF_ARG_SUBSYS_FILTERS); + } + + if (argmode==GF_ARGMODE_BASE) { + if ( gf_opts_get_key_count("gpac.aliasdoc")) { + gf_sys_format_help(helpout, help_flags, "\n"); + gpac_alias_help(GF_ARGMODE_BASE); + } + + gf_sys_format_help(helpout, help_flags, "\ngpac - GPAC command line filter engine - version %s\n%s\n", gf_gpac_version(), gf_gpac_copyright_cite() ); + } +} + +#ifndef GPAC_DISABLE_DOC +const char *gpac_config = +{ +"# Configuration file\n" +"GPAC uses a configuration file to modify default options of libgpac and filters. This configuration file is located in `$HOME/.gpac/GPAC.cfg`.\n" +"Applications in GPAC can also specify a different configuration file through the [-p](GPAC) option to indicate a profile. " +"This allows different configurations for different usages and simplifies command line typing.\n" +"EX gpac -p=foo []\n" +"This will load configuration from $HOME/.gpac/foo/GPAC.cfg, creating it if needed.\n" +"The reserved name `0` is used to disable configuration file writing.\n" +"By default the configuration file only holds a few system specific options and directories. It is possible to serialize " +"the entire set of options to the configuration file, using [-wc](GPAC) [-wf](GPAC). This should be avoided as the resulting " +"configuration file size will be quite large, hence larger memory usage for the applications.\n" +"The options specified in the configuration file may be overridden by the values in __restrict.cfg__ file located in GPAC share system directory (e.g. /usr/share/gpac), " +"if present; this allows enforcing system-wide configuration values.\n" +"Note: The methods describe in this section apply to any application in GPAC transferring their arguments " +"to libgpac. This is the case for __gpac__, __MP4Box__, __MP4Client/Osmo4__.\n" +"# Core options\n" +"The options from libgpac core can also be assigned though the config file from section __core__ using " +"option name **without initial dash** as key name.\n" +"EX [core]threads=2\n" +"Setting this in the config file is equivalent to using `-threads=2`.\n" +"The options specified at prompt overrides the value of the config file.\n" +"# Filter options in configuration\n" +"It is possible to alter the default value of a filter option by modifing the configuration file. Filter __foo__ options are stored in section " +"`[filter@foo]`, using option name and value as key-value pair. Options specified through the configuration file do not take precedence over " +"options specified at prompt or through alias.\n" +"EX [filter@rtpin]interleave=yes\n" +"This will force the rtp input filter to always request RTP over RTSP by default.\n" +"To generate a configuration file with all filters options serialized, use [-wf](GPAC).\n" +"# Global filter options\n" +"It is possible to specify options global to multiple filters using `--OPTNAME=VAL`. Global options do not override filter options but " +"take precedence over options loaded from configuration file.\n" +"This will set option `OPTNAME`, when present, to `VAL` in any loaded filter.\n" +"EX --buffer=100 -i file vout aout\n" +"This is equivalent to specifying `vout:buffer=100 aout:buffer=100`.\n" +"EX --buffer=100 -i file vout aout:buffer=10\n" +"This is equivalent to specifying `vout:buffer=100 aout:buffer=10`.\n" +"Warning: This syntax only applies to regular filter options. It cannot be used with builtin shortcuts (gfreg, enc, ...).\n" +"Meta-filter options can be set in the same way using the syntax `-+OPT_NAME=VAL`.\n" +"EX -+profile=Baseline -i file.cmp -o dump.264\n" +"This is equivalent to specifying `-o dump.264:profile=Baseline`.\n" +" \n" +"For both syntax, it is possible to specify the filter registry name of the option, using `--FNAME@OPTNAME=VAL`.\n" +"In this case the option will only be set for filters which are instances of registry FNAME. This is used when several registries use same option names.\n" +"EX --flist@timescale=100 -i plist1 -i plist2 -o live.mpd\n" +"This will set the timescale option on the playlists filters but not on the dasher filter.\n" +}; +#endif + +static void gpac_config_help() +{ + +#ifndef GPAC_DISABLE_DOC + gf_sys_format_help(helpout, help_flags, "%s", gf_sys_localized("gpac", "config", gpac_config) ); +#else + gf_sys_format_help(helpout, help_flags, "%s", "GPAC compiled without built-in doc.\n"); +#endif +} + + +static Bool logs_to_file=GF_FALSE; + +#define DEF_LOG_ENTRIES 10 + +struct _logentry +{ + u32 tool, level; + u32 nb_repeat; + u64 clock; + char *szMsg; +} *static_logs; +static u32 nb_log_entries = DEF_LOG_ENTRIES; + +static u32 log_write=0; + +static char *log_buf = NULL; +static u32 log_buf_size=0; +static void gpac_on_logs(void *cbck, GF_LOG_Level log_level, GF_LOG_Tool log_tool, const char* fmt, va_list vlist) +{ + va_list vlist_tmp; + va_copy(vlist_tmp, vlist); + u32 len = vsnprintf(NULL, 0, fmt, vlist_tmp); + va_end(vlist_tmp); + if (log_buf_size < len+2) { + log_buf_size = len+2; + log_buf = gf_realloc(log_buf, log_buf_size); + } + vsprintf(log_buf, fmt, vlist); + + if (log_write && static_logs[log_write-1].szMsg) { + if (!strcmp(static_logs[log_write-1].szMsg, log_buf)) { + static_logs[log_write-1].nb_repeat++; + return; + } + } + + static_logs[log_write].level = log_level; + static_logs[log_write].tool = log_tool; + if (static_logs[log_write].szMsg) gf_free(static_logs[log_write].szMsg); + static_logs[log_write].szMsg = gf_strdup(log_buf); + static_logs[log_write].clock = gf_net_get_utc(); + + log_write++; + if (log_write==nb_log_entries) { + log_write = nb_log_entries - 1; + gf_free(static_logs[0].szMsg); + memmove(&static_logs[0], &static_logs[1], sizeof (struct _logentry) * (nb_log_entries-1) ); + memset(&static_logs[log_write], 0, sizeof(struct _logentry)); + } +} + +u64 last_report_clock_us = 0; +static void print_date(u64 time) +{ + time_t gtime; + struct tm *t; + u32 sec; + u32 ms; + gtime = time / 1000; + sec = (u32)(time / 1000); + ms = (u32)(time - ((u64)sec) * 1000); + t = gf_gmtime(>ime); +// fprintf(stderr, "[%d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + t->tm_year, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, ms); + fprintf(stderr, "[%02d:%02d:%02d.%03dZ] ", t->tm_hour, t->tm_min, t->tm_sec, ms); +} + +static void gpac_print_report(GF_FilterSession *fsess, Bool is_init, Bool is_final) +{ + u32 i, count, nb_active; + u64 now; + + if (is_init) { + if (enable_reports==2) + gf_sys_set_console_code(stderr, GF_CONSOLE_SAVE); + + logs_to_file = gf_log_use_file(); + if (!logs_to_file && (enable_reports==2) ) { + if (!nb_log_entries) nb_log_entries = 1; + static_logs = gf_malloc(sizeof(struct _logentry) * nb_log_entries); + memset(static_logs, 0, sizeof(struct _logentry) * nb_log_entries); + gf_log_set_callback(fsess, gpac_on_logs); + } + last_report_clock_us = gf_sys_clock_high_res(); + return; + } + + now = gf_sys_clock_high_res(); + if ( (now - last_report_clock_us < 200000) && !is_final) + return; + + last_report_clock_us = now; + if (!is_final) + gf_sys_set_console_code(stderr, GF_CONSOLE_CLEAR); + + gf_sys_get_rti(100, &rti, 0); + gf_sys_set_console_code(stderr, GF_CONSOLE_CYAN); + print_date(gf_net_get_utc()); + fprintf(stderr, "GPAC Session Status: "); + gf_sys_set_console_code(stderr, GF_CONSOLE_RESET); + fprintf(stderr, "mem % 10"LLD_SUF" kb CPU % 2d", rti.gpac_memory/1000, rti.process_cpu_time); + fprintf(stderr, "\n"); + + gf_fs_lock_filters(fsess, GF_TRUE); + nb_active = count = gf_fs_get_filters_count(fsess); + for (i=0; itype==GF_EVENT_PROGRESS) { + if (event->progress.progress_type==3) { + gpac_print_report(fsess, GF_FALSE, GF_FALSE); + } + } + else if (event->type==GF_EVENT_QUIT) { + gf_fs_abort(fsess, GF_TRUE); + } + return GF_FALSE; +} + + +typedef enum +{ + GPAC_COM_UNDEF = 0, + GPAC_QUIT, + GPAC_EXIT, + GPAC_PRINT_STATS, + GPAC_PRINT_GRAPH, + GPAC_SEND_UPDATE, + GPAC_LIST_FILTERS, + GPAC_INSERT_FILTER, + GPAC_REMOVE_FILTER, + GPAC_PRINT_HELP +} GPAC_Command; + +struct _gpac_key +{ + u8 char_code; + GPAC_Command cmd_type; + const char *cmd_help; + u32 flags; +} GPAC_Keys[] = { + {'q', GPAC_QUIT, "flush all streams and exit", 0}, + {'x', GPAC_EXIT, "exit with no flush (may break output files)", 0}, + {'s', GPAC_PRINT_STATS, "print statistics", 0}, + {'g', GPAC_PRINT_GRAPH, "print filter graph", 0}, + {'l', GPAC_LIST_FILTERS, "list filters", 0}, + {'u', GPAC_SEND_UPDATE, "update argument of filter", 0}, + {'i', GPAC_INSERT_FILTER, "insert a filter in the chain", 0}, + {'r', GPAC_REMOVE_FILTER, "remove a filter from the chain", 0}, + {'h', GPAC_PRINT_HELP, "print this help", 0}, + {0} +}; + +static GPAC_Command get_cmd(u8 char_code) +{ + u32 i=0; + while (GPAC_Keys[i].char_code) { + if (GPAC_Keys[i].char_code == char_code) + return GPAC_Keys[i].cmd_type; + i++; + } + return GPAC_COM_UNDEF; +} + +static void gpac_fsess_task_help() +{ + gf_sys_format_help(helpout, help_flags, "Available runtime options/keys:\n"); + + u32 i=0; + while (GPAC_Keys[i].char_code) { + gf_sys_format_help(helpout, help_flags, "- %c: %s\n", GPAC_Keys[i].char_code, GPAC_Keys[i].cmd_help); + i++; + } +} + +char szFilter[100]; +char szCom[2048]; +static u64 run_start_time = 0; +static Bool gpac_fsess_task(GF_FilterSession *fsess, void *callback, u32 *reschedule_ms) +{ + if (enable_prompt && gf_prompt_has_input()) { + u32 i, count; + GF_Filter *filter; + const GF_Filter *link_from=NULL; + GF_Err e; + char *link_args = NULL; + GPAC_Command c = get_cmd(gf_prompt_get_char()); + switch (c) { + case GPAC_QUIT: + gf_fs_abort(fsess, GF_TRUE); + nb_loops = 0; + return GF_FALSE; + case GPAC_EXIT: + gf_fs_abort(fsess, GF_FALSE); + nb_loops = 0; + return GF_FALSE; + case GPAC_PRINT_STATS: + gf_fs_print_stats(fsess); + break; + case GPAC_PRINT_GRAPH: + gf_fs_print_connections(fsess); + break; + case GPAC_PRINT_HELP: + gpac_fsess_task_help(); + break; + case GPAC_SEND_UPDATE: + fprintf(stderr, "Sending filter update - enter the target filter ID, name, registry name or #N with N the 0-based index in loaded filter list:\n"); + + if (1 > scanf("%99s", szFilter)) { + fprintf(stderr, "Cannot read the filter ID, aborting.\n"); + break; + } + e = GF_OK; + if (szFilter[0]=='#') { + GF_FilterStats stats; + u32 idx = atoi(szFilter+1); + gf_fs_lock_filters(fsess, GF_TRUE); + e = gf_fs_get_filter_stats(fsess, idx, &stats); + gf_fs_lock_filters(fsess, GF_FALSE); + if (e==GF_OK) + strncpy(szFilter, stats.filter_id ? stats.filter_id : stats.name, 99); + } + if (e) { + fprintf(stderr, "Cannot get filter for ID %s, aborting.\n", szFilter); + break; + } + fprintf(stderr, "Enter the command to send\n"); + if (1 > scanf("%2047s", szCom)) { + fprintf(stderr, "Cannot read the command, aborting.\n"); + break; + } + gf_fs_send_update(fsess, szFilter, NULL, szCom, NULL, 0); + break; + case GPAC_LIST_FILTERS: + gf_fs_lock_filters(fsess, GF_TRUE); + count = gf_fs_get_filters_count(fsess); + fprintf(stderr, "Loaded filters:\n"); + for (i=0; i scanf("%99s", szFilter)) { + fprintf(stderr, "Cannot read the filter ID or index, aborting.\n"); + break; + } + link_args = strchr(szFilter, separator_set[SEP_LINK]); + if (link_args) { + link_args[0] = 0; + link_args++; + } + if (szFilter[0]=='#') { + GF_FilterStats stats; + u32 idx = atoi(szFilter+1); + gf_fs_lock_filters(fsess, GF_TRUE); + gf_fs_get_filter_stats(fsess, idx, &stats); + gf_fs_lock_filters(fsess, GF_FALSE); + link_from = stats.filter; + } else { + const GF_Filter *link_from_by_reg=NULL; + gf_fs_lock_filters(fsess, GF_TRUE); + count = gf_fs_get_filters_count(fsess); + for (i=0; i scanf("%2047s", szCom)) { + fprintf(stderr, "Cannot read the filter to insert, aborting.\n"); + break; + } + + if (!strncmp(szCom, "src=", 4)) { + filter = gf_fs_load_source(fsess, szCom+4, NULL, NULL, &e); + } else if (!strncmp(szCom, "dst=", 4)) { + filter = gf_fs_load_destination(fsess, szCom+4, NULL, NULL, &e); + } else { + filter = gf_fs_load_filter(fsess, szCom, &e); + } + + if (!filter) { + fprintf(stderr, "Cannot load filter %s: %s\n", szCom, gf_error_to_string(e)); + break; + } + gf_filter_set_source(filter, (GF_Filter *) link_from, link_args); + //reconnect outputs of source + gf_filter_reconnect_output((GF_Filter *) link_from); + break; + default: + break; + } + } + if (runfor>0) { + u64 now = gf_sys_clock_high_res(); + if (!run_start_time) run_start_time = now; + else if (now - run_start_time > runfor) { + if (runfor_exit) + exit(0); + + gf_fs_abort(fsess, GF_TRUE); + nb_loops = 0; + return GF_FALSE; + } + } + + if (gf_fs_is_last_task(fsess)) + return GF_FALSE; + *reschedule_ms = 500; + return GF_TRUE; +} + +static Bool sigint_catched=GF_FALSE; +static Bool sigint_processed=GF_FALSE; +#ifdef WIN32 +#include +static BOOL WINAPI gpac_sig_handler(DWORD sig) +{ + if (sig == CTRL_C_EVENT) { +#else +#include +static void gpac_sig_handler(int sig) +{ + if (sig == SIGINT) { +#endif + nb_loops = 0; + if (session) { + char input=0; + int res; + if (sigint_catched) { + if (sigint_processed) { + fprintf(stderr, "catched SIGINT twice and session not responding, forcing exit. Please report to GPAC devs https://github.com/gpac/gpac\n"); + } + exit(1); + } + sigint_catched = GF_TRUE; + fprintf(stderr, "catched SIGINT - flush session before exit ? (Y/n):\n"); + res = scanf("%c", &input); + if (res!=1) input=0; + switch (input) { + case 'Y': + case 'y': + case '\n': + sigint_processed = GF_TRUE; + gf_fs_abort(session, GF_TRUE); + break; + case 0: + break; + default: + sigint_processed = GF_TRUE; + gf_fs_abort(session, GF_FALSE); + break; + } + } + } +#ifdef WIN32 + return TRUE; +#endif +} + +static void parse_sep_set(const char *arg, Bool *override_seps) +{ + if (!arg) return; + u32 len = (u32) strlen(arg); + if (!len) return; + *override_seps = GF_TRUE; + if (len>=1) separator_set[0] = arg[0]; + if (len>=2) separator_set[1] = arg[1]; + if (len>=3) separator_set[2] = arg[2]; + if (len>=4) separator_set[3] = arg[3]; + if (len>=5) separator_set[4] = arg[4]; + if (len>=6) separator_set[5] = arg[5]; +} + + +static int gpac_exit_fun(int code, char **alias_argv, int alias_argc) +{ + u32 i; + for (i=1; i +static void gpac_load_suggested_filter_args() +{ + u32 i, count, k; + GF_Config *opts = NULL; + GF_FilterSession *fsess; + const char *version, *cfg_path; + char *all_opts; + + if (gf_opts_get_bool("core", "no-argchk")) + return; + + cfg_path = gf_opts_get_filename(); + all_opts = gf_url_concatenate(cfg_path, "all_opts.txt"); + + opts = gf_cfg_force_new("probe", all_opts); + gf_free(all_opts); + + version = gf_cfg_get_key(opts, "version", "version"); + if (version && !strcmp(version, gf_gpac_version()) ) { + gf_cfg_del(opts); + return; + } + gf_cfg_del_section(opts, "allopts"); + gf_cfg_set_key(opts, "version", "version", gf_gpac_version()); + + gf_sys_format_help(stderr, 0, "__Refreshing all options registry, this may take some time ... "); + + fsess = gf_fs_new(0, GF_FS_SCHEDULER_LOCK_FREE, GF_FS_FLAG_LOAD_META, NULL); + if (!fsess) { + gf_sys_format_help(stderr, 0, "\nWarning: Error creating session\n"); + gf_cfg_del(opts); + return; + } + + count = gf_fs_filters_registers_count(fsess); + for (i=0; iargs) { + const char *old_val; + char *argn=NULL; + const GF_FilterArgs *arg = &freg->args[k]; + if (!arg || !arg->arg_name) { + break; + } + k++; + if (arg->flags & GF_FS_ARG_HINT_HIDE) continue; + + if (arg->flags & GF_FS_ARG_META) { + gf_dynstrcat(&argn, "-+", NULL); + } else { + gf_dynstrcat(&argn, "--", NULL); + } + gf_dynstrcat(&argn, arg->arg_name, NULL); + + old_val = gf_cfg_get_key(opts, "allopts", argn); + if (old_val) { + char *newval = gf_strdup(freg->name); + gf_dynstrcat(&newval, old_val, " "); + gf_cfg_set_key(opts, "allopts", argn, newval); + gf_free(newval); + } else { + gf_cfg_set_key(opts, "allopts", argn, freg->name); + } + gf_free(argn); + } + } + gf_fs_del(fsess); + gf_cfg_del(opts); + gf_sys_format_help(stderr, 0, "done\n"); +} + + +static void gpac_suggest_arg(char *aname) +{ + u32 k; + const GF_GPACArg *args; + if (!aname) return; + Bool found=GF_FALSE; + for (k=0; k<2; k++) { + u32 i=0; + if (k==0) args = gpac_args; + else args = gf_sys_get_options(); + + while (args[i].name) { + const GF_GPACArg *arg = &args[i]; + i++; + if (gf_sys_word_match(aname, arg->name)) { + if (!found) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Unrecognized option \"%s\", did you mean:\n", aname)); + found = GF_TRUE; + } + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("\t-%s (see gpac -hx%s)\n", arg->name, k ? " core" : "")); + } + } + } + if (!found) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Unrecognized option \"%s\", check usage \"gpac -h\"\n", aname)); + } +} + +static void gpac_suggest_filter(char *fname, Bool is_help, Bool filter_only) +{ + Bool found = GF_FALSE; + u32 i, count; + if (!fname) return; + count = gf_fs_filters_registers_count(session); + for (i=0; iname)) { + if (!found) { + found = GF_TRUE; + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Closest filter names: \n")); + } + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("- %s\n", freg->name)); + } + } + if (!found && is_help) { + const char *doc_helps[] = { + "log", "core", "modules", "doc", "alias", "props", "colors", "cfg", "prompt", "codecs", "links", "bin", "filters", "filters:*", "filters:@", NULL + }; + i=0; + while (doc_helps[i]) { + if (gf_sys_word_match(fname, doc_helps[i])) { + if (!found) { + found = GF_TRUE; + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Closest help command: \n")); + } + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("-h %s\n", doc_helps[i])); + } + i++; + } + if (!filter_only) { + Bool arg_found=GF_FALSE; + u32 nb_alias = gf_opts_get_key_count("gpac.alias"); + for (i=0; iargs) { + const GF_FilterArgs *arg = ®->args[j]; + if (!arg || !arg->arg_name) break; + j++; + if (!gf_sys_word_match(fname, arg->arg_name)) continue; + + if (!arg_found) { + GF_LOG(GF_LOG_WARNING, GF_LOG_APP, ("Closest matching filter option:\n", fname)); + arg_found = GF_TRUE; + found = GF_TRUE; + } + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST, "%s.%s \n", reg->name, arg->arg_name); + } + } + } + } + if (!found) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("No filter %swith similar name found, see gpac -h filters%s\n", + is_help ? "or help command " : "", + is_help ? " or gpac -h" : "" + )); + } +} + +static void gpac_suggest_filter_arg(GF_Config *opts, char *argname, u32 atype) +{ + char *keyname; + const char *keyval; + u32 i, count, len, nb_filters, j; + Bool f_found = GF_FALSE; + char szSep[2]; + + if (gf_opts_get_bool("core", "no-argchk")) + return; + + szSep[0] = separator_set[0]; + szSep[1] = 0; + + len = (u32) strlen(argname); + keyname = gf_malloc(sizeof(char)*(len+3)); + sprintf(keyname, "-%c%s", (atype==2) ? '+' : '-', argname); + keyval = gf_cfg_get_key(opts, "allopts", keyname); + gf_free(keyname); + if (keyval) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Argument \"%s%s\" was set but not used by any filter\n", + (atype==2) ? "-+" : (atype ? "--" : szSep), argname)); + return; + } + + nb_filters = gf_fs_get_filters_count(session); + count = gf_cfg_get_key_count(opts, "allopts"); + for (i=0; i2*len) continue; + + for (j=0; j=2) || print_meta_filters || dump_codecs || print_filter_info) sflags |= GF_FS_FLAG_LOAD_META; + + if (view_filter_conn || list_filters || (print_filter_info && (argmode == GF_ARGMODE_ALL)) ) + gf_opts_set_key("temp", "gendoc", "yes"); + + +restart: + + session = gf_fs_new_defaults(sflags); + + if (!session) { + gpac_exit(1); + } + if (override_seps) gf_fs_set_separators(session, separator_set); + if (load_test_filters) gf_fs_register_test_filters(session); + + if (gf_fs_get_max_resolution_chain_length(session) <= 1 ) { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("\nDynamic resolution of filter connections disabled\n\n")); + } + + if (list_filters || print_filter_info) { + if (print_filters(argc, argv, session, argmode)==GF_FALSE) + e = GF_FILTER_NOT_FOUND; + goto exit; + } + if (view_filter_conn) { + gf_fs_print_all_connections(session, view_conn_for_filter, gf_sys_format_help); + goto exit; + } + if (dump_codecs) { + dump_all_codec(session); + goto exit; + } + if (write_profile || write_extensions || write_core_opts) { + if (write_core_opts) + write_core_options(); + if (write_extensions) + write_file_extensions(); + if (write_profile) + write_filters_options(session); + goto exit; + } + + if (session_js) { + e = gf_fs_load_script(session, session_js); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to load JS for session: %s\n", gf_error_to_string(e) )); + goto exit; + } + } + + //all good to go, load filters + has_xopt = GF_FALSE; + loaded_filters = gf_list_new(); + for (i=1; i1) { + link_prev_filter = atoi(arg+1); + if (link_prev_filter<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Wrong filter index %d, must be positive\n", link_prev_filter)); + e = GF_BAD_PARAM; + goto exit; + } + } + + if (ext) ext[0] = separator_set[SEP_FRAG]; + continue; + } + + if (!strncmp(arg, "src=", 4) ) { + filter = gf_fs_load_source(session, arg+4, NULL, NULL, &e); + } else if (!strncmp(arg, "dst=", 4) ) { + filter = gf_fs_load_destination(session, arg+4, NULL, NULL, &e); + } else { + e = GF_EOS; + char *need_gfio = strstr(arg, "@gfi://"); + if (!need_gfio) need_gfio = strstr(arg, "@gfo://"); + if (need_gfio) { + const char *fargs=NULL; + const char *fio_url; + char *updated_args; + u32 len = (u32) (need_gfio - arg); + updated_args = gf_malloc(sizeof(char)*(len+1)); + strncpy(updated_args, arg, len); + updated_args[len]=0; + + fio_url = make_fileio(need_gfio+7, &fargs, need_gfio[3]=='i' ? GF_TRUE : GF_FALSE, &e); + if (fio_url) { + gf_dynstrcat(&updated_args, fio_url, NULL); + if (fargs) + gf_dynstrcat(&updated_args, fargs, NULL); + + filter = gf_fs_load_filter(session, updated_args, &e); + } + gf_free(updated_args); + } else { + filter = gf_fs_load_filter(session, arg, &e); + } + is_simple=GF_TRUE; + if (!filter && has_xopt) + continue; + } + } + + if (!filter) { + if (!e) e = GF_FILTER_NOT_FOUND; + + if (e!=GF_FILTER_NOT_FOUND) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to load filter%s \"%s\": %s\n", is_simple ? "" : " for", arg, gf_error_to_string(e) )); + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to find filter%s \"%s\"\n", is_simple ? "" : " for", arg)); + + gpac_suggest_filter(arg, GF_FALSE, GF_TRUE); + } + nb_filters=0; + goto exit; + } + nb_filters++; + + if (link_prev_filter>=0) { + GF_Filter *link_from = gf_list_get(loaded_filters, gf_list_count(loaded_filters)-1-link_prev_filter); + if (!link_from) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Wrong filter index @%d\n", link_prev_filter)); + e = GF_BAD_PARAM; + goto exit; + } + link_prev_filter = -1; + gf_filter_set_source(filter, link_from, link_prev_filter_ext); + link_prev_filter_ext = NULL; + } + + gf_list_add(loaded_filters, filter); + } + if (!gf_list_count(loaded_filters) && !session_js) { + if (nothing_to_do && !gen_doc) { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Nothing to do, check usage \"gpac -h\"\ngpac - GPAC command line filter engine - version %s\n%s\n", gf_gpac_version(), gf_gpac_copyright_cite())); + e = GF_BAD_PARAM; + } else { + e = GF_EOS; + } + goto exit; + } + if (enable_reports) { + if (enable_reports==2) + gf_fs_set_ui_callback(session, gpac_event_proc, session); + + gf_fs_enable_reporting(session, GF_TRUE); + } + + if (enable_prompt || (runfor>0)) { + if (enable_prompt) { + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Running session, press 'h' for help\n")); + } + gf_fs_post_user_task(session, gpac_fsess_task, NULL, "gpac_fsess_task"); + } + if (!enable_prompt) { +#ifdef WIN32 + SetConsoleCtrlHandler((PHANDLER_ROUTINE)gpac_sig_handler, TRUE); +#else + signal(SIGINT, gpac_sig_handler); +#endif + } + + if (enable_reports) { + gpac_print_report(session, GF_TRUE, GF_FALSE); + } + + e = gf_fs_run(session); + if (e>0) e = GF_OK; + + if (e) { + fprintf(stderr, "session error %s\n", gf_error_to_string(e) ); + } else { + e = gf_fs_get_last_connect_error(session); + if (e<0) fprintf(stderr, "session last connect error %s\n", gf_error_to_string(e) ); + + if (!e) { + e = gf_fs_get_last_process_error(session); + if (e<0) fprintf(stderr, "session last process error %s\n", gf_error_to_string(e) ); + } + gpac_check_session_args(); + } + + if (enable_reports) { + if (enable_reports==2) { + gf_sys_set_console_code(stderr, GF_CONSOLE_RESTORE); + } + gpac_print_report(session, GF_FALSE, GF_TRUE); + } + +exit: + if (enable_reports==2) { + gf_log_set_callback(session, NULL); + } + + if (e && nb_filters) { + gf_fs_run(session); + } + if (dump_stats) + gf_fs_print_stats(session); + if (dump_graph) + gf_fs_print_connections(session); + + + tmp_sess = session; + session = NULL; + gf_fs_del(tmp_sess); + if (loaded_filters) gf_list_del(loaded_filters); + + cleanup_file_io(); + + if (!e && nb_loops) { + if (nb_loops>0) nb_loops--; + loops_done++; + fprintf(stderr, "session done, restarting (loop %d)\n", loops_done); + gf_log_reset_file(); + goto restart; + } + + gpac_exit(e<0 ? 1 : 0); +} + +GF_MAIN_FUNC(gpac_main) + + +/********************************************************* + Filter and property info/dump functions +*********************************************************/ + +static void dump_caps(u32 nb_caps, const GF_FilterCapability *caps) +{ + u32 i; + for (i=0;iflags & GF_CAPFLAG_IN_BUNDLE) && i+1==nb_caps) break; + if (!i) gf_sys_format_help(helpout, help_flags, "Capabilities Bundle:\n"); + else if (!(cap->flags & GF_CAPFLAG_IN_BUNDLE) ) { + gf_sys_format_help(helpout, help_flags, "Capabilities Bundle:\n"); + continue; + } + + szName = cap->name ? cap->name : gf_props_4cc_get_name(cap->code); + if (!szName) szName = gf_4cc_to_str(cap->code); + gf_sys_format_help(helpout, help_flags, "\t Flags:"); + if (cap->flags & GF_CAPFLAG_INPUT) gf_sys_format_help(helpout, help_flags, " Input"); + if (cap->flags & GF_CAPFLAG_OUTPUT) gf_sys_format_help(helpout, help_flags, " Output"); + if (cap->flags & GF_CAPFLAG_EXCLUDED) gf_sys_format_help(helpout, help_flags, " Exclude"); + if (cap->flags & GF_CAPFLAG_LOADED_FILTER) gf_sys_format_help(helpout, help_flags, " LoadedFilterOnly"); + + //dump some interesting predefined ones which are not mapped to types + if (cap->code==GF_PROP_PID_STREAM_TYPE) szVal = gf_stream_type_name(cap->val.value.uint); + else if (cap->code==GF_PROP_PID_CODECID) szVal = (const char *) gf_codecid_name(cap->val.value.uint); + else szVal = gf_props_dump_val(&cap->val, szDump, GF_FALSE, NULL); + + gf_sys_format_help(helpout, help_flags, " %s=\"%s\"", szName, szVal); + if (cap->priority) gf_sys_format_help(helpout, help_flags, ", priority=%d", cap->priority); + gf_sys_format_help(helpout, help_flags, "\n"); + } +} + +static void print_filter_arg(const GF_FilterArgs *a, u32 gen_doc) +{ + Bool is_enum = GF_FALSE; + + if ((a->arg_type==GF_PROP_UINT) && a->min_max_enum && strchr(a->min_max_enum, '|')) { + is_enum = GF_TRUE; + } + + if (gen_doc==1) { + gf_sys_format_help(helpout, help_flags, "", a->arg_name); + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST, "%s", a->arg_name); + gf_sys_format_help(helpout, help_flags, " (%s", is_enum ? "enum" : gf_props_get_type_name(a->arg_type)); + } else { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST, "%s (%s", a->arg_name, is_enum ? "enum" : gf_props_get_type_name(a->arg_type)); + } + if (a->arg_default_val) { + if (!strcmp(a->arg_default_val, "2147483647")) + gf_sys_format_help(helpout, help_flags, ", default: __+I__"); + else if (!strcmp(a->arg_default_val, "-2147483648")) + gf_sys_format_help(helpout, help_flags, ", default: __-I__"); + else + gf_sys_format_help(helpout, help_flags, ", default: __%s__", a->arg_default_val); + } else { +// gf_sys_format_help(helpout, help_flags, ", no default"); + } + if (a->min_max_enum && !is_enum) { + if (!strcmp(a->min_max_enum, "-2147483648-I")) + gf_sys_format_help(helpout, help_flags, ", %s: -I-I", /*strchr(a->min_max_enum, '|') ? "Enum" : */"minmax"); + else + gf_sys_format_help(helpout, help_flags, ", %s: %s", /*strchr(a->min_max_enum, '|') ? "Enum" : */"minmax", a->min_max_enum); + } + if (a->flags & GF_FS_ARG_UPDATE) gf_sys_format_help(helpout, help_flags, ", updatable"); +// if (a->flags & GF_FS_ARG_META) gf_sys_format_help(helpout, help_flags, ", meta"); + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_OPT_DESC, "): %s\n", a->arg_desc); + + //check syntax + if (gen_doc) { + GF_GPACArg _a; + memset(&_a, 0, sizeof(GF_GPACArg)); + _a.name = a->arg_name; + _a.description = a->arg_desc; + _a.flags = GF_ARG_HINT_HIDE; + gf_sys_print_arg(NULL, 0, &_a, ""); + } + + if (a->min_max_enum && strchr(a->min_max_enum, '|')) + gf_sys_format_help(helpout, help_flags, "\n"); +} + +static void print_filter_single_opt(const GF_FilterRegister *reg, char *optname, GF_Filter *filter_inst) +{ + u32 idx=0; + Bool found = GF_FALSE; + const GF_FilterArgs *args = NULL; + if (filter_inst) args = gf_filter_get_args(filter_inst); + else args = reg->args; + + if (!args) return; + + while (1) { + const GF_FilterArgs *a = & args[idx]; + if (!a || !a->arg_name) break; + idx++; + if (strcmp(a->arg_name, optname)) continue; + + print_filter_arg(a, 0); + found = GF_TRUE; + break; + } + if (found) return; + + idx = 0; + while (1) { + const GF_FilterArgs *a = & args[idx]; + if (!a || !a->arg_name) break; + idx++; + if (gf_sys_word_match(optname, a->arg_name) + || (a->arg_desc && strstr(a->arg_desc, optname)) + ) { + if (!found) { + found = GF_TRUE; + fprintf(stderr, "No such option %s for filter %s - did you mean:\n", optname, filter_inst ? gf_filter_get_name(filter_inst) : reg->name); + } + fprintf(stderr, " - %s: %s\n", a->arg_name, a->arg_desc); + } + } + if (found) return; + + fprintf(stderr, "No such option %s for filter %s\n", optname, filter_inst ? gf_filter_get_name(filter_inst) : reg->name); +} + +static void print_filter(const GF_FilterRegister *reg, GF_SysArgMode argmode, GF_Filter *filter_inst) +{ + const GF_FilterArgs *args = NULL; + + if (gen_doc==1) { + char szName[1024]; + sprintf(szName, "%s.md", reg->name); + if (gen_doc==1) { + gf_fclose(helpout); + helpout = gf_fopen(szName, "w"); + fprintf(helpout, "[**HOME**](Home) » [**Filters**](Filters) » %s\n", reg->description); + fprintf(helpout, "%s", auto_gen_md_warning); + + if (!sidebar_md) { + char *sbbuf = NULL; + if (gf_file_exists("_Sidebar.md")) { + char szLine[1024]; + u32 end_pos=0; + sidebar_md = gf_fopen("_Sidebar.md", "r"); + gf_fseek(sidebar_md, 0, SEEK_SET); + while (!feof(sidebar_md)) { + char *read = gf_fgets(szLine, 1024, sidebar_md); + if (!read) break; + if (!strncmp(szLine, "**Filters Help**", 16)) { + end_pos = (u32) gf_ftell(sidebar_md); + break; + } + } + if (!end_pos) end_pos = (u32) gf_ftell(sidebar_md); + if (end_pos) { + sbbuf = gf_malloc(end_pos+1); + gf_fseek(sidebar_md, 0, SEEK_SET); + end_pos = (u32) gf_fread(sbbuf, end_pos, sidebar_md); + sbbuf[end_pos]=0; + gf_fclose(sidebar_md); + } + } + sidebar_md = gf_fopen("_Sidebar.md", "w"); + if (sbbuf) { + fprintf(sidebar_md, "%s\n \n", sbbuf); + gf_free(sbbuf); + } + } +#ifndef GPAC_DISABLE_DOC + if (reg->description) { + fprintf(sidebar_md, "[[%s (%s)|%s]] \n", reg->description, reg->name, reg->name); + } else { + fprintf(sidebar_md, "[[%s|%s]] \n", reg->name, reg->name); + } + if (!reg->help) { + fprintf(stderr, "filter %s without help, forbidden\n", reg->name); + exit(1); + } + if (!reg->description) { + fprintf(stderr, "filter %s without description, forbidden\n", reg->name); + exit(1); + } +#endif + } + +#ifndef GPAC_DISABLE_DOC + gf_sys_format_help(helpout, help_flags, "# %s\n", reg->description); +#endif + gf_sys_format_help(helpout, help_flags, "Register name used to load filter: **%s**\n", reg->name); + if (reg->flags & GF_FS_REG_EXPLICIT_ONLY) { + gf_sys_format_help(helpout, help_flags, "This filter is not checked during graph resolution and needs explicit loading.\n"); + } else { + gf_sys_format_help(helpout, help_flags, "This filter may be automatically loaded during graph resolution.\n"); + } + if (reg->flags & GF_FS_REG_REQUIRES_RESOLVER) { + gf_sys_format_help(helpout, help_flags, "This filter requires the graph resolver to be activated.\n"); + } + } else { + gf_sys_format_help(helpout, help_flags, "# %s\n", filter_inst ? gf_filter_get_name(filter_inst) : reg->name); + if (filter_inst) + gf_sys_format_help(helpout, help_flags, "Description: %s\n", gf_filter_get_description(filter_inst) ); + else { +#ifndef GPAC_DISABLE_DOC + if (reg->description) gf_sys_format_help(helpout, help_flags, "Description: %s\n", reg->description); +#endif + + } + + if (filter_inst) + gf_sys_format_help(helpout, help_flags, "Version: %s\n", gf_filter_get_version(filter_inst) ); + else { + if (reg->version) { + if (!strncmp(reg->version, "! ", 2)) { + if (!gen_doc) + gf_sys_format_help(helpout, help_flags, "%s\n", reg->version+2); + } else { + gf_sys_format_help(helpout, help_flags, "Version: %s\n", reg->version); + } + } + } + } + + if (filter_inst) { + gf_sys_format_help(helpout, help_flags, "Author: %s\n", gf_filter_get_author(filter_inst) ); + gf_sys_format_help(helpout, help_flags, "\n%s\n\n", gf_filter_get_help(filter_inst) ); + } else { +#ifndef GPAC_DISABLE_DOC + if (reg->author) gf_sys_format_help(helpout, help_flags, "Author: %s\n", reg->author); + if (reg->help) { + u32 hf = help_flags; + if (gen_doc==1) hf |= GF_PRINTARG_ESCAPE_XML; + gf_sys_format_help(helpout, hf, "\n%s\n\n", reg->help); + } +#else + gf_sys_format_help(helpout, help_flags, "GPAC compiled without built-in doc\n"); +#endif + } + + if (argmode==GF_ARGMODE_EXPERT) { + if (reg->max_extra_pids==(u32) -1) gf_sys_format_help(helpout, help_flags, "Max Input PIDs: any\n"); + else gf_sys_format_help(helpout, help_flags, "Max Input PIDs: %d\n", 1 + reg->max_extra_pids); + + gf_sys_format_help(helpout, help_flags, "Flags:"); + if (reg->flags & GF_FS_REG_EXPLICIT_ONLY) gf_sys_format_help(helpout, help_flags, " ExplicitOnly"); + if (reg->flags & GF_FS_REG_MAIN_THREAD) gf_sys_format_help(helpout, help_flags, " MainThread"); + if (reg->flags & GF_FS_REG_CONFIGURE_MAIN_THREAD) gf_sys_format_help(helpout, help_flags, " ConfigureMainThread"); + if (reg->flags & GF_FS_REG_HIDE_WEIGHT) gf_sys_format_help(helpout, help_flags, " HideWeight"); + if (reg->flags & GF_FS_REG_REQUIRES_RESOLVER) gf_sys_format_help(helpout, help_flags, " RequireResolver"); + if (reg->flags & GF_FS_REG_DYNLIB) gf_sys_format_help(helpout, help_flags, " DynamicLib"); + if (reg->probe_url) gf_sys_format_help(helpout, help_flags, " URLMimeProber"); + if (reg->probe_data) gf_sys_format_help(helpout, help_flags, " DataProber"); + if (reg->reconfigure_output) gf_sys_format_help(helpout, help_flags, " ReconfigurableOutput"); + + gf_sys_format_help(helpout, help_flags, "\nPriority %d", reg->priority); + + gf_sys_format_help(helpout, help_flags, "\n"); + } + + if (filter_inst) args = gf_filter_get_args(filter_inst); + else args = reg->args; + + if (args) { + u32 idx=0; + if (gen_doc==1) { + gf_sys_format_help(helpout, help_flags, "# Options \n"); + } else { + switch (argmode) { + case GF_ARGMODE_ALL: + case GF_ARGMODE_EXPERT: + gf_sys_format_help(helpout, help_flags, "# Options (expert):\n"); + break; + case GF_ARGMODE_ADVANCED: + gf_sys_format_help(helpout, help_flags, "# Options (advanced):\n"); + break; + case GF_ARGMODE_BASE: + gf_sys_format_help(helpout, help_flags, "# Options (basic):\n"); + break; + } + } + + while (1) { + const GF_FilterArgs *a = & args[idx]; + if (!a || !a->arg_name) break; + idx++; + + if (a->flags & GF_FS_ARG_HINT_HIDE) continue; + + switch (argmode) { + case GF_ARGMODE_ALL: + case GF_ARGMODE_EXPERT: + break; + case GF_ARGMODE_ADVANCED: + if (a->flags & GF_FS_ARG_HINT_EXPERT) continue; + break; + case GF_ARGMODE_BASE: + if (a->flags & (GF_FS_ARG_HINT_EXPERT|GF_FS_ARG_HINT_ADVANCED)) continue; + break; + } + + print_filter_arg(a, gen_doc); + + if (!gen_doc) continue; + +#ifdef CHECK_DOC + if (a->flags & GF_FS_ARG_META) continue; + + u8 achar; + u32 j=0; + char szArg[100]; + sprintf(szArg, " %s ", a->arg_name); + if (reg->help && strstr(reg->help, szArg)) { + fprintf(stderr, "\nWARNING: filter %s bad help, uses arg %s without link\n", reg->name, a->arg_name); + exit(1); + } + while (1) { + const GF_FilterArgs *anarg = & args[j]; + if (!anarg || !anarg->arg_name) break; + j++; + if (a == anarg) continue; + if (reg->help && strstr(reg->help, szArg)) { + fprintf(stderr, "\nWARNING: filter %s bad description for argument %s, uses arg %s without link\n", reg->name, anarg->arg_name, a->arg_name); + exit(1); + } + } + + if (a->min_max_enum) { + //check format + if ((a->arg_type!=GF_PROP_UINT_LIST) && !(a->flags&GF_FS_ARG_META) && strchr(a->min_max_enum, '|') ) { + if (!strstr(a->arg_desc, "- ")) { + fprintf(stderr, "\nWARNING: filter %s bad description format for arg %s, missing list bullet \"- \"\n", reg->name, a->arg_name); + exit(1); + } + if (strstr(a->arg_desc, ":\n")) { + fprintf(stderr, "\nWARNING: filter %s bad description format for arg %s, should not use \":\\n\"\n", reg->name, a->arg_name); + exit(1); + } + } else if (!(a->flags&GF_FS_ARG_META) && strchr(a->arg_desc, '\n')) { + fprintf(stderr, "\nWARNING: filter %s bad description format for arg %s, should not contain \"\\n\"\n", reg->name, a->arg_name); + exit(1); + } + } + if (!(a->flags&GF_FS_ARG_META)) { + char *sep; + + achar = a->arg_desc[strlen(a->arg_desc)-1]; + if (achar == '\n') { + fprintf(stderr, "\nWARNING: filter %s bad description format for arg %s, should not end with \"\\n\"\n", reg->name, a->arg_name); + exit(1); + } + + achar = a->arg_desc[0]; + if ((achar >= 'A') && (achar <= 'Z')) { + achar = a->arg_desc[1]; + if ((achar < 'A') || (achar > 'Z')) { + fprintf(stderr, "\nWARNING: filter %s bad description format for arg %s, should start with lowercase\n", reg->name, a->arg_name); + exit(1); + } + } + if (a->arg_desc[0] == ' ') { + fprintf(stderr, "\nWARNING: filter %s bad description format for arg %s, first character should not be space\n", reg->name, a->arg_name); + exit(1); + } + sep = strchr(a->arg_desc+1, ' '); + if (sep) sep--; + if (sep && (sep[0] == 's') && (sep[-1] != 's')) { + fprintf(stderr, "\nWARNING: filter %s bad description format for arg %s, first word should be infinitive\n", reg->name, a->arg_name); + exit(1); + } + } +#endif + } + } else { + gf_sys_format_help(helpout, help_flags, "No options\n"); + } + + if (reg->nb_caps) { + if (!gen_doc && (argmode==GF_ARGMODE_ALL)) { + dump_caps(reg->nb_caps, reg->caps); + } + } + gf_sys_format_help(helpout, help_flags, "\n"); +} + +static Bool strstr_nocase(const char *text, const char *subtext, u32 subtext_len) +{ + if (!*text || !subtext || !subtext_len) + return GF_FALSE; + + while (*text) { + if (tolower(*text) == *subtext) { + if (!strnicmp(text, subtext, subtext_len)) + return GF_TRUE; + + } + text++; + } + return GF_FALSE; +} + +static Bool print_filters(int argc, char **argv, GF_FilterSession *session, GF_SysArgMode argmode) +{ + Bool found = GF_FALSE; + char *fname = NULL; + char *l_fname = NULL; + u32 lf_len = 0; + u32 i, count = gf_fs_filters_registers_count(session); + + if (!gen_doc && list_filters) gf_sys_format_help(helpout, help_flags, "Listing %d supported filters%s:\n", count, (list_filters==2) ? " including meta-filters" : ""); + for (i=0; iname) ) { + if (optname) + print_filter_single_opt(reg, optname, NULL); + else + print_filter(reg, argmode, NULL); + found = GF_TRUE; + } else { + char *sepo = strchr(arg, ':'); + char *sepd = strchr(reg->name, ':'); + Bool patch_meta = GF_FALSE; + if (sepo && sepd) { + char *subf = strstr(reg->name, sepo+1); + if (subf) { + u32 slen = (u32) strlen(sepo+1); + if ((subf[slen]==0) || (subf[slen]==',')) + patch_meta = GF_TRUE; + } + } + if (!strcmp(arg, "*:*") || !strcmp(arg, "@:@") + || (!sepo && (!strcmp(arg, "*") || !strcmp(arg, "@")) ) + || (sepo && (!strcmp(sepo, ":*") || !strcmp(sepo, ":@")) && !strncmp(reg->name, arg, 1+sepo - arg) ) + || patch_meta + ) { + if (optname) + print_filter_single_opt(reg, optname, NULL); + else + print_filter(reg, argmode, NULL); + found = GF_TRUE; + break; + } + //quick shortcuts + else if (!strcmp(reg->name, "jsf") && (!strncmp(arg, "jsf:", 4) || strstr(arg, ".js")) ) { + GF_Filter *f = gf_fs_load_filter(session, arg, NULL); + if (f) { + if (optname) + print_filter_single_opt(reg, optname, f); + else + print_filter(reg, argmode, f); + found = GF_TRUE; + } + } + } + if (sepe) sepe[0] = '.'; + } + } else { +#ifndef GPAC_DISABLE_DOC + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST, "%s: %s\n", reg->name, reg->description); +#else + gf_sys_format_help(helpout, help_flags, "%s (compiled without built-in doc)\n", reg->name); +#endif + found = GF_TRUE; + + } + } + if (found) return GF_TRUE; + if (!fname) return GF_FALSE; + if (!print_filter_info) return GF_FALSE; + if (gen_doc) return GF_FALSE; + + if (argmode==GF_ARGMODE_EXPERT) { + l_fname = gf_strdup(fname); + strlwr(l_fname); + lf_len = (u32) strlen(l_fname); + } + + for (i=0; iargs) { + const GF_FilterArgs *arg = ®->args[j]; + if (!arg || !arg->arg_name) break; + j++; + if (argmode==GF_ARGMODE_EXPERT) { + if (!arg->arg_desc || !strstr_nocase(arg->arg_desc, l_fname, lf_len)) continue; + if (!found) { + GF_LOG(GF_LOG_WARNING, GF_LOG_APP, ("\"%s\" is mentionned in the following filters options:\n", fname)); + found = GF_TRUE; + } + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST, "%s.%s \n", reg->name, arg->arg_name); +#if 0 + + } else { + if (strcmp(arg->arg_name, fname)) continue; + if (!found) { + GF_LOG(GF_LOG_WARNING, GF_LOG_APP, ("No such filter \"%s\" but found filters with matching options:\n", fname)); + found = GF_TRUE; + } + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST, "%s.%s: %s\n", reg->name, arg->arg_name, arg->arg_desc); +#endif + } + } + } + if (l_fname) gf_free(l_fname); + + + if (found) return GF_TRUE; + + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("No such filter \"%s\"\n", fname)); + gpac_suggest_filter(fname, GF_TRUE, GF_FALSE); + return GF_FALSE; +} + +static void dump_all_props(void) +{ + u32 i=0; + const GF_BuiltInProperty *prop_info; + + if (gen_doc==1) { + gf_sys_format_help(helpout, help_flags, "## Built-in property types\n" + " \n"); + + gf_sys_format_help(helpout, help_flags, "Name | Description \n"); + gf_sys_format_help(helpout, help_flags, "--- | --- \n"); + for (i=GF_PROP_FORBIDEN+1; iname) continue; + + if (gen_doc==1) { + strcpy(szFlags, ""); + if (prop_info->flags & GF_PROP_FLAG_GSF_REM) strcat(szFlags, "D"); + if (prop_info->flags & GF_PROP_FLAG_PCK) strcat(szFlags, "P"); + + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, "%s | %s | %s | %s | %s \n", prop_info->name, gf_props_get_type_name(prop_info->data_type), + szFlags, + prop_info->description, + gf_4cc_to_str(prop_info->type) + ); + } else if (gen_doc==2) { + gf_sys_format_help(helpout, help_flags, ".TP\n.B %s (%s,%s,%s%s)\n%s\n", prop_info->name, gf_4cc_to_str(prop_info->type), gf_props_get_type_name(prop_info->data_type), + (prop_info->flags & GF_PROP_FLAG_GSF_REM) ? "D" : " ", + (prop_info->flags & GF_PROP_FLAG_PCK) ? "P" : " ", + prop_info->description); + } else { + u32 len; + const char *ptype; + szFlags[0]=0; + if (prop_info->flags & GF_PROP_FLAG_GSF_REM) strcat(szFlags, "D"); + if (prop_info->flags & GF_PROP_FLAG_PCK) strcat(szFlags, "P"); + + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_HIGHLIGHT_FIRST, "%s", prop_info->name); + len = (u32) strlen(prop_info->name); + while (len<16) { + gf_sys_format_help(helpout, help_flags, " "); + len++; + } + ptype = gf_props_get_type_name(prop_info->data_type); + gf_sys_format_help(helpout, help_flags, " (%s %s %s):", gf_4cc_to_str(prop_info->type), ptype, szFlags); + len = (u32) strlen(ptype); + while (len<6) { + gf_sys_format_help(helpout, help_flags, " "); + len++; + } + + gf_sys_format_help(helpout, help_flags, "%s", prop_info->description); + + if (prop_info->data_type==GF_PROP_PIXFMT) { + gf_sys_format_help(helpout, help_flags, "\n\tNames: %s\n\tFile extensions: %s", gf_pixel_fmt_all_names(), gf_pixel_fmt_all_shortnames() ); + } else if (prop_info->data_type==GF_PROP_PCMFMT) { + gf_sys_format_help(helpout, help_flags, "\n\tNames: %s\n\tFile extensions: %s", gf_audio_fmt_all_names(), gf_audio_fmt_all_shortnames() ); + } else if (prop_info->type==GF_PROP_PID_STREAM_TYPE) { + gf_sys_format_help(helpout, help_flags, "\n\tNames: %s\n\t", gf_stream_type_all_names() ); + } + gf_sys_format_help(helpout, help_flags, "\n"); + } + } + if (gen_doc==1) { + u32 idx=0; + const char *name, *fileext, *desc; + gf_sys_format_help(helpout, help_flags, "# Pixel formats\n"); + gf_sys_format_help(helpout, help_flags, "Name | File extensions | Description \n"); + gf_sys_format_help(helpout, help_flags, " --- | --- | --- \n"); + while ( gf_pixel_fmt_enum(&idx, &name, &fileext, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, "%s | %s | %s \n", name, fileext, desc); + } + + idx=0; + gf_sys_format_help(helpout, help_flags, "# Audio formats\n"); + gf_sys_format_help(helpout, help_flags, " Name | File extensions | Description \n"); + gf_sys_format_help(helpout, help_flags, " --- | --- | --- \n"); + while ( gf_audio_fmt_enum(&idx, &name, &fileext, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, "%s | %s | %s \n", name, fileext, desc); + } + + idx=0; + gf_sys_format_help(helpout, help_flags, "# Stream types\n"); + gf_sys_format_help(helpout, help_flags, " Name | Description \n"); + gf_sys_format_help(helpout, help_flags, " --- | --- \n"); + while ( gf_stream_types_enum(&idx, &name, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, "%s | %s \n", name, desc); + } + + idx=0; + gf_sys_format_help(helpout, help_flags, "# Codecs\n"); + gf_sys_format_help(helpout, help_flags, "The codec name identifies a codec within GPAC. There can be several names for a given codec. The first name is used as a default file extension when dumping a raw media stream.\n" + " \n"); + + gf_sys_format_help(helpout, help_flags, " Name | Description \n"); + gf_sys_format_help(helpout, help_flags, " --- | --- \n"); + while ( gf_codecid_enum(idx, &name, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR | GF_PRINTARG_ESCAPE_PIPE, "%s | %s \n", name, desc); + idx++; + } + + } else if (gen_doc==2) { + u32 idx=0; + const char *name, *fileext, *desc; + gf_sys_format_help(helpout, help_flags, "# Pixel formats\n"); + while ( gf_pixel_fmt_enum(&idx, &name, &fileext, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, ".TP\n.B %s (ext *.%s)\n%s\n", name, fileext, desc); + } + + idx=0; + gf_sys_format_help(helpout, help_flags, "# Audio formats\n"); + while ( gf_audio_fmt_enum(&idx, &name, &fileext, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, ".TP\n.B %s (ext *.%s)\n%s\n", name, fileext, desc); + } + + idx=0; + gf_sys_format_help(helpout, help_flags, "# Stream types\n"); + while ( gf_stream_types_enum(&idx, &name, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, ".TP\n.B %s\n%s\n", name, desc); + } + + idx=0; + gf_sys_format_help(helpout, help_flags, "# Codecs\n"); + while ( gf_codecid_enum(idx, &name, &desc)) { + gf_sys_format_help(helpout, help_flags | GF_PRINTARG_NL_TO_BR, ".TP\n.B %s\n%s\n", name, desc); + idx++; + } + } +} +#include +static void dump_all_colors(void) +{ + u32 i=0; + GF_Color color; + const char *name; + while (gf_color_enum(&i, &color, &name)) { + gf_sys_format_help(helpout, help_flags|GF_PRINTARG_HIGHLIGHT_FIRST, "%s: 0x%08X\n", name, color); + } +} + +static void dump_all_codec(GF_FilterSession *session) +{ + GF_PropertyValue rawp, filep, stp; + GF_PropertyValue cp, acp; + char szFlags[10], szCap[2]; + u32 cidx=0; + u32 count = gf_fs_filters_registers_count(session); + + gf_sys_format_help(helpout, help_flags, "Codec support in filters, listed as `built_in_name[|variant] [FLAGS]: full_name (mime)` with possible FLAGS values:\n"); + gf_sys_format_help(helpout, help_flags, " - I: Raw format input (demux) support\n"); + gf_sys_format_help(helpout, help_flags, " - O: Raw format output (mux) support\n"); + gf_sys_format_help(helpout, help_flags, " - D: Decoder support\n"); + gf_sys_format_help(helpout, help_flags, " - E: Encoder support\n"); + gf_sys_format_help(helpout, help_flags, "\nNote: Raw output may still be possible even when no output serializer is given\n\n"); + + rawp.type = cp.type = GF_PROP_UINT; + rawp.value.uint = GF_CODECID_RAW; + filep.type = cp.type = GF_PROP_UINT; + filep.value.uint = GF_STREAM_FILE; + stp.type = GF_PROP_UINT; + cp.type = GF_PROP_UINT; + acp.type = GF_PROP_UINT; + szCap[1] = 0; + + while (1) { + u32 i; + const char *lname; + const char *sname; + const char *mime; + u32 rfc4cc; + Bool enc_found = GF_FALSE; + Bool dec_found = GF_FALSE; + Bool dmx_found = GF_FALSE; + Bool mx_found = GF_FALSE; + cp.value.uint = gf_codecid_enum(cidx, &sname, &lname); + cidx++; + if (cp.value.uint == GF_CODECID_NONE) break; + if (cp.value.uint == GF_CODECID_RAW) continue; + if (!sname) break; + + stp.value.uint = gf_codecid_type(cp.value.uint); + acp.value.uint = gf_codecid_alt(cp.value.uint); + + for (i=0; iname); + meta_sep = strchr(szSecName + 7, ':'); + if (meta_sep) meta_sep[0] = 0; + + while (freg->args) { + const GF_FilterArgs *arg = &freg->args[j]; + if (!arg || !arg->arg_name) break; + j++; + + if (arg->arg_default_val && !gf_opts_get_key(szSecName, arg->arg_name)) { + gf_opts_set_key(szSecName, arg->arg_name, arg->arg_default_val); + } + } + } +} + +/********************************************************* + Language file creation / update functions +*********************************************************/ + +static Bool lang_updated = GF_FALSE; +static void gpac_lang_set_key(GF_Config *cfg, const char *sec_name, const char *key_name, const char *key_val) +{ + char szKeyCRC[1024]; + const char *opt = gf_cfg_get_key(cfg, sec_name, key_name); + u32 crc_key = 0; + if (opt) { + sprintf(szKeyCRC, "%s_crc", key_name); + const char *crc_opt = gf_cfg_get_key(cfg, sec_name, szKeyCRC); + if (crc_opt) { + u32 old_crc = atoi(crc_opt); + crc_key = gf_crc_32((u8*)key_val, (u32) strlen(key_val)); + if (old_crc != crc_key) { + gf_sys_format_help(helpout, help_flags, "Warning: description has changed for %s:%s (crc %d - crc in file %d) - please check translation\n", sec_name, key_name, crc_key, old_crc); + } + return; + } + } + if (!opt) { + char szKeyCRCVal[100]; + if (!crc_key) { + sprintf(szKeyCRC, "%s_crc", key_name); + crc_key = gf_crc_32((u8*)key_val, (u32) strlen(key_val)); + } + sprintf(szKeyCRCVal, "%u", crc_key); + gf_cfg_set_key(cfg, sec_name, key_name, key_val); + gf_cfg_set_key(cfg, sec_name, szKeyCRC, szKeyCRCVal); + lang_updated = GF_TRUE; + } +} +static int gpac_make_lang(char *filename) +{ + GF_Config *cfg; + u32 i; + gf_sys_init(GF_MemTrackerNone, NULL); + + session = gf_fs_new_defaults(0); + if (!session) { + gf_sys_format_help(helpout, help_flags, "failed to load session, cannot create language file\n"); + return 1; + } + if (!gf_file_exists(filename)) { + FILE *f = gf_fopen(filename, "wt"); + if (!f) { + gf_sys_format_help(helpout, help_flags, "failed to open %s in write mode\n", filename); + gf_fs_del(session); + return 1; + } + gf_fclose(f); + } + + cfg = gf_cfg_new(NULL, filename); + + //print gpac help + i = 0; + while (gpac_args[i].name) { + gpac_lang_set_key(cfg, "gpac", gpac_args[i].name, gpac_args[i].description); + i++; + } + + //print gpac doc + gpac_lang_set_key(cfg, "gpac", "doc", gpac_doc); + + //print gpac alias doc + gpac_lang_set_key(cfg, "gpac", "alias", gpac_alias); + + //print libgpac core help + const GF_GPACArg *args = gf_sys_get_options(); + i = 0; + + while (args[i].name) { + gpac_lang_set_key(cfg, "core", args[i].name, args[i].description); + i++; + } + + //print properties + i=0; + const GF_BuiltInProperty *prop_info; + while ((prop_info = gf_props_get_description(i))) { + i++; + if (! prop_info->name || !prop_info->description) continue; + gpac_lang_set_key(cfg, "properties", prop_info->name, prop_info->description); + } + + //print filters + u32 count = gf_fs_filters_registers_count(session); + for (i=0; idescription) { + gpac_lang_set_key(cfg, reg->name, "desc", reg->description); + } + if (reg->help) { + gpac_lang_set_key(cfg, reg->name, "help", reg->help); + } + while (reg->args && reg->args[j].arg_name) { + gpac_lang_set_key(cfg, reg->name, reg->args[j].arg_name, reg->args[j].arg_desc); + j++; + } + } + + if (!lang_updated) { + gf_cfg_discard_changes(cfg); + fprintf(stderr, "lang file %s has not been modified\n", filename); + } else { + fprintf(stderr, "lang file generated in %s\n", filename); + } + gf_cfg_del(cfg); + + gf_fs_del(session); + gf_sys_close(); + return 0; +} + + +/********************************************************* + Alias functions +*********************************************************/ + +static GFINLINE void push_arg(char *_arg, Bool _dup) +{ + alias_argv = gf_realloc(alias_argv, sizeof(char**) * (alias_argc+1));\ + alias_argv[alias_argc] = _dup ? gf_strdup(_arg) : _arg; \ + if (_dup) { + if (!args_alloc) args_alloc = gf_list_new(); + gf_list_add(args_alloc, alias_argv[alias_argc]); + } + alias_argc++; +} + +static Bool gpac_expand_alias_arg(char *param, char *prefix, char *suffix, int arg_idx, int argc, char **argv); + +static Bool check_param_extension(char *szArg, int arg_idx, int argc, char **argv) +{ + char *par_start = strstr(szArg, "@{"); + if (par_start) { + char szPar[100]; + Bool ok; + char *par_end = strchr(par_start, '}'); + if (!par_end) { + fprintf(stderr, "Bad format %s for alias parameter, expecting @{N}\n", szArg); + return GF_FALSE; + } + par_end[0] = 0; + strcpy(szPar, par_start+2); + par_start[0] = 0; + + ok = gpac_expand_alias_arg(szPar, szArg, par_end+1, arg_idx, argc, argv); + if (!ok) return GF_FALSE; + par_start[0] = '@'; + par_end[0] = '}'; + return GF_TRUE; + } + //done, push arg + push_arg(szArg, 1); + return GF_TRUE; +} + +static Bool gpac_expand_alias_arg(char *param, char *prefix, char *suffix, int arg_idx, int argc, char **argv) +{ + char szArg[1024]; + char szSepList[2]; + char *oparam = param; + szSepList[0] = separator_set[SEP_LIST]; + szSepList[1] = 0; + + Bool is_list = param[0]=='-'; + Bool is_expand = param[0]=='+'; + + if (is_list || is_expand) param++; + strcpy(szArg, prefix); + while (param) { + u32 idx=0; + u32 last_idx=0; + char *sep = strchr(param, ','); + if (sep) sep[0]=0; + + if ((param[0]=='n') || (param[0]=='N')) { + idx = argc - arg_idx - 1; + if (param[1]=='-') { + u32 diff = atoi(param+2); + if (diff>=idx) { + if (sep) sep[0]=','; + fprintf(stderr, "Bad usage for alias parameter %s: not enough parameters\n", oparam); + return GF_FALSE; + } + idx -= diff; + } + } else { + char *lsep = strchr(param, ':'); + if (lsep) { + lsep[0] = 0; + if (strlen(param)) + idx = atoi(param); + else + idx=1; + + lsep[0] = ':'; + if ((lsep[1]=='n') || (lsep[1]=='N')) { + + last_idx = argc - arg_idx - 1; + if (lsep[2]=='-') { + u32 diff = atoi(lsep+3); + if (diff>=last_idx) { + fprintf(stderr, "Bad usage for alias parameter %s: not enough parameters\n", oparam); + return GF_FALSE; + } + last_idx -= diff; + } + } else { + last_idx = atoi(lsep+1); + } + } else { + idx = atoi(param); + } + } + if (!idx) { + if (sep) sep[0]=','; + fprintf(stderr, "Bad format for alias parameter %s: cannot extract argument index\n", oparam); + return GF_FALSE; + } + if ((int) idx + arg_idx >= argc) { + if (sep) sep[0]=','; + fprintf(stderr, "Bad format for alias parameter %s: argment out of bounds (not enough paramteters?)\n", oparam); + return GF_FALSE; + } + + if (!last_idx) last_idx=idx; + for (; idx<=last_idx;idx++) { + char *an_arg = argv[idx+arg_idx]; + + if (!args_used) args_used = gf_list_new(); + gf_list_add(args_used, an_arg); + + if (is_expand) { + strcpy(szArg, prefix); + strcat(szArg, an_arg); + strcat(szArg, suffix); + + Bool ok = check_param_extension(szArg, arg_idx, argc, argv); + if (!ok) { + if (sep) sep[0]=','; + return GF_FALSE; + } + } else { + strcat(szArg, an_arg); + if (is_list && (idx +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif +static u32 gpac_unit_tests(GF_MemTrackerType mem_track) +{ +#ifdef GPAC_ENABLE_COVERAGE + u32 ucs4_buf[4]; + u8 utf8_buf[7]; + + void *mem = gf_calloc(4, sizeof(u32)); + gf_free(mem); + + if (mem_track == GF_MemTrackerNone) return 0; + + gpac_fsess_task_help(); //for coverage + gf_dm_sess_last_error(NULL); + gf_log_use_color(); + GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[CoreUnitTests] performing tests\n")); + + utf8_buf[0] = 'a'; + utf8_buf[1] = 0; + if (! utf8_to_ucs4 (ucs4_buf, 1, (unsigned char *) utf8_buf)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] UCS-4 translation failed for single char\n")); + return 1; + } + utf8_buf[0] = 0xc2; + utf8_buf[1] = 0xa3; + utf8_buf[2] = 'a'; + utf8_buf[3] = 0; + if (! utf8_to_ucs4 (ucs4_buf, 3, (unsigned char *) utf8_buf)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] UCS-4 translation failed for 2-byte + 1-byte char\n")); + return 1; + } + utf8_buf[0] = 0xe0; + utf8_buf[1] = 0xa4; + utf8_buf[2] = 0xb9; + utf8_buf[3] = 0; + if (! utf8_to_ucs4 (ucs4_buf, 3, (unsigned char *) utf8_buf)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] UCS-4 translation failed for 3-byte char\n")); + return 1; + } + utf8_buf[0] = 0xf0; + utf8_buf[1] = 0x90; + utf8_buf[2] = 0x8d; + utf8_buf[3] = 0x88; + utf8_buf[4] = 0; + if (! utf8_to_ucs4 (ucs4_buf, 4, (unsigned char *) utf8_buf)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] UCS-4 translation failed for 4-byte char\n")); + return 1; + } + + utf8_buf[0] = 0xf8; + utf8_buf[1] = 0x80; + utf8_buf[2] = 0x80; + utf8_buf[3] = 0x80; + utf8_buf[4] = 0xaf; + utf8_buf[5] = 0; + if (! utf8_to_ucs4 (ucs4_buf, 5, (unsigned char *) utf8_buf)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] UCS-4 translation failed for 5-byte char\n")); + return 1; + } + utf8_buf[0] = 0xfc; + utf8_buf[1] = 0x80; + utf8_buf[2] = 0x80; + utf8_buf[3] = 0x80; + utf8_buf[4] = 0x80; + utf8_buf[5] = 0xaf; + utf8_buf[6] = 0; + if (! utf8_to_ucs4 (ucs4_buf, 6, (unsigned char *) utf8_buf)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] UCS-4 translation failed for 6-byte char\n")); + return 1; + } + //test error case + utf8_buf[0] = 0xf8; + utf8_to_ucs4 (ucs4_buf, 6, (unsigned char *) utf8_buf); + + char buf[5], obuf[3]; + obuf[0] = 1; + obuf[1] = 2; + u32 res = gf_base16_encode(obuf, 2, buf, 5); + if (res != 4) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] base16 encode fail\n")); + return 1; + } + u32 res2 = gf_base16_decode(buf, res, obuf, 3); + if (res2 != 2) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] base16 decode fail\n")); + return 1; + } + + u8 *zbuf; + u32 osize; + GF_Err e; + u8 *ozbuf; + +#ifndef GPAC_DISABLE_ZLIB + zbuf = gf_strdup("123451234512345123451234512345"); + osize=0; + e = gf_gz_compress_payload(&zbuf, 1 + (u32) strlen(zbuf), &osize); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] zlib compress fail\n")); + gf_free(zbuf); + return 1; + } + ozbuf=NULL; + res=0; + e = gf_gz_decompress_payload(zbuf, osize, &ozbuf, &res); + gf_free(zbuf); + if (ozbuf) gf_free(ozbuf); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] zlib decompress fail\n")); + return 1; + } +#endif + + zbuf = gf_strdup("123451234512345123451234512345"); + osize=0; + e = gf_lz_compress_payload(&zbuf, 1+(u32) strlen(zbuf), &osize); + if (e && (e!= GF_NOT_SUPPORTED)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] lzma compress fail\n")); + gf_free(zbuf); + return 1; + } + ozbuf=NULL; + res=0; + e = gf_lz_decompress_payload(zbuf, osize, &ozbuf, &res); + gf_free(zbuf); + if (ozbuf) gf_free(ozbuf); + if (e && (e!= GF_NOT_SUPPORTED)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] lzma decompress fail\n")); + return 1; + } + + gf_htonl(0xAABBCCDD); + gf_ntohl(0xAABBCCDD); + gf_htons(0xAABB); + gf_ntohs(0xAABB); + gf_errno_str(-1); + + /* these two lock the bash shell in test mode + gf_prompt_set_echo_off(GF_TRUE); + gf_prompt_set_echo_off(GF_FALSE); + */ + + gf_net_set_ntp_shift(-1000); + gf_net_get_ntp_diff_ms(gf_net_get_ntp_ts() ); + gf_net_get_timezone(); + gf_net_get_utc_ts(70, 1, 0, 0, 0, 0); + gf_net_ntp_diff_ms(1000000, 1000000); + gf_lang_get_count(); + gf_lang_get_2cc(2); + GF_Blob b; + b.data = (u8 *) "test"; + b.size = 5; + char url[100]; + u8 *data; + u32 size; + sprintf(url, "gmem://%p", &b); + + gf_sys_profiler_set_callback(NULL, NULL); + + gf_blob_get_data(url, &data, &size); + if (!data || strcmp((char *)data, "test")) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[CoreUnitTests] blob url parsing fail\n")); + return 1; + } + gf_sys_get_battery_state(NULL, NULL, NULL, NULL, NULL); + gf_sys_get_process_id(); + data = (u8 *) gf_log_get_tools_levels(); + if (data) gf_free(data); + + gf_sys_is_quiet(); + gf_sys_get_argv(); + gf_mx_get_num_locks(NULL); + sigint_catched = GF_TRUE; + +#ifdef WIN32 + gpac_sig_handler(CTRL_C_EVENT); +#else + gpac_sig_handler(SIGINT); +#endif + + gf_mkdir("testdir"); + gf_mkdir("testdir/somedir"); + strcpy(url, "testdir/somedir/test.bin"); + FILE *f=gf_fopen(url, "wb"); + fprintf(f, "some test\n"); +#ifdef GPAC_MEMORY_TRACKING + gf_memory_print(); +#endif + gf_fclose(f); + gf_file_modification_time(url); + gf_m2ts_probe_file(url); + + gf_cleanup_dir("testdir"); + gf_rmdir("testdir"); + + //math.c not covered yet by our sample files + GF_Matrix2D mx; + gf_mx2d_init(mx); + gf_mx2d_add_skew(&mx, FIX_ONE, FIX_ONE); + gf_mx2d_add_skew_x(&mx, GF_PI/4); + gf_mx2d_add_skew_y(&mx, GF_PI/4); + GF_Point2D scale, translate; + Fixed rotate; + gf_mx2d_decompose(&mx, &scale, &rotate, &translate); + GF_Rect rc1, rc2; + memset(&rc1, 0, sizeof(GF_Rect)); + memset(&rc2, 0, sizeof(GF_Rect)); + gf_rect_equal(&rc1, &rc2); + + GF_Matrix mat; + gf_mx_init(mat); + Fixed yaw, pitch, roll; + gf_mx_get_yaw_pitch_roll(&mat, &yaw, &pitch, &roll); + gf_mx_ortho_reverse_z(&mat, -20, 20, -20, 20, 0.1, 100.0); + gf_mx_perspective_reverse_z(&mat, 0.76, 1.0, 0.1, 100.0); + + GF_Ray ray; + GF_Vec center, outPoint; + memset(&ray, 0, sizeof(GF_Ray)); + ray.dir.z = FIX_ONE; + memset(¢er, 0, sizeof(GF_Vec)); + gf_ray_hit_sphere(&ray, ¢er, FIX_ONE, &outPoint); + + gf_closest_point_to_line(center, ray.dir, center); + + GF_Plane plane; + plane.d = FIX_ONE; + plane.normal = center; + gf_plane_intersect_line(&plane, ¢er, &ray.dir, &outPoint); + + GF_Vec4 rot, quat; + rot.x = rot.y = 0; + rot.z = FIX_ONE; + rot.q = GF_PI/4; + quat = gf_quat_from_rotation(rot); + gf_quat_get_inv(&quat); + gf_quat_rotate(&quat, &ray.dir); + gf_quat_slerp(quat, quat, FIX_ONE/2); + GF_BBox bbox; + memset(&bbox, 0, sizeof(GF_BBox)); + gf_bbox_equal(&bbox, &bbox); + + GF_Vec v; + v.x = v.y = v.z = 0; + gf_vec_scale_p(&v, 2*FIX_ONE); + + //token.c + char container[1024]; + gf_token_get_strip("12 34{ 56 : }", 0, "{:", " ", container, 1024); + + //netwok.c + char name[GF_MAX_IP_NAME_LEN]; + gf_sk_get_host_name(name); + gf_sk_set_usec_wait(NULL, 1000); + u32 fam; + u16 port; + //to remove once we have rtsp server back + gf_sk_get_local_info(NULL, &port, &fam); + gf_sk_receive_wait(NULL, NULL, 0, &fam, 1); + gf_sk_send_wait(NULL, NULL, 0, 1); + + //path2D + GF_Path *path = gf_path_new(); + gf_path_add_move_to(path, 0, 0); + gf_path_add_quadratic_to(path, 5, 5, 10, 0); + gf_path_point_over(path, 4, 0); + gf_path_del(path); + + //xml dom - to update once we find a way to integrate atsc demux in tests + GF_DOMParser *dom = gf_xml_dom_new(); + gf_xml_dom_parse_string(dom, "test"); + gf_xml_dom_get_error(dom); + gf_xml_dom_get_line(dom); + gf_xml_dom_get_root_nodes_count(dom); + gf_xml_dom_del(dom); + + //downloader - to update once we find a way to integrate atsc demux in tests + GF_DownloadManager *dm = gf_dm_new(NULL); + gf_dm_set_auth_callback(dm, NULL, NULL); + + gf_dm_set_data_rate(dm, 0); + gf_dm_get_data_rate(dm); + gf_dm_set_localcache_provider(dm, NULL, NULL); + + const DownloadedCacheEntry ent = gf_dm_add_cache_entry(dm, "http://localhost/test.dummy", "test", 4, 0, 0, "application/octet-string", GF_FALSE, 1); + + gf_dm_force_headers(dm, ent, "x-GPAC: test\r\n"); + gf_dm_sess_enum_headers(NULL, NULL, NULL, NULL);//this one is deactivated in test mode in httpin because of Date: header + gf_dm_sess_abort(NULL); + gf_dm_del(dm); + + //constants + gf_stream_type_afx_name(GPAC_AFX_3DMC); + //thread + gf_th_stop(NULL); + gf_list_swap(NULL, NULL); + //bitstream + GF_BitStream *bs = gf_bs_new("test", 4, GF_BITSTREAM_READ); + gf_bs_bits_available(bs); + gf_bs_get_bit_offset(bs); + gf_bs_read_vluimsbf5(bs); + gf_bs_del(bs); + //module + gf_module_load_static(NULL); + + gf_mp3_version_name(0); + char tsbuf[188]; + u8 is_pes=GF_TRUE; + memset(tsbuf, 0, 188); + tsbuf[0] = 0x47; + tsbuf[1] = 0x40; + tsbuf[4]=0x00; + tsbuf[5]=0x00; + tsbuf[6]=0x01; + tsbuf[10] = 0x80; + tsbuf[11] = 0xc0; + tsbuf[13] = 0x2 << 4; + gf_m2ts_restamp(tsbuf, 188, 1000, &is_pes); + + + gf_filter_post_task(NULL,NULL,NULL,NULL); + gf_filter_get_num_events_queued(NULL); + gf_filter_get_arg_str(NULL, NULL, NULL); + gf_filter_all_sinks_done(NULL); + + gf_opts_discard_changes(); + + gf_rtp_reset_ssrc(NULL); + gf_rtp_enable_nat_keepalive(NULL, 0); + gf_rtp_stop(NULL); + gf_rtp_streamer_get_payload_type(NULL); + gf_rtsp_unregister_interleave(NULL, 0); + gf_rtsp_reset_aggregation(NULL); + + get_cmd('h'); + gpac_suggest_arg("blcksize"); + gpac_suggest_filter("outf", GF_FALSE, GF_FALSE); + //todo: build tests for these two + gf_filter_pid_negociate_property_str(NULL, NULL, NULL); + gf_filter_pid_negociate_property_dyn(NULL, NULL, NULL); + + gf_props_parse_type("uint"); + //this one is just a wrapper around an internal function + gf_filter_pck_new_copy(NULL, NULL, NULL); + gf_filter_get_max_extra_input_pids(NULL); + gf_filter_remove(NULL); + gf_filter_reconnect_output(NULL); + + gf_audio_fmt_get_cicp_layout(2, 1, 1); + gf_audio_fmt_get_layout_from_cicp(3); + gf_audio_fmt_get_layout_name_from_cicp(3); + gf_audio_fmt_get_cicp_from_layout(GF_AUDIO_CH_FRONT_LEFT|GF_AUDIO_CH_FRONT_RIGHT); + + //old bifs parsing stuff + gf_odf_desc_del(gf_odf_desc_new(GF_ODF_ELEM_MASK_TAG)); + GF_TextConfig *txtc = (GF_TextConfig *)gf_odf_desc_new(GF_ODF_TEXT_CFG_TAG); + gf_odf_get_text_config(NULL, 0, 0, txtc); + gf_odf_dump_txtcfg(txtc, NULL, 0, GF_FALSE); + gf_odf_desc_del((GF_Descriptor *) txtc); + + //stuff only used by vtbdec + gf_media_hevc_read_pps_bs(NULL, NULL); + gf_media_hevc_read_sps_bs(NULL, NULL); + gf_media_hevc_read_vps_bs(NULL, NULL); + gf_mpegv12_get_config(NULL, 0, NULL); + + //hinting stuff + GF_HintPacket *hpck = gf_isom_hint_pck_new(GF_ISOM_BOX_TYPE_RTCP_STSD); + gf_isom_hint_pck_length(hpck); + gf_isom_hint_pck_size(hpck); + GF_BitStream *hbs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + gf_isom_hint_pck_write(hpck, hbs); + u8 *hbuf; + u32 hsize; + gf_bs_get_content(hbs, &hbuf, &hsize); + gf_bs_del(hbs); + hbs = gf_bs_new(hbuf, hsize, GF_BITSTREAM_READ); + gf_isom_hint_pck_read(hpck, hbs); + gf_bs_del(hbs); + gf_free(hbuf); + gf_isom_hint_pck_del(hpck); + + gf_isom_last_error(NULL); + gf_isom_get_media_time(NULL, 0, 0, NULL); + gf_isom_get_sample_description_index(NULL, 0, 0); + + +#endif + return 0; +} + +static Bool revert_cache_file(void *cbck, char *item_name, char *item_path, GF_FileEnumInfo *file_info) +{ + const char *url; + GF_Config *cached; + if (strncmp(item_name, "gpac_cache_", 11)) return GF_FALSE; + cached = gf_cfg_new(NULL, item_path); + url = gf_cfg_get_key(cached, "cache", "url"); + if (url) url = strstr(url, "://"); + if (url) { + u32 i, len, dir_len=0, k=0; + char *dst_name; + char *sep; + + sep = strstr(item_path, "gpac_cache_"); + if (sep) { + sep[0] = 0; + dir_len = (u32) strlen(item_path); + sep[0] = 'g'; + } + url+=3; + len = (u32) strlen(url); + dst_name = gf_malloc(len+dir_len+1); + memset(dst_name, 0, len+dir_len+1); + + strncpy(dst_name, item_path, dir_len); + k=dir_len; + for (i=0; ifilep) return GF_BAD_PARAM; + gf_fseek(ioctx->filep, offset, whence); + return GF_OK; +} +static u32 fio_read(GF_FileIO *fileio, u8 *buffer, u32 bytes) +{ + FileIOCtx *ioctx = gf_fileio_get_udta(fileio); + if (!ioctx || !ioctx->filep) return 0; + return (u32) gf_fread(buffer, bytes, ioctx->filep); +} +static u32 fio_write(GF_FileIO *fileio, u8 *buffer, u32 bytes) +{ + FileIOCtx *ioctx = gf_fileio_get_udta(fileio); + if (!ioctx || !ioctx->filep) return 0; + if (!bytes) { + fflush(ioctx->filep); + return 0; + } + return (u32) gf_fwrite(buffer, bytes, ioctx->filep); +} +static s64 fio_tell(GF_FileIO *fileio) +{ + FileIOCtx *ioctx = gf_fileio_get_udta(fileio); + if (!ioctx || !ioctx->filep) return -1; + return gf_ftell(ioctx->filep); +} +static Bool fio_eof(GF_FileIO *fileio) +{ + FileIOCtx *ioctx = gf_fileio_get_udta(fileio); + if (!ioctx || !ioctx->filep) return GF_TRUE; + return feof(ioctx->filep); +} +static int fio_printf(GF_FileIO *fileio, const char *format, va_list args) +{ + FileIOCtx *ioctx = gf_fileio_get_udta(fileio); + if (!ioctx || !ioctx->filep) return -1; + return vfprintf(ioctx->filep, format, args); +} + +static GF_FileIO *fio_open(GF_FileIO *fileio_ref, const char *url, const char *mode, GF_Err *out_err) +{ + GF_FileIO *gfio; + FileIOCtx *ioctx; + u32 i, count; + u64 file_size; + Bool no_concatenate = GF_FALSE; + FileIOCtx *ioctx_ref = gf_fileio_get_udta(fileio_ref); + + *out_err = GF_OK; + + if (!strcmp(mode, "ref")) { + ioctx_ref->nb_refs++; + return fileio_ref; + } + if (!strcmp(mode, "unref")) { + if (!ioctx_ref->nb_refs) return NULL; + ioctx_ref->nb_refs--; + if (ioctx_ref->nb_refs) + return fileio_ref; + + url = NULL; + } + + if (!strcmp(mode, "url")) { + if (!url) return NULL; + GF_SAFEALLOC(ioctx, FileIOCtx); + if (!ioctx) return NULL; + ioctx->path = gf_url_concatenate(ioctx_ref->path, url); + gfio = gf_fileio_new(ioctx->path, ioctx, fio_open, fio_seek, fio_read, fio_write, fio_tell, fio_eof, fio_printf); + if (!gfio) { + if (ioctx->path) gf_free(ioctx->path); + gf_free(ioctx); + return NULL; + } + //remember it but no need to keep a ref on it + gf_list_add(all_gfio_defined, gfio); + return gfio; + } + if (!strcmp(mode, "probe")) { + if (!gf_file_exists(url)) *out_err = GF_URL_ERROR; + return NULL; + } + + if (!url) { + if (ioctx_ref->filep) gf_fclose(ioctx_ref->filep); + ioctx_ref->filep = NULL; + + if (!ioctx_ref->nb_refs) { + gf_list_del_item(all_gfio_defined, fileio_ref); + gf_fileio_del(fileio_ref); + if (ioctx_ref->path) gf_free(ioctx_ref->path); + gf_free(ioctx_ref); + } + return NULL; + } + + //file handle not opened, we can use the current gfio + if (!ioctx_ref->filep && (!strnicmp(url, "gfio://", 7) || !strcmp(url, ioctx_ref->path)) ) { + ioctx_ref->filep = gf_fopen(ioctx_ref->path, mode); + if (!ioctx_ref->filep) { + *out_err = GF_IO_ERR; + return NULL; + } + file_size = gf_fsize(ioctx_ref->filep); + //in test mode we want to use our ftell and fseek wrappers + if (strchr(mode, 'r')) { + gf_fileio_set_stats(fileio_ref, file_size, file_size, GF_TRUE, 0); + } + return fileio_ref; + } + + //file handle already open (file is being opened twice), create a new gfio or check if we have already created one + gfio = NULL; + ioctx = NULL; + count = gf_list_count(all_gfio_defined); + for (i=0; ipath, url)) { + if (ioctx->filep) { + no_concatenate = GF_TRUE; + ioctx = NULL; + } + gfio = a_gfio; + break; + } + ioctx = NULL; + } + if (!ioctx) { + GF_SAFEALLOC(ioctx, FileIOCtx); + if (!ioctx) { + *out_err = GF_OUT_OF_MEM; + return NULL; + } + if (strnicmp(url, "gfio://", 7)) { + if (no_concatenate) + ioctx->path = gf_strdup(url); + else + ioctx->path = gf_url_concatenate(ioctx_ref->path, url); + } else { + ioctx->path = gf_strdup(ioctx_ref->path); + } + gfio = gf_fileio_new(ioctx->path, ioctx, fio_open, fio_seek, fio_read, fio_write, fio_tell, fio_eof, fio_printf); + if (!gfio) { + if (ioctx->path) gf_free(ioctx->path); + gf_free(ioctx); + *out_err = GF_OUT_OF_MEM; + } + } + + if (strnicmp(url, "gfio://", 7)) { + ioctx->filep = gf_fopen(ioctx->path, mode); + } else { + ioctx->filep = gf_fopen(ioctx_ref->path, mode); + } + + if (!ioctx->filep) { + *out_err = GF_IO_ERR; + gf_list_del_item(all_gfio_defined, gfio); + gf_fileio_del(gfio); + if (ioctx->path) gf_free(ioctx->path); + gf_free(ioctx); + return NULL; + } + + file_size = gf_fsize(ioctx->filep); + if (strchr(mode, 'r')) + gf_fileio_set_stats(gfio, file_size,file_size, GF_TRUE, 0); + return gfio; +} + + +static const char *make_fileio(const char *inargs, const char **out_arg, Bool is_input, GF_Err *e) +{ + FileIOCtx *ioctx; + GF_FileIO *fio; + char *sep = (char *) gf_url_colon_suffix(inargs); + *out_arg = NULL; + if (sep) sep[0] = 0; + + GF_SAFEALLOC(ioctx, FileIOCtx); + if (!ioctx) return NULL; + ioctx->path = gf_strdup(inargs); + if (!ioctx->path) { + gf_free(ioctx); + return NULL; + } + if (sep) { + sep[0] = ':'; + *out_arg = sep+1; + } + fio = gf_fileio_new(ioctx->path, ioctx, fio_open, fio_seek, fio_read, fio_write, fio_tell, fio_eof, fio_printf); + if (!fio) { + gf_free(ioctx->path); + gf_free(ioctx); + *e = GF_OUT_OF_MEM; + return NULL; + } + if (!all_gfio_defined) { + all_gfio_defined = gf_list_new(); + if (!all_gfio_defined) return NULL; + } + gf_list_add(all_gfio_defined, fio); + //keep alive until end + ioctx->nb_refs = 1; + return gf_fileio_url(fio); +} + +static void cleanup_file_io() +{ + if (!all_gfio_defined) return; + while (gf_list_count(all_gfio_defined)) { + GF_FileIO *gfio = gf_list_pop_back(all_gfio_defined); + FileIOCtx *ioctx = gf_fileio_get_udta(gfio); + gf_fileio_del(gfio); + + if (ioctx->filep) { + fprintf(stderr, "Warning: file IO for %s still opened!\n", ioctx->path); + gf_fclose(ioctx->filep); + } + if (ioctx->path) gf_free(ioctx->path); + gf_free(ioctx); + } + gf_list_del(all_gfio_defined); + all_gfio_defined = NULL; +} + diff --git a/applications/mp42avi/Makefile b/applications/mp42avi/Makefile deleted file mode 100644 index ab7c02c..0000000 --- a/applications/mp42avi/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/applications/mp42avi - -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 - - -ifeq ($(CONFIG_WIN32),yes) -EXE=.exe -PROG=MP42Avi$(EXE) -else -EXT= -PROG=MP42Avi -endif - -SRCS := $(OBJS:.o=.c) - -all: $(PROG) - -$(PROG): $(OBJS) - $(CC) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/$(TARGET_BIN_DIR) -lgpac -lz $(LDFLAGS) - -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 .depend diff --git a/applications/mp42avi/main.c b/applications/mp42avi/main.c deleted file mode 100644 index 619ff34..0000000 --- a/applications/mp42avi/main.c +++ /dev/null @@ -1,785 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2012 - * All rights reserved - * - * This file is part of GPAC / command-line mp4 toolbox - * - * 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 -#include - -#ifdef WIN32 -#include -#define GPAC_CFG_FILE "GPAC.cfg" -#else -#include -typedef struct tagBITMAPFILEHEADER -{ - u16 bfType; - u32 bfSize; - u16 bfReserved1; - u16 bfReserved2; - u32 bfOffBits; -} BITMAPFILEHEADER; - -typedef struct tagBITMAPINFOHEADER { - u32 biSize; - s32 biWidth; - s32 biHeight; - u16 biPlanes; - u16 biBitCount; - u32 biCompression; - u32 biSizeImage; - s32 biXPelsPerMeter; - s32 biYPelsPerMeter; - u32 biClrUsed; - u32 biClrImportant; -} BITMAPINFOHEADER; - -#define BI_RGB 0L - -#define GPAC_CFG_FILE ".gpacrc" -#endif - -#include -#include - -void PrintVersion() -{ - printf ("MP42AVI - GPAC version %s\n", GPAC_FULL_VERSION); -} - -void PrintUsage() -{ - printf ("MP42AVI [option] input\n" - "Dumps BIFS media frames as AVI, BMP or raw\n\n" - "Options\n" - "-fps Framerate: specifies extraction framerate - if not set computed from track length\n" - "-size WxH: forces output BIFS to the given resolution\n" - "-raw [frame]: uses raw format for output - only dumps one frame if specified\n" - "-bmp [frame]: uses BMP format for output - only dumps one frame if specified\n" - "-outpath path: specifies where to dump frames/movie\n" - "\n" - "Note: when dumping a frame, either the frame number can be specified or the frame time\n" - "in the format hh:mm:ss:xFz where hh, mm, ss are hours, minutes, seconds, x the number\n" - "of the frame in the seconds and z the frame rate used to express the time\n" - "\n" - "-cfg: specifies path to GPAC config file (GPAC.cfg)\n" - "-v: prints version\n" - "-h: prints this message\n" - "\nWritten by Jean Le Feuvre - (c) 2000-2005\n"); -} - - -typedef struct -{ - GF_Compositor *sr; - GF_SceneGraph *sg; - GF_BifsDecoder *bifs; - GF_ISOFile *file; - - u32 track; - u64 duration, cts; -} BIFSVID; - -void node_init(void *cbk, GF_Node *node) -{ - BIFSVID *b2v = cbk; - switch (gf_node_get_tag(node)) { - case TAG_MPEG4_Conditional: - case TAG_MPEG4_QuantizationParameter: - break; - default: - if (b2v->sr) gf_sc_on_node_init(b2v->sr, node); - break; - } -} - -void node_modif(void *cbk, GF_Node *node) -{ - BIFSVID *b2v = cbk; - if (b2v->sr) gf_sc_invalidate(b2v->sr, node); -} - -Double get_scene_time(void *cbk) -{ - Double res; - BIFSVID *b2v = cbk; - res = (Double) (s64) b2v->cts; - res /= (Double) (s64) b2v->duration; - return res; -} - -void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - char str[GF_MAX_PATH]; - BITMAPFILEHEADER fh; - BITMAPINFOHEADER fi; - FILE *fout; - u32 j, i; - char *ptr; - - if (img_num<10) { - sprintf(str, "%s_00%d.bmp", rad_name, img_num); - } else if (img_num<100) { - sprintf(str, "%s_0%d.bmp", rad_name, img_num); - } else { - sprintf(str, "%s_%d.bmp", rad_name, img_num); - } - - fout = gf_fopen(str, "wb"); - if (!fout) return; - - memset(&fh, 0, sizeof(fh)); - fh.bfType = 19778; - fh.bfOffBits = 14 + 40; - - memset(&fi, 0, sizeof(char)*40); - fi.biSize = sizeof(char)*40; - fi.biWidth = fb->width; - fi.biHeight = fb->height; - fi.biPlanes = 1; - fi.biBitCount = 24; - fi.biCompression = BI_RGB; - fi.biSizeImage = fb->pitch * fb->height; - - /*NOT ALIGNED!!*/ - gf_fwrite(&fh.bfType, 2, 1, fout); - gf_fwrite(&fh.bfSize, 4, 1, fout); - gf_fwrite(&fh.bfReserved1, 2, 1, fout); - gf_fwrite(&fh.bfReserved2, 2, 1, fout); - gf_fwrite(&fh.bfOffBits, 4, 1, fout); - - gf_fwrite(&fi, 1, 40, fout); - - for (j=fb->height; j>0; j--) { - ptr = fb->video_buffer + (j-1)*fb->pitch; - //gf_fwrite(ptr, 1, fb->width * 3, fout); - for (i=0; iwidth; i++) { - fputc(ptr[2], fout); - fputc(ptr[1], fout); - fputc(ptr[0], fout); - ptr+=3; - } - } - - gf_fclose(fout); -} - - -void write_raw(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - char str[GF_MAX_PATH]; - FILE *fout; - if (img_num<10) { - sprintf(str, "%s_00%d.raw", rad_name, img_num); - } else if (img_num<100) { - sprintf(str, "%s_0%d.raw", rad_name, img_num); - } else { - sprintf(str, "%s_%d.raw", rad_name, img_num); - } - - fout = gf_fopen(str, "wb"); - if (!fout) return; - gf_fwrite(fb->video_buffer , fb->height*fb->pitch, 1, fout); - gf_fclose(fout); -} - -void dump_frame(BIFSVID b2v, char *conv_buf, char *out_path, u32 dump_type, avi_t *avi_out, u32 frameNum) -{ - u32 k; - GF_VideoSurface fb; - - /*lock it*/ - gf_sc_get_screen_buffer(b2v.sr, &fb); - /*export frame*/ - switch (dump_type) { - case 0: - /*reverse frame*/ - for (k=0; kdependsOnESID && (esd->decoderConfig->streamType == GF_STREAM_SCENE)) break; - gf_odf_desc_del((GF_Descriptor *) esd); - esd = NULL; - } - if (!esd) { - printf("no bifs track found\n"); - goto err_exit; - } - - es_id = (u16) gf_isom_get_track_id(file, track_number+1); - e = gf_bifs_decoder_configure_stream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication); - if (e) { - printf("BIFS init error %s\n", gf_error_to_string(e)); - gf_odf_desc_del((GF_Descriptor *) esd); - esd = NULL; - goto err_exit; - } - - { - GF_ISOSample *samp = gf_isom_get_sample(file, track_number+1, 1, &di); - b2v.cts = samp->DTS + samp->CTS_Offset; - /*apply command*/ - gf_bifs_decode_au(b2v.bifs, es_id, samp->data, samp->dataLength, ((Double)(s64)b2v.cts)/1000.0); - gf_isom_sample_del(&samp); - } - - b2v.duration = gf_isom_get_media_duration(file, track_number+1); - - gf_odf_desc_del((GF_Descriptor *) esd); - - } - gf_sc_set_scene(b2v.sr, b2v.sg); - - if (!width || !height) { - gf_sg_get_scene_size_info(b2v.sg, &width, &height); - } - /*we work in RGB24, and we must make sure the pitch is %4*/ - if ((width*3)%4) { - printf("Adjusting width (%d) to have a stride multiple of 4\n", width); - while ((width*3)%4) width--; - } - gf_sc_set_size(b2v.sr, width, height); - gf_sc_get_screen_buffer(b2v.sr, &fb); - width = fb.width; - height = fb.height; - gf_sc_release_screen_buffer(b2v.sr, &fb); - - GF_SAFEALLOC(rendered_frames, nb_viewpoints*sizeof(char *)); - for (viewpoint_index = 1; viewpoint_index <= nb_viewpoints; viewpoint_index++) { - GF_SAFEALLOC(rendered_frames[viewpoint_index-1], fb.width*fb.height*3); - gf_sc_set_viewpoint(b2v.sr, viewpoint_index, NULL); - gf_sc_draw_frame(b2v.sr, 0, NULL); - /*needed for background2D !!*/ - gf_sc_draw_frame(b2v.sr, 0, NULL); - strcpy(out_path, ""); - if (out_dir) { - strcat(out_path, out_dir); - if (out_path[strlen(out_path)-1] != '\\') strcat(out_path, "\\"); - } - strcat(out_path, rad_name); - strcat(out_path, "_view"); - gf_sc_get_screen_buffer(b2v.sr, &fb); - write_bmp(&fb, out_path, viewpoint_index); - memcpy(rendered_frames[viewpoint_index-1], fb.video_buffer, fb.width*fb.height*3); - gf_sc_release_screen_buffer(b2v.sr, &fb); - } - - if (width != 800 || height != 480) { - printf("Wrong scene dimension, cannot produce output\n"); - goto err_exit; - } else { - u32 x, y; - GF_VideoSurface out_fb; - u32 bpp = 3; - out_fb.width = 800; - out_fb.height = 480; - out_fb.pitch = 800*bpp; - out_fb.pixel_format = GF_PIXEL_RGB_24; - out_fb.is_hardware_memory = 0; - GF_SAFEALLOC(out_fb.video_buffer, out_fb.pitch*out_fb.height) -#if 1 - for (y=0; ydependsOnESID && (esd->decoderConfig->streamType == GF_STREAM_SCENE)) break; - gf_odf_desc_del((GF_Descriptor *) esd); - esd = NULL; - } - if (!esd) { - printf("no bifs track found\n"); - goto err_exit; - } - - b2v.duration = gf_isom_get_media_duration(file, i+1); - timescale = gf_isom_get_media_timescale(file, i+1); - es_id = (u16) gf_isom_get_track_id(file, i+1); - e = gf_bifs_decoder_configure_stream(b2v.bifs, es_id, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, esd->decoderConfig->objectTypeIndication); - if (e) { - printf("BIFS init error %s\n", gf_error_to_string(e)); - gf_odf_desc_del((GF_Descriptor *) esd); - esd = NULL; - goto err_exit; - } - if (dump_time>=0) dump_time = dump_time *1000 / timescale; - - gf_sc_set_scene(b2v.sr, b2v.sg); - count = gf_isom_get_sample_count(file, i+1); - - reset_fps = 0; - if (!fps) { - fps = (Float) (count * timescale); - fps /= (Double) (s64) b2v.duration; - printf("Estimated BIFS FrameRate %g\n", fps); - reset_fps = 1; - } - - if (!width || !height) { - gf_sg_get_scene_size_info(b2v.sg, &width, &height); - } - /*we work in RGB24, and we must make sure the pitch is %4*/ - if ((width*3)%4) { - printf("Adjusting width (%d) to have a stride multiple of 4\n", width); - while ((width*3)%4) width--; - } - - gf_sc_set_size(b2v.sr, width, height); - gf_sc_draw_frame(b2v.sr, 0, NULL); - - gf_sc_get_screen_buffer(b2v.sr, &fb); - width = fb.width; - height = fb.height; - if (avi_out) { - AVI_set_video(avi_out, width, height, fps, comp); - 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); - - cur_time = 0; - - duration = (u32)(timescale / fps); - if (reset_fps) fps = 0; - - frameNum = 1; - first_dump = 1; - for (j=0; jDTS + samp->CTS_Offset; - /*apply command*/ - gf_bifs_decode_au(b2v.bifs, es_id, samp->data, samp->dataLength, ((Double)(s64)b2v.cts)/1000.0); - gf_isom_sample_del(&samp); - - if ((frameID>=0) && (j<(u32)frameID)) continue; - if ((dump_time>=0) && ((u32) dump_time>b2v.cts)) continue; - /*render frame*/ - gf_sc_draw_frame(b2v.sr, 0, NULL); - /*needed for background2D !!*/ - if (first_dump) { - gf_sc_draw_frame(b2v.sr, 0, NULL); - first_dump = 0; - } - - if (fps) { - if (cur_time > b2v.cts) continue; - - while (1) { - printf("dumped frame time %f (frame %d - sample %d)\r", ((Float)cur_time)/timescale, frameNum, j+1); - dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, frameNum); - frameNum++; - cur_time += duration; - if (cur_time > b2v.cts) break; - } - } else { - dump_frame(b2v, conv_buf, config_path, dump_type, avi_out, (frameID>=0) ? frameID : frameNum); - if (frameID>=0 || dump_time>=0) break; - frameNum++; - printf("dumped frame %d / %d\r", j+1, count); - } - - } - gf_odf_desc_del((GF_Descriptor *) esd); - - /*destroy everything*/ - gf_bifs_decoder_del(b2v.bifs); - gf_sg_del(b2v.sg); - gf_sc_set_scene(b2v.sr, NULL); - gf_sc_del(b2v.sr); - -err_exit: - if (avi_out) AVI_close(avi_out); - 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); -} - -int main (int argc, char **argv) -{ - Double fps_dump; - u32 i; - char rad[500]; - s32 frameID, h, m, s, f; - Float fps; - u32 dump_type; - s32 dump_time; - u32 dump_w, dump_h; - Bool copy; - char szConfigFile[4096]; - char *dump_out; - char *inName, *arg; - GF_ISOFile *file; - - if (argc < 2) { - PrintUsage(); - return 0; - } - - dump_type = 0; - fps_dump = 0.0f; - dump_w = dump_h = 0; - dump_out = NULL; - inName = NULL; - frameID = -1; - dump_time = -1; - szConfigFile[0] = 0; - - for (i = 1; i < (u32) argc ; i++) { - arg = argv[i]; - if (arg[0] != '-') { - inName = arg; - break; - } - if (!stricmp(arg, "-h")) { - PrintUsage(); - return 0; - } else if (!stricmp(arg, "-version")) { - PrintVersion(); - return 0; - } else if (!stricmp(arg, "-size")) { - sscanf(argv[i+1], "%dx%d", &dump_w, &dump_h); - i++; - } else if (!stricmp(arg, "-raw")) { - dump_type = 2; - if ((i+1<(u32)argc) && (argv[i+1][0]!='-')) { - if (strstr(argv[i+1], "T")) { - if (strstr(argv[i+1], "F")) { - sscanf(argv[i+1], "T%d:%d:%d:%dF%f", &h, &m, &s, &f, &fps); - dump_time = (s32) ((3600*h + 60*m + s)*1000 + 1000*f/fps); - } else { - sscanf(argv[i+1], "T%d:%d:%d", &h, &m, &s); - dump_time = (s32) ((3600*h + 60*m + s)*1000); - } - } else { - frameID = atoi(argv[i+1]); - } - i++; - } - } else if (!stricmp(arg, "-bmp")) { - dump_type = 1; - if ((i+1<(u32)argc) && (argv[i+1][0]!='-')) { - if (strstr(argv[i+1], "T")) { - if (strstr(argv[i+1], "F")) { - sscanf(argv[i+1], "T%d:%d:%d:%dF%f", &h, &m, &s, &f, &fps); - dump_time = (s32) ((3600*h + 60*m + s)*1000 + 1000*f/fps); - } else { - sscanf(argv[i+1], "T%d:%d:%d", &h, &m, &s); - dump_time = (s32) ((3600*h + 60*m + s)*1000); - } - } else { - frameID = atoi(argv[i+1]); - } - i++; - } - } else if (!stricmp(arg, "-3d")) { - dump_type = 3; - } else if (!stricmp(arg, "-outpath")) { - dump_out = argv[i+1]; - i++; - } else if (!stricmp(arg, "-fps")) { - fps_dump = atof(argv[i+1]); - i++; - } else if (!stricmp(arg, "-copy")) { - copy = 1; - } else if (!stricmp(arg, "-cfg")) { - strcpy(szConfigFile, argv[i+1]); - i += 1; - } else { - PrintUsage(); - return (0); - } - } - if (!inName) { - PrintUsage(); - return 0; - } - gf_sys_init(GF_MemTrackerNone); - - file = gf_isom_open(inName, GF_ISOM_OPEN_READ, NULL); - if (!file) { - printf("Error opening file: %s\n", gf_error_to_string(gf_isom_last_error(NULL))); - return 0; - } - - if (dump_out) { - arg = strrchr(inName, GF_PATH_SEPARATOR); - if (arg) { - strcpy(rad, arg + 1); - } else { - strcpy(rad, inName); - } - } else { - strcpy(rad, inName); - } - while (rad[strlen(rad)-1] != '.') rad[strlen(rad)-1] = 0; - rad[strlen(rad)-1] = 0; - if (dump_type == 3) { - bifs3d_viewpoints_merger(file, szConfigFile, dump_w, dump_h, rad, dump_type, dump_out, fps_dump, frameID, dump_time); - } - else bifs_to_vid(file, szConfigFile, dump_w, dump_h, rad, dump_type, dump_out, fps_dump, frameID, dump_time); - printf("\ndone\n"); - gf_isom_delete(file); - return 0; - -} - diff --git a/applications/mp42ts/Makefile b/applications/mp42ts/Makefile deleted file mode 100644 index 4565894..0000000 --- a/applications/mp42ts/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/applications/mp42ts - -CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -LINKFLAGS=-L../../bin/gcc -ifeq ($(CONFIG_WIN32),yes) -EXE=.exe -PROG=MP42TS$(EXE) -else -EXT= -PROG=MP42TS -endif - -ifeq ($(STATICBUILD),yes) -##include static modules and other deps for libgpac -include ../../static.mak - -#FIXME we have to disable AAC+bifs support in mp42ts since it reuses things from aac_in already in libgpac ... -ifeq ($(STATIC_MODULES), yes) -CFLAGS+=-DGPAC_DISABLE_PLAYER -endif - -LINKFLAGS+=-lgpac_static -LINKFLAGS+= $(GPAC_SH_FLAGS) -LINKFLAGS+=$(EXTRALIBS) -else -LINKFLAGS+=-lgpac -endif - -#common objs - insert after ../static if any to overwrite list of objects -OBJS= main.o - -SRCS := $(OBJS:.o=.c) - -all: $(PROG) - -$(PROG): $(OBJS) - $(CC) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) $(LDFLAGS) - -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 .depend diff --git a/applications/mp42ts/main.c b/applications/mp42ts/main.c deleted file mode 100644 index 90664d7..0000000 --- a/applications/mp42ts/main.c +++ /dev/null @@ -1,2884 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre, Cyril Concolato, Romain Bouqueau - * Copyright (c) Telecom ParisTech 2005-2012 - * All rights reserved - * - * This file is part of GPAC / mp4-to-ts (mp42ts) application - * - * 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 - -#ifndef GPAC_DISABLE_STREAMING -#include -#endif - -#ifndef GPAC_DISABLE_SENG -#include -#endif - -#ifndef GPAC_DISABLE_TTXT -#include -#endif - - -#ifdef GPAC_DISABLE_MPEG2TS_MUX -#error "Cannot compile MP42TS if GPAC is not built with MPEG2-TS Muxing support" -#endif - -#define MP42TS_PRINT_TIME_MS 500 /*refresh printed info every CLOCK_REFRESH ms*/ -#define MP42TS_VIDEO_FREQ 1000 /*meant to send AVC IDR only every CLOCK_REFRESH ms*/ - - -s32 temi_id_1 = -1; -s32 temi_id_2 = -1; - -u32 temi_url_insertion_delay = 1000; -u32 temi_offset = 0; -Bool temi_disable_loop = GF_FALSE; -FILE *logfile = NULL; - -static void on_gpac_log(void *cbk, GF_LOG_Level ll, GF_LOG_Tool lm, const char *fmt, va_list list) -{ - FILE *logs = (FILE*)cbk; - vfprintf(logs, fmt, list); - fflush(logs); -} - -static GFINLINE void usage() -{ - fprintf(stderr, "GPAC version " GPAC_FULL_VERSION "\n" - "GPAC Copyright (c) Telecom ParisTech 2000-2014\n" - "GPAC Configuration: " GPAC_CONFIGURATION "\n" - "Features: %s\n\n", gpac_features()); - fprintf(stderr, "mp42ts [options]\n" - "\n" - "Inputs:\n" - "-src filename[:OPTS] specifies an input file used for a TS service\n" - " * currently only supports ISO files and SDP files\n" - " * can be used several times, once for each program\n" - "By default each source is a program in a TS. \n" - "Source options are colon-separated list of options, as follows:\n" - "ID=N specifies the program ID for this source.\n" - " All sources with the same ID will be added to the same program\n" - "name=STR program name, as used in DVB service description table\n" - "provider=STR provider name, as used in DVB service description table\n" - - "\n" - "-prog filename same as -src filename\n" - "\n" - "Destinations:\n" - "Several destinations may be specified as follows, at least one is mandatory\n" - "-dst-udp UDP_address:port (multicast or unicast)\n" - "-dst-rtp RTP_address:port\n" - "-dst-file filename\n" - "The following parameters may be specified when -dst-file is used\n" - "-segment-dir dir server local directory to store segments (ends with a '/')\n" - "-segment-duration dur segment duration in seconds\n" - "-segment-manifest file m3u8 file basename\n" - "-segment-http-prefix p client address for accessing server segments\n" - "-segment-number n number of segments to list in the manifest\n" - "\n" - "Basic options:\n" - "-rate R specifies target rate in kbps of the multiplex (optional)\n" - "-real-time specifies the muxer will work in real-time mode\n" - " * if not specified, the muxer will generate the TS as quickly as possible\n" - " * automatically set for SDP or BT input\n" - "-pcr-init V sets initial value V for PCR - if not set, random value is used\n" - "-pcr-offset V offsets all timestamps from PCR by V, in 90kHz. Default value is computed based on input media.\n" - "-psi-rate V sets PSI refresh rate V in ms (default 100ms).\n" - " * If 0, PSI data is only send once at the beginning or before each IDR when -rap option is set.\n" - " * This should be set to 0 for DASH streams.\n" - "-time n request the muxer to stop after n ms\n" - "-single-au forces 1 PES = 1 AU (disabled by default)\n" - "-multi-au forces 1 PES = N AU for all streams (disabled by default).\n" - " By default, audio streams pack N AUs in one PES but video and systems data use 1 AU per PES.\n" - "-rap forces RAP/IDR to be aligned with PES start for video streams (disabled by default)\n" - " in this mode, PAT, PMT and PCR will be inserted before the first TS packet of the RAP PES\n" - "-flush-rap same as -rap but flushes all other streams (sends remaining PES packets) before inserting PAT/PMT\n" - "-nb-pack N specifies to pack up to N TS packets together before sending on network or writing to file\n" - "-pcr-ms N sets max interval in ms between 2 PCR. Default is 100 ms or at each PES header\n" - "-force-pcr-only allows sending PCR-only packets to enforce the requested PCR rate - STILL EXPERIMENTAL.\n" - "-ttl N specifies Time-To-Live for multicast. Default is 1.\n" - "-ifce IPIFCE specifies default IP interface to use. Default is IF_ANY.\n" - "-temi [URL] Inserts TEMI time codes in adaptation field. URL is optional, and can be a number for external timeline IDs\n" - "-temi-delay DelayMS Specifies delay between two TEMI url descriptors (default is 1000)\n" - "-temi-offset OffsetMS Specifies an offset in ms to add to TEMI (by default TEMI starts at 0)\n" - "-temi-noloop Do not restart the TEMI timeline at the end of the source\n" - "-temi2 ID Inserts a secondary TEMI time codes in adaptation field of the audio PID if any. ID shall be set to the desired external timeline IDs\n" - "-insert-ntp Inserts NTP timestamp in TEMI timeline descriptor\n" - "-sdt-rate MS Gives the SDT carrousel rate in milliseconds. If 0 (default), SDT is not sent\n" - "\n" - "MPEG-4/T-DMB options:\n" - "-bifs-src filename update file: must be either an .sdp or a .bt file\n" - "-audio url may be mp3/udp or aac/http (shoutcast/icecast)\n" - "-video url shall be a raw h264 frame\n" - "-mpeg4-carousel n carousel period in ms\n" - "-mpeg4 or -4on2 forces usage of MPEG-4 signaling (IOD and SL Config)\n" - "-4over2 same as -4on2 and uses PMT to carry OD Updates\n" - "-bifs-pes carries BIFS over PES instead of sections\n" - "-bifs-pes-ex carries BIFS over PES without writing timestamps in SL\n" - "\n" - "Misc options\n" -#ifdef GPAC_MEMORY_TRACKING - "-mem-track enables memory tracker\n" - "-mem-track-stack enables memory tracker stack dumping\n" -#endif - "-logs set log tools and levels, formatted as a ':'-separated list of toolX[:toolZ]@levelX\n" - "-h or -help print this screen\n" - "\n" - ); -} - - -#define MAX_MUX_SRC_PROG 100 -typedef struct -{ - -#ifndef GPAC_DISABLE_ISOM - GF_ISOFile *mp4; -#endif - - u32 nb_streams, pcr_idx; - GF_ESInterface streams[40]; - GF_Descriptor *iod; -#ifndef GPAC_DISABLE_SENG - GF_SceneEngine *seng; -#endif - GF_Thread *th; - char *bifs_src_name; - u32 rate; - Bool repeat; - u32 mpeg4_signaling; - Bool audio_configured; - u64 samples_done, samples_count; - u32 nb_real_streams; - Bool real_time; - GF_List *od_updates; - - u32 max_sample_size; - - char program_name[20]; - char provider_name[20]; - u32 ID; - Bool is_not_program_declaration; - - Double last_ntp; -} M2TSSource; - -#ifndef GPAC_DISABLE_ISOM -typedef struct -{ - GF_ISOFile *mp4; - u32 track, sample_number, sample_count; - u32 mstype, mtype; - GF_ISOSample *sample; - /*refresh rate for images*/ - u32 image_repeat_ms, nb_repeat_last; - void *dsi; - u32 dsi_size; - - void *dsi_and_rap; - Bool loop; - Bool is_repeat; - s64 ts_offset, cts_dts_shift; - M2TSSource *source; - - const char *temi_url; - u32 last_temi_url, timeline_id; - Bool insert_ntp; - -} GF_ESIMP4; -#endif - -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; - -typedef struct -{ - u32 size; - char *data; -} GF_SimpleDataDescriptor; - -//TODO: find a clean way to save this data -#ifndef GPAC_DISABLE_PLAYER -static u32 audio_OD_stream_id = (u32)-1; -#endif - -#define AUDIO_OD_ESID 100 -#define AUDIO_DATA_ESID 101 -#define VIDEO_DATA_ESID 105 - -/*output types*/ -enum -{ - GF_MP42TS_FILE, /*open mpeg2ts file*/ - GF_MP42TS_UDP, /*open udp socket*/ - GF_MP42TS_RTP, /*open rtp socket*/ -#ifndef GPAC_DISABLE_PLAYER - GF_MP42TS_HTTP, /*open http downloader*/ -#endif -}; - -static u32 format_af_descriptor(char *af_data, u32 timeline_id, u64 timecode, u32 timescale, u64 ntp, const char *temi_url, u32 *last_url_time) -{ - u32 res; - u32 len; - u32 last_time; - GF_BitStream *bs = gf_bs_new(af_data, 188, GF_BITSTREAM_WRITE); - - if (ntp) { - last_time = 1000*(ntp>>32); - last_time += 1000*(ntp&0xFFFFFFFF)/0xFFFFFFFF; - } else { - last_time = (u32) (1000*timecode/timescale); - } - if (temi_url && (!*last_url_time || (last_time - *last_url_time + 1 >= temi_url_insertion_delay)) ) { - *last_url_time = last_time + 1; - len = 0; - gf_bs_write_int(bs, GF_M2TS_AFDESC_LOCATION_DESCRIPTOR, 8); - gf_bs_write_int(bs, len, 8); - - gf_bs_write_int(bs, 0, 1); //force_reload - gf_bs_write_int(bs, 0, 1); //is_announcement - gf_bs_write_int(bs, 0, 1); //splicing_flag - gf_bs_write_int(bs, 0, 1); //use_base_temi_url - gf_bs_write_int(bs, 0xFF, 5); //reserved - gf_bs_write_int(bs, timeline_id, 7); //timeline_id - - if (strlen(temi_url)) { - char *url = (char *)temi_url; - if (!strnicmp(temi_url, "http://", 7)) { - gf_bs_write_int(bs, 1, 8); //url_scheme - url = (char *) temi_url + 7; - } else if (!strnicmp(temi_url, "https://", 8)) { - gf_bs_write_int(bs, 2, 8); //url_scheme - url = (char *) temi_url + 8; - } else { - gf_bs_write_int(bs, 0, 8); //url_scheme - } - gf_bs_write_u8(bs, (u32) strlen(url)); //url_path_len - gf_bs_write_data(bs, url, (u32) strlen(url) ); //url - gf_bs_write_u8(bs, 0); //nb_addons - } - //rewrite len - len = (u32) gf_bs_get_position(bs) - 2; - af_data[1] = len; - } - - if (timescale || ntp) { - Bool use64 = (timecode > 0xFFFFFFFFUL) ? GF_TRUE : GF_FALSE; - len = 3; //3 bytes flags - - if (timescale) len += 4 + (use64 ? 8 : 4); - if (ntp) len += 8; - - //write timeline descriptor - gf_bs_write_int(bs, GF_M2TS_AFDESC_TIMELINE_DESCRIPTOR, 8); - gf_bs_write_int(bs, len, 8); - - gf_bs_write_int(bs, timescale ? (use64 ? 2 : 1) : 0, 2); //has_timestamp - gf_bs_write_int(bs, ntp ? 1 : 0, 1); //has_ntp - gf_bs_write_int(bs, 0, 1); //has_ptp - gf_bs_write_int(bs, 0, 2); //has_timecode - gf_bs_write_int(bs, 0, 1); //force_reload - gf_bs_write_int(bs, 0, 1); //paused - gf_bs_write_int(bs, 0, 1); //discontinuity - gf_bs_write_int(bs, 0xFF, 7); //reserved - gf_bs_write_int(bs, timeline_id, 8); //timeline_id - if (timescale) { - gf_bs_write_u32(bs, timescale); //timescale - if (use64) - gf_bs_write_u64(bs, timecode); //timestamp - else - gf_bs_write_u32(bs, (u32) timecode); //timestamp - } - if (ntp) { - gf_bs_write_u64(bs, ntp); //ntp - } - } - res = (u32) gf_bs_get_position(bs); - gf_bs_del(bs); - return res; -} - -#ifndef GPAC_DISABLE_ISOM - -static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) -{ - char af_data[188]; - GF_ESIMP4 *priv = (GF_ESIMP4 *)ifce->input_udta; - if (!priv) return GF_BAD_PARAM; - - switch (act_type) { - case GF_ESI_INPUT_DATA_FLUSH: - { - GF_ESIPacket pck; -#ifndef GPAC_DISABLE_TTXT - GF_List *cues = NULL; -#endif - 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; - } - - memset(&pck, 0, sizeof(GF_ESIPacket)); - - 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->is_repeat) pck.flags |= GF_ESI_DATA_REPEAT; - - if (priv->timeline_id) { - u64 ntp=0; - u64 tc = priv->sample->DTS + priv->sample->CTS_Offset + priv->cts_dts_shift; - if (temi_disable_loop) { - tc += priv->ts_offset; - } - - if (temi_offset) { - tc += ((u64) temi_offset) * ifce->timescale / 1000; - } - - if (priv->insert_ntp) { - u32 sec, frac; - gf_net_get_ntp(&sec, &frac); - ntp = sec; - ntp <<= 32; - ntp |= frac; - } - pck.mpeg2_af_descriptors_size = format_af_descriptor(af_data, priv->timeline_id - 1, tc, ifce->timescale, ntp, priv->temi_url, &priv->last_temi_url); - pck.mpeg2_af_descriptors = af_data; - } - - if (priv->nb_repeat_last) { - pck.cts += priv->nb_repeat_last*ifce->timescale * priv->image_repeat_ms / 1000; - } - - pck.dts = pck.cts; - if (priv->cts_dts_shift) { - pck.cts += + priv->cts_dts_shift; - pck.flags |= GF_ESI_DATA_HAS_DTS; - } - - if (priv->sample->CTS_Offset) { - pck.cts += priv->sample->CTS_Offset; - pck.flags |= GF_ESI_DATA_HAS_DTS; - } - - if (priv->sample->IsRAP && priv->dsi && priv->dsi_size) { - pck.data = (char*)priv->dsi; - pck.data_len = priv->dsi_size; - ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); - pck.flags &= ~GF_ESI_DATA_AU_START; - } - - pck.flags |= GF_ESI_DATA_AU_END; - pck.data = priv->sample->data; - pck.data_len = priv->sample->dataLength; - pck.duration = gf_isom_get_sample_duration(priv->mp4, priv->track, priv->sample_number+1); -#ifndef GPAC_DISABLE_TTXT - if (priv->mtype==GF_ISOM_MEDIA_TEXT && priv->mstype==GF_ISOM_SUBTYPE_WVTT) { - u64 start; - GF_WebVTTCue *cue; - GF_List *gf_webvtt_parse_iso_cues(GF_ISOSample *iso_sample, u64 start); - start = (priv->sample->DTS * 1000) / ifce->timescale; - cues = gf_webvtt_parse_iso_cues(priv->sample, start); - if (gf_list_count(cues)>1) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] More than one cue in sample\n")); - } - cue = (GF_WebVTTCue *)gf_list_get(cues, 0); - if (cue) { - pck.data = cue->text; - pck.data_len = (u32)strlen(cue->text)+1; - } else { - pck.data = NULL; - pck.data_len = 0; - } - } -#endif - ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] Track %d: sample %d CTS %d\n", priv->track, priv->sample_number+1, pck.cts)); - -#ifndef GPAC_DISABLE_VTT - if (cues) { - while (gf_list_count(cues)) { - GF_WebVTTCue *cue = (GF_WebVTTCue *)gf_list_get(cues, 0); - gf_list_rem(cues, 0); - gf_webvtt_cue_del(cue); - } - gf_list_del(cues); - cues = NULL; - } -#endif - gf_isom_sample_del(&priv->sample); - priv->sample_number++; - - if (!priv->source->real_time && !priv->is_repeat) { - priv->source->samples_done++; - gf_set_progress("Converting to MPEG-2 TS", priv->source->samples_done, priv->source->samples_count); - } - - 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; - priv->is_repeat = (priv->sample_count==1) ? GF_TRUE : GF_FALSE; - } - else if (priv->image_repeat_ms && priv->source->nb_real_streams) { - priv->nb_repeat_last++; - priv->sample_number--; - priv->is_repeat = GF_TRUE; - } else { - if (!(ifce->caps & GF_ESI_STREAM_IS_OVER)) { - ifce->caps |= GF_ESI_STREAM_IS_OVER; - if (priv->sample_count>1) { - assert(priv->source->nb_real_streams); - priv->source->nb_real_streams--; - } - } - } - } - } - return GF_OK; - - case GF_ESI_INPUT_DESTROY: - 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: - return GF_BAD_PARAM; - } -} - -static void fill_isom_es_ifce(M2TSSource *source, GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_num, u32 bifs_use_pes, Bool compute_max_size) -{ - GF_ESIMP4 *priv; - char *_lan; - GF_ESD *esd; - Bool is_hevc=GF_FALSE; - u64 avg_rate, duration; - s32 ref_count; - s64 mediaOffset; - - GF_SAFEALLOC(priv, GF_ESIMP4); - if (!priv) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate MP4 input handler\n")); - return; - } - - priv->mp4 = mp4; - priv->track = track_num; - priv->mtype = gf_isom_get_media_type(priv->mp4, priv->track); - priv->mstype = gf_isom_get_media_subtype(priv->mp4, priv->track, 1); - priv->loop = source->real_time ? GF_TRUE : GF_FALSE; - priv->sample_count = gf_isom_get_sample_count(mp4, track_num); - source->samples_count += priv->sample_count; - if (priv->sample_count>1) - source->nb_real_streams++; - - priv->source = source; - memset(ifce, 0, sizeof(GF_ESInterface)); - ifce->stream_id = gf_isom_get_track_id(mp4, track_num); - - esd = gf_media_map_esd(mp4, track_num); - - if (esd) { - ifce->stream_type = esd->decoderConfig->streamType; - ifce->object_type_indication = esd->decoderConfig->objectTypeIndication; - if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->dataLength) { - switch (esd->decoderConfig->objectTypeIndication) { - case GPAC_OTI_AUDIO_AAC_MPEG4: - case GPAC_OTI_AUDIO_AAC_MPEG2_MP: - case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: - case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: - case GPAC_OTI_VIDEO_MPEG4_PART2: - ifce->decoder_config = (char *)gf_malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); - ifce->decoder_config_size = esd->decoderConfig->decoderSpecificInfo->dataLength; - memcpy(ifce->decoder_config, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); - if (esd->decoderConfig->objectTypeIndication == GPAC_OTI_VIDEO_MPEG4_PART2) { - priv->dsi = (char *)gf_malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); - priv->dsi_size = esd->decoderConfig->decoderSpecificInfo->dataLength; - memcpy(priv->dsi, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); - } - break; - case GPAC_OTI_VIDEO_HEVC: - case GPAC_OTI_VIDEO_LHVC: - is_hevc=GF_TRUE; - case GPAC_OTI_VIDEO_AVC: - case GPAC_OTI_VIDEO_SVC: - case GPAC_OTI_VIDEO_MVC: - gf_isom_set_nalu_extract_mode(mp4, track_num, GF_ISOM_NALU_EXTRACT_LAYER_ONLY | GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG | GF_ISOM_NALU_EXTRACT_ANNEXB_FLAG | GF_ISOM_NALU_EXTRACT_VDRD_FLAG); - break; - case GPAC_OTI_SCENE_VTT_MP4: - ifce->decoder_config = (char *)gf_malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); - ifce->decoder_config_size = esd->decoderConfig->decoderSpecificInfo->dataLength; - memcpy(ifce->decoder_config, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); - break; - } - } - gf_odf_desc_del((GF_Descriptor *)esd); - } - gf_isom_get_media_language(mp4, track_num, &_lan); - if (!_lan || !strcmp(_lan, "und")) { - ifce->lang = 0; - } else { - ifce->lang = GF_4CC(_lan[0],_lan[1],_lan[2],' '); - } - if (_lan) { - gf_free(_lan); - } - - ifce->timescale = gf_isom_get_media_timescale(mp4, track_num); - 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; - if (0!=(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; - - ifce->bit_rate = (u32) avg_rate; - ifce->duration = (Double) (s64) gf_isom_get_media_duration(mp4, track_num); - ifce->duration /= ifce->timescale; - - GF_SAFEALLOC(ifce->sl_config, GF_SLConfig); - if (!ifce->sl_config) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate interface SLConfig\n")); - return; - } - - ifce->sl_config->tag = GF_ODF_SLC_TAG; - ifce->sl_config->useAccessUnitStartFlag = 1; - ifce->sl_config->useAccessUnitEndFlag = 1; - ifce->sl_config->useRandomAccessPointFlag = 1; - ifce->sl_config->useTimestampsFlag = 1; - ifce->sl_config->timestampLength = 33; - ifce->sl_config->timestampResolution = ifce->timescale; - - /*test mode in which time stamps are 90khz and not coded but copied over from PES header*/ - if (bifs_use_pes==2) { - ifce->sl_config->timestampLength = 0; - ifce->sl_config->timestampResolution = 90000; - } - -#ifdef GPAC_DISABLE_ISOM_WRITE - fprintf(stderr, "Warning: GPAC was compiled without ISOM Write support, can't set SL Config!\n"); -#else - gf_isom_set_extraction_slc(mp4, track_num, 1, ifce->sl_config); -#endif - - ifce->input_ctrl = mp4_input_ctrl; - if (priv != ifce->input_udta) { - if (ifce->input_udta) - gf_free(ifce->input_udta); - ifce->input_udta = priv; - } - - - if (! gf_isom_get_edit_list_type(mp4, track_num, &mediaOffset)) { - priv->ts_offset = mediaOffset; - } - - if (gf_isom_has_time_offset(mp4, track_num)==2) { - priv->cts_dts_shift = gf_isom_get_cts_to_dts_shift(mp4, track_num); - } - - ifce->depends_on_stream = 0; - ref_count = gf_isom_get_reference_count(mp4, track_num, GF_ISOM_REF_SCAL); - if (ref_count > 0) { - gf_isom_get_reference_ID(mp4, track_num, GF_ISOM_REF_SCAL, (u32) ref_count, &ifce->depends_on_stream); - } else if (is_hevc) { - ref_count = gf_isom_get_reference_count(mp4, track_num, GF_ISOM_REF_BASE); - if (ref_count > 0) { - gf_isom_get_reference_ID(mp4, track_num, GF_ISOM_REF_BASE, (u32) ref_count, &ifce->depends_on_stream); - } - } - - if (compute_max_size) { - u32 i; - for (i=0; i < priv->sample_count; i++) { - u32 s = gf_isom_get_sample_size(mp4, track_num, i+1); - if (s>source->max_sample_size) source->max_sample_size = s; - } - } - -} - -#endif //GPAC_DISABLE_ISOM - - -#ifndef GPAC_DISABLE_SENG -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 - if (ifce->input_udta) - gf_free(ifce->input_udta); - ifce->input_udta = NULL; - return GF_OK; - } - - return GF_OK; -} -#endif - - -#ifndef GPAC_DISABLE_STREAMING -typedef struct -{ - /*RTP channel*/ - GF_RTPChannel *rtp_ch; - - /*depacketizer*/ - GF_RTPDepacketizer *depacketizer; - - GF_ESIPacket pck; - - GF_ESInterface *ifce; - - Bool cat_dsi, is_264; - void *dsi_and_rap; - u32 avc_dsi_size; - - Bool use_carousel; - u32 au_sn; - - s64 ts_offset; - Bool rtcp_init; - M2TSSource *source; - - u32 min_dts_inc; - u64 prev_cts; - u64 prev_dts; -} GF_ESIRTP; - -static GF_Err rtp_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) -{ - u32 size, PayloadStart; - GF_Err e; - GF_RTPHeader hdr; - char buffer[8000]; - GF_ESIRTP *rtp = (GF_ESIRTP*)ifce->input_udta; - - if (!ifce->input_udta) return GF_BAD_PARAM; - - switch (act_type) { - case GF_ESI_INPUT_DATA_FLUSH: - /*flush rtcp channel*/ - while (1) { - Bool has_sr = GF_FALSE; - size = gf_rtp_read_rtcp(rtp->rtp_ch, buffer, 8000); - if (!size) break; - e = gf_rtp_decode_rtcp(rtp->rtp_ch, buffer, size, &has_sr); - - if (e == GF_EOS) ifce->caps |= GF_ESI_STREAM_IS_OVER; - - if (has_sr && !rtp->rtcp_init) { - Double time = rtp->rtp_ch->last_SR_NTP_sec; - time += ((Double)rtp->rtp_ch->last_SR_NTP_frac)/0xFFFFFFFF; - if (!rtp->source->last_ntp) { - rtp->source->last_ntp = time; - } - if (time >= rtp->source->last_ntp) { - time -= rtp->source->last_ntp; - } else { - time = 0; - } - rtp->ts_offset = rtp->rtp_ch->last_SR_rtp_time; - rtp->ts_offset -= (s64) (time * rtp->rtp_ch->TimeScale); - rtp->rtcp_init = GF_TRUE; - } - } - /*flush rtp channel*/ - while (1) { - size = gf_rtp_read_rtp(rtp->rtp_ch, buffer, 8000); - if (!size) break; - e = gf_rtp_decode_rtp(rtp->rtp_ch, buffer, size, &hdr, &PayloadStart); - if (e) return e; - gf_rtp_depacketizer_process(rtp->depacketizer, &hdr, buffer + PayloadStart, size - PayloadStart); - } - return GF_OK; - case GF_ESI_INPUT_DESTROY: - gf_rtp_depacketizer_del(rtp->depacketizer); - if (rtp->dsi_and_rap) gf_free(rtp->dsi_and_rap); - gf_rtp_del(rtp->rtp_ch); - gf_free(rtp); - - if (ifce->decoder_config) { - gf_free(ifce->decoder_config); - ifce->decoder_config = NULL; - } - ifce->input_udta = NULL; - return GF_OK; - } - return GF_OK; -} - -static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader *hdr, GF_Err e) -{ - GF_ESIRTP *rtp = (GF_ESIRTP*)udta; - - /*sync not found yet, cannot start (since we don't support PCR discontinuities yet ...)*/ - if (!rtp->rtcp_init) return; - - /*try to compute a DTS*/ - if (hdr->accessUnitStartFlag && !hdr->decodingTimeStampFlag) { - if (!rtp->prev_cts) { - rtp->prev_cts = rtp->prev_dts = hdr->compositionTimeStamp; - } - - if (hdr->compositionTimeStamp > rtp->prev_cts) { - u32 diff = (u32) (hdr->compositionTimeStamp - rtp->prev_cts); - if (!rtp->min_dts_inc || (rtp->min_dts_inc > diff)) { - rtp->min_dts_inc = diff; - rtp->prev_dts = hdr->compositionTimeStamp - diff; - } - } - hdr->decodingTimeStampFlag = 1; - hdr->decodingTimeStamp = rtp->prev_dts + rtp->min_dts_inc; - rtp->prev_dts += rtp->min_dts_inc; - if (hdr->compositionTimeStamp < hdr->decodingTimeStamp) { - hdr->decodingTimeStamp = hdr->compositionTimeStamp; - } - } - - rtp->pck.data = payload; - rtp->pck.data_len = size; - rtp->pck.dts = hdr->decodingTimeStamp + rtp->ts_offset; - rtp->pck.cts = hdr->compositionTimeStamp + rtp->ts_offset; - rtp->pck.flags = 0; - if (hdr->compositionTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_CTS; - if (hdr->decodingTimeStampFlag) rtp->pck.flags |= GF_ESI_DATA_HAS_DTS; - if (hdr->randomAccessPointFlag) rtp->pck.flags |= GF_ESI_DATA_AU_RAP; - if (hdr->accessUnitStartFlag) rtp->pck.flags |= GF_ESI_DATA_AU_START; - if (hdr->accessUnitEndFlag) rtp->pck.flags |= GF_ESI_DATA_AU_END; - - if (rtp->use_carousel) { - if ((hdr->AU_sequenceNumber==rtp->au_sn) && hdr->randomAccessPointFlag) rtp->pck.flags |= GF_ESI_DATA_REPEAT; - rtp->au_sn = hdr->AU_sequenceNumber; - } - - if (rtp->is_264) { - if (!payload) return; - - /*send a NALU delim: copy over NAL ref idc*/ - if (hdr->accessUnitStartFlag) { - char sc[6]; - sc[0] = sc[1] = sc[2] = 0; - sc[3] = 1; - sc[4] = (payload[4] & 0x60) | GF_AVC_NALU_ACCESS_UNIT; - sc[5] = 0xF0 /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/; - - rtp->pck.data = sc; - rtp->pck.data_len = 6; - rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); - - rtp->pck.flags &= ~GF_ESI_DATA_AU_START; - - /*since we don't inspect the RTP content, we can only concatenate SPS and PPS indicated in SDP*/ - if (hdr->randomAccessPointFlag && rtp->dsi_and_rap) { - rtp->pck.data = (char*)rtp->dsi_and_rap; - rtp->pck.data_len = rtp->avc_dsi_size; - - rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); - } - - rtp->pck.data = payload; - rtp->pck.data_len = size; - } - - rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); - } else { - if (rtp->cat_dsi && hdr->randomAccessPointFlag && hdr->accessUnitStartFlag) { - if (rtp->dsi_and_rap) gf_free(rtp->dsi_and_rap); - rtp->pck.data_len = size + rtp->depacketizer->sl_map.configSize; - rtp->dsi_and_rap = gf_malloc(sizeof(char)*(rtp->pck.data_len)); - memcpy(rtp->dsi_and_rap, rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize); - memcpy((char *) rtp->dsi_and_rap + rtp->depacketizer->sl_map.configSize, payload, size); - rtp->pck.data = (char*)rtp->dsi_and_rap; - } - rtp->ifce->output_ctrl(rtp->ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &rtp->pck); - } -} - -static void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp, M2TSSource *source) -{ - u32 i; - GF_Err e; - GF_X_Attribute*att; - GF_ESIRTP *rtp; - GF_RTPMap*map; - GF_SDPConnection *conn; - GF_RTSPTransport trans; - - /*check connection*/ - conn = sdp->c_connection; - if (!conn) conn = (GF_SDPConnection*)gf_list_get(media->Connections, 0); - - /*check payload type*/ - map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0); - GF_SAFEALLOC(rtp, GF_ESIRTP); - if (!rtp) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate RTP input handler\n")); - return; - } - - memset(ifce, 0, sizeof(GF_ESInterface)); - rtp->rtp_ch = gf_rtp_new(); - i=0; - while ((att = (GF_X_Attribute*)gf_list_enum(media->Attributes, &i))) { - if (!stricmp(att->Name, "mpeg4-esid") && att->Value) ifce->stream_id = atoi(att->Value); - } - - memset(&trans, 0, sizeof(GF_RTSPTransport)); - trans.Profile = media->Profile; - trans.source = conn ? conn->host : sdp->o_address; - trans.IsUnicast = gf_sk_is_multicast_address(trans.source) ? GF_FALSE : GF_TRUE; - if (!trans.IsUnicast) { - trans.port_first = media->PortNumber; - trans.port_last = media->PortNumber + 1; - trans.TTL = conn ? conn->TTL : 0; - } else { - trans.client_port_first = media->PortNumber; - trans.client_port_last = media->PortNumber + 1; - } - - if (gf_rtp_setup_transport(rtp->rtp_ch, &trans, NULL) != GF_OK) { - gf_rtp_del(rtp->rtp_ch); - fprintf(stderr, "Cannot initialize RTP transport\n"); - return; - } - /*setup depacketizer*/ - rtp->depacketizer = gf_rtp_depacketizer_new(media, rtp_sl_packet_cbk, rtp); - if (!rtp->depacketizer) { - gf_rtp_del(rtp->rtp_ch); - fprintf(stderr, "Cannot create RTP depacketizer\n"); - return; - } - /*setup channel*/ - gf_rtp_setup_payload(rtp->rtp_ch, map); - ifce->input_udta = rtp; - ifce->input_ctrl = rtp_input_ctrl; - rtp->ifce = ifce; - rtp->source = source; - - 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 = GF_TRUE; - break; - case GPAC_OTI_VIDEO_AVC: - case GPAC_OTI_VIDEO_SVC: - case GPAC_OTI_VIDEO_MVC: - rtp->is_264 = GF_TRUE; - rtp->depacketizer->flags |= GF_RTP_AVC_USE_ANNEX_B; - { -#ifndef GPAC_DISABLE_AV_PARSERS - GF_AVCConfig *avccfg = gf_odf_avc_cfg_read(rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize); - if (avccfg) { - GF_AVCConfigSlot *slc; - u32 i; - GF_BitStream *bs; - - bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - for (i=0; isequenceParameterSets); i++) { - slc = (GF_AVCConfigSlot*)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_AVCConfigSlot*)gf_list_get(avccfg->pictureParameterSets, i); - gf_bs_write_u32(bs, 1); - gf_bs_write_data(bs, slc->data, slc->size); - } - gf_bs_get_content(bs, (char **) &rtp->dsi_and_rap, &rtp->avc_dsi_size); - gf_bs_del(bs); - } - gf_odf_avc_cfg_del(avccfg); -#endif - } - break; - case GPAC_OTI_AUDIO_AAC_MPEG4: - ifce->decoder_config = (char*)gf_malloc(sizeof(char) * rtp->depacketizer->sl_map.configSize); - ifce->decoder_config_size = rtp->depacketizer->sl_map.configSize; - memcpy(ifce->decoder_config, rtp->depacketizer->sl_map.config, rtp->depacketizer->sl_map.configSize); - break; - } - } - if (rtp->depacketizer->sl_map.StreamStateIndication) { - rtp->use_carousel = GF_TRUE; - rtp->au_sn=0; - } - - /*DTS signaling is only supported for MPEG-4 visual*/ - if (rtp->depacketizer->sl_map.DTSDeltaLength) ifce->caps |= GF_ESI_SIGNAL_DTS; - - gf_rtp_depacketizer_reset(rtp->depacketizer, GF_TRUE); - e = gf_rtp_initialize(rtp->rtp_ch, 0x100000ul, GF_FALSE, 0, 10, 200, NULL); - if (e!=GF_OK) { - gf_rtp_del(rtp->rtp_ch); - fprintf(stderr, "Cannot initialize RTP channel: %s\n", gf_error_to_string(e)); - return; - } - fprintf(stderr, "RTP interface initialized\n"); -} -#endif /*GPAC_DISABLE_STREAMING*/ - -#ifndef GPAC_DISABLE_SENG -static GF_Err void_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) -{ - return GF_OK; -} -#endif - -/*AAC import features*/ -#ifndef GPAC_DISABLE_PLAYER - -void *audio_prog = NULL; -static void SampleCallBack(void *calling_object, u16 ESID, char *data, u32 size, u64 ts); -#define DONT_USE_TERMINAL_MODULE_API -#include "../../modules/aac_in/aac_in.c" -AACReader *aac_reader = NULL; -u64 audio_discontinuity_offset = 0; - -/*create an OD codec and encode the descriptor*/ -static GF_Err encode_audio_desc(GF_ESD *esd, GF_SimpleDataDescriptor *audio_desc) -{ - GF_Err e; - GF_ODCodec *odc = gf_odf_codec_new(); - GF_ODUpdate *od_com = (GF_ODUpdate*)gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); - GF_ObjectDescriptor *od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); - assert( esd ); - assert( audio_desc ); - gf_list_add(od->ESDescriptors, esd); - od->objectDescriptorID = AUDIO_DATA_ESID; - gf_list_add(od_com->objectDescriptors, od); - - e = gf_odf_codec_add_com(odc, (GF_ODCom*)od_com); - if (e) { - fprintf(stderr, "Audio input error add the command to be encoded\n"); - return e; - } - e = gf_odf_codec_encode(odc, 0); - if (e) { - fprintf(stderr, "Audio input error encoding the descriptor\n"); - return e; - } - e = gf_odf_codec_get_au(odc, &audio_desc->data, &audio_desc->size); - if (e) { - fprintf(stderr, "Audio input error getting the descriptor\n"); - return e; - } - e = gf_odf_com_del((GF_ODCom**)&od_com); - if (e) { - fprintf(stderr, "Audio input error deleting the command\n"); - return e; - } - gf_odf_codec_del(odc); - - return GF_OK; -} - -#endif - - -static void SampleCallBack(void *calling_object, u16 ESID, char *data, u32 size, u64 ts) -{ - u32 i; - //fprintf(stderr, "update: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); - - if (calling_object) { - M2TSSource *source = (M2TSSource *)calling_object; - -#ifndef GPAC_DISABLE_PLAYER - if (ESID == AUDIO_DATA_ESID) { - if (audio_OD_stream_id != (u32)-1) { - /*this is the first time we get some audio data. Therefore we are sure we can retrieve the audio descriptor. Then we'll - send it by calling this callback recursively so that a player gets the audio descriptor before audio data. - Hack: the descriptor is carried thru the input_udta, you shall delete it*/ - GF_SimpleDataDescriptor *audio_desc = source->streams[audio_OD_stream_id].input_udta; - if (audio_desc && !audio_desc->data) /*intended for HTTP/AAC: an empty descriptor was set (vs already filled for RTP/UDP MP3)*/ - { - /*get the audio descriptor and encode it*/ - GF_ESD *esd = AAC_GetESD(aac_reader); - assert(esd->slConfig->timestampResolution); - esd->slConfig->useAccessUnitStartFlag = 1; - esd->slConfig->useAccessUnitEndFlag = 1; - esd->slConfig->useTimestampsFlag = 1; - esd->slConfig->timestampLength = 33; - /*audio stream, all samples are RAPs*/ - esd->slConfig->useRandomAccessPointFlag = 0; - esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; - for (i=0; inb_streams; i++) { - if (source->streams[i].stream_id == AUDIO_DATA_ESID) { - GF_Err e; - source->streams[i].timescale = esd->slConfig->timestampResolution; - e = gf_m2ts_program_stream_update_ts_scale(&source->streams[i], esd->slConfig->timestampResolution); - if (e != GF_OK) { - fprintf(stderr, "Failed updating TS program timescale\n"); - } - else if (!source->streams[i].sl_config) - source->streams[i].sl_config = (GF_SLConfig *)gf_odf_desc_new(GF_ODF_SLC_TAG); - - memcpy(source->streams[i].sl_config, esd->slConfig, sizeof(GF_SLConfig)); - break; - } - } - esd->ESID = AUDIO_DATA_ESID; - assert(audio_OD_stream_id != (u32)-1); - encode_audio_desc(esd, audio_desc); - - /*build the ESI*/ - { - /*audio OD descriptor: rap=1 and vers_inc=0*/ - GF_SAFEALLOC(source->streams[audio_OD_stream_id].input_udta, GF_ESIStream); - if (!source->streams[audio_OD_stream_id].input_udta) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate aac input handler\n")); - return; - } - ((GF_ESIStream*)source->streams[audio_OD_stream_id].input_udta)->rap = 1; - - /*we have the descriptor; now call this callback recursively so that a player gets the audio descriptor before audio data.*/ - source->repeat = 1; - SampleCallBack(source, AUDIO_OD_ESID, audio_desc->data, audio_desc->size, 0/*gf_m2ts_get_sys_clock(muxer)*/); - source->repeat = 0; - - /*clean*/ - gf_free(audio_desc->data); - gf_free(audio_desc); - gf_free(source->streams[audio_OD_stream_id].input_udta); - source->streams[audio_OD_stream_id].input_udta = NULL; - } - } - } - /*update the timescale if needed*/ - else if (!source->audio_configured) { - GF_ESD *esd = AAC_GetESD(aac_reader); - assert(esd->slConfig->timestampResolution); - for (i=0; inb_streams; i++) { - if (source->streams[i].stream_id == AUDIO_DATA_ESID) { - GF_Err e; - source->streams[i].timescale = esd->slConfig->timestampResolution; - source->streams[i].decoder_config = esd->decoderConfig->decoderSpecificInfo->data; - source->streams[i].decoder_config_size = esd->decoderConfig->decoderSpecificInfo->dataLength; - esd->decoderConfig->decoderSpecificInfo->data = NULL; - esd->decoderConfig->decoderSpecificInfo->dataLength = 0; - e = gf_m2ts_program_stream_update_ts_scale(&source->streams[i], esd->slConfig->timestampResolution); - if (!e) - source->audio_configured = 1; - break; - } - } - gf_odf_desc_del((GF_Descriptor *)esd); - } - - /*overwrite timing as it is flushed to 0 on discontinuities*/ - ts += audio_discontinuity_offset; - } -#endif - i=0; - while (inb_streams) { - if (source->streams[i].output_ctrl==NULL) { - fprintf(stderr, "MULTIPLEX NOT YET CREATED\n"); - return; - } - if (source->streams[i].stream_id == ESID) { - GF_ESIStream *priv = (GF_ESIStream *)source->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_HAS_DTS; - pck.flags |= GF_ESI_DATA_AU_START; - pck.flags |= GF_ESI_DATA_AU_END; - if (ts) pck.cts = pck.dts = ts; - - if (priv->rap) - pck.flags |= GF_ESI_DATA_AU_RAP; - if (source->repeat || !priv->vers_inc) { - pck.flags |= GF_ESI_DATA_REPEAT; - fprintf(stderr, "RAP carousel from scene engine sent: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); - } else { - if (ESID != AUDIO_DATA_ESID && ESID != VIDEO_DATA_ESID) /*don't log A/V inputs*/ - fprintf(stderr, "Update from scene engine sent: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); - } - source->streams[i].output_ctrl(&source->streams[i], GF_ESI_OUTPUT_DATA_DISPATCH, &pck); - return; - } - i++; - } - } - return; -} - -//static gf_seng_callback * SampleCallBack = &mySampleCallBack; - - -static volatile Bool run = 1; - -#ifndef GPAC_DISABLE_SENG -static GF_ESIStream * set_broadcast_params(M2TSSource *source, 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 (source->streams[i].stream_id == esid) { - priv = (GF_ESIStream *)source->streams[i].input_udta; - esi = &source->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(source->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; -} -#endif - -#ifndef GPAC_DISABLE_SENG - -static u32 seng_output(void *param) -{ - GF_Err e; - u64 last_src_modif, mod_time; - M2TSSource *source = (M2TSSource *)param; - GF_SceneEngine *seng = source->seng; -#ifndef GPAC_DISABLE_PLAYER - GF_SimpleDataDescriptor *audio_desc; -#endif - Bool update_context=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; - e = GF_OK; - gf_sleep(2000); /*TODO: events instead? What are we waiting for?*/ - gf_seng_encode_context(seng, SampleCallBack); - - last_src_modif = source->bifs_src_name ? gf_file_modification_time(source->bifs_src_name) : 0; - - /*send the audio descriptor*/ -#ifndef GPAC_DISABLE_PLAYER - if (source->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_FULL && audio_OD_stream_id!=(u32)-1) { - audio_desc = source->streams[audio_OD_stream_id].input_udta; - if (audio_desc && audio_desc->data) /*RTP/UDP + MP3 case*/ - { - assert(audio_OD_stream_id != (u32)-1); - assert(!aac_reader); /*incompatible with AAC*/ - source->repeat = 1; - SampleCallBack(source, AUDIO_OD_ESID, audio_desc->data, audio_desc->size, 0/*gf_m2ts_get_sys_clock(muxer)*/); - source->repeat = 0; - gf_free(audio_desc->data); - gf_free(audio_desc); - source->streams[audio_OD_stream_id].input_udta = NULL; - } - } -#endif - - while (run) { - if (!gf_prompt_has_input()) { - if (source->bifs_src_name) { - mod_time = gf_file_modification_time(source->bifs_src_name); - if (mod_time != last_src_modif) { - FILE *srcf; - char flag_buf[201], *flag; - fprintf(stderr, "Update file modified - processing\n"); - last_src_modif = mod_time; - - srcf = gf_fopen(source->bifs_src_name, "rt"); - if (!srcf) continue; - - /*checks if we have a broadcast config*/ - if (!fgets(flag_buf, 200, srcf)) - flag_buf[0] = '\0'; - gf_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(source, 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, source->bifs_src_name, SampleCallBack); - if (e) { - fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); - } else - gf_seng_aggregate_context(seng, 0); - - update_context=1; - - - - } - } - if (update_context) { - source->repeat = 1; - e = gf_seng_encode_context(seng, SampleCallBack); - source->repeat = 0; - update_context = 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(stderr, "Enter command to send:\n"); - fflush(stdin); - szCom[0] = 0; - if (1 > scanf("%[^\t\n]", szCom)) { - fprintf(stderr, "No command has been properly entered, aborting.\n"); - break; - } - e = gf_seng_encode_from_string(seng, 0, 0, szCom, SampleCallBack); - if (e) { - fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); - } - update_context=1; - } - break; - case 'p': - { - char rad[GF_MAX_PATH]; - fprintf(stderr, "Enter output file name - \"std\" for stderr: "); - if (1 > scanf("%s", rad)) { - fprintf(stderr, "No outfile name has been entered, aborting.\n"); - break; - } - e = gf_seng_save_context(seng, !strcmp(rad, "std") ? NULL : rad); - fprintf(stderr, "Dump done (%s)\n", gf_error_to_string(e)); - } - break; - case 'q': - { - run = 0; - } - } - e = GF_OK; - } - } - - - return e ? 1 : 0; -} - -void fill_seng_es_ifce(GF_ESInterface *ifce, u32 i, GF_SceneEngine *seng, u32 period) -{ - GF_Err e = GF_OK; - u32 len; - GF_ESIStream *stream; - char *config_buffer = NULL; - - memset(ifce, 0, sizeof(GF_ESInterface)); - e = gf_seng_get_stream_config(seng, i, (u16*) &(ifce->stream_id), &config_buffer, &len, (u32*) &(ifce->stream_type), (u32*) &(ifce->object_type_indication), &(ifce->timescale)); - if (e) { - fprintf(stderr, "Cannot set the stream config for stream %d to %d: %s\n", ifce->stream_id, period, gf_error_to_string(e)); - } - - ifce->repeat_rate = period; - GF_SAFEALLOC(stream, GF_ESIStream); - if (!stream) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate SENG input handler\n")); - return; - } - - stream->rap = 1; - if (ifce->input_udta) - gf_free(ifce->input_udta); - ifce->input_udta = stream; - - //fprintf(stderr, "Caroussel period: %d\n", period); -// e = gf_seng_set_carousel_time(seng, ifce->stream_id, period); - if (e) { - fprintf(stderr, "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; - -} -#endif - -static Bool open_source(M2TSSource *source, char *src, u32 carousel_rate, u32 mpeg4_signaling, char *update, char *audio_input_ip, u16 audio_input_port, char *video_buffer, Bool force_real_time, u32 bifs_use_pes, const char *temi_url, Bool compute_max_size, Bool insert_ntp) -{ -#ifndef GPAC_DISABLE_STREAMING - GF_SDPInfo *sdp; -#endif - - memset(source, 0, sizeof(M2TSSource)); - source->mpeg4_signaling = mpeg4_signaling; - - /*open ISO file*/ -#ifndef GPAC_DISABLE_ISOM - if (gf_isom_probe_file(src)) { - u32 i; - u32 nb_tracks; - Bool has_bifs_od = 0; - Bool temi_assigned = 0; - u32 first_audio = 0; - u32 first_other = 0; - s64 min_offset = 0; - u32 min_offset_timescale = 0; - source->mp4 = gf_isom_open(src, GF_ISOM_OPEN_READ, 0); - source->nb_streams = 0; - source->real_time = force_real_time; - /*on MPEG-2 TS, carry 3GPP timed text as MPEG-4 Part17*/ - gf_isom_text_set_streaming_mode(source->mp4, 1); - nb_tracks = gf_isom_get_track_count(source->mp4); - - for (i=0; imp4, i+1) == GF_ISOM_MEDIA_HINT) - continue; - - fill_isom_es_ifce(source, &source->streams[i], source->mp4, i+1, bifs_use_pes, compute_max_size); - if (min_offset > ((GF_ESIMP4 *)source->streams[i].input_udta)->ts_offset) { - min_offset = ((GF_ESIMP4 *)source->streams[i].input_udta)->ts_offset; - min_offset_timescale = source->streams[i].timescale; - } - - switch(source->streams[i].stream_type) { - case GF_STREAM_OD: - has_bifs_od = 1; - source->streams[i].repeat_rate = carousel_rate; - break; - case GF_STREAM_SCENE: - has_bifs_od = 1; - source->streams[i].repeat_rate = carousel_rate; - break; - case GF_STREAM_VISUAL: - /*turn on image repeat*/ - switch (source->streams[i].object_type_indication) { - case GPAC_OTI_IMAGE_JPEG: - case GPAC_OTI_IMAGE_PNG: - ((GF_ESIMP4 *)source->streams[i].input_udta)->image_repeat_ms = carousel_rate; - break; - default: - check_deps = 1; - if (gf_isom_get_sample_count(source->mp4, i+1)>1) { - /*get first visual stream as PCR*/ - if (!source->pcr_idx) { - source->pcr_idx = i+1; - if ((temi_id_1>=0) || (temi_id_2>=0)) { - temi_assigned = GF_TRUE; - ((GF_ESIMP4 *)source->streams[i].input_udta)->timeline_id = (u32) ( (temi_id_1>=0) ? temi_id_1 + 1 : temi_id_2 + 1 ); - ((GF_ESIMP4 *)source->streams[i].input_udta)->insert_ntp = insert_ntp; - - if (temi_url && (temi_id_1>=0)) - ((GF_ESIMP4 *)source->streams[i].input_udta)->temi_url = temi_url; - - if (temi_id_1>=0) temi_id_1 = -1; - else temi_id_2 = -1; - } - } - } - break; - } - break; - case GF_STREAM_AUDIO: - if (!first_audio) first_audio = i+1; - check_deps = 1; - break; - default: - /*log not supported stream type: %s*/ - break; - } - source->nb_streams++; - if (gf_isom_get_sample_count(source->mp4, i+1)>1) first_other = i+1; - - if (check_deps) { - u32 k; - Bool found_dep = 0; - for (k=0; kmp4, k+1) != GF_ISOM_MEDIA_OD) - continue; - - /*this stream is not refered to by any OD, send as regular PES*/ - if (gf_isom_has_track_reference(source->mp4, k+1, GF_ISOM_REF_OD, gf_isom_get_track_id(source->mp4, i+1) )==1) { - found_dep = 1; - break; - } - } - if (!found_dep) { - source->streams[i].caps |= GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS; - } - } - } - if (has_bifs_od && !source->mpeg4_signaling) source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; - if ( !temi_assigned && first_audio && ((temi_id_1>=0) || (temi_id_2>=0) ) ) { - ((GF_ESIMP4 *)source->streams[first_audio-1].input_udta)->timeline_id = (u32) ( (temi_id_1>=0) ? temi_id_1 + 1 : temi_id_2 + 1 ); - ((GF_ESIMP4 *)source->streams[first_audio-1].input_udta)->insert_ntp = insert_ntp; - - if (temi_url && (temi_id_1>=0) ) - ((GF_ESIMP4 *)source->streams[first_audio-1].input_udta)->temi_url = temi_url; - - if (temi_id_1>=0) temi_id_1 = -1; - else temi_id_2 = -1; - } - - /*if no visual PCR found, use first audio*/ - if (!source->pcr_idx) source->pcr_idx = first_audio; - if (!source->pcr_idx) source->pcr_idx = first_other; - if (source->pcr_idx) { - GF_ESIMP4 *priv; - source->pcr_idx-=1; - priv = source->streams[source->pcr_idx].input_udta; - gf_isom_set_default_sync_track(source->mp4, priv->track); - } - - if (min_offset < 0) { - for (i=0; inb_streams; i++) { - Double scale = source->streams[i].timescale; - scale /= min_offset_timescale; - ((GF_ESIMP4 *)source->streams[i].input_udta)->ts_offset += (s64) (-min_offset * scale); - } - } - - source->iod = gf_isom_get_root_od(source->mp4); - if (source->iod) { - GF_ObjectDescriptor*iod = (GF_ObjectDescriptor*)source->iod; - if (gf_list_count( ((GF_ObjectDescriptor*)source->iod)->ESDescriptors) == 0) { - gf_odf_desc_del(source->iod); - source->iod = NULL; - } else { - fprintf(stderr, "IOD found for program %s\n", src); - - /*if using 4over2, get rid of OD tracks*/ - if (source->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_SCENE) { - for (i=0; iESDescriptors); i++) { - u32 track_num, k; - GF_M2TSDescriptor *oddesc; - GF_ISOSample *sample; - GF_ESD *esd = gf_list_get(iod->ESDescriptors, i); - if (esd->decoderConfig->streamType!=GF_STREAM_OD) continue; - track_num = gf_isom_get_track_by_id(source->mp4, esd->ESID); - if (gf_isom_get_sample_count(source->mp4, track_num)>1) continue; - - sample = gf_isom_get_sample(source->mp4, track_num, 1, NULL); - if (sample->dataLength >= 255-2) { - gf_isom_sample_del(&sample); - continue; - } - /*rewrite ESD dependencies*/ - for (k=0; kESDescriptors); k++) { - GF_ESD *dep_esd = gf_list_get(iod->ESDescriptors, k); - if (dep_esd->dependsOnESID==esd->ESID) dep_esd->dependsOnESID = esd->dependsOnESID; - } - - for (k=0; knb_streams; k++) { - if (source->streams[k].stream_id==esd->ESID) { - source->streams[k].stream_type = 0; - break; - } - } - - if (!source->od_updates) source->od_updates = gf_list_new(); - GF_SAFEALLOC(oddesc, GF_M2TSDescriptor); - oddesc->data_len = sample->dataLength; - oddesc->data = sample->data; - oddesc->tag = GF_M2TS_MPEG4_ODUPDATE_DESCRIPTOR; - sample->data = NULL; - gf_isom_sample_del(&sample); - gf_list_add(source->od_updates, oddesc); - - gf_list_rem(iod->ESDescriptors, i); - i--; - gf_odf_desc_del((GF_Descriptor *) esd); - source->samples_count--; - } - } - - } - } - return 1; - } -#endif - - -#ifndef GPAC_DISABLE_STREAMING - /*open SDP file*/ - if (strstr(src, ".sdp")) { - GF_X_Attribute *att; - char *sdp_buf; - u32 sdp_size, i; - GF_Err e; - FILE *_sdp = gf_fopen(src, "rt"); - if (!_sdp) { - fprintf(stderr, "Error opening %s - no such file\n", src); - return 0; - } - gf_fseek(_sdp, 0, SEEK_END); - sdp_size = (u32)gf_ftell(_sdp); - gf_fseek(_sdp, 0, SEEK_SET); - sdp_buf = (char*)gf_malloc(sizeof(char)*sdp_size); - memset(sdp_buf, 0, sizeof(char)*sdp_size); - sdp_size = (u32) fread(sdp_buf, 1, sdp_size, _sdp); - gf_fclose(_sdp); - - sdp = gf_sdp_info_new(); - e = gf_sdp_info_parse(sdp, sdp_buf, sdp_size); - 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 = (u32) strlen(buf64) - 1; - size = gf_base64_decode(buf64, size64, buf, 2000); - - gf_odf_desc_read(buf, size, &source->iod); - break; - } - - source->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(&source->streams[i], media, sdp, source); - switch(source->streams[i].stream_type) { - case GF_STREAM_OD: - case GF_STREAM_SCENE: - source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; - source->streams[i].repeat_rate = carousel_rate; - break; - } - if (!source->pcr_idx && (source->streams[i].stream_type == GF_STREAM_VISUAL)) { - source->pcr_idx = i+1; - } - } - - if (source->pcr_idx) source->pcr_idx-=1; - gf_sdp_info_del(sdp); - - return 2; - } else -#endif /*GPAC_DISABLE_STREAMING*/ - -#ifndef GPAC_DISABLE_SENG - if (strstr(src, ".bt")) //open .bt file - { - u32 i; - u32 load_type=0; - source->seng = gf_seng_init(source, src, load_type, NULL, (load_type == GF_SM_LOAD_DIMS) ? 1 : 0); - if (!source->seng) { - fprintf(stderr, "Cannot create scene engine\n"); - exit(1); - } - else { - fprintf(stderr, "Scene engine created.\n"); - } - assert( source ); - assert( source->seng); - source->iod = gf_seng_get_iod(source->seng); - if (! source->iod) { - fprintf(stderr, __FILE__": No IOD\n"); - } - - source->nb_streams = gf_seng_get_stream_count(source->seng); - source->rate = carousel_rate; - source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; - - for (i=0; inb_streams; i++) { - fill_seng_es_ifce(&source->streams[i], i, source->seng, source->rate); - //fprintf(stderr, "Fill interface\n"); - if (!source->pcr_idx && (source->streams[i].stream_type == GF_STREAM_AUDIO)) { - source->pcr_idx = i+1; - } - } - -#ifndef GPAC_DISABLE_PLAYER - /*when an audio input is present, declare it and store OD + ESD_U*/ - if (audio_input_ip) { - /*add the audio program*/ - source->pcr_idx = source->nb_streams; - source->streams[source->nb_streams].stream_type = GF_STREAM_AUDIO; - /*hack: http urls are not decomposed therefore audio_input_port remains null*/ - if (audio_input_port) { /*UDP/RTP*/ - source->streams[source->nb_streams].object_type_indication = GPAC_OTI_AUDIO_MPEG1; - } else { /*HTTP*/ - aac_reader->oti = source->streams[source->nb_streams].object_type_indication = GPAC_OTI_AUDIO_AAC_MPEG4; - } - source->streams[source->nb_streams].input_ctrl = void_input_ctrl; - source->streams[source->nb_streams].stream_id = AUDIO_DATA_ESID; - source->streams[source->nb_streams].timescale = 1000; - - GF_SAFEALLOC(source->streams[source->nb_streams].input_udta, GF_ESIStream); - if (!source->streams[source->nb_streams].input_udta) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate audio input handler\n")); - return 0; - } - - ((GF_ESIStream*)source->streams[source->nb_streams].input_udta)->vers_inc = 1; /*increment version number at every audio update*/ - assert( source ); - //assert( source->iod); - if (source->iod && ((source->iod->tag!=GF_ODF_IOD_TAG) || (mpeg4_signaling != GF_M2TS_MPEG4_SIGNALING_SCENE))) { - /*create the descriptor*/ - GF_ESD *esd; - GF_SimpleDataDescriptor *audio_desc; - GF_SAFEALLOC(audio_desc, GF_SimpleDataDescriptor); - if (audio_input_port) { /*UDP/RTP*/ - esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = source->streams[source->nb_streams].stream_type; - esd->decoderConfig->objectTypeIndication = source->streams[source->nb_streams].object_type_indication; - } else { /*HTTP*/ - esd = AAC_GetESD(aac_reader); /*in case of AAC, we have to wait the first ADTS chunk*/ - } - assert( esd ); - esd->ESID = source->streams[source->nb_streams].stream_id; - if (esd->slConfig->timestampResolution) /*in case of AAC, we have to wait the first ADTS chunk*/ - encode_audio_desc(esd, audio_desc); - else - gf_odf_desc_del((GF_Descriptor *)esd); - - /*find the audio OD stream and attach its descriptor*/ - for (i=0; inb_streams; i++) { - if (source->streams[i].stream_id == AUDIO_OD_ESID) { - if (source->streams[i].input_udta) - gf_free(source->streams[i].input_udta); - source->streams[i].input_udta = (void*)audio_desc; /*Hack: the real input_udta type (for our SampleCallBack function) is GF_ESIStream*/ - audio_OD_stream_id = i; - break; - } - } - if (audio_OD_stream_id == (u32)-1) { - fprintf(stderr, "Error: could not find an audio OD stream with ESID=100 in '%s'\n", src); - return 0; - } - } else { - source->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_SCENE; - } - source->nb_streams++; - } -#endif - - /*when an audio input is present, declare it and store OD + ESD_U*/ - if (video_buffer) { - /*add the video program*/ - source->streams[source->nb_streams].stream_type = GF_STREAM_VISUAL; - source->streams[source->nb_streams].object_type_indication = GPAC_OTI_VIDEO_AVC; - source->streams[source->nb_streams].input_ctrl = void_input_ctrl; - source->streams[source->nb_streams].stream_id = VIDEO_DATA_ESID; - source->streams[source->nb_streams].timescale = 1000; - - GF_SAFEALLOC(source->streams[source->nb_streams].input_udta, GF_ESIStream); - if (!source->streams[source->nb_streams].input_udta) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to allocate video input handler\n")); - return 0; - } - ((GF_ESIStream*)source->streams[source->nb_streams].input_udta)->vers_inc = 1; /*increment version number at every video update*/ - assert(source); - - if (source->iod && ((source->iod->tag!=GF_ODF_IOD_TAG) || (mpeg4_signaling != GF_M2TS_MPEG4_SIGNALING_SCENE))) { - assert(0); /*TODO*/ -#if 0 - /*create the descriptor*/ - GF_ESD *esd; - GF_SimpleDataDescriptor *video_desc; - GF_SAFEALLOC(video_desc, GF_SimpleDataDescriptor); - esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = source->streams[source->nb_streams].stream_type; - esd->decoderConfig->objectTypeIndication = source->streams[source->nb_streams].object_type_indication; - esd->ESID = source->streams[source->nb_streams].stream_id; - - /*find the audio OD stream and attach its descriptor*/ - for (i=0; inb_streams; i++) { - if (source->streams[i].stream_id == 103/*TODO: VIDEO_OD_ESID*/) { - if (source->streams[i].input_udta) - gf_free(source->streams[i].input_udta); - source->streams[i].input_udta = (void*)video_desc; - audio_OD_stream_id = i; - break; - } - } - if (audio_OD_stream_id == (u32)-1) { - fprintf(stderr, "Error: could not find an audio OD stream with ESID=100 in '%s'\n", src); - return 0; - } -#endif - } else { - assert (source->mpeg4_signaling == GF_M2TS_MPEG4_SIGNALING_SCENE); - } - - source->nb_streams++; - } - - if (!source->pcr_idx) source->pcr_idx=1; - source->th = gf_th_new("Carousel"); - source->bifs_src_name = update; - gf_th_run(source->th, seng_output, source); - return 1; - } else -#endif - { - FILE *f = gf_fopen(src, "rt"); - if (f) { - gf_fclose(f); - fprintf(stderr, "Error opening %s - not a supported input media, skipping.\n", src); - } else { - fprintf(stderr, "Error opening %s - no such file.\n", src); - } - return 0; - } -} - -#ifdef GPAC_MEMORY_TRACKING -GF_MemTrackerType mem_track = GF_MemTrackerNone; -#endif - -/*macro to keep retro compatibility with '=' and spaces in parse_args*/ -#define CHECK_PARAM(param) (!strnicmp(arg, param, strlen(param)) \ - && ( ((arg[strlen(param)] == '=') && (next_arg = arg+strlen(param)+1)) \ - || ((strlen(arg) == strlen(param)) && ++i && (i0xFF) { - fprintf(stderr, "TEMI external timeline IDs shall be in the range [0x80, 0xFF], but %d was specified\n", temi_id); - return GF_BAD_PARAM; - } - } - if (!temi_id) { - *temi_url = next_arg; - if (strlen(next_arg) > 150) { - fprintf(stderr, "URLs longer than 150 bytes are not currently supported\n"); - return GF_NOT_SUPPORTED; - } - temi_id_1 = 0; - } else { - temi_id_1 = temi_id; - *temi_url = NULL; - } - } - } else if (CHECK_PARAM("-temi2")) { - u32 temi_id = 0; - if (next_arg[0]=='-') { - fprintf(stderr, "No ID for secondary external TEMI timeline specified\n"); - return GF_BAD_PARAM; - } - if (sscanf(next_arg, "%d", &temi_id) == 1) { - if (temi_id < 0x80 || temi_id>0xFF) { - fprintf(stderr, "TEMI external timeline IDs shall be in the range [0x80, 0xFF], but %d was specified\n", temi_id); - return GF_BAD_PARAM; - } - temi_id_2 = temi_id; - } else { - fprintf(stderr, "No ID for secondary external TEMI timeline specified\n"); - return GF_BAD_PARAM; - } - } else if (CHECK_PARAM("-temi-delay")) { - temi_url_insertion_delay = atoi(next_arg); - } else if (CHECK_PARAM("-temi-offset")) { - temi_offset = atoi(next_arg); - } else if (!stricmp(arg, "-temi-noloop")) { - temi_disable_loop = 1; - } else if (!stricmp(arg, "-insert-ntp")) { - insert_ntp = GF_TRUE; - } - else if (CHECK_PARAM("-dst-udp")) { - char *sep = strchr(next_arg, ':'); - dst_found = 1; - *real_time=1; - if (sep) { - *output_port = atoi(sep+1); - sep[0]=0; - *udp_out = gf_strdup(next_arg); - sep[0]=':'; - } else { - *udp_out = gf_strdup(next_arg); - } - } - else if (CHECK_PARAM("-dst-rtp")) { - char *sep = strchr(next_arg, ':'); - dst_found = 1; - *real_time=1; - if (sep) { - *output_port = atoi(sep+1); - sep[0]=0; - *rtp_out = gf_strdup(next_arg); - sep[0]=':'; - } else { - *rtp_out = gf_strdup(next_arg); - } - } else if (CHECK_PARAM("-src")) { //second pass arguments - } else if (CHECK_PARAM("-prog")) { //second pass arguments - } - else { - error_msg = "unknown option"; - goto error; - } - } - if (*real_time) force_real_time = 1; - rate_found = 1; - - /*second pass: open sources*/ - for (i=1; i=0) gf_m2ts_mux_set_initial_pcr(muxer, (u64) pcr_init_val); - gf_m2ts_mux_set_pcr_max_interval(muxer, pcr_ms); - gf_m2ts_mux_enable_pcr_only_packets(muxer, enable_forced_pcr); - - - if (ts_out != NULL) { - if (segment_duration) { - strcpy(segment_prefix, ts_out); - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); - } else { - sprintf(segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index); - } - } else { - sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); - } - ts_out = gf_strdup(segment_name); - if (!segment_manifest) { - sprintf(segment_manifest_default, "%s.m3u8", segment_prefix); - segment_manifest = segment_manifest_default; - } - //write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index, 0, 0); - } - if (!strcmp(ts_out, "stdout") || !strcmp(ts_out, "-") ) { - ts_output_file = stdout; - is_stdout = GF_TRUE; - } else { - ts_output_file = gf_fopen(ts_out, "wb"); - is_stdout = GF_FALSE; - } - if (!ts_output_file) { - fprintf(stderr, "Error opening %s\n", ts_out); - goto exit; - } - } - if (udp_out != NULL) { - ts_output_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); - if (gf_sk_is_multicast_address((char *)udp_out)) { - e = gf_sk_setup_multicast(ts_output_udp_sk, (char *)udp_out, output_port, ttl, 0, (char *) ip_ifce); - } else { - e = gf_sk_bind(ts_output_udp_sk, ip_ifce, output_port, (char *)udp_out, output_port, GF_SOCK_REUSE_PORT); - } - if (e) { - fprintf(stderr, "Error initializing UDP socket: %s\n", gf_error_to_string(e)); - goto exit; - } - } -#ifndef GPAC_DISABLE_STREAMING - if (rtp_out != NULL) { - ts_output_rtp = gf_rtp_new(); - gf_rtp_set_ports(ts_output_rtp, output_port); - memset(&tr, 0, sizeof(GF_RTSPTransport)); - tr.IsUnicast = gf_sk_is_multicast_address((char *)rtp_out) ? 0 : 1; - tr.Profile="RTP/AVP"; - tr.destination = (char *)rtp_out; - tr.source = "0.0.0.0"; - tr.IsRecord = 0; - tr.Append = 0; - tr.SSRC = rand(); - tr.port_first = output_port; - tr.port_last = output_port+1; - if (tr.IsUnicast) { - tr.client_port_first = output_port; - tr.client_port_last = output_port+1; - } else { - tr.source = (char *)rtp_out; - tr.TTL = ttl; - } - e = gf_rtp_setup_transport(ts_output_rtp, &tr, (char *)ts_out); - if (e != GF_OK) { - fprintf(stderr, "Cannot setup RTP transport info : %s\n", gf_error_to_string(e)); - goto exit; - } - e = gf_rtp_initialize(ts_output_rtp, 0, 1, 1500, 0, 0, (char *) ip_ifce); - if (e != GF_OK) { - fprintf(stderr, "Cannot initialize RTP sockets : %s\n", gf_error_to_string(e)); - goto exit; - } - memset(&hdr, 0, sizeof(GF_RTPHeader)); - hdr.Version = 2; - hdr.PayloadType = 33; /*MP2T*/ - hdr.SSRC = tr.SSRC; - hdr.Marker = 0; - } -#endif /*GPAC_DISABLE_STREAMING*/ - - /************************************/ - /* create streaming audio input */ - /************************************/ - if (audio_input_ip) - switch(audio_input_type) { - case GF_MP42TS_UDP: - audio_input_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); - if (gf_sk_is_multicast_address((char *)audio_input_ip)) { - e = gf_sk_setup_multicast(audio_input_udp_sk, (char *)audio_input_ip, audio_input_port, 32, 0, NULL); - } else { - e = gf_sk_bind(audio_input_udp_sk, NULL, audio_input_port, (char *)audio_input_ip, audio_input_port, GF_SOCK_REUSE_PORT); - } - if (e) { - fprintf(stderr, "Error initializing UDP socket for %s:%d : %s\n", audio_input_ip, audio_input_port, gf_error_to_string(e)); - goto exit; - } - gf_sk_set_buffer_size(audio_input_udp_sk, 0, GF_M2TS_UDP_BUFFER_SIZE); - gf_sk_set_block_mode(audio_input_udp_sk, 0); - - /*allocate data buffer*/ - audio_input_buffer = (char*)gf_malloc(audio_input_buffer_length); - assert(audio_input_buffer); - break; - case GF_MP42TS_RTP: - /*TODO: not implemented*/ - assert(0); - break; -#ifndef GPAC_DISABLE_PLAYER - case GF_MP42TS_HTTP: - audio_prog = (void*)&sources[nb_sources-1]; - aac_download_file(aac_reader, audio_input_ip); - break; -#endif - case GF_MP42TS_FILE: - assert(0); /*audio live input is restricted to realtime/streaming*/ - break; - default: - assert(0); - } - - if (!nb_sources) { - fprintf(stderr, "No program to mux, quitting.\n"); - } - - for (i=0; iiod = sources[i].iod; - if (sources[i].od_updates) { - program->loop_descriptors = sources[i].od_updates; - sources[i].od_updates = NULL; - } - } else { - program = gf_m2ts_mux_program_find(muxer, sources[i].ID); - } - if (!program) continue; - - for (j=0; jstart_pes_at_rap = 1; - } - - cur_pid += sources[i].nb_streams; - while (cur_pid % 10) - cur_pid ++; - - if (sources[i].program_name[0] || sources[i].provider_name[0] ) gf_m2ts_mux_program_set_name(program, sources[i].program_name, sources[i].provider_name); - } - muxer->flush_pes_at_rap = (split_rap == 2) ? GF_TRUE : GF_FALSE; - - if (sdt_refresh_rate) { - gf_m2ts_mux_enable_sdt(muxer, sdt_refresh_rate); - } - gf_m2ts_mux_update_config(muxer, 1); - - if (nb_pck_pack>1) { - ts_pack_buffer = gf_malloc(sizeof(char) * 188 * nb_pck_pack); - } - - /*****************/ - /* main loop */ - /*****************/ - last_print_time = gf_sys_clock(); - while (run) { - u32 status; - - /*check for some audio input from the network*/ - if (audio_input_ip) { - u32 read; - switch (audio_input_type) { - case GF_MP42TS_UDP: - case GF_MP42TS_RTP: - /*e =*/ - gf_sk_receive(audio_input_udp_sk, audio_input_buffer, audio_input_buffer_length, 0, &read); - if (read) { - SampleCallBack((void*)&sources[nb_sources-1], AUDIO_DATA_ESID, audio_input_buffer, read, gf_m2ts_get_sys_clock(muxer)); - } - break; -#ifndef GPAC_DISABLE_PLAYER - case GF_MP42TS_HTTP: - /*nothing to do: AAC_OnLiveData is called automatically*/ - /*check we're still alive*/ - if (gf_dm_is_thread_dead(aac_reader->dnload)) { - GF_ESD *esd; - aac_download_file(aac_reader, audio_input_ip); - esd = AAC_GetESD(aac_reader); - if (!esd) - break; - assert(esd->slConfig->timestampResolution); /*if we don't have this value we won't be able to adjust the timestamps within the MPEG2-TS*/ - if (esd->slConfig->timestampResolution) - audio_discontinuity_offset = gf_m2ts_get_sys_clock(muxer) * (u64)esd->slConfig->timestampResolution / 1000; - gf_odf_desc_del((GF_Descriptor *)esd); - } - break; -#endif - default: - assert(0); - } - } - - /*flush all packets*/ - nb_pck_in_pack=0; - while ((ts_pck = gf_m2ts_mux_process(muxer, &status, &usec_till_next)) != NULL) { - - if (ts_pack_buffer ) { - memcpy(ts_pack_buffer + 188 * nb_pck_in_pack, ts_pck, 188); - nb_pck_in_pack++; - - if (nb_pck_in_pack < nb_pck_pack) - continue; - - ts_pck = (const char *) ts_pack_buffer; - } else { - nb_pck_in_pack = 1; - } - -call_flush: - if (ts_output_file != NULL) { - gf_fwrite(ts_pck, 1, 188 * nb_pck_in_pack, ts_output_file); - if (segment_duration && (muxer->time.sec > prev_seg_time.sec + segment_duration)) { - prev_seg_time = muxer->time; - gf_fclose(ts_output_file); - segment_index++; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); - } else { - sprintf(segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index); - } - } else { - sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); - } - ts_output_file = gf_fopen(segment_name, "wb"); - if (!ts_output_file) { - fprintf(stderr, "Error opening %s\n", segment_name); - goto exit; - } - /* delete the oldest segment */ - if (segment_number && ((s32) (segment_index - segment_number - 1) >= 0)) { - char old_segment_name[GF_MAX_PATH]; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(old_segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); - } else { - sprintf(old_segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); - } - } else { - sprintf(old_segment_name, "%s_%d.ts", segment_prefix, segment_index - segment_number - 1); - } - gf_delete_file(old_segment_name); - } - write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, -// (segment_index >= segment_number/2 ? segment_index - segment_number/2 : 0), segment_index >1 ? segment_index-1 : 0, 0); - ( (segment_index > segment_number ) ? segment_index - segment_number : 0), segment_index >1 ? segment_index-1 : 0, 0); - } - } - - if (ts_output_udp_sk != NULL) { - e = gf_sk_send(ts_output_udp_sk, (char*)ts_pck, 188 * nb_pck_in_pack); - if (e) { - fprintf(stderr, "Error %s sending UDP packet\n", gf_error_to_string(e)); - } - } -#ifndef GPAC_DISABLE_STREAMING - if (ts_output_rtp != NULL) { - u32 ts; - 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_output_rtp, &hdr, (char*)ts_pck, 188 * nb_pck_in_pack, 0); - if (e) { - fprintf(stderr, "Error %s sending RTP packet\n", gf_error_to_string(e)); - } - } -#endif - - nb_pck_in_pack = 0; - - if (status>=GF_M2TS_STATE_PADDING) { - break; - } - } - if (nb_pck_in_pack) { - ts_pck = (const char *) ts_pack_buffer; - goto call_flush; - } - - /*push video*/ - { - u32 now=gf_sys_clock(); - if (now/MP42TS_VIDEO_FREQ != last_video_time/MP42TS_VIDEO_FREQ) { - /*should use carrousel behaviour instead of being pushed manually*/ - if (video_buffer) - SampleCallBack((void*)&sources[nb_sources-1], VIDEO_DATA_ESID, video_buffer, video_buffer_size, gf_m2ts_get_sys_clock(muxer)+1000/*try buffering due to VLC msg*/); - last_video_time = now; - } - } - - if (real_time) { - /*refresh every MP42TS_PRINT_TIME_MS ms*/ - u32 now=gf_sys_clock(); - if (now > last_print_time + MP42TS_PRINT_TIME_MS) { - last_print_time = now; - fprintf(stderr, "M2TS: time % 6d - TS time % 6d - bitrate % 8d\r", gf_m2ts_get_sys_clock(muxer), gf_m2ts_get_ts_clock(muxer), muxer->average_birate_kbps); - - if (gf_prompt_has_input()) { - char c = gf_prompt_get_char(); - if (c=='q') break; - } - } - if (status == GF_M2TS_STATE_IDLE) { -#if 0 - /*wait till next packet is ready to be sent*/ - if (usec_till_next>1000) { - //fprintf(stderr, "%d usec till next packet\n", usec_till_next); - gf_sleep(usec_till_next / 1000); - } -#else - //we don't have enough precision on usec counting and we end up eating one core on most machines, so let's just sleep - //one second whenever we are idle - it's maybe too much but the muxer will catchup afterwards - gf_sleep(1); -#endif - } - } - - - if (run_time) { - if (gf_m2ts_get_ts_clock(muxer) > run_time) { - fprintf(stderr, "Stopping multiplex at %d ms (requested runtime %d ms)\n", gf_m2ts_get_ts_clock(muxer), run_time); - break; - } - } - if (status==GF_M2TS_STATE_EOS) { - break; - } - } - - { - u64 bits = muxer->tot_pck_sent*8*188; - u64 dur_ms = gf_m2ts_get_ts_clock(muxer); - if (!dur_ms) dur_ms = 1; - fprintf(stderr, "Done muxing - %.02f sec - %sbitrate %d kbps "LLD" packets written\n", ((Double) dur_ms)/1000.0,mux_rate ? "" : "average ", (u32) (bits/dur_ms), muxer->tot_pck_sent); - fprintf(stderr, " Padding: "LLD" packets (%g kbps) - "LLD" PES padded bytes (%g kbps)\n", muxer->tot_pad_sent, (Double) (muxer->tot_pad_sent*188*8.0/dur_ms) , muxer->tot_pes_pad_bytes, (Double) (muxer->tot_pes_pad_bytes*8.0/dur_ms) ); - } - -exit: - if (ts_pack_buffer) gf_free(ts_pack_buffer); - run = 0; - if (segment_duration) { - write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index - segment_number, segment_index, 1); - } - if (ts_output_file && !is_stdout) gf_fclose(ts_output_file); - if (ts_output_udp_sk) gf_sk_del(ts_output_udp_sk); -#ifndef GPAC_DISABLE_STREAMING - if (ts_output_rtp) gf_rtp_del(ts_output_rtp); -#endif - if (ts_out) gf_free(ts_out); - if (audio_input_udp_sk) gf_sk_del(audio_input_udp_sk); - if (audio_input_buffer) gf_free (audio_input_buffer); - if (video_buffer) gf_free(video_buffer); - if (udp_out) gf_free(udp_out); -#ifndef GPAC_DISABLE_STREAMING - if (rtp_out) gf_free(rtp_out); -#endif - if (muxer) gf_m2ts_mux_del(muxer); - - for (i=0; i.depend distclean: clean diff --git a/applications/mp4box/filedump.c b/applications/mp4box/filedump.c index c9499ba..a56f8b9 100644 --- a/applications/mp4box/filedump.c +++ b/applications/mp4box/filedump.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2012 + * Copyright (c) Telecom ParisTech 2000-2020 * All rights reserved * * This file is part of GPAC / mp4box application @@ -23,7 +23,7 @@ * */ -#include +#include "mp4box.h" #if defined(GPAC_DISABLE_ISOM) || defined(GPAC_DISABLE_ISOM_WRITE) @@ -43,8 +43,6 @@ #include #include #include -/*for asctime and gmtime*/ -#include /*ISO 639 languages*/ #include #include @@ -53,19 +51,17 @@ #include #endif #include -#include #include +/*for built-in box printing*/ +#include extern u32 swf_flags; extern Float swf_flatten_angle; extern GF_FileType get_file_type_by_ext(char *inName); +extern u32 fs_dump_flags; void scene_coding_log(void *cbk, GF_LOG_Level log_level, GF_LOG_Tool log_tool, const char *fmt, va_list vlist); -#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT) -GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample); -#endif - void PrintLanguages() { u32 i=0, count = gf_lang_get_count(); @@ -86,8 +82,7 @@ static const char *GetLanguage(char *lcode) GF_Err dump_isom_cover_art(GF_ISOFile *file, char *inName, Bool is_final_name) { - const char *tag; - char szName[1024]; + const u8 *tag; FILE *t; u32 tag_len; GF_Err e = gf_isom_apple_get_tag(file, GF_ISOM_ITUNE_COVER_ART, &tag, &tag_len); @@ -100,6 +95,7 @@ GF_Err dump_isom_cover_art(GF_ISOFile *file, char *inName, Bool is_final_name) } if (inName) { + char szName[1024]; if (is_final_name) { strcpy(szName, inName); } else { @@ -113,40 +109,15 @@ GF_Err dump_isom_cover_art(GF_ISOFile *file, char *inName, Bool is_final_name) } else { t = stdout; } - gf_fwrite(tag, tag_len & 0x7FFFFFFF, 1, t); + gf_fwrite(tag, tag_len & 0x7FFFFFFF, t); if (inName) gf_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 = gf_fopen(inName, "rb"); - gf_fseek(t, 0, SEEK_END); - tag_len = (u32) gf_ftell(t); - gf_fseek(t, 0, SEEK_SET); - tag = gf_malloc(sizeof(char) * tag_len); - tag_len = (u32) fread(tag, sizeof(char), tag_len, t); - gf_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); - gf_free(tag); - return e; -} - -#endif - #ifndef GPAC_DISABLE_SCENE_DUMP -GF_Err dump_isom_scene(char *file, char *inName, Bool is_final_name, GF_SceneDumpFormat dump_mode, Bool do_log) +GF_Err dump_isom_scene(char *file, char *inName, Bool is_final_name, GF_SceneDumpFormat dump_mode, Bool do_log, Bool no_odf_conv) { GF_Err e; GF_SceneManager *ctx; @@ -178,12 +149,16 @@ GF_Err dump_isom_scene(char *file, char *inName, Bool is_final_name, GF_SceneDum gf_sg_del(sg); return e; } + if (no_odf_conv) + gf_isom_disable_odf_conversion(load.isom, GF_TRUE); + } else if (ftype==GF_FILE_TYPE_LSR_SAF) { load.isom = gf_isom_open("saf_conv", GF_ISOM_WRITE_EDIT, NULL); #ifndef GPAC_DISABLE_MEDIA_IMPORT - if (load.isom) - e = import_file(load.isom, file, 0, 0, 0); - else + if (load.isom) { + GF_Fraction _frac = {0,0}; + e = import_file(load.isom, file, 0, _frac, 0, NULL, NULL, 0); + } else #else fprintf(stderr, "Warning: GPAC was compiled without Media Import support\n"); #endif @@ -234,7 +209,7 @@ GF_Err dump_isom_scene(char *file, char *inName, Bool is_final_name, GF_SceneDum #ifndef GPAC_DISABLE_SCENE_STATS -static void dump_stats(FILE *dump, GF_SceneStatistics *stats) +static void dump_stats(FILE *dump, const GF_SceneStatistics *stats) { u32 i; s32 created, count, draw_created, draw_count, deleted, draw_deleted; @@ -394,7 +369,7 @@ void dump_isom_scene_stats(char *file, char *inName, Bool is_final_name, u32 sta e = gf_sm_load_init(&load); if (!e) e = gf_sm_load_run(&load); gf_sm_load_done(&load); - if (e) goto exit; + if (e<0) goto exit; if (inName) { strcpy(szBuf, inName); @@ -413,8 +388,12 @@ void dump_isom_scene_stats(char *file, char *inName, Bool is_final_name, u32 sta fprintf(stderr, "Analysing Scene\n"); fprintf(dump, "\n"); - fprintf(dump, "\n"); - fprintf(dump, "\n", file, (stat_level==1) ? "full scene" : ((stat_level==2) ? "AccessUnit based" : "SceneGraph after each AU")); + fprintf(dump, "\n"); + + fprintf(dump, "\n", gf_file_basename(file), (stat_level==1) ? "full scene" : ((stat_level==2) ? "AccessUnit based" : "SceneGraph after each AU")); sm = gf_sm_stats_new(); @@ -456,9 +435,9 @@ void dump_isom_scene_stats(char *file, char *inName, Bool is_final_name, u32 sta if (e) goto exit; } if (stat_level==2) { - fprintf(dump, "\n", au->owner->ESID, LLD_CAST au->timing); + fprintf(dump, "\n", au->owner->ESID, au->timing); } else { - fprintf(dump, "\n", au->owner->ESID, LLD_CAST au->timing); + fprintf(dump, "\n", au->owner->ESID, au->timing); } /*dump stats*/ dump_stats(dump, gf_sm_stats_get(sm) ); @@ -548,60 +527,21 @@ static void PrintNodeSFField(u32 type, void *far_ptr) } #endif -void PrintNode(const char *name, u32 graph_type) +#ifndef GPAC_DISABLE_VRML +static void do_print_node(GF_Node *node, GF_SceneGraph *sg, const char *name, u32 graph_type, Bool is_nodefield, Bool do_cov) { -#ifdef GPAC_DISABLE_VRML - fprintf(stderr, "VRML/MPEG-4/X3D scene graph is disabled in this build of GPAC\n"); - return; -#else - const char *nname, *std_name; - char szField[1024]; - GF_Node *node; - GF_SceneGraph *sg; - u32 tag, nbF, i; + u32 nbF, i; GF_FieldInfo f; #ifndef GPAC_DISABLE_BIFS u8 qt, at; Fixed bmin, bmax; u32 nbBits; #endif /*GPAC_DISABLE_BIFS*/ - Bool is_nodefield = 0; - - char *sep = strchr(name, '.'); - if (sep) { - strcpy(szField, sep+1); - sep[0] = 0; - is_nodefield = 1; - } - - if (graph_type==1) { -#ifndef GPAC_DISABLE_X3D - tag = gf_node_x3d_type_by_class_name(name); - std_name = "X3D"; -#else - fprintf(stderr, "X3D node printing is not supported (X3D support disabled)\n"); - return; -#endif - } else { - tag = gf_node_mpeg4_type_by_class_name(name); - std_name = "MPEG4"; - } - if (!tag) { - fprintf(stderr, "Unknown %s node %s\n", std_name, name); - return; - } - sg = gf_sg_new(); - node = gf_node_new(sg, tag); - gf_node_register(node, NULL); - nname = gf_node_get_class_name(node); - if (!node) { - fprintf(stderr, "Node %s not supported in current built\n", nname); - return; - } nbF = gf_node_get_field_count(node); if (is_nodefield) { + char szField[1024]; u32 tfirst, tlast; if (gf_node_get_field_by_name(node, szField, &f) != GF_OK) { fprintf(stderr, "Field %s is not a member of node %s\n", szField, name); @@ -628,8 +568,29 @@ void PrintNode(const char *name, u32 graph_type) } return; } + if (do_cov) { + u32 ndt; + if (graph_type==0) { + u32 all; + gf_node_mpeg4_type_by_class_name(name); + gf_bifs_get_child_table(node); + all = gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL); + for (i=0; icount; i++) { - if (i) fprintf(stderr, " "); - gf_sg_vrml_mf_get_item(f.far_ptr, f.fieldType, &ptr, i); + for (j=0; jcount; j++) { + if (j) fprintf(stderr, " "); + gf_sg_vrml_mf_get_item(f.far_ptr, f.fieldType, &ptr, j); PrintNodeSFField(sftype, ptr); } fprintf(stderr, "]"); @@ -673,18 +634,72 @@ void PrintNode(const char *name, u32 graph_type) } #endif /*GPAC_DISABLE_BIFS*/ fprintf(stderr, "\n"); + + if (do_cov) { + gf_node_get_field_by_name(node, (char *) f.name, &f); + } } fprintf(stderr, "}\n\n"); +} +#endif + + +void PrintNode(const char *name, u32 graph_type) +{ +#ifdef GPAC_DISABLE_VRML + fprintf(stderr, "VRML/MPEG-4/X3D scene graph is disabled in this build of GPAC\n"); + return; +#else + const char *std_name; + GF_Node *node; + GF_SceneGraph *sg; + u32 tag; +#ifndef GPAC_DISABLE_BIFS +#endif /*GPAC_DISABLE_BIFS*/ + Bool is_nodefield = 0; + + char *sep = strchr(name, '.'); + if (sep) { + sep[0] = 0; + is_nodefield = 1; + } + + if (graph_type==1) { +#ifndef GPAC_DISABLE_X3D + tag = gf_node_x3d_type_by_class_name(name); + std_name = "X3D"; +#else + fprintf(stderr, "X3D node printing is not supported (X3D support disabled)\n"); + return; +#endif + } else { + tag = gf_node_mpeg4_type_by_class_name(name); + std_name = "MPEG4"; + } + if (!tag) { + fprintf(stderr, "Unknown %s node %s\n", std_name, name); + return; + } + + sg = gf_sg_new(); + node = gf_node_new(sg, tag); + gf_node_register(node, NULL); + name = gf_node_get_class_name(node); + if (!node) { + fprintf(stderr, "Node %s not supported in current built\n", name); + return; + } + do_print_node(node, sg, name, graph_type, is_nodefield, GF_FALSE); + gf_node_unregister(node, NULL); gf_sg_del(sg); #endif /*GPAC_DISABLE_VRML*/ } -void PrintBuiltInNodes(u32 graph_type) +void PrintBuiltInNodes(u32 graph_type, Bool dump_nodes) { #if !defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_X3D) && !defined(GPAC_DISABLE_SVG) - GF_Node *node; GF_SceneGraph *sg; u32 i, nb_in, nb_not_in, start_tag, end_tag; @@ -724,10 +739,14 @@ void PrintBuiltInNodes(u32 graph_type) fprintf(stderr, "Available MPEG-4 nodes in this build (encoding/decoding/dumping):\n"); } for (i=start_tag; i\n"); //index 0 is our internal unknown box handler for (i=1; i\n"); } @@ -766,9 +803,9 @@ void dump_isom_rtp(GF_ISOFile *file, char *inName, Bool is_final_name) u32 i, j, size; FILE *dump; const char *sdp; - char szBuf[1024]; if (inName) { + char szBuf[1024]; strcpy(szBuf, inName); if (!is_final_name) strcat(szBuf, "_rtp.xml"); dump = gf_fopen(szBuf, "wt"); @@ -791,9 +828,11 @@ void dump_isom_rtp(GF_ISOFile *file, char *inName, Bool is_final_name) gf_isom_sdp_track_get(file, i+1, &sdp, &size); fprintf(dump, "%s", sdp); +#ifndef GPAC_DISABLE_ISOM_HINTING for (j=0; j\n"); } fprintf(dump, "\n"); @@ -802,14 +841,23 @@ void dump_isom_rtp(GF_ISOFile *file, char *inName, Bool is_final_name) #endif -void dump_isom_timestamps(GF_ISOFile *file, char *inName, Bool is_final_name) +void dump_isom_timestamps(GF_ISOFile *file, char *inName, Bool is_final_name, u32 dump_mode) { u32 i, j, k, count; - Bool has_error; + Bool has_ctts_error, is_fragmented=GF_FALSE; FILE *dump; - char szBuf[1024]; + Bool skip_offset = ((dump_mode==2) || (dump_mode==4)) ? GF_TRUE : GF_FALSE; + Bool check_ts = ((dump_mode==3) || (dump_mode==4)) ? GF_TRUE : GF_FALSE; + struct _ts_info { + u64 dts; + s64 cts; + }; + struct _ts_info *timings = NULL; + u32 nb_timings=0, nb_timings_alloc = 0; + if (inName) { + char szBuf[1024]; strcpy(szBuf, inName); if (!is_final_name) strcat(szBuf, "_ts.txt"); dump = gf_fopen(szBuf, "wt"); @@ -820,20 +868,37 @@ void dump_isom_timestamps(GF_ISOFile *file, char *inName, Bool is_final_name) } else { dump = stdout; } + if (gf_isom_is_fragmented(file)) + is_fragmented = GF_TRUE; - has_error = 0; + has_ctts_error = GF_FALSE; for (i=0; iDTS; cts = dts + (s32) samp->CTS_Offset; - fprintf(dump, "Sample %d\tDTS "LLD"\tCTS "LLD"\t%d\t%d\t"LLD"\t%d\t%d\t%d\t%d\t%d\t%d\t%d", j+1, LLD_CAST dts, LLD_CAST cts, samp->dataLength, samp->IsRAP, offset, isLeading, dependsOn, dependedOn, redundant, is_rap, has_roll, roll_distance); - if (ctsdataLength, samp->IsRAP); + + if (!skip_offset) + fprintf(dump, "\t"LLU, offset); + + fprintf(dump, "\t%d\t%d\t%d\t%d\t%d\t%d\t%d", isLeading, dependsOn, dependedOn, redundant, is_rap, roll_type, roll_distance); + + if (cts< (s64) dts) { if (has_cts_offset==2) { - if (cts_dts_shift && (cts+cts_dts_shiftDTS; - acts = adts + (s32) samp->CTS_Offset; - - if (adts==dts) { + if (timings[k].dts==dts) { fprintf(dump, " #SAME DTS USED!!!"); - has_error = 1; + has_ctts_error = 1; } - if (acts==cts) { + if (timings[k].cts==cts) { fprintf(dump, " #SAME CTS USED!!! "); - has_error = 1; + has_ctts_error = 1; } - - gf_isom_sample_del(&samp); } + timings[nb_timings].dts = dts; + timings[nb_timings].cts = cts; + nb_timings++; } + gf_isom_sample_del(&samp); + + if (is_fragmented) { + fprintf(dump, "\t%d", gf_isom_sample_is_fragment_start(file, i+1, j+1, NULL) ); + } fprintf(dump, "\n"); - gf_set_progress("Analysing Track Timing", j+1, count); + gf_set_progress("Dumping track timing", j+1, count); } fprintf(dump, "\n\n"); - gf_set_progress("Analysing Track Timing", count, count); + gf_set_progress("Dumping track timing", count, count); } + if (timings) gf_free(timings); + if (inName) gf_fclose(dump); - if (has_error) fprintf(stderr, "\tFile has CTTS table errors\n"); + if (has_ctts_error) fprintf(stderr, "\tFile has CTTS table errors\n"); } -static u32 read_nal_size_hdr(char *ptr, u32 nalh_size) +static u32 read_nal_size_hdr(u8 *ptr, u32 nalh_size) { u32 nal_size=0; u32 v = nalh_size; @@ -909,340 +980,31 @@ static u32 read_nal_size_hdr(char *ptr, u32 nalh_size) } #ifndef GPAC_DISABLE_AV_PARSERS - -static void dump_sei(FILE *dump, u8 *ptr, u32 ptr_size, Bool is_hevc) -{ - u32 sei_idx=0; - u32 i=2; - fprintf(dump, " SEI=\""); - while (i+1 < ptr_size) { - u32 sei_type = 0; - u32 sei_size = 0; - while (ptr[i] == 0xFF) { - sei_type+= 255; - i++; - } - sei_type += ptr[i]; - i++; - while (ptr[i] == 0xFF) { - sei_size += 255; - i++; - } - sei_size += ptr[i]; - i++; - i+=sei_size; - - if (sei_idx) fprintf(dump, ","); - fprintf(dump, "(type=%u, size=%u)", sei_type, sei_size); - sei_idx++; - if (ptr[i]== 0x80) { - i=ptr_size; - break; - } - } - if (i!=ptr_size) fprintf(dump, "(garbage at end)"); - fprintf(dump, "\""); -} - -static void dump_nalu(FILE *dump, char *ptr, u32 ptr_size, Bool is_svc, HEVCState *hevc, AVCState *avc, u32 nalh_size) -{ - s32 res; - u8 type; - u8 dependency_id, quality_id, temporal_id; - u8 track_ref_index; - s8 sample_offset; - u32 data_offset, idx, data_size; - GF_BitStream *bs; - - if (!ptr_size) { - fprintf(dump, "error=\"invalid nal size 0\""); - return; - } - if (hevc) { -#ifndef GPAC_DISABLE_HEVC - res = gf_media_hevc_parse_nalu(ptr, ptr_size, hevc, &type, &temporal_id, &quality_id); - - fprintf(dump, "code=\"%d\" type=\"", type); - switch (type) { - case GF_HEVC_NALU_SLICE_TRAIL_N: - fputs("TRAIL_N slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_TRAIL_R: - fputs("TRAIL_R slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_TSA_N: - fputs("TSA_N slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_TSA_R: - fputs("TSA_R slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_STSA_N: - fputs("STSA_N slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_STSA_R: - fputs("STSA_R slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_RADL_N: - fputs("RADL_N slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_RADL_R: - fputs("RADL_R slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_RASL_N: - fputs("RASL_N slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_RASL_R: - fputs("RASL_R slice segment", dump); - break; - case GF_HEVC_NALU_SLICE_BLA_W_LP: - fputs("Broken link access slice (W LP)", dump); - break; - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - fputs("Broken link access slice (W DLP)", dump); - break; - case GF_HEVC_NALU_SLICE_BLA_N_LP: - fputs("Broken link access slice (N LP)", dump); - break; - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - fputs("IDR slice (W DLP)", dump); - break; - case GF_HEVC_NALU_SLICE_IDR_N_LP: - fputs("IDR slice (N LP)", dump); - break; - case GF_HEVC_NALU_SLICE_CRA: - fputs("CRA slice", dump); - break; - - case GF_HEVC_NALU_VID_PARAM: - gf_media_hevc_read_vps(ptr, ptr_size, hevc); - fputs("Video Parameter Set", dump); - break; - case GF_HEVC_NALU_SEQ_PARAM: - gf_media_hevc_read_sps(ptr, ptr_size, hevc); - fputs("Sequence Parameter Set", dump); - break; - case GF_HEVC_NALU_PIC_PARAM: - gf_media_hevc_read_pps(ptr, ptr_size, hevc); - fputs("Picture Parameter Set", dump); - break; - case GF_HEVC_NALU_ACCESS_UNIT: - fputs("AU Delimiter", dump); - fprintf(dump, "\" primary_pic_type=\"%d", ptr[2] >> 5); - break; - case GF_HEVC_NALU_END_OF_SEQ: - fputs("End of Sequence", dump); - break; - case GF_HEVC_NALU_END_OF_STREAM: - fputs("End of Stream", dump); - break; - case GF_HEVC_NALU_FILLER_DATA: - fputs("Filler Data", dump); - break; - case GF_HEVC_NALU_SEI_PREFIX: - fputs("SEI Prefix", dump); - break; - case GF_HEVC_NALU_SEI_SUFFIX: - fputs("SEI Suffix", dump); - break; - case 48: - fputs("HEVCAggregator", dump); - break; - case 49: - fputs("HEVCExtractor", dump); - track_ref_index = (u8) ptr[3]; - sample_offset = (s8) ptr[4]; - data_offset = read_nal_size_hdr(&ptr[5], nalh_size); - data_size = read_nal_size_hdr(&ptr[5+nalh_size], nalh_size); - fprintf(dump, "\" track_ref_index=\"%d\" sample_offset=\"%d\" data_offset=\"%d\" data_size=\"%d", track_ref_index, sample_offset, data_offset, data_size); - break; - default: - fprintf(dump, "UNKNOWN (parsing return %d)", res); - break; - } - fputs("\"", dump); - - if ((type==GF_HEVC_NALU_SEI_PREFIX) || (type==GF_HEVC_NALU_SEI_SUFFIX)) { - dump_sei(dump, (u8 *) ptr, ptr_size, hevc ? GF_TRUE : GF_FALSE); - } - - if (types_info.slice_type==GF_HEVC_SLICE_TYPE_I) ? "I" : (hevc->s_info.slice_type==GF_HEVC_SLICE_TYPE_P) ? "P" : (hevc->s_info.slice_type==GF_HEVC_SLICE_TYPE_B) ? "B" : "Unknown", hevc->s_info.poc); - fprintf(dump, " first_slice_in_pic=\"%d\"", hevc->s_info.first_slice_segment_in_pic_flag); - fprintf(dump, " dependent_slice_segment=\"%d\"", hevc->s_info.dependent_slice_segment_flag); - } - - fprintf(dump, " layer_id=\"%d\" temporal_id=\"%d\"", quality_id, temporal_id); - -#endif //GPAC_DISABLE_HEVC - return; - } - - bs = gf_bs_new(ptr, ptr_size, GF_BITSTREAM_READ); - type = gf_bs_read_u8(bs) & 0x1F; - fprintf(dump, "code=\"%d\" type=\"", type); - res = 0; - switch (type) { - case GF_AVC_NALU_NON_IDR_SLICE: - res = gf_media_avc_parse_nalu(bs, ptr[0], avc); - fputs("Non IDR slice", dump); - - if (res>=0) - fprintf(dump, "\" poc=\"%d", avc->s_info.poc); - break; - case GF_AVC_NALU_DP_A_SLICE: - fputs("DP Type A slice", dump); - break; - case GF_AVC_NALU_DP_B_SLICE: - fputs("DP Type B slice", dump); - break; - case GF_AVC_NALU_DP_C_SLICE: - fputs("DP Type C slice", dump); - break; - case GF_AVC_NALU_IDR_SLICE: - res = gf_media_avc_parse_nalu(bs, ptr[0], avc); - fputs("IDR slice", dump); - if (res>=0) - fprintf(dump, "\" poc=\"%d", avc->s_info.poc); - break; - case GF_AVC_NALU_SEI: - fputs("SEI Message", dump); - break; - case GF_AVC_NALU_SEQ_PARAM: - fputs("SequenceParameterSet", dump); - idx = gf_media_avc_read_sps(ptr, ptr_size, avc, 0, NULL); - assert (idx >= 0); - fprintf(dump, "\" sps_id=\"%d", idx); - fprintf(dump, "\" frame_mbs_only_flag=\"%d", avc->sps->frame_mbs_only_flag); - fprintf(dump, "\" mb_adaptive_frame_field_flag=\"%d", avc->sps->mb_adaptive_frame_field_flag); - fprintf(dump, "\" vui_parameters_present_flag=\"%d", avc->sps->vui_parameters_present_flag); - fprintf(dump, "\" max_num_ref_frames=\"%d", avc->sps->max_num_ref_frames); - fprintf(dump, "\" gaps_in_frame_num_value_allowed_flag=\"%d", avc->sps->gaps_in_frame_num_value_allowed_flag); - fprintf(dump, "\" chroma_format_idc=\"%d", avc->sps->chroma_format); - fprintf(dump, "\" bit_depth_luma_minus8=\"%d", avc->sps->luma_bit_depth_m8); - fprintf(dump, "\" bit_depth_chroma_minus8=\"%d", avc->sps->chroma_bit_depth_m8); - fprintf(dump, "\" width=\"%d", avc->sps->width); - fprintf(dump, "\" height=\"%d", avc->sps->height); - fprintf(dump, "\" crop_top=\"%d", avc->sps->crop.top); - fprintf(dump, "\" crop_left=\"%d", avc->sps->crop.left); - fprintf(dump, "\" crop_bottom=\"%d", avc->sps->crop.bottom); - fprintf(dump, "\" crop_right=\"%d", avc->sps->crop.right); - if (avc->sps->vui_parameters_present_flag) { - fprintf(dump, "\" vui_video_full_range_flag=\"%d", avc->sps->vui.video_full_range_flag); - fprintf(dump, "\" vui_video_signal_type_present_flag=\"%d", avc->sps->vui.video_signal_type_present_flag); - fprintf(dump, "\" vui_aspect_ratio_info_present_flag=\"%d", avc->sps->vui.aspect_ratio_info_present_flag); - fprintf(dump, "\" vui_aspect_ratio_num=\"%d", avc->sps->vui.par_num); - fprintf(dump, "\" vui_aspect_ratio_den=\"%d", avc->sps->vui.par_den); - fprintf(dump, "\" vui_overscan_info_present_flag=\"%d", avc->sps->vui.overscan_info_present_flag); - fprintf(dump, "\" vui_colour_description_present_flag=\"%d", avc->sps->vui.colour_description_present_flag); - fprintf(dump, "\" vui_colour_primaries=\"%d", avc->sps->vui.colour_primaries); - fprintf(dump, "\" vui_transfer_characteristics=\"%d", avc->sps->vui.transfer_characteristics); - fprintf(dump, "\" vui_matrix_coefficients=\"%d", avc->sps->vui.matrix_coefficients); - fprintf(dump, "\" vui_low_delay_hrd_flag=\"%d", avc->sps->vui.low_delay_hrd_flag); - } - break; - case GF_AVC_NALU_PIC_PARAM: - fputs("PictureParameterSet", dump); - idx = gf_media_avc_read_pps(ptr, ptr_size, avc); - assert (idx >= 0); - fprintf(dump, "\" pps_id=\"%d\" sps_id=\"%d", idx, avc->pps[idx].sps_id); - fprintf(dump, "\" entropy_coding_mode_flag=\"%d", avc->pps[idx].entropy_coding_mode_flag); - - break; - case GF_AVC_NALU_ACCESS_UNIT: - fputs("AccessUnit delimiter", dump); - fprintf(dump, "\" primary_pic_type=\"%d", gf_bs_read_u8(bs) >> 5); - break; - case GF_AVC_NALU_END_OF_SEQ: - fputs("EndOfSequence", dump); - break; - case GF_AVC_NALU_END_OF_STREAM: - fputs("EndOfStream", dump); - break; - case GF_AVC_NALU_FILLER_DATA: - fputs("Filler data", dump); - break; - case GF_AVC_NALU_SEQ_PARAM_EXT: - fputs("SequenceParameterSetExtension", dump); - break; - case GF_AVC_NALU_SVC_PREFIX_NALU: - fputs("SVCPrefix", dump); - break; - case GF_AVC_NALU_SVC_SUBSEQ_PARAM: - fputs("SVCSubsequenceParameterSet", dump); - idx = gf_media_avc_read_sps(ptr, ptr_size, avc, 1, NULL); - assert (idx >= 0); - fprintf(dump, "\" sps_id=\"%d", idx - GF_SVC_SSPS_ID_SHIFT); - break; - case GF_AVC_NALU_SLICE_AUX: - fputs("Auxiliary Slice", dump); - break; - - case GF_AVC_NALU_SVC_SLICE: - gf_media_avc_parse_nalu(bs, ptr[0], avc); - fputs(is_svc ? "SVCSlice" : "CodedSliceExtension", dump); - dependency_id = (ptr[2] & 0x70) >> 4; - quality_id = (ptr[2] & 0x0F); - temporal_id = (ptr[3] & 0xE0) >> 5; - fprintf(dump, "\" dependency_id=\"%d\" quality_id=\"%d\" temporal_id=\"%d", dependency_id, quality_id, temporal_id); - fprintf(dump, "\" poc=\"%d", avc->s_info.poc); - break; - case 30: - fputs("SVCAggregator", dump); - break; - case 31: - fputs("SVCExtractor", dump); - track_ref_index = (u8) ptr[4]; - sample_offset = (s8) ptr[5]; - data_offset = read_nal_size_hdr(&ptr[6], nalh_size); - data_size = read_nal_size_hdr(&ptr[6+nalh_size], nalh_size); - fprintf(dump, "\" track_ref_index=\"%d\" sample_offset=\"%d\" data_offset=\"%d\" data_size=\"%d\"", track_ref_index, sample_offset, data_offset, data_size); - break; - - default: - fputs("UNKNOWN", dump); - break; - } - fputs("\"", dump); - - if (type==GF_AVC_NALU_SEI) { - dump_sei(dump, (u8 *) ptr, ptr_size, GF_FALSE); - } - - if (res<0) - fprintf(dump, " status=\"error decoding slice\""); - - if (bs) gf_bs_del(bs); -} +void gf_inspect_dump_nalu(FILE *dump, u8 *ptr, u32 ptr_size, Bool is_svc, HEVCState *hevc, AVCState *avc, u32 nalh_size, Bool dump_crc, Bool is_encrypted); #endif -void dump_isom_nal_ex(GF_ISOFile *file, u32 trackID, FILE *dump) + +static void dump_isom_nal_ex(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, u32 dump_flags) { - u32 i, count, track, nalh_size, timescale, cur_extract_mode; + u32 i, j, count, nb_descs, track, nalh_size, timescale, cur_extract_mode; s32 countRef; - Bool is_adobe_protection = GF_FALSE; -#ifndef GPAC_DISABLE_AV_PARSERS + Bool is_adobe_protected = GF_FALSE; + Bool is_cenc_protected = GF_FALSE; Bool is_hevc = GF_FALSE; +#ifndef GPAC_DISABLE_AV_PARSERS AVCState avc; HEVCState hevc; +#endif GF_AVCConfig *avccfg, *svccfg; GF_HEVCConfig *hevccfg, *lhvccfg; GF_AVCConfigSlot *slc; -#endif + Bool has_svcc = GF_FALSE; track = gf_isom_get_track_by_id(file, trackID); #ifndef GPAC_DISABLE_AV_PARSERS memset(&avc, 0, sizeof(AVCState)); - avccfg = gf_isom_avc_config_get(file, track, 1); - svccfg = gf_isom_svc_config_get(file, track, 1); memset(&hevc, 0, sizeof(HEVCState)); - hevccfg = gf_isom_hevc_config_get(file, track, 1); - lhvccfg = gf_isom_lhvc_config_get(file, track, 1); - if (!avccfg && !svccfg && !hevccfg && !lhvccfg) { - fprintf(stderr, "Error: Track #%d is not NALU-based!\n", trackID); - return; - } #endif count = gf_isom_get_sample_count(file, track); @@ -1251,84 +1013,132 @@ void dump_isom_nal_ex(GF_ISOFile *file, u32 trackID, FILE *dump) cur_extract_mode = gf_isom_get_nalu_extract_mode(file, track); + nb_descs = gf_isom_get_sample_description_count(file, track); + if (!nb_descs) { + fprintf(stderr, "Error: Track #%d has no sample description so is likely not NALU-based!\n", trackID); + return; + } + fprintf(dump, "\n", trackID, count, timescale); #ifndef GPAC_DISABLE_AV_PARSERS - //for tile tracks the hvcC is stored in the 'tbas' track - if (!hevccfg && gf_isom_get_reference_count(file, track, GF_4CC('t','b','a','s'))) { - u32 tk = 0; - gf_isom_get_reference(file, track, GF_4CC('t','b','a','s'), 1, &tk); - hevccfg = gf_isom_hevc_config_get(file, tk, 1); - } - fprintf(dump, " \n"); -#define DUMP_ARRAY(arr, name, loc)\ +#define DUMP_ARRAY(arr, name, loc, _is_svc)\ + if (arr) {\ + fprintf(dump, " <%sArray location=\"%s\">\n", name, loc);\ + for (i=0; isize);\ + gf_inspect_dump_nalu(dump, (u8 *) slc->data, slc->size, _is_svc, is_hevc ? &hevc : NULL, &avc, nalh_size, (dump_flags&1) ? GF_TRUE : GF_FALSE, GF_FALSE);\ + fprintf(dump, "/>\n");\ + }\ + fprintf(dump, " \n", name);\ + }\ + +#else + +#define DUMP_ARRAY(arr, name, loc, _is_svc)\ if (arr) {\ fprintf(dump, " <%sArray location=\"%s\">\n", name, loc);\ for (i=0; isize);\ - dump_nalu(dump, slc->data, slc->size, svccfg ? 1 : 0, is_hevc ? &hevc : NULL, &avc, nalh_size);\ + fprintf(dump, " size);\ fprintf(dump, "/>\n");\ }\ fprintf(dump, " \n", name);\ }\ - + +#endif + nalh_size = 0; - if (avccfg) { - nalh_size = avccfg->nal_unit_size; - - DUMP_ARRAY(avccfg->sequenceParameterSets, "AVCSPS", "avcC") - DUMP_ARRAY(avccfg->pictureParameterSets, "AVCPPS", "avcC") - DUMP_ARRAY(avccfg->sequenceParameterSetExtensions, "AVCSPSEx", "avcC") - } - if (svccfg) { - if (!nalh_size) nalh_size = svccfg->nal_unit_size; - DUMP_ARRAY(svccfg->sequenceParameterSets, "SVCSPS", "svcC") - DUMP_ARRAY(svccfg->pictureParameterSets, "SVCPPS", "svcC") - } - if (hevccfg) { -#ifndef GPAC_DISABLE_HEVC - u32 idx; - nalh_size = hevccfg->nal_unit_size; - is_hevc = 1; - for (idx=0; idxparam_array); idx++) { - GF_HEVCParamArray *ar = gf_list_get(hevccfg->param_array, idx); - if (ar->type==GF_HEVC_NALU_SEQ_PARAM) { - DUMP_ARRAY(ar->nalus, "HEVCSPS", "hvcC") - } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) { - DUMP_ARRAY(ar->nalus, "HEVCPPS", "hvcC") - } else if (ar->type==GF_HEVC_NALU_VID_PARAM) { - DUMP_ARRAY(ar->nalus, "HEVCVPS", "hvcC") - } else { - DUMP_ARRAY(ar->nalus, "HEVCUnknownPS", "hvcC") + for (j=0; j\n"); + + if (!avccfg && !svccfg && !hevccfg && !lhvccfg) { + fprintf(stderr, "Error: Track #%d is not NALU-based!\n", trackID); + return; + } + + if (avccfg) { + nalh_size = avccfg->nal_unit_size; + + DUMP_ARRAY(avccfg->sequenceParameterSets, "AVCSPS", "avcC", is_svc); + DUMP_ARRAY(avccfg->pictureParameterSets, "AVCPPS", "avcC", is_svc) + DUMP_ARRAY(avccfg->sequenceParameterSetExtensions, "AVCSPSEx", "avcC", is_svc) + } + if (is_svc) { + if (!nalh_size) nalh_size = svccfg->nal_unit_size; + DUMP_ARRAY(svccfg->sequenceParameterSets, "SVCSPS", "svcC", is_svc) + DUMP_ARRAY(svccfg->pictureParameterSets, "SVCPPS", "svcC", is_svc) + } + if (mvccfg) { + if (!nalh_size) nalh_size = mvccfg->nal_unit_size; + DUMP_ARRAY(mvccfg->sequenceParameterSets, "SVCSPS", "mvcC", is_svc) + DUMP_ARRAY(mvccfg->pictureParameterSets, "SVCPPS", "mvcC", is_svc) + } + if (hevccfg) { + u32 idx; + nalh_size = hevccfg->nal_unit_size; + is_hevc = 1; + for (idx=0; idxparam_array); idx++) { + GF_HEVCParamArray *ar = gf_list_get(hevccfg->param_array, idx); + if (ar->type==GF_HEVC_NALU_SEQ_PARAM) { + DUMP_ARRAY(ar->nalus, "HEVCSPS", "hvcC", 0) + } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) { + DUMP_ARRAY(ar->nalus, "HEVCPPS", "hvcC", 0) + } else if (ar->type==GF_HEVC_NALU_VID_PARAM) { + DUMP_ARRAY(ar->nalus, "HEVCVPS", "hvcC", 0) + } else { + DUMP_ARRAY(ar->nalus, "HEVCUnknownPS", "hvcC", 0) + } } } -#endif - } - if (lhvccfg) { -#ifndef GPAC_DISABLE_HEVC - u32 idx; - nalh_size = lhvccfg->nal_unit_size; - is_hevc = 1; - for (idx=0; idxparam_array); idx++) { - GF_HEVCParamArray *ar = gf_list_get(lhvccfg->param_array, idx); - if (ar->type==GF_HEVC_NALU_SEQ_PARAM) { - DUMP_ARRAY(ar->nalus, "HEVCSPS", "lhcC") - } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) { - DUMP_ARRAY(ar->nalus, "HEVCPPS", "lhcC") - } else if (ar->type==GF_HEVC_NALU_VID_PARAM) { - DUMP_ARRAY(ar->nalus, "HEVCVPS", "lhcC") - } else { - DUMP_ARRAY(ar->nalus, "HEVCUnknownPS", "lhcC") + if (lhvccfg) { + u32 idx; + nalh_size = lhvccfg->nal_unit_size; + is_hevc = 1; + for (idx=0; idxparam_array); idx++) { + GF_HEVCParamArray *ar = gf_list_get(lhvccfg->param_array, idx); + if (ar->type==GF_HEVC_NALU_SEQ_PARAM) { + DUMP_ARRAY(ar->nalus, "HEVCSPS", "lhcC", 0) + } else if (ar->type==GF_HEVC_NALU_PIC_PARAM) { + DUMP_ARRAY(ar->nalus, "HEVCPPS", "lhcC", 0) + } else if (ar->type==GF_HEVC_NALU_VID_PARAM) { + DUMP_ARRAY(ar->nalus, "HEVCVPS", "lhcC", 0) + } else { + DUMP_ARRAY(ar->nalus, "HEVCUnknownPS", "lhcC", 0) + } } } -#endif - } + fprintf(dump, " \n"); -#endif - fprintf(dump, " \n"); + if (avccfg) gf_odf_avc_cfg_del(avccfg); + if (svccfg) { + gf_odf_avc_cfg_del(svccfg); + has_svcc = GF_TRUE; + } + if (hevccfg) gf_odf_hevc_cfg_del(hevccfg); + if (lhvccfg) gf_odf_hevc_cfg_del(lhvccfg); + } /*fixme: for dumping encrypted track: we don't have neither avccfg nor svccfg*/ if (!nalh_size) nalh_size = 4; @@ -1337,7 +1147,7 @@ void dump_isom_nal_ex(GF_ISOFile *file, u32 trackID, FILE *dump) countRef = gf_isom_get_reference_count(file, track, GF_ISOM_REF_SCAL); if (countRef > 0) { - u32 refTrackID; + GF_ISOTrackID refTrackID; fprintf(dump, " \n"); for (i = 1; i <= (u32) countRef; i++) { @@ -1350,26 +1160,38 @@ void dump_isom_nal_ex(GF_ISOFile *file, u32 trackID, FILE *dump) fprintf(dump, " \n"); gf_isom_set_nalu_extract_mode(file, track, GF_ISOM_NALU_EXTRACT_INSPECT); - is_adobe_protection = gf_isom_is_adobe_protection_media(file, track, 1); + is_adobe_protected = gf_isom_is_adobe_protection_media(file, track, 1); + is_cenc_protected = gf_isom_is_cenc_media(file, track, 1); for (i=0; i\n", i+1); continue; } dts = samp->DTS; cts = dts + (s32) samp->CTS_Offset; + is_rap = samp->IsRAP; + if (!is_rap) gf_isom_get_sample_rap_roll_info(file, track, i+1, &is_rap, NULL, NULL); + + if (dump_flags&2) { + fprintf(dump, " dataLength, is_rap); + } else { + fprintf(dump, " dataLength, is_rap); + } + if (nb_descs>1) + fprintf(dump, " sample_description=\"%d\"", di); + fprintf(dump, " >\n"); - fprintf(dump, " \n", i+1, dts, cts, samp->dataLength, samp->IsRAP); if (cts\n"); idx = 1; ptr = samp->data; size = samp->dataLength; - if (is_adobe_protection) { + if (is_adobe_protected) { u8 encrypted_au = ptr[0]; if (encrypted_au) { fprintf(dump, " \n", i+1); @@ -1385,13 +1207,21 @@ void dump_isom_nal_ex(GF_ISOFile *file, u32 trackID, FILE *dump) nal_size = read_nal_size_hdr(ptr, nalh_size); ptr += nalh_size; - if (nalh_size + nal_size > size) { + if (nal_size >= UINT_MAX-nalh_size || nalh_size + nal_size > size) { fprintf(dump, " \n", idx, nal_size, size); break; } else { - fprintf(dump, " \n"); } @@ -1403,30 +1233,211 @@ void dump_isom_nal_ex(GF_ISOFile *file, u32 trackID, FILE *dump) gf_isom_sample_del(&samp); fprintf(dump, "\n"); - gf_set_progress("Analysing Track NALUs", i+1, count); + gf_set_progress("Analysing Track NALUs", i+1, count); + } + fprintf(dump, " \n"); + fprintf(dump, "\n"); + + gf_isom_set_nalu_extract_mode(file, track, cur_extract_mode); +} + +static void dump_isom_obu(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, Bool dump_crc); +static void dump_qt_prores(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, Bool dump_crc); + +void dump_isom_nal(GF_ISOFile *file, GF_ISOTrackID trackID, char *inName, Bool is_final_name, u32 dump_flags) +{ + Bool is_av1 = GF_FALSE; + Bool is_prores = GF_FALSE; + + FILE *dump; + if (inName) { + GF_ESD* esd; + char szBuf[GF_MAX_PATH]; + + strcpy(szBuf, inName); + + u32 track = gf_isom_get_track_by_id(file, trackID); + esd = gf_isom_get_esd(file, track, 1); + + if (!esd || !esd->decoderConfig) { + switch (gf_isom_get_media_subtype(file, track, 1)) { + case GF_ISOM_SUBTYPE_AV01: + is_av1 = GF_TRUE; + break; + case GF_QT_SUBTYPE_APCH: + case GF_QT_SUBTYPE_APCO: + case GF_QT_SUBTYPE_APCN: + case GF_QT_SUBTYPE_APCS: + case GF_QT_SUBTYPE_AP4X: + case GF_QT_SUBTYPE_AP4H: + is_prores = GF_TRUE; + break; + } + } + else if (esd->decoderConfig->objectTypeIndication == GF_CODECID_AV1) { + is_av1 = GF_TRUE; + } + if (esd) gf_odf_desc_del((GF_Descriptor*)esd); + + if (!is_final_name) sprintf(szBuf, "%s_%d_%s.xml", inName, trackID, is_av1 ? "obu" : "nalu"); + dump = gf_fopen(szBuf, "wt"); + if (!dump) { + fprintf(stderr, "Failed to open %s for dumping\n", szBuf); + return; + } + } else { + dump = stdout; + } + + if (is_av1) + dump_isom_obu(file, trackID, dump, dump_flags); + else if (is_prores) + dump_qt_prores(file, trackID, dump, dump_flags); + else + dump_isom_nal_ex(file, trackID, dump, dump_flags); + + if (inName) gf_fclose(dump); +} + +#ifndef GPAC_DISABLE_AV_PARSERS +void gf_inspect_dump_obu(FILE *dump, AV1State *av1, u8 *obu, u64 obu_length, ObuType obu_type, u64 obu_size, u32 hdr_size, Bool dump_crc); +#endif + +static void dump_isom_obu(GF_ISOFile *file, GF_ISOTrackID trackID, FILE *dump, Bool dump_crc) +{ +#ifndef GPAC_DISABLE_AV_PARSERS + u32 i, count, track, timescale; + AV1State av1; + ObuType obu_type; + u64 obu_size; + u32 hdr_size; + GF_BitStream *bs; + u32 idx; + + track = gf_isom_get_track_by_id(file, trackID); + + gf_av1_init_state(&av1); + av1.config = gf_isom_av1_config_get(file, track, 1); + if (!av1.config) { + fprintf(stderr, "Error: Track #%d is not AV1!\n", trackID); + return; + } + + count = gf_isom_get_sample_count(file, track); + timescale = gf_isom_get_media_timescale(file, track); + + fprintf(dump, "\n", trackID, count, timescale); + + fprintf(dump, " \n"); + + for (i=0; iobu_array); i++) { + GF_AV1_OBUArrayEntry *obu = gf_list_get(av1.config->obu_array, i); + bs = gf_bs_new(obu->obu, (u32) obu->obu_length, GF_BITSTREAM_READ); + gf_media_aom_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1); + gf_inspect_dump_obu(dump, &av1, obu->obu, obu->obu_length, obu_type, obu_size, hdr_size, dump_crc); + gf_bs_del(bs); + } + fprintf(dump, " \n"); + + fprintf(dump, " \n"); + + for (i=0; i\n", i+1); + continue; + } + dts = samp->DTS; + cts = dts + (s32) samp->CTS_Offset; + + fprintf(dump, " \n", i+1, dts, cts, samp->dataLength, samp->IsRAP); + if (cts\n"); + + idx = 1; + ptr = samp->data; + size = samp->dataLength; + + bs = gf_bs_new(ptr, size, GF_BITSTREAM_READ); + while (size) { + gf_media_aom_av1_parse_obu(bs, &obu_type, &obu_size, &hdr_size, &av1); + if (obu_size > size) { + fprintf(dump, " \n", idx, (u32) obu_size, size); + break; + } + gf_inspect_dump_obu(dump, &av1, ptr, obu_size, obu_type, obu_size, hdr_size, dump_crc); + ptr += obu_size; + size -= (u32)obu_size; + idx++; + } + gf_bs_del(bs); + fprintf(dump, " \n"); + gf_isom_sample_del(&samp); + + fprintf(dump, "\n"); + gf_set_progress("Analysing Track OBUs", i+1, count); + } + fprintf(dump, " \n"); + fprintf(dump, "\n"); + + if (av1.config) gf_odf_av1_cfg_del(av1.config); + gf_av1_reset_state(&av1, GF_TRUE); +#endif +} + +static void dump_qt_prores(GF_ISOFile *file, u32 trackID, FILE *dump, Bool dump_crc) +{ +#ifndef GPAC_DISABLE_AV_PARSERS + u32 i, count, track, timescale; + + track = gf_isom_get_track_by_id(file, trackID); + + count = gf_isom_get_sample_count(file, track); + timescale = gf_isom_get_media_timescale(file, track); + + fprintf(dump, "\n", trackID, count, timescale); + + for (i=0; i\n", i+1); + continue; + } + dts = samp->DTS; + cts = dts + (s32) samp->CTS_Offset; + + if (cts!=dts) fprintf(dump, "\n", cts, dts); + if (!samp->IsRAP) fprintf(dump, "\n"); + + fprintf(dump, " \n", i+1, cts, samp->dataLength); + + gf_inspect_dump_prores(dump, samp->data, samp->dataLength, dump_crc); + fprintf(dump, " \n"); + + gf_isom_sample_del(&samp); + + fprintf(dump, "\n"); + gf_set_progress("Analysing ProRes Track", i+1, count); } - fprintf(dump, " \n"); - fprintf(dump, "\n"); - -#ifndef GPAC_DISABLE_AV_PARSERS - if (avccfg) gf_odf_avc_cfg_del(avccfg); - if (svccfg) gf_odf_avc_cfg_del(svccfg); -#ifndef GPAC_DISABLE_HEVC - if (hevccfg) gf_odf_hevc_cfg_del(hevccfg); - if (lhvccfg) gf_odf_hevc_cfg_del(lhvccfg); + fprintf(dump, "\n"); #endif - -#endif - gf_isom_set_nalu_extract_mode(file, track, cur_extract_mode); } -void dump_isom_nal(GF_ISOFile *file, u32 trackID, char *inName, Bool is_final_name) +void dump_isom_saps(GF_ISOFile *file, GF_ISOTrackID trackID, u32 dump_saps_mode, char *inName, Bool is_final_name) { FILE *dump; + u32 i, count; + s64 media_offset=0; + u32 track = gf_isom_get_track_by_id(file, trackID); if (inName) { char szBuf[GF_MAX_PATH]; strcpy(szBuf, inName); - if (!is_final_name) sprintf(szBuf, "%s_%d_nalu.xml", inName, trackID); + + if (!is_final_name) sprintf(szBuf, "%s_%d_cues.xml", inName, trackID); dump = gf_fopen(szBuf, "wt"); if (!dump) { fprintf(stderr, "Failed to open %s for dumping\n", szBuf); @@ -1435,8 +1446,64 @@ void dump_isom_nal(GF_ISOFile *file, u32 trackID, char *inName, Bool is_final_na } else { dump = stdout; } - dump_isom_nal_ex(file, gf_isom_get_track_id(file, trackID), dump); + fprintf(dump, "\n"); + fprintf(dump, "\n"); + fprintf(dump, "\n"); + + count = gf_isom_get_sample_count(file, track); + for (i=0; iIsRAP; + if (!sap_type) { + Bool is_rap; + GF_ISOSampleRollType roll_type; + s32 roll_dist; + gf_isom_get_sample_rap_roll_info(file, track, i+1, &is_rap, &roll_type, &roll_dist); + if (roll_type) sap_type = SAP_TYPE_4; + else if (is_rap) sap_type = SAP_TYPE_3; + } + + if (!sap_type) { + gf_isom_sample_del(&samp); + continue; + } + + dts = cts = samp->DTS; + cts += samp->CTS_Offset; + fprintf(dump, "\n"); + + gf_isom_sample_del(&samp); + } + fprintf(dump, "\n"); + fprintf(dump, "\n"); if (inName) gf_fclose(dump); } @@ -1446,9 +1513,9 @@ void dump_isom_ismacryp(GF_ISOFile *file, char *inName, Bool is_final_name) { u32 i, j; FILE *dump; - char szBuf[1024]; if (inName) { + char szBuf[1024]; strcpy(szBuf, inName); if (!is_final_name) strcat(szBuf, "_ismacryp.xml"); dump = gf_fopen(szBuf, "wt"); @@ -1481,12 +1548,11 @@ void dump_isom_ismacryp(GF_ISOFile *file, char *inName, Bool is_final_name) } -void dump_isom_timed_text(GF_ISOFile *file, u32 trackID, char *inName, Bool is_final_name, Bool is_convert, GF_TextDumpType dump_type) +void dump_isom_timed_text(GF_ISOFile *file, GF_ISOTrackID trackID, char *inName, Bool is_final_name, Bool is_convert, GF_TextDumpType dump_type) { FILE *dump; GF_Err e; u32 track; - char szBuf[1024]; track = gf_isom_get_track_by_id(file, trackID); if (!track) { @@ -1504,6 +1570,7 @@ void dump_isom_timed_text(GF_ISOFile *file, u32 trackID, char *inName, Bool is_f } if (inName) { + char szBuf[1024]; char *ext; ext = ((dump_type==GF_TEXTDUMPTYPE_SVG) ? "svg" : ((dump_type==GF_TEXTDUMPTYPE_SRT) ? "srt" : "ttxt")); if (is_final_name) { @@ -1512,7 +1579,7 @@ void dump_isom_timed_text(GF_ISOFile *file, u32 trackID, char *inName, Bool is_f sprintf(szBuf, "%s.%s", inName, ext) ; else sprintf(szBuf, "%s_%d_text.%s", inName, trackID, ext); - + dump = gf_fopen(szBuf, "wt"); if (!dump) { fprintf(stderr, "Failed to open %s for dumping\n", szBuf); @@ -1537,13 +1604,12 @@ void dump_isom_sdp(GF_ISOFile *file, char *inName, Bool is_final_name) const char *sdp; u32 size, i; FILE *dump; - char szBuf[1024]; if (inName) { - char *ext; + char szBuf[1024]; strcpy(szBuf, inName); if (!is_final_name) { - ext = strchr(szBuf, '.'); + char *ext = strchr(szBuf, '.'); if (ext) ext[0] = 0; strcat(szBuf, "_sdp.txt"); } @@ -1558,7 +1624,8 @@ void dump_isom_sdp(GF_ISOFile *file, char *inName, Bool is_final_name) } //get the movie SDP gf_isom_sdp_get(file, &sdp, &size); - fprintf(dump, "%s", sdp); + if (sdp && size) + fprintf(dump, "%s", sdp); fprintf(dump, "\r\n"); //then tracks @@ -1576,15 +1643,15 @@ void dump_isom_sdp(GF_ISOFile *file, char *inName, Bool is_final_name) #ifndef GPAC_DISABLE_ISOM_DUMP -GF_Err dump_isom_xml(GF_ISOFile *file, char *inName, Bool is_final_name, Bool do_track_dump) +GF_Err dump_isom_xml(GF_ISOFile *file, char *inName, Bool is_final_name, Bool do_track_dump, Bool merge_vtt_cues, Bool skip_init, Bool skip_samples) { GF_Err e; FILE *dump = stdout; Bool do_close=GF_FALSE; - char szBuf[1024]; if (!file) return GF_ISOM_INVALID_FILE; - + if (inName) { + char szBuf[1024]; strcpy(szBuf, inName); if (!is_final_name) { strcat(szBuf, do_track_dump ? "_dump.xml" : "_info.xml"); @@ -1601,22 +1668,22 @@ GF_Err dump_isom_xml(GF_ISOFile *file, char *inName, Bool is_final_name, Bool do if (do_track_dump) { fprintf(dump, "\n"); } - e = gf_isom_dump(file, dump); + e = gf_isom_dump(file, dump, skip_init, skip_samples); if (e) { fprintf(stderr, "Error dumping ISO structure\n"); } - if ( gf_isom_get_track_count(file) == 0 ) - do_track_dump = GF_FALSE; if (do_track_dump) { - u32 i, j; +#ifndef GPAC_DISABLE_MEDIA_EXPORT + u32 i; //because of dump mode we need to reopen in regular read mode to avoid mem leaks GF_ISOFile *the_file = gf_isom_open(gf_isom_get_filename(file), GF_ISOM_OPEN_READ, NULL); u32 tcount = gf_isom_get_track_count(the_file); fprintf(dump, "\n"); + for (i=0; i\n", name, trackID); - scount=gf_isom_get_sample_count(the_file, i+1); +#ifndef GPAC_DISABLE_ISOM_HINTING + u32 j, scount=gf_isom_get_sample_count(the_file, i+1); for (j=0; j\n", name); fmt_handled = GF_TRUE; +#endif /*GPAC_DISABLE_ISOM_HINTING*/ } else if (gf_isom_get_avc_svc_type(the_file, i+1, 1) || gf_isom_get_hevc_lhvc_type(the_file, i+1, 1)) { - dump_isom_nal_ex(the_file, trackID, dump); + dump_isom_nal_ex(the_file, trackID, dump, GF_FALSE); fmt_handled = GF_TRUE; } else if ((mtype==GF_ISOM_MEDIA_TEXT) || (mtype==GF_ISOM_MEDIA_SUBT) ) { if (msubtype==GF_ISOM_SUBTYPE_WVTT) { - gf_webvtt_dump_iso_track(&dumper, NULL, i+1, GF_FALSE, GF_TRUE); + gf_webvtt_dump_iso_track(&dumper, i+1, merge_vtt_cues, GF_TRUE); fmt_handled = GF_TRUE; } else if ((msubtype==GF_ISOM_SUBTYPE_TX3G) || (msubtype==GF_ISOM_SUBTYPE_TEXT)) { gf_isom_text_dump(the_file, i+1, dump, GF_TEXTDUMPTYPE_TTXT_BOXES); @@ -1659,15 +1729,18 @@ GF_Err dump_isom_xml(GF_ISOFile *file, char *inName, Bool is_final_name, Bool do } if (!fmt_handled) { - dumper.nhml_only = GF_TRUE; - dumper.flags = GF_EXPORT_NATIVE | GF_EXPORT_NHML | GF_EXPORT_NHML_FULL; - gf_media_export_nhml(&dumper, GF_FALSE); + dumper.flags = GF_EXPORT_NHML | GF_EXPORT_NHML_FULL; + dumper.print_stats_graph = fs_dump_flags; + gf_media_export(&dumper); } } +#else + return GF_NOT_SUPPORTED; +#endif /*GPAC_DISABLE_MEDIA_EXPORT*/ gf_isom_delete(the_file); fprintf(dump, "\n"); + fprintf(dump, "\n"); } - fprintf(dump, "\n"); if (do_close) gf_fclose(dump); return e; } @@ -1715,7 +1788,7 @@ static char *format_date(u64 time, char *szTime) } else { time -= 2082844800; now = (u32) time; - sprintf(szTime, "GMT %s", asctime(gmtime(&now)) ); + sprintf(szTime, "GMT %s", asctime(gf_gmtime(&now)) ); } return szTime; } @@ -1740,7 +1813,7 @@ void print_udta(GF_ISOFile *file, u32 track_number) GF_Err dump_isom_udta(GF_ISOFile *file, char *inName, Bool is_final_name, u32 dump_udta_type, u32 dump_udta_track) { - char szName[1024], *data; + u8 *data; FILE *t; bin128 uuid; u32 count, res; @@ -1761,11 +1834,12 @@ GF_Err dump_isom_udta(GF_ISOFile *file, char *inName, Bool is_final_name, u32 du return e; } if (inName) { + char szName[1024]; if (is_final_name) strcpy(szName, inName); else sprintf(szName, "%s_%s.udta", inName, gf_4cc_to_str(dump_udta_type) ); - + t = gf_fopen(szName, "wb"); if (!t) { gf_free(data); @@ -1775,31 +1849,55 @@ GF_Err dump_isom_udta(GF_ISOFile *file, char *inName, Bool is_final_name, u32 du } else { t = stdout; } - res = (u32) fwrite(data, 1, count, t); + res = (u32) gf_fwrite(data+8, count-8, t); if (inName) gf_fclose(t); gf_free(data); - if (count != res) { + if (count-8 != res) { fprintf(stderr, "Error writing udta to file\n"); - gf_free(data); return GF_IO_ERR; } return GF_OK; } -GF_Err dump_isom_chapters(GF_ISOFile *file, char *inName, Bool is_final_name, Bool dump_ogg) +GF_Err dump_isom_chapters(GF_ISOFile *file, char *inName, Bool is_final_name, u32 dump_mode) { - char szName[1024]; FILE *t; u32 i, count; + u32 chap_tk = 0; count = gf_isom_get_chapter_count(file, 0); + + if (dump_mode==2) dump_mode = GF_TEXTDUMPTYPE_OGG_CHAP; + else if (dump_mode==3) dump_mode = GF_TEXTDUMPTYPE_ZOOM_CHAP; + else dump_mode = GF_TEXTDUMPTYPE_TTXT_CHAP; + + if (!count) { + for (i=0; i\n"); + fprintf(t, "\n"); + fprintf(t, "\n"); + fprintf(t, "\n"); + fprintf(t, "\n"); + } + for (i=0; i%s\n" + , format_duration(chapter_time, 1000, szDur), name); } } + if (dump_mode==GF_TEXTDUMPTYPE_TTXT_CHAP) { + fprintf(t, "\n"); + } if (inName) gf_fclose(t); return GF_OK; } @@ -1850,8 +1962,9 @@ static void DumpMetaItem(GF_ISOFile *file, Bool root_meta, u32 tk_num, char *nam const char *it_name, *mime, *enc, *url, *urn; Bool self_ref; u32 ID; - gf_isom_get_meta_item_info(file, root_meta, tk_num, i+1, &ID, NULL, &self_ref, &it_name, &mime, &enc, &url, &urn); - fprintf(stderr, "Item #%d - ID %d", i+1, ID); + u32 it_type; + gf_isom_get_meta_item_info(file, root_meta, tk_num, i+1, &ID, &it_type, NULL, &self_ref, &it_name, &mime, &enc, &url, &urn); + fprintf(stderr, "Item #%d - ID %d - type %s ", i+1, ID, gf_4cc_to_str(it_type)); if (self_ref) fprintf(stderr, " - Self-Reference"); else if (it_name) fprintf(stderr, " - Name: %s", it_name); if (mime) fprintf(stderr, " - MimeType: %s", mime); @@ -1866,10 +1979,9 @@ static void DumpMetaItem(GF_ISOFile *file, Bool root_meta, u32 tk_num, char *nam static void print_config_hash(GF_List *xps_array, char *szName) { u32 i, j; - GF_AVCConfigSlot *slc; u8 hash[20]; for (i=0; idata, slc->size, hash); fprintf(stderr, "\t%s#%d hash: ", szName, i+1); for (j=0; j<20; j++) fprintf(stderr, "%02X", hash[j]); @@ -1877,10 +1989,16 @@ static void print_config_hash(GF_List *xps_array, char *szName) } } -#if !defined(GPAC_DISABLE_HEVC) && !defined( GPAC_DISABLE_AV_PARSERS) -void dump_hevc_track_info(GF_ISOFile *file, u32 trackNum, GF_HEVCConfig *hevccfg, HEVCState *hevc_state) +void dump_hevc_track_info(GF_ISOFile *file, u32 trackNum, GF_HEVCConfig *hevccfg +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) + , HEVCState *hevc_state +#endif /*GPAC_DISABLE_AV_PARSERS && defined(GPAC_DISABLE_HEVC)*/ + ) { - u32 k, idx; +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) + u32 idx; +#endif + u32 k; Bool non_hevc_base_layer=GF_FALSE; fprintf(stderr, "\t%s Info:", hevccfg->is_lhvc ? "LHVC" : "HEVC"); if (!hevccfg->is_lhvc) @@ -1902,17 +2020,21 @@ void dump_hevc_track_info(GF_ISOFile *file, u32 trackNum, GF_HEVCConfig *hevccfg if (ar->type==GF_HEVC_NALU_VID_PARAM) { fprintf(stderr, "%d VPS ", gf_list_count(ar->nalus)); +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) for (idx=0; idxnalus); idx++) { GF_AVCConfigSlot *vps = gf_list_get(ar->nalus, idx); - s32 idx=gf_media_hevc_read_vps(vps->data, vps->size, hevc_state); - if (hevccfg->is_lhvc && (idx>=0)) { - non_hevc_base_layer = ! hevc_state->vps[idx].base_layer_internal_flag; + s32 ps_idx=gf_media_hevc_read_vps(vps->data, vps->size, hevc_state); + if (hevccfg->is_lhvc && (ps_idx>=0)) { + non_hevc_base_layer = ! hevc_state->vps[ps_idx].base_layer_internal_flag; } } +#endif + } } fprintf(stderr, "\n"); +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) for (k=0; kparam_array); k++) { GF_HEVCParamArray *ar=gf_list_get(hevccfg->param_array, k); u32 width, height; @@ -1936,8 +2058,8 @@ void dump_hevc_track_info(GF_ISOFile *file, u32 trackNum, GF_HEVCConfig *hevccfg fprintf(stderr, "\nFailed to read SPS: %s\n\n", gf_error_to_string((e) )); } } - } +#endif if (!hevccfg->is_lhvc) fprintf(stderr, "\tBit Depth luma %d - Chroma %d - %d temporal layers\n", hevccfg->luma_bit_depth, hevccfg->chroma_bit_depth, hevccfg->numTemporalLayers); else @@ -1953,21 +2075,25 @@ void dump_hevc_track_info(GF_ISOFile *file, u32 trackNum, GF_HEVCConfig *hevccfg else if (ar->type==GF_HEVC_NALU_VID_PARAM) print_config_hash(ar->nalus, "VPS"); } } -#endif -void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) +void DumpTrackInfo(GF_ISOFile *file, GF_ISOTrackID trackID, Bool full_dump, Bool is_track_num) { Float scale; Bool is_od_track = 0; - u32 trackNum, i, j, max_rate, rate, ts, mtype, msub_type, timescale, sr, nb_ch, count, alt_group, nb_groups, nb_edits; + u32 trackNum, i, j, max_rate, rate, ts, mtype, msub_type, timescale, sr, nb_ch, count, alt_group, nb_groups, nb_edits, cdur, csize, bps; u64 time_slice, dur, size; - u8 bps; + s32 cts_shift; GF_ESD *esd; char szDur[50]; char *lang; - trackNum = gf_isom_get_track_by_id(file, trackID); + if (!is_track_num) { + trackNum = gf_isom_get_track_by_id(file, trackID); + } else { + trackNum = trackID; + trackID = gf_isom_get_track_id(file, trackNum); + } if (!trackNum) { fprintf(stderr, "No track with ID %d found\n", trackID); return; @@ -1978,10 +2104,18 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, "Media Duration %s - ", format_duration(gf_isom_get_media_duration(file, trackNum), timescale, szDur)); fprintf(stderr, "Indicated Duration %s\n", format_duration(gf_isom_get_media_original_duration(file, trackNum), timescale, szDur)); - nb_edits = gf_isom_get_edit_segment_count(file, trackNum); + if (gf_isom_check_data_reference(file, trackNum, 1) != GF_OK) { + fprintf(stderr, "Track uses external data reference not supported by GPAC!\n"); + } + + nb_edits = gf_isom_get_edits_count(file, trackNum); if (nb_edits) fprintf(stderr, "Track has %d edit lists: track duration is %s\n", nb_edits, format_duration(gf_isom_get_track_duration(file, trackNum), gf_isom_get_timescale(file), szDur)); + cts_shift = gf_isom_get_composition_offset_shift(file, trackNum); + if (cts_shift) + fprintf(stderr, "Track composition offset shift (negative CTS offset): %d\n", cts_shift); + if (gf_isom_is_track_in_root_od(file, trackNum) ) fprintf(stderr, "Track is present in Root OD\n"); if (!gf_isom_is_track_enabled(file, trackNum)) fprintf(stderr, "Track is disabled\n"); gf_isom_get_media_language(file, trackNum, &lang); @@ -1997,16 +2131,26 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) for (i = 0; i < count; i++) { char *kind_scheme, *kind_value; gf_isom_get_track_kind(file, trackNum, i, &kind_scheme, &kind_value); - fprintf(stderr, "Kind: %s - %s\n", kind_scheme, kind_value); + fprintf(stderr, "Kind: %s - %s\n", kind_scheme ? kind_scheme : "null", kind_value ? kind_value : "null"); if (kind_scheme) gf_free(kind_scheme); if (kind_value) gf_free(kind_value); } if (gf_isom_is_track_fragmented(file, trackID) ) { + u32 defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess; + u8 defaultPadding; + u16 defaultDegradationPriority; u32 frag_samples; u64 frag_duration; gf_isom_get_fragmented_samples_info(file, trackID, &frag_samples, &frag_duration); fprintf(stderr, "Fragmented track: %d samples - Media Duration %s\n", frag_samples, format_duration(frag_duration, timescale, szDur)); + + gf_isom_get_fragment_defaults(file, trackNum, &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority); + + fprintf(stderr, "Fragment sample defaults: duration %d size %d stsd %d sync %d padding %d degradation_priority %d\n", + defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, + (u32) defaultPadding, (u32) defaultDegradationPriority + ); } if (!gf_isom_is_self_contained(file, trackNum, 1)) { @@ -2023,9 +2167,15 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) print_udta(file, trackNum); - if (mtype==GF_ISOM_MEDIA_VISUAL) { + if (gf_isom_is_video_handler_type(mtype) ) { s32 tx, ty; u32 w, h; + u16 bit_depth; + + gf_isom_get_visual_info(file, trackNum, 1, &w, &h); + gf_isom_get_visual_bit_depth(file, trackNum, 1, &bit_depth); + fprintf(stderr, "Visual Sample Entry Info: width=%d height=%d (depth=%d bits)\n", w, h, (int)bit_depth); + gf_isom_get_track_layout_info(file, trackNum, &w, &h, &tx, &ty, NULL); fprintf(stderr, "Visual Track layout: x=%d y=%d width=%d height=%d\n", tx, ty, w, h); } @@ -2034,8 +2184,10 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) gf_isom_set_nalu_extract_mode(file, trackNum, GF_ISOM_NALU_EXTRACT_INSPECT); msub_type = gf_isom_get_media_subtype(file, trackNum, 1); + if (msub_type==GF_ISOM_SUBTYPE_MPEG4_CRYP) + gf_isom_get_original_format_type(file, trackNum, 1, &msub_type); + if ((msub_type==GF_ISOM_SUBTYPE_MPEG4) - || (msub_type==GF_ISOM_SUBTYPE_MPEG4_CRYP) || (msub_type==GF_ISOM_SUBTYPE_AVC_H264) || (msub_type==GF_ISOM_SUBTYPE_AVC2_H264) || (msub_type==GF_ISOM_SUBTYPE_AVC3_H264) @@ -2052,10 +2204,11 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) || (msub_type==GF_ISOM_SUBTYPE_HVT1) ) { esd = gf_isom_get_esd(file, trackNum, 1); - if (!esd) { + if (!esd || !esd->decoderConfig) { fprintf(stderr, "WARNING: Broken MPEG-4 Track\n"); + if (esd) gf_odf_desc_del((GF_Descriptor *)esd); } else { - const char *st = gf_odf_stream_type_name(esd->decoderConfig->streamType); + const char *st = gf_stream_type_name(esd->decoderConfig->streamType); if (st) { fprintf(stderr, "MPEG-4 Config%s%s Stream - ObjectTypeIndication 0x%02x\n", full_dump ? "\n\t" : ": ", st, esd->decoderConfig->objectTypeIndication); @@ -2070,7 +2223,7 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) u32 w, h; u16 rvc_predef; w = h = 0; - if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { + if (esd->decoderConfig->objectTypeIndication==GF_CODECID_MPEG4_PART2) { #ifndef GPAC_DISABLE_AV_PARSERS if (!esd->decoderConfig->decoderSpecificInfo) { #else @@ -2094,16 +2247,12 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } #endif } else if (gf_isom_get_avc_svc_type(file, trackNum, 1) != GF_ISOM_AVCTYPE_NONE) { -#ifndef GPAC_DISABLE_AV_PARSERS GF_AVCConfig *avccfg, *svccfg, *mvccfg; - GF_AVCConfigSlot *slc; - s32 par_n, par_d; -#endif gf_isom_get_visual_info(file, trackNum, 1, &w, &h); if (full_dump) fprintf(stderr, "\t"); fprintf(stderr, "AVC/H264 Video - Visual Size %d x %d\n", w, h); -#ifndef GPAC_DISABLE_AV_PARSERS + avccfg = gf_isom_avc_config_get(file, trackNum, 1); svccfg = gf_isom_svc_config_get(file, trackNum, 1); mvccfg = gf_isom_mvc_config_get(file, trackNum, 1); @@ -2113,8 +2262,11 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, "\tAVC Info: %d SPS - %d PPS", gf_list_count(avccfg->sequenceParameterSets) , gf_list_count(avccfg->pictureParameterSets) ); fprintf(stderr, " - Profile %s @ Level %g\n", gf_avc_get_profile_name(avccfg->AVCProfileIndication), ((Double)avccfg->AVCLevelIndication)/10.0 ); fprintf(stderr, "\tNAL Unit length bits: %d\n", 8*avccfg->nal_unit_size); + +#ifndef GPAC_DISABLE_AV_PARSERS for (i=0; isequenceParameterSets); i++) { - slc = gf_list_get(avccfg->sequenceParameterSets, i); + s32 par_n, par_d; + GF_AVCConfigSlot *slc = gf_list_get(avccfg->sequenceParameterSets, i); gf_avc_get_sps_info(slc->data, slc->size, NULL, NULL, NULL, &par_n, &par_d); if ((par_n>0) && (par_d>0)) { u32 tw, th; @@ -2123,6 +2275,8 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } if (!full_dump) break; } +#endif + if (avccfg->chroma_bit_depth) { fprintf(stderr, "\tChroma format %s - Luma bit depth %d - chroma bit depth %d\n", gf_avc_hevc_get_chroma_format_name(avccfg->chroma_format), avccfg->luma_bit_depth, avccfg->chroma_bit_depth); } @@ -2135,9 +2289,11 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) if (svccfg) { fprintf(stderr, "\n\tSVC Info: %d SPS - %d PPS - Profile %s @ Level %g\n", gf_list_count(svccfg->sequenceParameterSets) , gf_list_count(svccfg->pictureParameterSets), gf_avc_get_profile_name(svccfg->AVCProfileIndication), ((Double)svccfg->AVCLevelIndication)/10.0 ); fprintf(stderr, "\tSVC NAL Unit length bits: %d\n", 8*svccfg->nal_unit_size); +#ifndef GPAC_DISABLE_AV_PARSERS for (i=0; isequenceParameterSets); i++) { - slc = gf_list_get(svccfg->sequenceParameterSets, i); + GF_AVCConfigSlot *slc = gf_list_get(svccfg->sequenceParameterSets, i); if (slc) { + s32 par_n, par_d; u32 s_w, s_h, sps_id; gf_avc_get_sps_info(slc->data, slc->size, &sps_id, &s_w, &s_h, &par_n, &par_d); fprintf(stderr, "\t\tSPS ID %d - Visual Size %d x %d\n", sps_id, s_w, s_h); @@ -2148,6 +2304,7 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } } } +#endif print_config_hash(svccfg->sequenceParameterSets, "SPS"); print_config_hash(svccfg->pictureParameterSets, "PPS"); print_config_hash(svccfg->sequenceParameterSetExtensions, "SPSEx"); @@ -2158,10 +2315,12 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) if (mvccfg) { fprintf(stderr, "\n\tMVC Info: %d SPS - %d PPS - Profile %s @ Level %g\n", gf_list_count(mvccfg->sequenceParameterSets) , gf_list_count(mvccfg->pictureParameterSets), gf_avc_get_profile_name(mvccfg->AVCProfileIndication), ((Double)mvccfg->AVCLevelIndication)/10.0 ); fprintf(stderr, "\tMVC NAL Unit length bits: %d\n", 8*mvccfg->nal_unit_size); +#ifndef GPAC_DISABLE_AV_PARSERS for (i=0; isequenceParameterSets); i++) { - slc = gf_list_get(mvccfg->sequenceParameterSets, i); + GF_AVCConfigSlot *slc = gf_list_get(mvccfg->sequenceParameterSets, i); if (slc) { u32 s_w, s_h, sps_id; + s32 par_n, par_d; gf_avc_get_sps_info(slc->data, slc->size, &sps_id, &s_w, &s_h, &par_n, &par_d); fprintf(stderr, "\t\tSPS ID %d - Visual Size %d x %d\n", sps_id, s_w, s_h); if ((par_n>0) && (par_d>0)) { @@ -2171,19 +2330,19 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } } } +#endif print_config_hash(mvccfg->sequenceParameterSets, "SPS"); print_config_hash(mvccfg->pictureParameterSets, "PPS"); gf_odf_avc_cfg_del(mvccfg); } -#endif /*GPAC_DISABLE_AV_PARSERS*/ - } else if ((esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_HEVC) - || (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_LHVC) + } else if ((esd->decoderConfig->objectTypeIndication==GF_CODECID_HEVC) + || (esd->decoderConfig->objectTypeIndication==GF_CODECID_LHVC) ) { + GF_HEVCConfig *hevccfg, *lhvccfg; GF_OperatingPointsInformation *oinf; #if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) HEVCState hevc_state; - GF_HEVCConfig *hevccfg, *lhvccfg; memset(&hevc_state, 0, sizeof(HEVCState)); hevc_state.sps_active_idx = -1; #endif @@ -2191,18 +2350,17 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) gf_isom_get_visual_info(file, trackNum, 1, &w, &h); if (full_dump) fprintf(stderr, "\t"); fprintf(stderr, "HEVC Video - Visual Size %d x %d\n", w, h); -#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) hevccfg = gf_isom_hevc_config_get(file, trackNum, 1); lhvccfg = gf_isom_lhvc_config_get(file, trackNum, 1); if (msub_type==GF_ISOM_SUBTYPE_HVT1) { - const char *data; - u32 size; - u32 is_default, x,y,w,h, id, independent; + const u8 *data; + u32 tsize; + u32 is_default, tx,ty,tw,th, id, independent; Bool full_frame; - if (gf_isom_get_tile_info(file, trackNum, 1, &is_default, &id, &independent, &full_frame, &x, &y, &w, &h)) { - fprintf(stderr, "\tHEVC Tile - ID %d independent %d (x,y,w,h)=%d,%d,%d,%d \n", id, independent, x, y, w, h); - } else if (gf_isom_get_sample_group_info(file, trackNum, 1, GF_4CC('t','r','i','f'), &is_default, &data, &size)) { + if (gf_isom_get_tile_info(file, trackNum, 1, &is_default, &id, &independent, &full_frame, &tx, &ty, &tw, &th)) { + fprintf(stderr, "\tHEVC Tile - ID %d independent %d (x,y,w,h)=%d,%d,%d,%d \n", id, independent, tx, ty, tw, th); + } else if (gf_isom_get_sample_group_info(file, trackNum, 1, GF_ISOM_SAMPLE_GROUP_TRIF, &is_default, &data, &tsize)) { fprintf(stderr, "\tHEVC Tile track containing a tile set\n"); } else { fprintf(stderr, "\tHEVC Tile track without tiling info\n"); @@ -2210,17 +2368,25 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } else if (!hevccfg && !lhvccfg) { fprintf(stderr, "\n\n\tNon-compliant HEVC track: No hvcC or shcC found in sample description\n"); } - - if (gf_isom_get_reference_count(file, trackNum, GF_4CC('s','a','b','t'))) { + + if (gf_isom_get_reference_count(file, trackNum, GF_ISOM_REF_SABT)) { fprintf(stderr, "\tHEVC Tile base track\n"); } if (hevccfg) { - dump_hevc_track_info(file, trackNum, hevccfg, &hevc_state); + dump_hevc_track_info(file, trackNum, hevccfg +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) + , &hevc_state +#endif + ); gf_odf_hevc_cfg_del(hevccfg); fprintf(stderr, "\n"); } if (lhvccfg) { - dump_hevc_track_info(file, trackNum, lhvccfg, &hevc_state); + dump_hevc_track_info(file, trackNum, lhvccfg +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) + , &hevc_state +#endif + ); gf_odf_hevc_cfg_del(lhvccfg); } @@ -2244,27 +2410,26 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, ") num_profile_tier_level %d ", gf_list_count(oinf->profile_tier_levels) ); fprintf(stderr, " num_operating_points %d dependency layers %d \n", gf_list_count(oinf->operating_points), gf_list_count(oinf->dependency_layers) ); } -#endif /*GPAC_DISABLE_AV_PARSERS && defined(GPAC_DISABLE_HEVC)*/ } /*OGG media*/ - else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_MEDIA_OGG) { + else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_THEORA) { char *szName; gf_isom_get_visual_info(file, trackNum, 1, &w, &h); if (full_dump) fprintf(stderr, "\t"); - if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[3], "theora", 6)) szName = "Theora"; + if (!strnicmp((char *) &esd->decoderConfig->decoderSpecificInfo->data[3], "theora", 6)) szName = "Theora"; else szName = "Unknown"; fprintf(stderr, "Ogg/%s video / GPAC Mux - Visual Size %d x %d\n", szName, w, h); } - else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG) { + else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_JPEG) { gf_isom_get_visual_info(file, trackNum, 1, &w, &h); fprintf(stderr, "JPEG Stream - Visual Size %d x %d\n", w, h); } - else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_PNG) { + else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_PNG) { gf_isom_get_visual_info(file, trackNum, 1, &w, &h); fprintf(stderr, "PNG Stream - Visual Size %d x %d\n", w, h); } - else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG_2000) { + else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_J2K) { gf_isom_get_visual_info(file, trackNum, 1, &w, &h); fprintf(stderr, "JPEG2000 Stream - Visual Size %d x %d\n", w, h); } @@ -2285,11 +2450,11 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) #endif Bool is_mp2 = GF_FALSE; switch (esd->decoderConfig->objectTypeIndication) { - case GPAC_OTI_AUDIO_AAC_MPEG2_MP: - case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: - case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: + case GF_CODECID_AAC_MPEG2_MP: + case GF_CODECID_AAC_MPEG2_LCP: + case GF_CODECID_AAC_MPEG2_SSRP: is_mp2 = GF_TRUE; - case GPAC_OTI_AUDIO_AAC_MPEG4: + case GF_CODECID_AAC_MPEG4: #ifndef GPAC_DISABLE_AV_PARSERS if (!esd->decoderConfig->decoderSpecificInfo) e = GF_NON_COMPLIANT_BITSTREAM; @@ -2298,12 +2463,19 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) if (full_dump) fprintf(stderr, "\t"); if (e) fprintf(stderr, "Corrupted AAC Config\n"); else { + char *signaling = "implicit"; char *heaac = ""; if (!is_mp2 && a_cfg.has_sbr) { if (a_cfg.has_ps) heaac = "(HE-AAC v2) "; else heaac = "(HE-AAC v1) "; } - fprintf(stderr, "%s %s- %d Channel(s) - SampleRate %d", gf_m4a_object_type_name(a_cfg.base_object_type), heaac, a_cfg.nb_chan, a_cfg.base_sr); + if (a_cfg.base_object_type==2) { + if (a_cfg.has_ps || a_cfg.has_sbr) + signaling = "backward compatible"; + } else { + signaling = "hierarchical"; + } + fprintf(stderr, "%s (AOT=%d %s) %s- %d Channel(s) - SampleRate %d", gf_m4a_object_type_name(a_cfg.base_object_type), a_cfg.base_object_type, signaling, heaac, a_cfg.nb_chan, a_cfg.base_sr); if (is_mp2) fprintf(stderr, " (MPEG-2 Signaling)"); if (a_cfg.has_sbr) fprintf(stderr, " - SBR: SampleRate %d Type %s", a_cfg.sbr_sr, gf_m4a_object_type_name(a_cfg.sbr_object_type)); if (a_cfg.has_ps) fprintf(stderr, " - PS"); @@ -2313,21 +2485,21 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, "MPEG-2/4 Audio - %d Channels - SampleRate %d\n", nb_ch, sr); #endif break; - case GPAC_OTI_AUDIO_MPEG2_PART3: - case GPAC_OTI_AUDIO_MPEG1: + case GF_CODECID_MPEG2_PART3: + case GF_CODECID_MPEG_AUDIO: if (msub_type == GF_ISOM_SUBTYPE_MPEG4_CRYP) { fprintf(stderr, "MPEG-1/2 Audio - %d Channels - SampleRate %d\n", nb_ch, sr); } else { #ifndef GPAC_DISABLE_AV_PARSERS GF_ISOSample *samp = gf_isom_get_sample(file, trackNum, 1, &oti); if (samp) { - oti = GF_4CC((u8)samp->data[0], (u8)samp->data[1], (u8)samp->data[2], (u8)samp->data[3]); + u32 mhdr = GF_4CC((u8)samp->data[0], (u8)samp->data[1], (u8)samp->data[2], (u8)samp->data[3]); if (full_dump) fprintf(stderr, "\t"); fprintf(stderr, "%s Audio - %d Channel(s) - SampleRate %d - Layer %d\n", - gf_mp3_version_name(oti), - gf_mp3_num_channels(oti), - gf_mp3_sampling_rate(oti), - gf_mp3_layer(oti) + gf_mp3_version_name(mhdr), + gf_mp3_num_channels(mhdr), + gf_mp3_sampling_rate(mhdr), + gf_mp3_layer(mhdr) ); gf_isom_sample_del(&samp); } else { @@ -2339,30 +2511,28 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } break; /*OGG media*/ - case GPAC_OTI_MEDIA_OGG: - { - char *szName; - if (full_dump) fprintf(stderr, "\t"); - if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[3], "vorbis", 6)) szName = "Vorbis"; - else if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[2], "Speex", 5)) szName = "Speex"; - else if (!strnicmp(&esd->decoderConfig->decoderSpecificInfo->data[2], "Flac", 4)) szName = "Flac"; - else szName = "Unknown"; - fprintf(stderr, "Ogg/%s audio / GPAC Mux - Sample Rate %d - %d channel(s)\n", szName, sr, nb_ch); - } - break; - case GPAC_OTI_AUDIO_EVRC_VOICE: + case GF_CODECID_VORBIS: + fprintf(stderr, "Ogg/Vorbis audio / GPAC Mux - Sample Rate %d - %d channel(s)\n", sr, nb_ch); + break; + case GF_CODECID_FLAC: + fprintf(stderr, "Ogg/FLAC audio / GPAC Mux - Sample Rate %d - %d channel(s)\n", sr, nb_ch); + break; + case GF_CODECID_SPEEX: + fprintf(stderr, "Ogg/Speex audio / GPAC Mux - Sample Rate %d - %d channel(s)\n", sr, nb_ch); + break; + case GF_CODECID_EVRC: fprintf(stderr, "EVRC Audio - Sample Rate 8000 - 1 channel\n"); break; - case GPAC_OTI_AUDIO_SMV_VOICE: + case GF_CODECID_SMV: fprintf(stderr, "SMV Audio - Sample Rate 8000 - 1 channel\n"); break; - case GPAC_OTI_AUDIO_13K_VOICE: + case GF_CODECID_QCELP: fprintf(stderr, "QCELP Audio - Sample Rate 8000 - 1 channel\n"); break; /*packetVideo hack for EVRC...*/ - case 0xD1: + case GF_CODECID_EVRC_PV: if (esd->decoderConfig->decoderSpecificInfo && (esd->decoderConfig->decoderSpecificInfo->dataLength==8) - && !strnicmp(esd->decoderConfig->decoderSpecificInfo->data, "pvmm", 4)) { + && !strnicmp((char *)esd->decoderConfig->decoderSpecificInfo->data, "pvmm", 4)) { if (full_dump) fprintf(stderr, "\t"); fprintf(stderr, "EVRC Audio (PacketVideo Mux) - Sample Rate 8000 - 1 channel\n"); } @@ -2377,19 +2547,19 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, "\tWidth %d Height %d Pixel Metrics %s\n", b_cfg->pixelWidth, b_cfg->pixelHeight, b_cfg->pixelMetrics ? "yes" : "no"); } gf_odf_desc_del((GF_Descriptor *)b_cfg); - } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_SCENE_AFX) { + } else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_AFX) { u8 tag = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data[0] : 0xFF; - const char *afxtype = gf_afx_get_type_description(tag); + const char *afxtype = gf_stream_type_afx_name(tag); fprintf(stderr, "AFX Stream - type %s (%d)\n", afxtype, tag); - } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_FONT) { + } else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_FONT) { fprintf(stderr, "Font Data stream\n"); - } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_SCENE_LASER) { + } else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_LASER) { GF_LASERConfig l_cfg; gf_odf_get_laser_config(esd->decoderConfig->decoderSpecificInfo, &l_cfg); fprintf(stderr, "LASER Stream - %s\n", l_cfg.newSceneIndicator ? "Full Scene" : "Scene Segment"); - } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_TEXT_MPEG4) { + } else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_TEXT_MPEG4) { fprintf(stderr, "MPEG-4 Streaming Text stream\n"); - } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_SCENE_SYNTHESIZED_TEXTURE) { + } else if (esd->decoderConfig->objectTypeIndication==GF_CODECID_SYNTHESIZED_TEXTURE) { fprintf(stderr, "Synthetized Texture stream stream\n"); } else { fprintf(stderr, "Unknown Systems stream OTI %d\n", esd->decoderConfig->objectTypeIndication); @@ -2440,10 +2610,11 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, "Rights Issuer: %s\n", KMS_URI); fprintf(stderr, "Content ID: %s\n", scheme_URI); if (textHdrs) { - u32 i, offset; + u32 offset; const char *start = textHdrs; fprintf(stderr, "OMA Textual Headers:\n"); - i=offset=0; + i=0; + offset=0; while (i>16, version&0xFFFF); - if (IV_size) fprintf(stderr, "Initialization Vector size: %d bits\n", IV_size*8); + if (IV_size) + fprintf(stderr, "Initialization Vector size: %d bits\n", IV_size*8); + if (gf_isom_cenc_is_pattern_mode(file, trackNum, 1)) + fprintf(stderr, "Pattern mode enabled\n"); + } else if(gf_isom_is_adobe_protection_media(file, trackNum, 1)) { - gf_isom_get_adobe_protection_info(file, trackNum, 1, NULL, &scheme_type, &version); + gf_isom_get_adobe_protection_info(file, trackNum, 1, NULL, &scheme_type, &version, NULL); fprintf(stderr, "\n*Encrypted stream - Adobe protection scheme %s (version %d)\n", gf_4cc_to_str(scheme_type), version); } else { - fprintf(stderr, "\n*Encrypted stream - unknown scheme %s\n", gf_4cc_to_str(gf_isom_is_media_encrypted(file, trackNum, 1) )); + fprintf(stderr, "\n*Encrypted stream - unknown scheme %s\n", gf_4cc_to_str(gf_isom_is_media_encrypted(file, trackNum, 0) )); } } } + } else if (msub_type == GF_ISOM_SUBTYPE_AV01) { + GF_AV1Config *av1c; + u32 w, h; + gf_isom_get_visual_info(file, trackNum, 1, &w, &h); + fprintf(stderr, "\tAOM AV1 stream - Resolution %d x %d\n", w, h); + + av1c = gf_isom_av1_config_get(file, trackNum, 1); + fprintf(stderr, "\tversion=%u, profile=%u, level_idx0=%u, tier=%u\n", (u32)av1c->version, (u32)av1c->seq_profile, (u32)av1c->seq_level_idx_0, (u32)av1c->seq_tier_0); + fprintf(stderr, "\thigh_bitdepth=%u, twelve_bit=%u, monochrome=%u\n", (u32)av1c->high_bitdepth, (u32)av1c->twelve_bit, (u32)av1c->monochrome); + fprintf(stderr, "\tchroma: subsampling_x=%u, subsampling_y=%u, sample_position=%u\n", (u32)av1c->chroma_subsampling_x, (u32)av1c->chroma_subsampling_y, (u32)av1c->chroma_sample_position); + + if (av1c->initial_presentation_delay_present) + fprintf(stderr, "\tInitial presentation delay %u\n", (u32) av1c->initial_presentation_delay_minus_one+1); + + count = gf_list_count(av1c->obu_array); + for (i=0; iobu_array, i); + gf_sha1_csum((u8*)obu->obu, (u32)obu->obu_length, hash); + fprintf(stderr, "\tOBU#%d %s hash: ", i+1, gf_av1_get_obu_name(obu->obu_type) ); + for (j=0; j<20; j++) fprintf(stderr, "%02X", hash[j]); + fprintf(stderr, "\n"); + } + gf_odf_av1_cfg_del(av1c); } else if (msub_type == GF_ISOM_SUBTYPE_3GP_H263) { u32 w, h; gf_isom_get_visual_info(file, trackNum, 1, &w, &h); fprintf(stderr, "\t3GPP H263 stream - Resolution %d x %d\n", w, h); - } else if (msub_type == GF_4CC('m','j','p','2')) { + } else if (msub_type == GF_ISOM_SUBTYPE_MJP2) { u32 w, h; gf_isom_get_visual_info(file, trackNum, 1, &w, &h); fprintf(stderr, "\tMotionJPEG2000 stream - Resolution %d x %d\n", w, h); @@ -2488,26 +2687,25 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, "\t3GPP QCELP stream - Sample Rate %d - %d channel(s) %d bps\n", sr, nb_ch, (u32) bps); } else if (msub_type == GF_ISOM_SUBTYPE_MP3) { fprintf(stderr, "\tMPEG 1/2 Audio stream - Sample Rate %d - %d channel(s) %d bps\n", sr, nb_ch, (u32) bps); - } else if (msub_type == GF_ISOM_SUBTYPE_AC3) { + } else if ((msub_type == GF_ISOM_SUBTYPE_AC3) || (msub_type == GF_ISOM_SUBTYPE_EC3)) { u32 br = 0; - Bool lfe = 0; - Bool is_ec3 = 0; + const char *lfe = ""; + Bool is_ec3 = (msub_type == GF_ISOM_SUBTYPE_EC3) ? GF_TRUE : GF_FALSE; #ifndef GPAC_DISABLE_AV_PARSERS GF_AC3Config *ac3 = gf_isom_ac3_config_get(file, trackNum, 1); if (ac3) { - int i; nb_ch = gf_ac3_get_channels(ac3->streams[0].acmod); for (i=0; istreams[0].nb_dep_sub; ++i) { assert(ac3->streams[0].nb_dep_sub == 1); nb_ch += gf_ac3_get_channels(ac3->streams[0].chan_loc); } - lfe = ac3->streams[0].lfon; + if (ac3->streams[0].lfon) lfe = ".1"; br = ac3->is_ec3 ? ac3->brcode : gf_ac3_get_bitrate(ac3->brcode); is_ec3 = ac3->is_ec3; gf_free(ac3); } #endif - fprintf(stderr, "\t%s stream - Sample Rate %d - %d%s channel(s) - bitrate %d\n", is_ec3 ? "EC-3" : "AC-3", sr, nb_ch, lfe ? ".1" : "", br); + fprintf(stderr, "\t%s stream - Sample Rate %d - %d%s channel(s) - bitrate %d\n", is_ec3 ? "EC-3" : "AC-3", sr, nb_ch, lfe, br); } else if (msub_type == GF_ISOM_SUBTYPE_3GP_SMV) { fprintf(stderr, "\t3GPP SMV stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps); } else if (msub_type == GF_ISOM_SUBTYPE_3GP_DIMS) { @@ -2524,10 +2722,10 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) if (dims.content_script_types) fprintf(stderr, "\tscript languages %s\n", dims.content_script_types); } else if (mtype==GF_ISOM_MEDIA_HINT) { u32 refTrack; - s32 i, refCount = gf_isom_get_reference_count(file, trackNum, GF_ISOM_REF_HINT); - if (refCount) { + s32 refCount = gf_isom_get_reference_count(file, trackNum, GF_ISOM_REF_HINT); + if (refCount>0) { fprintf(stderr, "Streaming Hint Track for track%s ", (refCount>1) ? "s" :""); - for (i=0; i0) { + for (i=0; i<(u32) refCount; i++) { + const char *name = gf_isom_get_payt_info(file, trackNum, i+1, &refTrack); + fprintf(stderr, "\tPayload ID %d: type %s\n", refTrack, name); + } } #endif } else if (mtype==GF_ISOM_MEDIA_FLASH) { @@ -2619,11 +2819,42 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } else { fprintf(stderr, "Unknown Metadata Stream\n"); } + } else if ((msub_type == GF_ISOM_SUBTYPE_MH3D_MHA1) || (msub_type == GF_ISOM_SUBTYPE_MH3D_MHA2)) { + fprintf(stderr, "\tMPEG-H Audio stream - Sample Rate %d - %d channel(s) %d bps\n", sr, nb_ch, (u32) bps); + esd = gf_media_map_esd(file, trackNum, 1); + if (!esd || !esd->decoderConfig || !esd->decoderConfig->decoderSpecificInfo + || !esd->decoderConfig->decoderSpecificInfo->data || (esd->decoderConfig->decoderSpecificInfo->dataLength<5) + ) { + fprintf(stderr, "\tInvalid MPEG-H audio config\n"); + } else { + fprintf(stderr, "\tProfileLevelIndication: %02X\n", esd->decoderConfig->decoderSpecificInfo->data[1]); + } + if (esd) gf_odf_desc_del((GF_Descriptor *)esd); + } else if ((msub_type == GF_ISOM_SUBTYPE_MH3D_MHM1) || (msub_type == GF_ISOM_SUBTYPE_MH3D_MHM2)) { + fprintf(stderr, "\tMPEG-H AudioMux stream - Sample Rate %d - %d channel(s) %d bps\n", sr, nb_ch, (u32) bps); + esd = gf_media_map_esd(file, trackNum, 1); + if (!esd || !esd->decoderConfig || !esd->decoderConfig->decoderSpecificInfo + || !esd->decoderConfig->decoderSpecificInfo->data) { + GF_ISOSample *samp = gf_isom_get_sample(file, trackNum, 1, NULL); + if (samp) { + s32 PL = gf_mpegh_get_mhas_pl(samp->data, samp->dataLength); + if (PL>=0) + fprintf(stderr, "\tProfileLevelIndication: %02X\n", PL); + gf_isom_sample_del(&samp); + } + } else if (esd->decoderConfig->decoderSpecificInfo->dataLength<5) { + fprintf(stderr, "\tInvalid MPEG-H audio config\n"); + } else { + fprintf(stderr, "\tProfileLevelIndication: %02X\n", esd->decoderConfig->decoderSpecificInfo->data[1]); + } + if (esd) gf_odf_desc_del((GF_Descriptor *)esd); } else { GF_GenericSampleDescription *udesc = gf_isom_get_generic_sample_description(file, trackNum, 1); if (udesc) { - if (mtype==GF_ISOM_MEDIA_VISUAL) { - fprintf(stderr, "Visual Track - Compressor \"%s\" - Resolution %d x %d\n", udesc->compressor_name, udesc->width, udesc->height); + if (gf_isom_is_video_handler_type(mtype) ) { + fprintf(stderr, "%s Track - Compressor \"%s\" - Resolution %d x %d\n", + (mtype == GF_ISOM_MEDIA_VISUAL?"Visual":"Auxiliary Video"), + udesc->compressor_name, udesc->width, udesc->height); } else if (mtype==GF_ISOM_MEDIA_AUDIO) { fprintf(stderr, "Audio Track - Sample Rate %d - %d channel(s)\n", udesc->samplerate, udesc->nb_channels); } else { @@ -2643,9 +2874,11 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } { - char szCodec[100]; - gf_media_get_rfc_6381_codec_name(file, trackNum, szCodec, GF_FALSE, GF_FALSE); - fprintf(stderr, "\tRFC6381 Codec Parameters: %s\n", szCodec); + char szCodec[RFC6381_CODEC_NAME_SIZE_MAX]; + GF_Err e = gf_media_get_rfc_6381_codec_name(file, trackNum, szCodec, GF_FALSE, GF_FALSE); + if (e == GF_OK) { + fprintf(stderr, "\tRFC6381 Codec Parameters: %s\n", szCodec); + } } DumpMetaItem(file, 0, trackNum, "Track Meta"); @@ -2691,6 +2924,7 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stderr, "\tNo sync sample found\n"); break; } + fprintf(stderr, "\tMax sample duration: %d / %d\n", gf_isom_get_max_sample_delta(file, trackNum), timescale); if (!full_dump) { fprintf(stderr, "\n"); @@ -2701,28 +2935,40 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) max_rate = rate = 0; time_slice = 0; ts = gf_isom_get_media_timescale(file, trackNum); - for (j=0; jDTS+samp->CTS_Offset; - size += samp->dataLength; - rate += samp->dataLength; - if (samp->DTS - time_slice>ts) { - if (max_rate < rate) max_rate = rate; - rate = 0; - time_slice = samp->DTS; + csize = gf_isom_get_constant_sample_size(file, trackNum); + cdur = gf_isom_get_constant_sample_duration(file, trackNum); + count = gf_isom_get_sample_count(file, trackNum); + if (csize && cdur) { + size = count * csize; + dur = cdur * count; + } else { + + for (j=0; jDTS+samp->CTS_Offset; + size += samp->dataLength; + rate += samp->dataLength; + if (samp->DTS - time_slice>ts) { + if (max_rate < rate) max_rate = rate; + rate = 0; + time_slice = samp->DTS; + } + gf_isom_sample_del(&samp); } - gf_isom_sample_del(&samp); } fprintf(stderr, "\nComputed info from media:\n"); + if (csize && cdur) { + fprintf(stderr, "\tConstant sample size %d bytes and dur %d / %d\n", csize, cdur, ts); + } scale = 1000; scale /= ts; dur = (u64) (scale * (s64)dur); @@ -2733,7 +2979,12 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } /*rate in byte, dur is in ms*/ rate = (u32) ((size * 8 * 1000) / dur); - max_rate *= 8; + + if (!max_rate) + max_rate = rate; + else + max_rate *= 8; + if (rate >= 1500) { rate /= 1000; max_rate /= 1000; @@ -2752,7 +3003,6 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) count = gf_isom_get_chapter_count(file, trackNum); if (count) { - char szDur[20]; const char *name; u64 time; fprintf(stderr, "\nChapters:\n"); @@ -2763,58 +3013,21 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } } -static const char* ID3v1Genres[] = { - "Blues", "Classic Rock", "Country", "Dance", "Disco", - "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", - "New Age", "Oldies", "Other", "Pop", "R&B", - "Rap", "Reggae", "Rock", "Techno", "Industrial", - "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", - "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", - "Fusion", "Trance", "Classical", "Instrumental", "Acid", - "House", "Game", "Sound Clip", "Gospel", "Noise", - "AlternRock", "Bass", "Soul", "Punk", "Space", - "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", - "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", - "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", - "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", - "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", - "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", - "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", - "Folk", "Folk/Rock", "National Folk", "Swing", -}; -static const char *id3_get_genre(u32 tag) -{ - if ((tag>0) && (tag <= (sizeof(ID3v1Genres)/sizeof(const char *)) )) { - return ID3v1Genres[tag-1]; - } - return "Unknown"; -} -u32 id3_get_genre_tag(const char *name) -{ - u32 i, count = sizeof(ID3v1Genres)/sizeof(const char *); - if (!name) return 0; - for (i=0; iSDTs) ; GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Program Description found - %d desc:\n", count)); for (i=0; iSDTs, i); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("\tServiceID %d - Provider %s - Name %s\n", sdt->service_id, sdt->provider, sdt->service)); } +#endif break; case GF_M2TS_EVT_SDT_UPDATE: +#ifndef GPAC_DISABLE_LOG count = gf_list_count(ts->SDTs) ; GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Program Description updated - %d desc\n", count)); for (i=0; iSDTs, i); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("\tServiceID %d - Provider %s - Name %s\n", sdt->service_id, sdt->provider, sdt->service)); } +#endif break; case GF_M2TS_EVT_SDT_REPEAT: break; @@ -3119,7 +3340,7 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) if (interpolated_pcr_value) fprintf(dumper->timestamps_info_file, "%f", interpolated_pcr_value/(300.0 * 90000)); fprintf(dumper->timestamps_info_file, "\t"); if (pck->DTS) fprintf(dumper->timestamps_info_file, "%f", (pck->DTS / 90000.0)); - fprintf(dumper->timestamps_info_file, "\t%f\t%d\t%d", pck->PTS / 90000.0, (pck->flags & GF_M2TS_PES_PCK_RAP ? 1 : 0), (pck->flags & GF_M2TS_PES_PCK_DISCONTINUITY ? 1 : 0)); + fprintf(dumper->timestamps_info_file, "\t%f\t%d\t%d", pck->PTS / 90000.0, (pck->flags & GF_M2TS_PES_PCK_RAP) ? 1 : 0, (pck->flags & GF_M2TS_PES_PCK_DISCONTINUITY) ? 1 : 0); if (interpolated_pcr_value) { diff = (pck->DTS ? pck->DTS : pck->PTS) / 90000.0; diff -= pes->last_pcr_value / (300.0 * 90000); @@ -3132,7 +3353,7 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) } if (dumper->has_seen_pat && dumper->pes_out && (dumper->dump_pid == pck->stream->pid)) { - gf_fwrite(pck->data, pck->data_len, 1, dumper->pes_out); + gf_fwrite(pck->data, pck->data_len, dumper->pes_out); } break; case GF_M2TS_EVT_PES_PCR: @@ -3140,7 +3361,7 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) if (gf_list_count(ts->programs)>1 && pck->stream->program->number != dumper->prog_number) break; if (dumper->timestamps_info_file) { - fprintf(dumper->timestamps_info_file, "%u\t%d\t%f\t\t\t\t%d\n", pck->stream->program->last_pcr_value_pck_number, pck->stream->pid, pck->PTS / (300*90000.0), (pck->flags & GF_M2TS_PES_PCK_DISCONTINUITY ? 1 : 0)); + fprintf(dumper->timestamps_info_file, "%u\t%d\t%f\t\t\t\t%d\n", pck->stream->program->last_pcr_value_pck_number, pck->stream->pid, pck->PTS / (300*90000.0), (pck->flags & GF_M2TS_PES_PCK_DISCONTINUITY) ? 1 : 0); } break; case GF_M2TS_EVT_SL_PCK: @@ -3153,7 +3374,7 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) if (sl_pck->stream->mpeg4_es_id) { GF_ESD *esd = ((GF_M2TS_PES*)sl_pck->stream)->esd; if (!dumper->is_info_dumped) { - if (esd->decoderConfig->decoderSpecificInfo) gf_fwrite(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, 1, dumper->pes_out_info); + if (esd->decoderConfig->decoderSpecificInfo) gf_fwrite(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, dumper->pes_out_info); dumper->is_info_dumped = 1; fprintf(dumper->pes_out_nhml, "pes_out_nhml, "timeScale=\"%d\" ", esd->slConfig->timestampResolution); @@ -3164,8 +3385,8 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) fprintf(dumper->pes_out_nhml, "inRootOD=\"yes\">\n"); } gf_sl_depacketize(esd->slConfig, &header, sl_pck->data, sl_pck->data_len, &header_len); - gf_fwrite(sl_pck->data+header_len, sl_pck->data_len-header_len, 1, dumper->pes_out); - fprintf(dumper->pes_out_nhml, "\n", LLD_CAST header.decodingTimeStamp, sl_pck->data_len-header_len, (header.randomAccessPointFlag?"yes":"no")); + gf_fwrite(sl_pck->data+header_len, sl_pck->data_len-header_len, dumper->pes_out); + fprintf(dumper->pes_out_nhml, "\n", header.decodingTimeStamp, sl_pck->data_len-header_len, (header.randomAccessPointFlag?"yes":"no")); } } } @@ -3176,7 +3397,7 @@ static void on_m2ts_dump_event(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num) { - char data[188]; + u8 data[188]; GF_M2TS_Dump dumper; u32 size; @@ -3184,6 +3405,10 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num) GF_M2TS_Demuxer *ts; FILE *src; + if (!prog_num && !out_name) { + fprintf(stderr, "No program number nor output filename specified. No timestamp file will be generated."); + } + src = gf_fopen(mpeg2ts_file, "rb"); if (!src) { fprintf(stderr, "Cannot open %s: no such file\n", mpeg2ts_file); @@ -3220,7 +3445,7 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num) /* first loop to process all packets between two PAT, and assume all signaling was found between these 2 PATs */ while (!feof(src)) { - size = (u32) fread(data, 1, 188, src); + size = (u32) gf_fread(data, 188, src); if (size<188) break; gf_m2ts_process_data(ts, data, size); @@ -3228,6 +3453,16 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num) } dumper.has_seen_pat = GF_TRUE; + if (!prog_num) { + GF_M2TS_Program *p = gf_list_get(ts->programs, 0); + if (p) prog_num = p->number; + fprintf(stderr, "No program number specified, defaulting to first program\n"); + } + + if (!prog_num && !out_name) { + fprintf(stderr, "No program number nor output filename specified. No timestamp file will be generated\n"); + } + if (prog_num) { sprintf(dumper.timestamps_info_name, "%s_prog_%d_timestamps.txt", mpeg2ts_file, prog_num/*, mpeg2ts_file*/); dumper.timestamps_info_file = gf_fopen(dumper.timestamps_info_name, "wt"); @@ -3243,7 +3478,7 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num) fdone = 0; while (!feof(src)) { - size = (u32) fread(data, 1, 188, src); + size = (u32) gf_fread(data, 188, src); if (size<188) break; gf_m2ts_process_data(ts, data, size); @@ -3265,5 +3500,274 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *out_name, Bool prog_num) if (dumper.timestamps_info_file) gf_fclose(dumper.timestamps_info_file); } - #endif /*GPAC_DISABLE_MPEG2TS*/ + + +#include +#include + +void get_file_callback(void *usr_cbk, GF_NETIO_Parameter *parameter) +{ + if (parameter->msg_type==GF_NETIO_DATA_EXCHANGE) { + u64 tot_size, done, max; + u32 bps; + gf_dm_sess_get_stats(parameter->sess, NULL, NULL, &tot_size, &done, &bps, NULL); + if (tot_size) { + max = done; + max *= 100; + max /= tot_size; + fprintf(stderr, "download %02d %% at %05d kpbs\r", (u32) max, bps*8/1000); + } + } +} + +static GF_DownloadSession *get_file(const char *url, GF_DownloadManager *dm, GF_Err *e) +{ + GF_DownloadSession *sess; + sess = gf_dm_sess_new(dm, url, GF_NETIO_SESSION_NOT_THREADED, get_file_callback, NULL, e); + if (!sess) return NULL; + *e = gf_dm_sess_process(sess); + if (*e) { + gf_dm_sess_del(sess); + return NULL; + } + return sess; +} + +static void revert_cache_file(char *item_path) +{ + char szPATH[GF_MAX_PATH]; + const char *url; + GF_Config *cached; + + if (!strstr(item_path, "gpac_cache_")) { + fprintf(stderr, "%s is not a gpac cache file\n", item_path); + return; + } + if (!strncmp(item_path, "./", 2) || !strncmp(item_path, ".\\", 2)) + item_path += 2; + + strcpy(szPATH, item_path); + strcat(szPATH, ".txt"); + + cached = gf_cfg_new(NULL, szPATH); + url = gf_cfg_get_key(cached, "cache", "url"); + if (url) url = strstr(url, "://"); + if (url) { + u32 i, len, dir_len=0, k=0; + char *sep; + char *dst_name; + sep = strstr(item_path, "gpac_cache_"); + if (sep) { + sep[0] = 0; + dir_len = (u32) strlen(item_path); + sep[0] = 'g'; + } + url+=3; + len = (u32) strlen(url); + dst_name = gf_malloc(len+dir_len+1); + memset(dst_name, 0, len+dir_len+1); + + strncpy(dst_name, item_path, dir_len); + k=dir_len; + for (i=0; itype==GF_MPD_TYPE_DYNAMIC) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("MPD rip is not supported on live sources\n")); + e = GF_NOT_SUPPORTED; + goto err_exit; + } + + i=0; + while ((period = (GF_MPD_Period *) gf_list_enum(mpd->periods, &i))) { + char *initTemplate = NULL; + Bool segment_base = GF_FALSE; + u32 j=0; + + if (period->segment_base) segment_base=GF_TRUE; + + if (period->segment_template && period->segment_template->initialization) { + initTemplate = period->segment_template->initialization; + } + + while ((as = gf_list_enum(period->adaptation_sets, &j))) { + u32 k=0; + if (!initTemplate && as->segment_template && as->segment_template->initialization) { + initTemplate = as->segment_template->initialization; + } + if (as->segment_base) segment_base=GF_TRUE; + + while ((rep = gf_list_enum(as->representations, &k))) { + u64 out_range_start, out_range_end, segment_duration; + Bool is_in_base_url; + char *seg_url; + u32 seg_idx=0; + if (rep->segment_template && rep->segment_template->initialization) { + initTemplate = rep->segment_template->initialization; + } else if (k>1) { + initTemplate = NULL; + } + if (rep->segment_base) segment_base=GF_TRUE; + + e = gf_mpd_resolve_url(mpd, rep, as, period, mpd_src, 0, GF_MPD_RESOLVE_URL_INIT, 0, 0, &seg_url, &out_range_start, &out_range_end, &segment_duration, &is_in_base_url, NULL, NULL); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Error resolving init segment name : %s\n", gf_error_to_string(e))); + continue; + } + //not a byte range, replace URL + if (segment_base) { + + } else if (out_range_start || out_range_end || !seg_url) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("byte range rip not yet implemented\n")); + if (seg_url) gf_free(seg_url); + e = GF_NOT_SUPPORTED; + goto err_exit; + } + + fprintf(stderr, "Downloading %s\n", seg_url); + sess = get_file(seg_url, dm, &e); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Error downloading init segment %s from MPD %s : %s\n", seg_url, mpd_src, gf_error_to_string(e))); + goto err_exit; + } + revert_cache_file((char *) gf_dm_sess_get_cache_name(sess) ); + gf_free(seg_url); + gf_dm_sess_del(sess); + + if (segment_base) continue; + + while (1) { + e = gf_mpd_resolve_url(mpd, rep, as, period, mpd_src, 0, GF_MPD_RESOLVE_URL_MEDIA, seg_idx, 0, &seg_url, &out_range_start, &out_range_end, &segment_duration, NULL, NULL, NULL); + if (e) { + if (e<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Error resolving segment name : %s\n", gf_error_to_string(e))); + } + break; + } + + seg_idx++; + + if (out_range_start || out_range_end || !seg_url) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("byte range rip not yet implemented\n")); + if (seg_url) gf_free(seg_url); + break; + } + fprintf(stderr, "Downloading %s\n", seg_url); + sess = get_file(seg_url, dm, &e); + if (e) { + gf_free(seg_url); + if (e != GF_URL_ERROR) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Error downloading segment %s: %s\n", seg_url, gf_error_to_string(e))); + } else { + //todo, properly detect end of dash representation + e = GF_OK; + } + break; + } + revert_cache_file((char *) gf_dm_sess_get_cache_name(sess) ); + gf_free(seg_url); + gf_dm_sess_del(sess); + } + } + } + } + +err_exit: + if (mpd) gf_mpd_del(mpd); + gf_dm_del(dm); + return e; +} diff --git a/applications/mp4box/fileimport.c b/applications/mp4box/fileimport.c index 437110b..1ad2e19 100644 --- a/applications/mp4box/fileimport.c +++ b/applications/mp4box/fileimport.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2012 + * Copyright (c) Telecom ParisTech 2000-2020 * All rights reserved * * This file is part of GPAC / mp4box application @@ -24,7 +24,8 @@ */ -#include +#include "mp4box.h" + #include #include #include @@ -46,6 +47,7 @@ #ifndef GPAC_DISABLE_ISOM_WRITE #include +#include typedef struct { @@ -56,7 +58,7 @@ typedef struct GF_Err set_file_udta(GF_ISOFile *dest, u32 tracknum, u32 udta_type, char *src, Bool is_box_array) { - char *data = NULL; + u8 *data = NULL; GF_Err res = GF_OK; u32 size; bin128 uuid; @@ -64,7 +66,7 @@ GF_Err set_file_udta(GF_ISOFile *dest, u32 tracknum, u32 udta_type, char *src, B if (!udta_type && !is_box_array) return GF_BAD_PARAM; - if (!src) { + if (!src || !strlen(src)) { return gf_isom_remove_user_data(dest, tracknum, udta_type, uuid); } @@ -73,22 +75,12 @@ GF_Err set_file_udta(GF_ISOFile *dest, u32 tracknum, u32 udta_type, char *src, B src += 7; size = (u32) strlen(src); data = gf_malloc(sizeof(char) * size); - size = gf_base64_decode(src, size, data, size); + size = gf_base64_decode((u8 *)src, size, data, size); } else #endif { - FILE *t = gf_fopen(src, "rb"); - if (!t) return GF_IO_ERR; - fseek(t, 0, SEEK_END); - size = ftell(t); - fseek(t, 0, SEEK_SET); - data = gf_malloc(sizeof(char)*size); - if (size != fread(data, 1, size, t) ) { - gf_free(data); - gf_fclose(t); - return GF_IO_ERR; - } - gf_fclose(t); + GF_Err e = gf_file_load_data(src, (u8 **) &data, &size); + if (e) return e; } if (size && data) { @@ -107,10 +99,11 @@ GF_Err set_file_udta(GF_ISOFile *dest, u32 tracknum, u32 udta_type, char *src, B extern u32 swf_flags; extern Float swf_flatten_angle; extern Bool keep_sys_tracks; +extern u32 fs_dump_flags; void scene_coding_log(void *cbk, GF_LOG_Level log_level, GF_LOG_Tool log_tool, const char *fmt, va_list vlist); -void convert_file_info(char *inName, u32 trackID) +void convert_file_info(char *inName, GF_ISOTrackID trackID) { GF_Err e; u32 i; @@ -120,6 +113,8 @@ void convert_file_info(char *inName, u32 trackID) import.trackID = trackID; import.in_name = inName; import.flags = GF_IMPORT_PROBE_ONLY; + import.print_stats_graph = fs_dump_flags; + e = gf_media_import(&import); if (e) { fprintf(stderr, "Error probing file %s: %s\n", inName, gf_error_to_string(e)); @@ -144,80 +139,73 @@ void convert_file_info(char *inName, u32 trackID) if (!trackID) fprintf(stderr, "\tTrack %d type: ", import.tk_info[i].track_num); else fprintf(stderr, "Track type: "); - switch (import.tk_info[i].type) { - case GF_ISOM_MEDIA_VISUAL: - fprintf(stderr, "Video (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); + switch (import.tk_info[i].stream_type) { + case GF_STREAM_VISUAL: + if (import.tk_info[i].media_subtype == GF_ISOM_MEDIA_AUXV) fprintf(stderr, "Auxiliary Video"); + else if (import.tk_info[i].media_subtype == GF_ISOM_MEDIA_PICT) fprintf(stderr, "Picture Sequence"); + else fprintf(stderr, "Video"); + if (import.tk_info[i].video_info.temporal_enhancement) fprintf(stderr, " Temporal Enhancement"); break; - case GF_ISOM_MEDIA_AUDIO: - fprintf(stderr, "Audio (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); + case GF_STREAM_AUDIO: + fprintf(stderr, "Audio"); break; - case GF_ISOM_MEDIA_TEXT: - fprintf(stderr, "Text (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); + case GF_STREAM_TEXT: + fprintf(stderr, "Text"); break; - case GF_ISOM_MEDIA_SCENE: - fprintf(stderr, "Scene (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); + case GF_STREAM_SCENE: + fprintf(stderr, "Scene"); break; - case GF_ISOM_MEDIA_OD: - fprintf(stderr, "OD (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); + case GF_STREAM_OD: + fprintf(stderr, "OD"); break; - case GF_ISOM_MEDIA_META: - fprintf(stderr, "Metadata (%s)", gf_4cc_to_str(import.tk_info[i].media_type)); + case GF_STREAM_METADATA: + fprintf(stderr, "Metadata"); break; default: - fprintf(stderr, "Other (4CC: %s)", gf_4cc_to_str(import.tk_info[i].type)); + fprintf(stderr, "Other (%s)", gf_4cc_to_str(import.tk_info[i].stream_type)); break; } + if (import.tk_info[i].codecid) fprintf(stderr, " Codec %s (ID %d)", gf_codecid_name(import.tk_info[i].codecid), import.tk_info[i].codecid); - if (import.tk_info[i].lang) fprintf(stderr, " - lang %s", gf_4cc_to_str(import.tk_info[i].lang)); + if (import.tk_info[i].lang) fprintf(stderr, " lang %s", gf_4cc_to_str(import.tk_info[i].lang)); - if (import.tk_info[i].mpeg4_es_id) fprintf(stderr, " - MPEG-4 ESID %d", import.tk_info[i].mpeg4_es_id); + if (import.tk_info[i].mpeg4_es_id) fprintf(stderr, " MPEG-4 ESID %d", import.tk_info[i].mpeg4_es_id); if (import.tk_info[i].prog_num) { if (!import.nb_progs) { - fprintf(stderr, " - Program %d", import.tk_info[i].prog_num); + fprintf(stderr, " Program %d", import.tk_info[i].prog_num); } else { u32 j; for (j=0; j> 16, import.tk_info[i].video_info.par & 0xFFFF); + if (import.tk_info[i].stream_type==GF_STREAM_VISUAL) { + if (import.tk_info[i].video_info.par) fprintf(stderr, " PAR: %d:%d", import.tk_info[i].video_info.par >> 16, import.tk_info[i].video_info.par & 0xFFFF); + } + fprintf(stderr, "\n"); } - else if ((import.tk_info[i].type==GF_ISOM_MEDIA_AUDIO) && import.tk_info[i].audio_info.sample_rate) { - fprintf(stderr, "Source: %s - SampleRate %d - %d channels\n", gf_4cc_to_str(import.tk_info[i].media_type), import.tk_info[i].audio_info.sample_rate, import.tk_info[i].audio_info.nb_channels); - } else { - fprintf(stderr, "Source: %s\n", gf_4cc_to_str(import.tk_info[i].media_type)); + else if ((import.tk_info[i].stream_type==GF_STREAM_AUDIO) && import.tk_info[i].audio_info.sample_rate) { + fprintf(stderr, "\tSampleRate %d - %d channels\n", import.tk_info[i].audio_info.sample_rate, import.tk_info[i].audio_info.nb_channels); } - - fprintf(stderr, "\nImport Capabilities:\n"); - if (import.tk_info[i].flags & GF_IMPORT_USE_DATAREF) fprintf(stderr, "\tCan use data referencing\n"); - if (import.tk_info[i].flags & GF_IMPORT_NO_FRAME_DROP) fprintf(stderr, "\tCan use fixed FPS import\n"); - if (import.tk_info[i].flags & GF_IMPORT_FORCE_PACKED) fprintf(stderr, "\tCan force packed bitstream import\n"); - if (import.tk_info[i].flags & GF_IMPORT_OVERRIDE_FPS) fprintf(stderr, "\tCan override source frame rate\n"); - if (import.tk_info[i].flags & (GF_IMPORT_SBR_IMPLICIT|GF_IMPORT_SBR_EXPLICIT)) fprintf(stderr, "\tCan use AAC-SBR signaling\n"); - if (import.tk_info[i].flags & (GF_IMPORT_PS_IMPLICIT|GF_IMPORT_PS_EXPLICIT)) fprintf(stderr, "\tCan use AAC-PS signaling\n"); - if (import.tk_info[i].flags & GF_IMPORT_FORCE_MPEG4) fprintf(stderr, "\tCan force MPEG-4 Systems signaling\n"); - if (import.tk_info[i].flags & GF_IMPORT_3GPP_AGGREGATION) fprintf(stderr, "\tCan use 3GPP frame aggregation\n"); - if (import.tk_info[i].flags & GF_IMPORT_NO_DURATION) fprintf(stderr, "\tCannot use duration-based import\n"); - - found = 1; - break; + if (trackID) { + found = 1; + break; + } } fprintf(stderr, "\n"); + fprintf(stderr, "For more details, use `gpac -i %s inspect[:deep][:analyze]`\n", gf_file_basename(inName)); if (!found && trackID) fprintf(stderr, "Cannot find track %d in file\n", trackID); } @@ -226,8 +214,8 @@ static void set_chapter_track(GF_ISOFile *file, u32 track, u32 chapter_ref_trak) u64 ref_duration, chap_duration; Double scale; - gf_isom_set_track_reference(file, chapter_ref_trak, GF_4CC('c','h','a','p'), gf_isom_get_track_id(file, track) ); - gf_isom_set_track_enabled(file, track, 0); + gf_isom_set_track_reference(file, chapter_ref_trak, GF_ISOM_REF_CHAP, gf_isom_get_track_id(file, track) ); + gf_isom_set_track_enabled(file, track, GF_FALSE); ref_duration = gf_isom_get_media_duration(file, chapter_ref_trak); chap_duration = gf_isom_get_media_duration(file, track); @@ -240,27 +228,96 @@ static void set_chapter_track(GF_ISOFile *file, u32 track, u32 chapter_ref_trak) chap_duration = ref_duration - chap_duration; gf_isom_set_last_sample_duration(file, track, (u32) chap_duration); } +#ifdef GPAC_ENABLE_COVERAGE + if (gf_sys_is_cov_mode()) { + u8 NbBits; + u32 switchGroupID, nb_crit, size, reserved; + u8 priority; + Bool discardable; + GF_AudioChannelLayout layout; + gf_isom_get_sample_size(file, track, 1); + gf_isom_get_sample_dts(file, track, 1); + gf_isom_get_sample_from_dts(file, track, 0); + gf_isom_set_sample_padding(file, track, 0); + gf_isom_has_padding_bits(file, track); + gf_isom_get_sample_padding_bits(file, track, 1, &NbBits); + gf_isom_keep_utc_times(file, 1); +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + gf_isom_set_single_moof_mode(file, GF_TRUE); + gf_isom_reset_sample_count(NULL); + gf_isom_set_traf_mss_timeext(NULL, 0, 0, 0); + gf_isom_get_next_moof_number(NULL); + gf_isom_set_fragment_reference_time(NULL, 0, 0, 0); +#endif + //this one is not tested in master due to old-arch compat, to remove when we enable tests without old-arch + gf_isom_get_audio_layout(file, track, 1, &layout); + + gf_isom_get_track_switch_parameter(file, track, 1, &switchGroupID, &nb_crit); + gf_isom_sample_has_subsamples(file, track, 1, 0); + gf_isom_sample_get_subsample(file, track, 1, 0, 1, &size, &priority, &reserved, &discardable); +#ifndef GPAC_DISABLE_ISOM_HINTING + gf_isom_hint_blank_data(NULL, 0, 0); + gf_isom_hint_sample_description_data(NULL, 0, 0, 1, 0, 0, 0); + gf_isom_get_payt_info(NULL, 0, 0, NULL); +#endif + gf_isom_estimate_size(file); + + } +#endif } -GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample) +GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, GF_FilterSession *fsess, char **mux_args_if_first_pass, u32 tk_idx) { - u32 track_id, i, j, timescale, track, stype, profile, level, new_timescale, rescale, svc_mode, txt_flags, split_tile_mode, temporal_mode; - s32 par_d, par_n, prog_id, delay; + u32 track_id, i, j, timescale, track, stype, profile, level, new_timescale, rescale_num, rescale_den, svc_mode, txt_flags, split_tile_mode, temporal_mode, nb_tracks; + s32 par_d, par_n, prog_id, delay, force_rate, moov_timescale; s32 tw, th, tx, ty, txtw, txth, txtx, txty; - Bool do_audio, do_video, do_all, disable, track_layout, text_layout, chap_ref, is_chap, is_chap_file, keep_handler, negative_cts_offset, rap_only; + Bool do_audio, do_video, do_auxv,do_pict, do_all, disable, track_layout, text_layout, chap_ref, is_chap, is_chap_file, keep_handler, negative_cts_offset, rap_only, refs_only, force_par, rewrite_bs; u32 group, handler, rvc_predefined, check_track_for_svc, check_track_for_lhvc, check_track_for_hevc; const char *szLan; - GF_Err e; + GF_Err e = GF_OK; + u32 tmcd_track = 0; + Bool keep_audelim = GF_FALSE; + u32 print_stats_graph=fs_dump_flags; GF_MediaImporter import; char *ext, szName[1000], *handler_name, *rvc_config, *chapter_name; GF_List *kinds; GF_TextFlagsMode txt_mode = GF_ISOM_TEXT_FLAGS_OVERWRITE; u8 max_layer_id_plus_one, max_temporal_id_plus_one; + u32 clap_wn, clap_wd, clap_hn, clap_hd, clap_hon, clap_hod, clap_von, clap_vod; + Bool has_clap=GF_FALSE; + Bool use_stz2=GF_FALSE; + Bool has_mx=GF_FALSE; + s32 mx[9]; + u32 bitdepth=0; + u32 dv_profile=0; /*Dolby Vision*/ + u32 clr_type=0; + u32 clr_prim; + u32 clr_tranf; + u32 clr_mx; + u32 clr_full_range=GF_FALSE; + Bool fmt_ok = GF_TRUE; + u32 icc_size=0; + u8 *icc_data = NULL; + u32 tc_fps_num=0, tc_fps_den=0, tc_h=0, tc_m=0, tc_s=0, tc_f=0, tc_frames_per_tick=0; + Bool tc_force_counter=GF_FALSE; + Bool tc_drop_frame = GF_FALSE; + char *ext_start; + u32 xps_inband=0; + u64 source_magic=0; + char *opt_src = NULL; + char *opt_dst = NULL; + char *fchain = NULL; + Bool set_ccst=GF_FALSE; + Bool has_last_sample_dur=GF_FALSE; + GF_Fraction last_sample_dur = {0,0}; + + clap_wn = clap_wd = clap_hn = clap_hd = clap_hon = clap_hod = clap_von = clap_vod = 0; rvc_predefined = 0; chapter_name = NULL; new_timescale = 1; - rescale = 0; + moov_timescale = 0; + rescale_num = rescale_den = 0; text_layout = 0; /*0: merge all 1: split base and all SVC in two tracks @@ -296,38 +353,91 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc split_tile_mode = 0; temporal_mode = 0; rap_only = 0; + refs_only = 0; txt_flags = 0; max_layer_id_plus_one = max_temporal_id_plus_one = 0; + force_rate = -1; tw = th = tx = ty = txtw = txth = txtx = txty = 0; - par_d = par_n = -2; - /*use ':' as separator, but beware DOS paths...*/ - ext = strchr(szName, ':'); - if (ext && ext[1]=='\\') ext = strchr(szName+2, ':'); + par_d = par_n = -1; + force_par = rewrite_bs = GF_FALSE; + + ext = gf_url_colon_suffix(szName); handler_name = NULL; rvc_config = NULL; while (ext) { - char *ext2 = strchr(ext+1, ':'); - if (ext2 && !strncmp(ext2, "://", 3)) ext2 = strchr(ext2+1, ':'); - if (ext2 && !strncmp(ext2, ":\\", 2)) ext2 = strchr(ext2+1, ':'); + char *ext2 = gf_url_colon_suffix(ext+1); + if (ext2) ext2[0] = 0; /*all extensions for track-based importing*/ - if (!strnicmp(ext+1, "dur=", 4)) import.duration = (u32) (atof(ext+5) * 1000); - else if (!strnicmp(ext+1, "lang=", 5)) szLan = ext+6; + if (!strnicmp(ext+1, "dur=", 4)) { + s32 dur_n=0, dur_d=0; + if (strchr(ext, '/')) { + sscanf(ext+5, "%d/%d", &dur_n, &dur_d); + } else if (strchr(ext, '-')) { + dur_n = atoi(ext+5); + dur_d = 1; + } else { + //use 1/10 of millisecond precision + dur_n = (u32)( (atof(ext+5) * 10000) + 0.5 ); + dur_d = 10000; + } + import.duration.num = dur_n; + import.duration.den = dur_d; + } + else if (!strnicmp(ext+1, "lang=", 5)) { + /* prevent leak if param is set twice */ + if (szLan) + gf_free((char*) szLan); + + szLan = gf_strdup(ext+6); + } else if (!strnicmp(ext+1, "delay=", 6)) delay = atoi(ext+7); else if (!strnicmp(ext+1, "par=", 4)) { - if (!stricmp(ext+5, "none")) { - par_n = par_d = -1; + if (!stricmp(ext + 5, "none")) { + par_n = par_d = 0; + } else if (!stricmp(ext + 5, "auto")) { + force_par = GF_TRUE; + } else if (!stricmp(ext + 5, "force")) { + par_n = par_d = 1; + force_par = GF_TRUE; } else { - if (ext2) ext2[0] = ':'; - if (ext2) ext2 = strchr(ext2+1, ':'); - if (ext2) ext2[0] = 0; - sscanf(ext+5, "%d:%d", &par_n, &par_d); + if (ext2) { + ext2[0] = ':'; + ext2 = strchr(ext2+1, ':'); + if (ext2) ext2[0] = 0; + } + if (ext[5]=='w') { + rewrite_bs = GF_TRUE; + sscanf(ext+6, "%d:%d", &par_n, &par_d); + } else { + sscanf(ext+5, "%d:%d", &par_n, &par_d); + } + } + } + else if (!strnicmp(ext+1, "clap=", 5)) { + if (!stricmp(ext+6, "none")) { + has_clap=GF_TRUE; + } else { + if (sscanf(ext+6, "%d,%d,%d,%d,%d,%d,%d,%d", &clap_wn, &clap_wd, &clap_hn, &clap_hd, &clap_hon, &clap_hod, &clap_von, &clap_vod)==8) { + has_clap=GF_TRUE; + } } } - else if (!strnicmp(ext+1, "name=", 5)) handler_name = gf_strdup(ext+6); + else if (!strnicmp(ext+1, "mx=", 3)) { + if (strstr(ext+4, "0x")) { + if (sscanf(ext+4, "0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d", &mx[0], &mx[1], &mx[2], &mx[3], &mx[4], &mx[5], &mx[6], &mx[7], &mx[8])==9) { + has_mx=GF_TRUE; + } + } else if (sscanf(ext+4, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &mx[0], &mx[1], &mx[2], &mx[3], &mx[4], &mx[5], &mx[6], &mx[7], &mx[8])==9) { + has_mx=GF_TRUE; + } + } + else if (!strnicmp(ext+1, "name=", 5)) { + handler_name = gf_strdup(ext+6); + } else if (!strnicmp(ext+1, "ext=", 4)) { /*extensions begin with '.'*/ if (*(ext+5) == '.') @@ -345,20 +455,24 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc if (!group) group = gf_isom_get_next_alternate_group_id(dest); } else if (!strnicmp(ext+1, "fps=", 4)) { - if (!strcmp(ext+5, "auto")) force_fps = GF_IMPORT_AUTO_FPS; - else if (strchr(ext+5, '-')) { - u32 ticks, dts_inc; - sscanf(ext+5, "%u-%u", &ticks, &dts_inc); + u32 ticks, dts_inc; + if (!strcmp(ext+5, "auto")) { + fprintf(stderr, "Warning, fps=auto option is deprecated\n"); + } else if ((sscanf(ext+5, "%u-%u", &ticks, &dts_inc) == 2) || (sscanf(ext+5, "%u/%u", &ticks, &dts_inc) == 2)) { if (!dts_inc) dts_inc=1; - force_fps = ticks; - force_fps /= dts_inc; + force_fps.num = ticks; + force_fps.den = dts_inc; + } else { + force_fps.den = 1000; + force_fps.num = (u32) (atof(ext+5) * force_fps.den); } - else force_fps = atof(ext+5); } else if (!stricmp(ext+1, "rap")) rap_only = 1; + else if (!stricmp(ext+1, "refs")) refs_only = 1; else if (!stricmp(ext+1, "trailing")) import_flags |= GF_IMPORT_KEEP_TRAILING; else if (!strnicmp(ext+1, "agg=", 4)) frames_per_sample = atoi(ext+5); else if (!stricmp(ext+1, "dref")) import_flags |= GF_IMPORT_USE_DATAREF; + else if (!stricmp(ext+1, "keep_refs")) import_flags |= GF_IMPORT_KEEP_REFS; 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; @@ -378,14 +492,16 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc if (!stricmp(mode, "splitnox")) svc_mode = 3; + else if (!stricmp(mode, "splitnoxib")) + svc_mode = 4; else if (!stricmp(mode, "splitall") || !stricmp(mode, "split")) svc_mode = 2; else if (!stricmp(mode, "splitbase")) svc_mode = 1; - else if (!stricmp(mode, "merged")) + else if (!stricmp(mode, "merged") || !stricmp(mode, "merge")) svc_mode = 0; } - /*split SVC layers*/ + /*split SHVC temporal sublayers*/ else if (!strnicmp(ext+1, "temporal=", 9)) { char *mode = ext+10; if (!stricmp(mode, "split")) @@ -400,8 +516,13 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc } } else if (!stricmp(ext+1, "subsamples")) import_flags |= GF_IMPORT_SET_SUBSAMPLES; + else if (!stricmp(ext+1, "deps")) import_flags |= GF_IMPORT_SAMPLE_DEPS; + else if (!stricmp(ext+1, "ccst")) set_ccst = GF_TRUE; + else if (!stricmp(ext+1, "alpha")) import.is_alpha = GF_TRUE; else if (!stricmp(ext+1, "forcesync")) import_flags |= GF_IMPORT_FORCE_SYNC; - else if (!stricmp(ext+1, "xps_inband")) import_flags |= GF_IMPORT_FORCE_XPS_INBAND; + else if (!stricmp(ext+1, "xps_inband")) xps_inband = 1; + else if (!stricmp(ext+1, "xps_inbandx")) xps_inband = 2; + else if (!stricmp(ext+1, "au_delim")) keep_audelim = GF_TRUE; else if (!strnicmp(ext+1, "max_lid=", 8) || !strnicmp(ext+1, "max_tid=", 8)) { s32 val = atoi(ext+9); if (val < 0) { @@ -409,7 +530,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc } else { if (!strnicmp(ext+1, "max_lid=", 8)) max_layer_id_plus_one = 1 + (u8) val; - else + else max_temporal_id_plus_one = 1 + (u8) val; } } @@ -423,7 +544,9 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc stype = GF_4CC(ext[7], ext[8], ext[9], ext[10]); } else if (!stricmp(ext+1, "chap")) is_chap = 1; - else if (!strnicmp(ext+1, "chapter=", 8)) chapter_name = gf_strdup(ext+9); + else if (!strnicmp(ext+1, "chapter=", 8)) { + chapter_name = gf_strdup(ext+9); + } else if (!strnicmp(ext+1, "chapfile=", 9)) { chapter_name = gf_strdup(ext+10); is_chap_file=1; @@ -437,11 +560,18 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc } } else if (!strnicmp(ext+1, "rescale=", 8)) { - rescale = atoi(ext+9); + if (sscanf(ext+9, "%d/%d", &rescale_num, &rescale_den) != 2) { + rescale_num = atoi(ext+9); + rescale_den = 0; + } } else if (!strnicmp(ext+1, "timescale=", 10)) { new_timescale = atoi(ext+11); } + else if (!strnicmp(ext+1, "moovts=", 7)) { + moov_timescale = atoi(ext+8); + } + else if (!stricmp(ext+1, "noedit")) import_flags |= GF_IMPORT_NO_EDIT_LIST; @@ -454,6 +584,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc else if (!strnicmp(ext+1, "profile=", 8)) profile = atoi(ext+9); else if (!strnicmp(ext+1, "level=", 6)) level = atoi(ext+7); else if (!strnicmp(ext+1, "novpsext", 8)) import_flags |= GF_IMPORT_NO_VPS_EXTENSIONS; + else if (!strnicmp(ext+1, "keepav1t", 8)) import_flags |= GF_IMPORT_KEEP_AV1_TEMPORAL_OBU; 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); @@ -479,7 +610,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc else if (!stricmp(ext+1, "swf-same-app")) import.swf_flags |= GF_SM_SWF_REUSE_APPEARANCE; else if (!strnicmp(ext+1, "swf-flatten=", 12)) import.swf_flatten_angle = (Float) atof(ext+13); #endif - + else if (!strnicmp(ext+1, "kind=", 5)) { char *kind_scheme, *kind_value; char *kind_data = ext+6; @@ -510,10 +641,142 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc txt_mode = GF_ISOM_TEXT_FLAGS_UNTOGGLE; } } + else if (!strnicmp(ext+1, "rate=", 5)) { + force_rate = atoi(ext+6); + } + else if (!stricmp(ext+1, "fstat")) + print_stats_graph |= 1; + else if (!stricmp(ext+1, "fgraph")) + print_stats_graph |= 2; + else if (!strncmp(ext+1, "sopt", 4) || !strncmp(ext+1, "dopt", 4) || !strncmp(ext+1, "@@", 2)) { + if (ext2) ext2[0] = ':'; + opt_src = strstr(ext, ":sopt:"); + opt_dst = strstr(ext, ":dopt:"); + fchain = strstr(ext, ":@@"); + if (opt_src) opt_src[0] = 0; + if (opt_dst) opt_dst[0] = 0; + if (fchain) fchain[0] = 0; + + if (opt_src) import.filter_src_opts = opt_src+6; + if (opt_dst) import.filter_dst_opts = opt_dst+6; + if (fchain) import.filter_chain = fchain+3; + ext = NULL; + break; + } + + else if (!strnicmp(ext+1, "asemode=", 8)){ + char *mode = ext+9; + if (!stricmp(mode, "v0-bs")) + import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v0_BS; + else if (!stricmp(mode, "v0-2")) + import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v0_2; + else if (!stricmp(mode, "v1")) + import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v1_MPEG; + else if (!stricmp(mode, "v1-qt")) + import.asemode = GF_IMPORT_AUDIO_SAMPLE_ENTRY_v1_QTFF; + else + fprintf(stderr, "Unrecognized audio sample entry mode %s, ignoring\n", mode); + } + + else if (!strnicmp(ext+1, "audio_roll=", 11)) { + import.audio_roll_change = GF_TRUE; + import.audio_roll = atoi(ext+12); + } + else if (!strcmp(ext+1, "stz2")) { + use_stz2 = GF_TRUE; + } else if (!strnicmp(ext+1, "bitdepth=", 9)) { + bitdepth=atoi(ext+10); + } + else if (!strnicmp(ext+1, "colr=", 5)) { + char *cval = ext+6; + if (strlen(cval)<6) { + fmt_ok = GF_FALSE; + } else { + clr_type = GF_4CC(cval[0],cval[1],cval[2],cval[3]); + cval+=4; + if (cval[0] != ',') { + fmt_ok = GF_FALSE; + } + else if (clr_type==GF_ISOM_SUBTYPE_NCLX) { + if (sscanf(cval+1, "%d,%d,%d,%d", &clr_prim, &clr_tranf, &clr_mx, &clr_full_range) != 4) + fmt_ok=GF_FALSE; + } + else if (clr_type==GF_ISOM_SUBTYPE_NCLC) { + if (sscanf(cval+1, "%d,%d,%d", &clr_prim, &clr_tranf, &clr_mx) != 3) + fmt_ok=GF_FALSE; + } + else if ((clr_type==GF_ISOM_SUBTYPE_RICC) || (clr_type==GF_ISOM_SUBTYPE_PROF)) { + FILE *f = gf_fopen(cval+1, "rb"); + if (!f) { + fprintf(stderr, "Failed to open file %s\n", cval+1); + fmt_ok = GF_FALSE; + } else { + gf_fseek(f, 0, SEEK_END); + icc_size = (u32) gf_ftell(f); + icc_data = gf_malloc(sizeof(char)*icc_size); + gf_fseek(f, 0, SEEK_SET); + icc_size = (u32) gf_fread(icc_data, icc_size, f); + gf_fclose(f); + } + } else { + fprintf(stderr, "unrecognized profile %s\n", gf_4cc_to_str(clr_type) ); + fmt_ok = GF_FALSE; + } + } + if (!fmt_ok) { + fprintf(stderr, "Bad format for clr option, check help\n"); + e = GF_BAD_PARAM; + goto exit; + } + } + else if (!strnicmp(ext + 1, "dv-profile=", 11)) { + dv_profile = atoi(ext + 12); + } + else if (!strnicmp(ext+1, "tc=", 3)) { + char *tc_str = ext+4; + if (tc_str[0] == 'd') { + tc_drop_frame=GF_TRUE; + tc_str+=1; + } + if (sscanf(tc_str, "%d/%d,%d,%d,%d,%d,%d", &tc_fps_num, &tc_fps_den, &tc_h, &tc_m, &tc_s, &tc_f, &tc_frames_per_tick) == 7) { + } else if (sscanf(tc_str, "%d/%d,%d,%d,%d,%d", &tc_fps_num, &tc_fps_den, &tc_h, &tc_m, &tc_s, &tc_f) == 6) { + } else if (sscanf(tc_str, "%d,%d,%d,%d,%d,%d", &tc_fps_num, &tc_h, &tc_m, &tc_s, &tc_f, &tc_frames_per_tick) == 6) { + tc_fps_den = 1; + } else if (sscanf(tc_str, "%d,%d,%d,%d,%d", &tc_fps_num, &tc_h, &tc_m, &tc_s, &tc_f) == 5) { + tc_fps_den = 1; + } else if (sscanf(tc_str, "%d/%d,%d,%d", &tc_fps_num, &tc_fps_den, &tc_f, &tc_frames_per_tick) == 4) { + tc_force_counter = GF_TRUE; + tc_h = tc_m = tc_s = 0; + } else if (sscanf(tc_str, "%d/%d,%d", &tc_fps_num, &tc_fps_den, &tc_f) == 3) { + tc_force_counter = GF_TRUE; + tc_h = tc_m = tc_s = 0; + } else if (sscanf(tc_str, "%d,%d,%d", &tc_fps_num, &tc_f, &tc_frames_per_tick) == 3) { + tc_force_counter = GF_TRUE; + tc_h = tc_m = tc_s = 0; + tc_fps_den = 1; + } else if (sscanf(tc_str, "%d,%d", &tc_fps_num, &tc_f) == 2) { + tc_force_counter = GF_TRUE; + tc_h = tc_m = tc_s = 0; + tc_fps_den = 1; + } else { + fprintf(stderr, "Bad format %s for timecode, ignoring\n", ext+1); + } + } + else if (!strnicmp(ext+1, "lastsampdur", 11)) { + has_last_sample_dur = GF_TRUE; + if (!strnicmp(ext+1, "lastsampdur=", 12)) { + if (sscanf(ext+13, "%d/%u", &last_sample_dur.num, &last_sample_dur.den)==2) { + } else { + last_sample_dur.num = atoi(ext+13); + last_sample_dur.den = 1000; + } + } + } /*unrecognized, assume name has colon in it*/ else { fprintf(stderr, "Unrecognized import option %s, ignoring\n", ext+1); + if (ext2) ext2[0] = ':'; ext = ext2; continue; } @@ -521,34 +784,45 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc if (ext2) ext2[0] = ':'; ext[0] = 0; - ext = strchr(ext+1, ':'); + + /* restart from where we stopped + * if we didn't stop (ext2 null) then the end has been reached + * so we can stop the whole thing */ + ext = ext2; } /*check duration import (old syntax)*/ ext = strrchr(szName, '%'); if (ext) { - import.duration = (u32) (atof(ext+1) * 1000); + import.duration.num = (u32) (atof(ext+1) * 1000000); + import.duration.den = 1000000; ext[0] = 0; } /*select switches for av containers import*/ - do_audio = do_video = 0; + do_audio = do_video = do_auxv = do_pict = 0; track_id = prog_id = 0; do_all = 1; - 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); - if (e) goto exit; + ext_start = gf_file_ext_start(szName); + ext = strrchr(ext_start ? ext_start : szName, '#'); + if (ext) ext[0] = 0; if (ext) { ext++; + char *sep = gf_url_colon_suffix(ext); + if (sep) sep[0] = 0; + + //we have a fragment, we need to check if the track or the program is present in source + import.in_name = szName; + import.flags = GF_IMPORT_PROBE_ONLY; + e = gf_media_import(&import); + if (e) goto exit; + if (!strnicmp(ext, "audio", 5)) do_audio = 1; else if (!strnicmp(ext, "video", 5)) do_video = 1; + else if (!strnicmp(ext, "auxv", 4)) do_auxv = 1; + else if (!strnicmp(ext, "pict", 4)) do_pict = 1; else if (!strnicmp(ext, "trackID=", 8)) track_id = atoi(&ext[8]); else if (!strnicmp(ext, "PID=", 4)) track_id = atoi(&ext[4]); else if (!strnicmp(ext, "program=", 8)) { @@ -565,17 +839,53 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc do_all = 0; } else track_id = atoi(ext); + + //figure out trackID + if (do_audio || do_video || do_auxv || do_pict || track_id) { + Bool found = track_id ? GF_FALSE : GF_TRUE; + for (i=0; i0) { - gf_isom_append_edit_segment(import.dest, i+1, (timescale*delay)/1000, 0, GF_ISOM_EDIT_EMPTY); - gf_isom_append_edit_segment(import.dest, i+1, tk_dur, 0, GF_ISOM_EDIT_NORMAL); - } else if (delay<0) { - u64 to_skip = (timescale*(-delay))/1000; - if (to_skip=0) && (par_d>=0)) { - e = gf_media_change_par(import.dest, i+1, par_n, par_d); - } + if (e) { + if (import.update_mux_args) gf_free(import.update_mux_args); + goto exit; + } - if (rap_only) { - e = gf_media_remove_non_rap(import.dest, i+1); - } + if (fsess) { + *mux_args_if_first_pass = import.update_mux_args; + import.update_mux_args = NULL; + goto exit; + } + } - if (handler_name) gf_isom_set_handler_name(import.dest, i+1, handler_name); - else if (!keep_handler) { - char szHName[1024]; - const char *fName = gf_url_get_resource_name((const char *)inName); - fName = strchr(fName, '.'); - if (fName) fName += 1; - else fName = "?"; + nb_tracks = gf_isom_get_track_count(dest); + for (i=0; i>=32; + + keep_handler = (tk_source_magic & 1) ? GF_TRUE : GF_FALSE; - if (group) { - gf_isom_set_alternate_group_id(import.dest, i+1, group); + media_type = gf_isom_get_media_type(dest, track); + + if (moov_timescale) { + if (moov_timescale<0) moov_timescale = gf_isom_get_media_timescale(dest, track); + gf_isom_set_timescale(dest, moov_timescale); + moov_timescale = 0; + } + + timescale = gf_isom_get_timescale(dest); + if (szLan) gf_isom_set_media_language(dest, track, (char *) szLan); + if (disable) gf_isom_set_track_enabled(dest, track, GF_FALSE); + + if (import_flags & GF_IMPORT_NO_EDIT_LIST) + gf_isom_remove_edits(dest, track); + + if (delay) { + u64 tk_dur; + gf_isom_remove_edits(dest, track); + tk_dur = gf_isom_get_track_duration(dest, track); + if (delay>0) { + gf_isom_append_edit(dest, track, (timescale*delay)/1000, 0, GF_ISOM_EDIT_EMPTY); + gf_isom_append_edit(dest, track, tk_dur, 0, GF_ISOM_EDIT_NORMAL); + } else { + u64 to_skip = (timescale*(-delay))/1000; + if (to_skip=0) && (par_d>=0)) || force_par) { + e = gf_media_change_par(dest, track, par_n, par_d, force_par, rewrite_bs); } - if (stype) - gf_isom_set_media_subtype(import.dest, i+1, 1, stype); - - if (is_chap && chap_ref) { - set_chapter_track(import.dest, i+1, chap_ref); + if (has_clap) { + e = gf_isom_set_clean_aperture(dest, track, 1, clap_wn, clap_wd, clap_hn, clap_hd, clap_hon, clap_hod, clap_von, clap_vod); } - - for (j = 0; j < gf_list_count(kinds); j+=2) { - char *kind_scheme = (char *)gf_list_get(kinds, j); - char *kind_value = (char *)gf_list_get(kinds, j+1); - gf_isom_add_track_kind(import.dest, i+1, kind_scheme, kind_value); + if (bitdepth) { + gf_isom_set_visual_bit_depth(dest, track, 1, bitdepth); } - - 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; - - gf_isom_set_composition_offset_mode(import.dest, i+1, negative_cts_offset); - - if (gf_isom_get_avc_svc_type(import.dest, i+1, 1)>=GF_ISOM_AVCTYPE_AVC_SVC) - check_track_for_svc = i+1; - - switch (gf_isom_get_hevc_lhvc_type(import.dest, i+1, 1)) { - case GF_ISOM_HEVCTYPE_HEVC_LHVC: - case GF_ISOM_HEVCTYPE_LHVC_ONLY: - check_track_for_lhvc = i+1; - break; - case GF_ISOM_HEVCTYPE_HEVC_ONLY: - check_track_for_hevc=1; - break; + if (clr_type) { + gf_isom_set_visual_color_info(dest, track, 1, clr_type, clr_prim, clr_tranf, clr_mx, clr_full_range, icc_data, icc_size); } - - if (txt_flags) { - gf_isom_text_set_display_flags(import.dest, i+1, 0, txt_flags, txt_mode); + if (dv_profile) { + gf_isom_set_dolby_vision_profile(dest, track, 1, dv_profile); } - - if (split_tile_mode) { - switch (gf_isom_get_media_subtype(import.dest, i+1, 1)) { - case GF_ISOM_SUBTYPE_HVC1: - case GF_ISOM_SUBTYPE_HEV1: - case GF_ISOM_SUBTYPE_HVC2: - case GF_ISOM_SUBTYPE_HEV2: - break; - default: - split_tile_mode = 0; - break; - } + if (set_ccst) { + gf_isom_set_image_sequence_coding_constraints(dest, track, 1, GF_FALSE, GF_FALSE, GF_TRUE, 15); } } - } else { - for (i=0; i0) { - gf_isom_append_edit_segment(import.dest, track, (timescale*delay)/1000, 0, GF_ISOM_EDIT_EMPTY); - gf_isom_append_edit_segment(import.dest, track, tk_dur, 0, GF_ISOM_EDIT_NORMAL); - } else { - u64 to_skip = (timescale*(-delay))/1000; - if (to_skip=-1) && (par_d>=-1)) { - e = gf_media_change_par(import.dest, track, par_n, par_d); - } - if (rap_only) { - e = gf_media_remove_non_rap(import.dest, track); - } - if (handler_name) gf_isom_set_handler_name(import.dest, track, handler_name); - else if (!keep_handler) { - char szHName[1024]; - const char *fName = gf_url_get_resource_name((const char *)inName); - fName = strchr(fName, '.'); - if (fName) fName += 1; - else fName = "?"; + sprintf(szHName, "%s@GPAC%s", fName, gf_gpac_version()); + gf_isom_set_handler_name(dest, track, szHName); + } + if (handler) gf_isom_set_media_type(dest, track, handler); - sprintf(szHName, "%s@GPAC%s", fName, GPAC_FULL_VERSION); - gf_isom_set_handler_name(import.dest, track, szHName); - } - if (handler) gf_isom_set_media_type(import.dest, track, handler); + if (group) { + gf_isom_set_alternate_group_id(dest, track, group); + } - if (group) { - gf_isom_set_alternate_group_id(import.dest, track, group); - } + if (track_layout) { + gf_isom_set_track_layout_info(dest, track, tw<<16, th<<16, tx<<16, ty<<16, 0); + } + if (stype) + gf_isom_set_media_subtype(dest, track, 1, stype); - if (track_layout) { - gf_isom_set_track_layout_info(import.dest, track, tw<<16, th<<16, tx<<16, ty<<16, 0); - } - if (stype) - gf_isom_set_media_subtype(import.dest, track, 1, stype); + if (is_chap && chap_ref) { + set_chapter_track(dest, track, chap_ref); + } - if (is_chap && chap_ref) { - set_chapter_track(import.dest, track, chap_ref); - } - for (j = 0; j < gf_list_count(kinds); j+=2) { - char *kind_scheme = (char *)gf_list_get(kinds, j); - char *kind_value = (char *)gf_list_get(kinds, j+1); - gf_isom_add_track_kind(import.dest, i+1, kind_scheme, kind_value); - } + for (j = 0; j < gf_list_count(kinds); j+=2) { + char *kind_scheme = (char *)gf_list_get(kinds, j); + char *kind_value = (char *)gf_list_get(kinds, j+1); + gf_isom_add_track_kind(dest, i+1, kind_scheme, kind_value); + } - if (profile || level) - gf_media_change_pl(import.dest, track, profile, level); + if (profile || level) + gf_media_change_pl(dest, track, profile, level); - if (gf_isom_get_mpeg4_subtype(import.dest, track, 1)) - keep_sys_tracks = 1; + if (gf_isom_get_mpeg4_subtype(dest, track, 1)) + keep_sys_tracks = 1; - if (new_timescale>1) { - gf_isom_set_media_timescale(import.dest, track, new_timescale, 0); - } + if (new_timescale>1) { + gf_isom_set_media_timescale(dest, track, new_timescale, 0, 0); + } - if (rescale>1) { - switch (gf_isom_get_media_type(import.dest, track)) { - case GF_ISOM_MEDIA_AUDIO: - fprintf(stderr, "Cannot force media timescale for audio media types - ignoring\n"); - break; - default: - gf_isom_set_media_timescale(import.dest, track, rescale, 1); - break; + if (rescale_num > 1) { + switch (gf_isom_get_media_type(dest, track)) { + case GF_ISOM_MEDIA_AUDIO: + fprintf(stderr, "Cannot force media timescale for audio media types - ignoring\n"); + break; + default: + e = gf_isom_set_media_timescale(dest, track, rescale_num, rescale_den, 1); + if (e==GF_EOS) { + fprintf(stderr, "Rescale ignored, same config in source file\n"); + e = GF_OK; + } else if (e) { + fprintf(stderr, "Error rescaling media track %d\n", track); + goto exit; } + break; } + } - if (rvc_config) { - FILE *f = gf_fopen(rvc_config, "rb"); - if (f) { - char *data; - u32 size; - size_t read; - gf_fseek(f, 0, SEEK_END); - size = (u32) gf_ftell(f); - gf_fseek(f, 0, SEEK_SET); - data = gf_malloc(sizeof(char)*size); - read = fread(data, 1, size, f); - gf_fclose(f); - if (read != size) { - fprintf(stderr, "Error: could not read rvc config from %s\n", rvc_config); - e = GF_IO_ERR; - goto exit; - } + if (has_last_sample_dur) { + gf_isom_set_last_sample_duration_ex(dest, track, last_sample_dur.num, last_sample_dur.den); + } + if (rvc_config) { + u8 *data; + u32 size; + e = gf_file_load_data(rvc_config, (u8 **) &data, &size); + if (e) { + fprintf(stderr, "Error: failed to load rvc config from file: %s\n", gf_error_to_string(e) ); + } else { #ifdef GPAC_DISABLE_ZLIB - fprintf(stderr, "Error: no zlib support - RVC not available\n"); - e = GF_NOT_SUPPORTED; - goto exit; + fprintf(stderr, "Error: no zlib support - RVC not available\n"); + e = GF_NOT_SUPPORTED; + gf_free(data); + goto exit; #else - gf_gz_compress_payload(&data, size, &size); + gf_gz_compress_payload(&data, size, &size); #endif - gf_isom_set_rvc_config(import.dest, track, 1, 0, "application/rvc-config+xml+gz", data, size); - gf_free(data); - } - } else if (rvc_predefined>0) { - gf_isom_set_rvc_config(import.dest, track, 1, rvc_predefined, NULL, NULL, 0); + gf_isom_set_rvc_config(dest, track, 1, 0, "application/rvc-config+xml+gz", data, size); + gf_free(data); } + } else if (rvc_predefined>0) { + gf_isom_set_rvc_config(dest, track, 1, rvc_predefined, NULL, NULL, 0); + } - gf_isom_set_composition_offset_mode(import.dest, track, negative_cts_offset); + gf_isom_set_composition_offset_mode(dest, track, negative_cts_offset); - if (gf_isom_get_avc_svc_type(import.dest, track, 1)>=GF_ISOM_AVCTYPE_AVC_SVC) - check_track_for_svc = track; + if (gf_isom_get_avc_svc_type(dest, track, 1)>=GF_ISOM_AVCTYPE_AVC_SVC) + check_track_for_svc = track; - switch (gf_isom_get_hevc_lhvc_type(import.dest, track, 1)) { - case GF_ISOM_HEVCTYPE_HEVC_LHVC: - case GF_ISOM_HEVCTYPE_LHVC_ONLY: - check_track_for_lhvc = i+1; - break; - case GF_ISOM_HEVCTYPE_HEVC_ONLY: - check_track_for_hevc=1; - break; - } + switch (gf_isom_get_hevc_lhvc_type(dest, track, 1)) { + case GF_ISOM_HEVCTYPE_HEVC_LHVC: + case GF_ISOM_HEVCTYPE_LHVC_ONLY: + check_track_for_lhvc = i+1; + break; + case GF_ISOM_HEVCTYPE_HEVC_ONLY: + check_track_for_hevc=1; + break; + default: + break; + } - if (txt_flags) { - gf_isom_text_set_display_flags(import.dest, track, 0, txt_flags, txt_mode); - } + if (txt_flags) { + gf_isom_text_set_display_flags(dest, track, 0, txt_flags, txt_mode); + } + if (force_rate>=0) { + gf_isom_update_bitrate(dest, i+1, 1, force_rate, force_rate, 0); + } - if (split_tile_mode) { - switch (gf_isom_get_media_subtype(import.dest, track, 1)) { - case GF_ISOM_SUBTYPE_HVC1: - case GF_ISOM_SUBTYPE_HEV1: - case GF_ISOM_SUBTYPE_HVC2: - case GF_ISOM_SUBTYPE_HEV2: - break; - default: - split_tile_mode = 0; - break; - } + if (split_tile_mode) { + switch (gf_isom_get_media_subtype(dest, track, 1)) { + case GF_ISOM_SUBTYPE_HVC1: + case GF_ISOM_SUBTYPE_HEV1: + case GF_ISOM_SUBTYPE_HVC2: + case GF_ISOM_SUBTYPE_HEV2: + break; + default: + split_tile_mode = 0; + break; } } - if (track_id) fprintf(stderr, "WARNING: Track ID %d not found in file\n", track_id); - else if (do_video) fprintf(stderr, "WARNING: Video track not found\n"); - else if (do_audio) fprintf(stderr, "WARNING: Audio track not found\n"); } if (chapter_name) { if (is_chap_file) { - e = gf_media_import_chapters(import.dest, chapter_name, 0); + GF_Fraction a_fps = {0,0}; + e = gf_media_import_chapters(dest, chapter_name, a_fps, GF_FALSE); } else { - e = gf_isom_add_chapter(import.dest, 0, 0, chapter_name); + e = gf_isom_add_chapter(dest, 0, 0, chapter_name); + } + } + + if (tmcd_track) { + u32 tmcd_id = gf_isom_get_track_id(dest, tmcd_track); + for (i=0; i < gf_isom_get_track_count(dest); i++) { + switch (gf_isom_get_media_type(dest, i+1)) { + case GF_ISOM_MEDIA_VISUAL: + case GF_ISOM_MEDIA_AUXV: + case GF_ISOM_MEDIA_PICT: + break; + default: + continue; + } + gf_isom_set_track_reference(dest, i+1, GF_ISOM_REF_TMCD, tmcd_id); } } /*force to rewrite all dependencies*/ - for (i = 1; i <= gf_isom_get_track_count(import.dest); i++) + for (i = 1; i <= gf_isom_get_track_count(dest); i++) { - e = gf_isom_rewrite_track_dependencies(import.dest, i); + e = gf_isom_rewrite_track_dependencies(dest, i); if (e) { - fprintf(stderr, "Warning: track ID %d has references to a track not imported\n", gf_isom_get_track_id(import.dest, i)); + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("Warning: track ID %d has references to a track not imported\n", gf_isom_get_track_id(dest, i) )); e = GF_OK; } } +#ifndef GPAC_DISABLE_AV_PARSERS if (max_layer_id_plus_one || max_temporal_id_plus_one) { - for (i = 1; i <= gf_isom_get_track_count(import.dest); i++) + for (i = 1; i <= gf_isom_get_track_count(dest); i++) { - e = gf_media_filter_hevc(import.dest, i, max_temporal_id_plus_one, max_layer_id_plus_one); + e = gf_media_filter_hevc(dest, i, max_temporal_id_plus_one, max_layer_id_plus_one); if (e) { - fprintf(stderr, "Warning: track ID %d: error while filtering LHVC layers\n", gf_isom_get_track_id(import.dest, i)); + fprintf(stderr, "Warning: track ID %d: error while filtering LHVC layers\n", gf_isom_get_track_id(dest, i)); e = GF_OK; } } } +#endif if (check_track_for_svc) { if (svc_mode) { - e = gf_media_split_svc(import.dest, check_track_for_svc, (svc_mode==2) ? 1 : 0); + e = gf_media_split_svc(dest, check_track_for_svc, (svc_mode==2) ? 1 : 0); if (e) goto exit; } else { - e = gf_media_merge_svc(import.dest, check_track_for_svc, 1); + e = gf_media_merge_svc(dest, check_track_for_svc, 1); if (e) goto exit; } } -#ifndef GPAC_DISABLE_HEVC +#ifndef GPAC_DISABLE_AV_PARSERS if (check_track_for_lhvc) { if (svc_mode) { - e = gf_media_split_lhvc(import.dest, check_track_for_lhvc, GF_FALSE, (svc_mode==1) ? 0 : 1, (svc_mode==3) ? 0 : 1 ); + GF_LHVCExtractoreMode xmode = GF_LHVC_EXTRACTORS_ON; + if (svc_mode==3) xmode = GF_LHVC_EXTRACTORS_OFF; + else if (svc_mode==4) xmode = GF_LHVC_EXTRACTORS_OFF_FORCE_INBAND; + e = gf_media_split_lhvc(dest, check_track_for_lhvc, GF_FALSE, (svc_mode==1) ? 0 : 1, xmode ); if (e) goto exit; } else { //TODO - merge, temporal sublayers } } +#ifndef GPAC_DISABLE_HEVC if (check_track_for_hevc) { if (split_tile_mode) { - e = gf_media_split_hevc_tiles(import.dest, split_tile_mode - 1); + e = gf_media_split_hevc_tiles(dest, split_tile_mode - 1); if (e) goto exit; } if (temporal_mode) { - e = gf_media_split_lhvc(import.dest, check_track_for_hevc, GF_TRUE, (temporal_mode==1) ? GF_FALSE : GF_TRUE, (temporal_mode==3) ? GF_FALSE : GF_TRUE ); + GF_LHVCExtractoreMode xmode = (temporal_mode==3) ? GF_LHVC_EXTRACTORS_OFF : GF_LHVC_EXTRACTORS_ON; + e = gf_media_split_lhvc(dest, check_track_for_hevc, GF_TRUE, (temporal_mode==1) ? GF_FALSE : GF_TRUE, xmode ); if (e) goto exit; } } +#endif -#endif /*GPAC_DISABLE_HEVC*/ + if (tc_fps_num) { + u32 desc_index=0; + u32 tmcd_tk, tmcd_id; + u32 video_ref = 0; + GF_BitStream *bs; + GF_ISOSample *samp; + for (i=0; iIsRAP = SAP_TYPE_1; + gf_bs_get_content(bs, &samp->data, &samp->dataLength); + gf_bs_del(bs); + e = gf_isom_add_sample(dest, tmcd_tk, desc_index, samp); + gf_isom_sample_del(&samp); + + if (video_ref) { + u64 video_ref_dur = gf_isom_get_media_duration(dest, video_ref); + video_ref_dur *= tc_fps_num; + video_ref_dur /= gf_isom_get_media_timescale(dest, video_ref); + gf_isom_set_last_sample_duration(dest, tmcd_tk, (u32) video_ref_dur); + } else { + gf_isom_set_last_sample_duration(dest, tmcd_tk, tc_fps_den ? tc_fps_den : 1); + } + } + +#endif /*GPAC_DISABLE_AV_PARSERS*/ exit: while (gf_list_count(kinds)) { @@ -960,6 +1306,10 @@ exit: gf_list_rem(kinds, 0); if (kind) gf_free(kind); } + if (opt_src) opt_src[0] = ':'; + if (opt_dst) opt_dst[0] = ':'; + if (fchain) fchain[0] = ':'; + gf_list_del(kinds); if (handler_name) gf_free(handler_name); if (chapter_name ) gf_free(chapter_name); @@ -967,657 +1317,186 @@ exit: if (import.streamFormat) gf_free(import.streamFormat); if (import.force_ext) gf_free(import.force_ext); if (rvc_config) gf_free(rvc_config); + if (szLan) gf_free((char *)szLan); + if (icc_data) gf_free(icc_data); return e; } -typedef struct + +static Bool on_split_event(void *_udta, GF_Event *evt) { - u32 tk; - Bool has_non_raps; - u32 last_sample; - u32 sample_count; - u32 time_scale; - u64 firstDTS, lastDTS; - u32 dst_tk; - /*set if media can be duplicated at split boundaries - only used for text tracks and provate tracks, this assumes all - samples are RAP*/ - Bool can_duplicate; - /*controls import by time rather than by sample (otherwise we would have to remove much more samples video vs audio for example*/ - Bool first_sample_done; - Bool next_sample_is_rap; - u32 stop_state; -} TKInfo; - -GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u64 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start_time, Bool adjust_split_end, char *outName, const char *tmpdir) + Double progress; + u32 *prev_progress = (u32 *)_udta; + if (!_udta) return GF_FALSE; + if (evt->type != GF_EVENT_PROGRESS) return GF_FALSE; + if (!evt->progress.total) return GF_FALSE; + + progress = (Double) (100*evt->progress.done) / evt->progress.total; + if ((u32) progress==*prev_progress) + return GF_FALSE; + + *prev_progress = (u32) progress; +#ifndef GPAC_DISABLE_LOG + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Spliting: % 2.2f %%\r", progress)); +#else + fprintf(stderr, "Spliting: % 2.2f %%\r", progress); +#endif + return GF_FALSE; +} + +GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u64 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start_time, Bool adjust_split_end, char *outName, const char *tmpdir, Bool force_rap_split, const char *split_range_str) { - u32 i, count, nb_tk, needs_rap_sync, cur_file, conv_type, nb_tk_done, nb_samp, nb_done, di; - Double max_dur, cur_file_time; - Bool do_add, all_duplicatable, size_exceeded, chunk_extraction, rap_split, split_until_end; - GF_ISOFile *dest; - GF_ISOSample *samp; + Bool chunk_extraction, rap_split, split_until_end; GF_Err e; - TKInfo *tks, *tki; - char *ext, szName[1000], szFile[1000]; + char *ext, szName[GF_MAX_PATH], szFile[GF_MAX_PATH+100], szArgs[100]; Double chunk_start = (Double) chunk_start_time; - - chunk_extraction = (chunk_start>=0) ? 1 : 0; - split_until_end = 0; - rap_split = 0; - if (split_size_kb == (u64)-1) rap_split = 1; - if (split_dur == -1) rap_split = 1; - else if (split_dur==-2) { + char *filter_args = NULL; + GF_FilterSession *fs; + GF_Filter *src, *reframe, *dst; + u32 progress = (u32) -1; + + chunk_extraction = (chunk_start>=0) ? GF_TRUE : GF_FALSE; + if (split_range_str) + chunk_extraction = GF_TRUE; + split_until_end = GF_FALSE; + rap_split = GF_FALSE; + if (split_size_kb == (u64)-1) rap_split = GF_TRUE; + if (split_dur == -1) rap_split = GF_TRUE; + else if (split_dur <= -2) { split_size_kb = 0; - split_until_end = 1; - split_dur = 0; + split_until_end = GF_TRUE; } + else if (force_rap_split) + rap_split = GF_TRUE; - if (rap_split) { - split_size_kb = 0; - split_dur = (double) GF_MAX_FLOAT; - } - - - ext = strrchr(inName, '/'); - if (!ext) ext = strrchr(inName, '\\'); - strcpy(szName, ext ? ext+1 : inName); + //split in same dir as source + strcpy(szName, inName); ext = strrchr(szName, '.'); if (ext) ext[0] = 0; - ext = strrchr(inName, '.'); - dest = NULL; - - conv_type = 0; - switch (gf_isom_guess_specification(mp4)) { - case GF_4CC('I','S','M','A'): - conv_type = 1; - break; - case GF_ISOM_BRAND_3GP4: - case GF_ISOM_BRAND_3GP5: - case GF_ISOM_BRAND_3GP6: - case GF_ISOM_BRAND_3GG6: - case GF_ISOM_BRAND_3G2A: - conv_type = 2; - break; + fs = gf_fs_new_defaults(0); + if (!fs) { + fprintf(stderr, "Failed to load filter session, aborting\n"); + return GF_IO_ERR; } - if (!stricmp(ext, ".3gp") || !stricmp(ext, ".3g2")) conv_type = 2; - - count = gf_isom_get_track_count(mp4); - tks = (TKInfo *)gf_malloc(sizeof(TKInfo)*count); - memset(tks, 0, sizeof(TKInfo)*count); - - e = GF_OK; - max_dur = 0; - nb_tk = 0; - all_duplicatable = 1; - needs_rap_sync = 0; - nb_samp = 0; - for (i=0; i1) { - break; - } - continue; - case GF_ISOM_MEDIA_HINT: - case GF_ISOM_MEDIA_SCENE: - case GF_ISOM_MEDIA_OCR: - case GF_ISOM_MEDIA_OD: - case GF_ISOM_MEDIA_OCI: - case GF_ISOM_MEDIA_IPMP: - case GF_ISOM_MEDIA_MPEGJ: - case GF_ISOM_MEDIA_MPEG7: - case GF_ISOM_MEDIA_FLASH: - fprintf(stderr, "WARNING: Track ID %d (type %s) not handled by splitter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype)); - continue; - default: - /*for all other track types, only split if more than one sample*/ - if (gf_isom_get_sample_count(mp4, i+1)==1) { - fprintf(stderr, "WARNING: Track ID %d (type %s) not handled by splitter - skipping\n", gf_isom_get_track_id(mp4, i+1), gf_4cc_to_str(mtype)); - continue; - } - tks[nb_tk].can_duplicate = 1; - } - tks[nb_tk].sample_count = gf_isom_get_sample_count(mp4, i+1); - nb_samp += tks[nb_tk].sample_count; - tks[nb_tk].last_sample = 0; - tks[nb_tk].firstDTS = 0; - tks[nb_tk].time_scale = gf_isom_get_media_timescale(mp4, i+1); - tks[nb_tk].has_non_raps = gf_isom_has_sync_points(mp4, i+1); - /*seen that on some 3gp files from nokia ...*/ - if (mtype==GF_ISOM_MEDIA_AUDIO) tks[nb_tk].has_non_raps = 0; - dur = (Double) (s64) gf_isom_get_media_duration(mp4, i+1); - dur /= tks[nb_tk].time_scale; - if (max_dur=max_dur) { - fprintf(stderr, "Input file (%f) shorter than requested split start offset (%f)\n", max_dur, chunk_start); - gf_free(tks); - return GF_NOT_SUPPORTED; + //default output name formatting + if (!outName) { + strcpy(szFile, szName); + strcat(szFile, "_$num%03d$"); } - if (split_until_end) { - split_dur = max_dur; - } else if (!rap_split && (max_dur<=split_dur)) { - fprintf(stderr, "Input file (%f) shorter than requested split duration (%f)\n", max_dur, split_dur); - gf_free(tks); - return GF_NOT_SUPPORTED; - } - if (needs_rap_sync) { - Bool has_enough_sync = GF_FALSE; - tki = &tks[needs_rap_sync-1]; - - if (chunk_start == 0.0f) - has_enough_sync = GF_TRUE; - else if (gf_isom_get_sync_point_count(mp4, tki->tk) > 1) - has_enough_sync = GF_TRUE; - else if (gf_isom_get_sample_group_info(mp4, tki->tk, 1, GF_4CC('r', 'a', 'p', ' '), NULL, NULL, NULL)) - has_enough_sync = GF_TRUE; - if (!has_enough_sync) { - fprintf(stderr, "Not enough Random Access points in input file - cannot split\n"); - gf_free(tks); - return GF_NOT_SUPPORTED; - } - } - split_size_kb *= 1024; - cur_file_time = 0; - - if (chunk_start>0) { - if (needs_rap_sync) { - u32 sample_num; - Double start; - tki = &tks[needs_rap_sync-1]; - - start = (Double) (s64) gf_isom_get_sample_dts(mp4, tki->tk, tki->sample_count); - start /= tki->time_scale; - if (startstop_state = 2; - } else { - e = gf_isom_get_sample_for_media_time(mp4, tki->tk, (u64) (chunk_start*tki->time_scale), &di, GF_ISOM_SEARCH_SYNC_BACKWARD, &samp, &sample_num); - if (e!=GF_OK) { - fprintf(stderr, "Cannot locate RAP in track ID %d for chunk extraction from %02.2f sec\n", gf_isom_get_track_id(mp4, tki->tk), chunk_start); - gf_free(tks); - return GF_NOT_SUPPORTED; - } - start = (Double) (s64) samp->DTS; - start /= tki->time_scale; - gf_isom_sample_del(&samp); - fprintf(stderr, "Adjusting chunk start time to previous random access at %02.2f sec\n", start); - split_dur += (chunk_start - start); - chunk_start = start; - } - } - /*sync all tracks*/ - for (i=0; ilast_samplesample_count) { - Double time; - u64 dts; - dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1); - time = (Double) (s64) dts; - time /= tki->time_scale; - if (time>=chunk_start) { - /*rewind one sample (text tracks & co)*/ - if (tki->can_duplicate && tki->last_sample) { - tki->last_sample--; - tki->firstDTS = (u64) (chunk_start*tki->time_scale); - } else { - tki->firstDTS = dts; - } - break; - } - tki->last_sample++; + gf_dynstrcat(&filter_args, "reframer:splitrange", NULL); + if (rap_split) { + gf_dynstrcat(&filter_args, ":xs=SAP", NULL); + } else if (split_size_kb) { + sprintf(szArgs, ":xs=S"LLU"k", split_size_kb); + gf_dynstrcat(&filter_args, szArgs, NULL); + } else if (chunk_extraction) { + gf_dynstrcat(&filter_args, ":xround=closest", NULL); + if (split_range_str) { + char *end = (char *) strchr(split_range_str, '-'); + assert(end); + end[0] = 0; + sprintf(szArgs, ":xs=T%s:xe=T%s", split_range_str, end+1); + end[0] = '-'; + } else if (split_until_end) { + Double end=0; + if (split_dur<-2) { + end = (Double) gf_isom_get_duration(mp4); + end /= gf_isom_get_timescale(mp4); + split_dur = -2 - split_dur; + if (end > split_dur) end-=split_dur; + else end = 0; + } + if (end>0) { + sprintf(szArgs, ":xs=%u/1000:xe=%u/1000", (u32) (chunk_start*1000), (u32) (end * 1000) ); + } else { + sprintf(szArgs, ":xs=%u/1000", (u32) (chunk_start*1000)); } - } - cur_file_time = chunk_start; - } else { - chunk_start = 0; - } - - dest = NULL; - nb_done = 0; - nb_tk_done = 0; - cur_file = 0; - while (nb_tk_donestop_state==2) continue; - - e = gf_isom_clone_track(mp4, tki->tk, dest, GF_FALSE, &tki->dst_tk); - if (e) { - fprintf(stderr, "Error cloning track %d\n", tki->tk); - goto err_exit; - } - /*use non-packet CTS offsets (faster add/remove)*/ - if (gf_isom_has_time_offset(mp4, tki->tk)) { - gf_isom_set_cts_packing(dest, tki->dst_tk, GF_TRUE); - } - gf_isom_remove_edit_segments(dest, tki->dst_tk); - } - do_add = 1; - is_last_rap = 0; - last_rap_sample_time = 0; - file_split_dur = split_dur; - - size_exceeded = 0; - max_dts = 0; - while (do_add) { - Bool is_rap; - Double time; - u32 nb_over, nb_av = 0; - /*perfom basic de-interleaving to make sure we're not importing too much of a given track*/ - u32 nb_add = 0; - /*add one sample of each track*/ - for (i=0; ican_duplicate) nb_av++; - - if (tki->stop_state) - continue; - if (tki->last_sample==tki->sample_count) - continue; - - /*get sample info, see if we need to check it (basic de-interleaver)*/ - dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1); - - /*reinsertion (timed text)*/ - if (dts < tki->firstDTS) { - samp = gf_isom_get_sample(mp4, tki->tk, tki->last_sample+1, &di); - samp->DTS = 0; - e = gf_isom_add_sample(dest, tki->dst_tk, di, samp); - if (!e) { - e = gf_isom_copy_sample_info(dest, tki->dst_tk, mp4, tki->tk, tki->last_sample+1); - } - - gf_isom_sample_del(&samp); - tki->last_sample += 1; - dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1); - } - dts -= tki->firstDTS; - - - t = (Double) (s64) dts; - t /= tki->time_scale; - if (tki->first_sample_done) { - if (!all_av_done && (t>max_dts)) continue; - } else { - /*here's the trick: only take care of a/v media for splitting, and add other media - only if thir dts is less than the max AV dts found. Otherwise with some text streams we will end up importing - too much video and corrupting the last sync point indication*/ - if (!tki->can_duplicate && (t>max_dts)) max_dts = t; - tki->first_sample_done = 1; - } - samp = gf_isom_get_sample(mp4, tki->tk, tki->last_sample+1, &di); - samp->DTS -= tki->firstDTS; - - nb_add += 1; - - is_rap = GF_FALSE; - if (samp->IsRAP) { - is_rap = GF_TRUE; - } else { - Bool has_roll; - gf_isom_get_sample_rap_roll_info(mp4, tki->tk, tki->last_sample+1, &is_rap, &has_roll, NULL); - } - - - if (tki->has_non_raps && is_rap) { - GF_ISOSample *next_rap; - u32 next_rap_num, sdi; - last_rap_sample_time = (Double) (s64) samp->DTS; - last_rap_sample_time /= tki->time_scale; - e = gf_isom_get_sample_for_media_time(mp4, tki->tk, samp->DTS+tki->firstDTS+2, &sdi, GF_ISOM_SEARCH_SYNC_FORWARD, &next_rap, &next_rap_num); - if (e==GF_EOS) - is_last_rap = 1; - if (next_rap) { - if (!next_rap->IsRAP) - is_last_rap = 1; - gf_isom_sample_del(&next_rap); - } - } - tki->lastDTS = samp->DTS; - e = gf_isom_add_sample(dest, tki->dst_tk, di, samp); - gf_isom_sample_del(&samp); - - if (!e) { - e = gf_isom_copy_sample_info(dest, tki->dst_tk, mp4, tki->tk, tki->last_sample+1); - } - tki->last_sample += 1; - gf_set_progress("Splitting", nb_done, nb_samp); - nb_done++; - if (e) { - fprintf(stderr, "Error cloning track %d sample %d\n", tki->tk, tki->last_sample); - goto err_exit; - } - - tki->next_sample_is_rap = 0; - if (rap_split && tki->has_non_raps) { - if ( gf_isom_get_sample_sync(mp4, tki->tk, tki->last_sample+1)) - tki->next_sample_is_rap = 1; - } - } - - /*test by size/duration*/ - nb_over = 0; - - /*test by file size: same as duration test, only dynamically increment import duration*/ - if (split_size_kb) { - u64 est_size = gf_isom_estimate_size(dest); - /*while below desired size keep importing*/ - if (est_sizestop_state) { - nb_over++; - if (!tki->can_duplicate && (tki->last_sample==tki->sample_count) ) - nb_av--; - continue; - } - time = (Double) (s64) tki->lastDTS; - time /= tki->time_scale; - if (size_exceeded - || (tki->last_sample==tki->sample_count) - || (!tki->can_duplicate && (time>file_split_dur)) - || (rap_split && tki->has_non_raps && tki->next_sample_is_rap) - ) { - nb_over++; - tki->stop_state = 1; - if (tki->last_samplesample_count) - is_last_rap = 0; - else if (tki->first_sample_done) - is_last_rap = 0; - - if (rap_split && tki->next_sample_is_rap) { - file_split_dur = (Double) ( gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1) - tki->firstDTS); - file_split_dur /= tki->time_scale; - } - } - /*special tracks (not audio, not video)*/ - else if (tki->can_duplicate) { - u64 dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1); - time = (Double) (s64) (dts - tki->firstDTS); - time /= tki->time_scale; - if (time>file_split_dur) { - nb_over++; - tki->stop_state = 1; - } - } - if (!nb_add && (!max_dts || (tki->lastDTS <= 1 + (u64) (tki->time_scale*max_dts) ))) - tki->first_sample_done = 0; - } - if (nb_over==nb_tk) do_add = 0; - - if (!nb_av) - all_av_done = GF_TRUE; - } - - /*remove samples - first figure out smallest duration*/ - file_split_dur = (Double) GF_MAX_FLOAT; - for (i=0; istop_state==2) || (!is_last_rap && (tki->sample_count == tki->last_sample)) ) { - if (tki->has_non_raps) last_rap_sample_time = 0; - time = (Double) (s64) ( gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1) - tki->firstDTS); - time /= tki->time_scale; - if (file_split_dur==(Double)GF_MAX_FLOAT || file_split_durlastDTS) - { - //time = (Double) (s64) tki->lastDTS; - time = (Double) (s64) ( gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1) - tki->firstDTS); - time /= tki->time_scale; - if ((!tki->can_duplicate || all_duplicatable) && timenext_sample_is_rap) file_split_dur = time; - } + sprintf(szArgs, ":xs=%u/1000:xe=%u/1000", (u32) (chunk_start*1000), (u32) ((chunk_start+split_dur) * 1000) ); } - if (file_split_dur == (Double) GF_MAX_FLOAT) { - fprintf(stderr, "Cannot split file (duration too small or size too small)\n"); - goto err_exit; + gf_dynstrcat(&filter_args, szArgs, NULL); + if (adjust_split_end) { + gf_dynstrcat(&filter_args, ":xadjust", NULL); } - if (chunk_extraction) { - if (adjust_split_end) { - fprintf(stderr, "Adjusting chunk end time to previous random access at %02.2f sec\n", chunk_start + last_rap_sample_time); - file_split_dur = last_rap_sample_time; - if (outName) strcpy(szFile, outName); - else sprintf(szFile, "%s_%d_%d%s", szName, (u32) chunk_start, (u32) (chunk_start+file_split_dur), ext); - gf_isom_set_final_name(dest, szFile); - } - else file_split_dur = split_dur; + if (!outName) { + sprintf(szFile, "%s_$FS$", szName); } - - /*don't split if eq to copy...*/ - if (is_last_rap && !cur_file && !chunk_start) { - fprintf(stderr, "Cannot split file (Not enough sync samples, duration too large or size too big)\n"); - goto err_exit; - } - - - /*if not last chunk and longer duration adjust to previous RAP point*/ - if ( (size_exceeded || !split_size_kb) && (file_split_dur>split_dur) && !chunk_start) { - /*if larger than last RAP, rewind till it*/ - if (last_rap_sample_time && (last_rap_sample_timedst_tk); - - time = (Double) (s64) gf_isom_get_media_duration(dest, tki->dst_tk); - //time could get slightly higher than requests dur due to rounding precision. We use 1/4 of the last sample dur as safety marge - time -= (Double) (s64) gf_isom_get_sample_duration(dest, tki->dst_tk, tki->last_sample) / 4; - time /= tki->time_scale; - - if (last_samp<=1) break; - - /*done*/ - if (tki->last_sample==tki->sample_count) { - if (!chunk_extraction && !tki->can_duplicate) { - tki->stop_state=2; - break; - } - } - - if (time <= file_split_dur) break; - - gf_isom_remove_sample(dest, tki->dst_tk, last_samp); - tki->last_sample--; - assert(tki->last_sample); - nb_done--; - gf_set_progress("Splitting", nb_done, nb_samp); - } - if (tki->last_samplesample_count) { - u64 dts; - tki->stop_state = 0; - dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1); - time = (Double) (s64) (dts - tki->firstDTS); - time /= tki->time_scale; - /*re-insert prev sample*/ - if (tki->can_duplicate && (time>file_split_dur) ) { - Bool was_insert = GF_FALSE; - tki->last_sample--; - dts = gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1); - if (dts < tki->firstDTS) was_insert = GF_TRUE; - tki->firstDTS += (u64) (file_split_dur*tki->time_scale); - //the original, last sample added starts before the first sample in the file: we have re-inserted - //a single sample, use split duration as target duration - if (was_insert) { - gf_isom_set_last_sample_duration(dest, tki->dst_tk, (u32) (file_split_dur*tki->time_scale)); - } else { - gf_isom_set_last_sample_duration(dest, tki->dst_tk, (u32) (tki->firstDTS - dts) ); - } - } else { - tki->firstDTS = dts; - } - tki->first_sample_done = 0; - } else { - nb_tk_done++; - } - - } + } else if (split_dur) { + sprintf(szArgs, ":xs=D%u", (u32) (split_dur*1000)); + gf_dynstrcat(&filter_args, szArgs, NULL); + if (adjust_split_end) { + gf_dynstrcat(&filter_args, ":xadjust", NULL); } + } else { + gf_fs_del(fs); + gf_free(filter_args); + fprintf(stderr, "Unrecognized split syntax\n"); + return GF_BAD_PARAM; + } - if (chunk_extraction) { - fprintf(stderr, "Extracting chunk %s - duration %02.2fs (%02.2fs->%02.2fs)\n", szFile, file_split_dur, chunk_start, (chunk_start+split_dur)); - } else { - fprintf(stderr, "Storing split-file %s - duration %02.2f seconds\n", szFile, file_split_dur); - } + reframe = gf_fs_load_filter(fs, filter_args, &e); + gf_free(filter_args); + if (!reframe) { + fprintf(stderr, "Failed to load reframer filter: %s\n", gf_error_to_string(e) ); + gf_fs_del(fs); + return e; + } - /*repack CTSs*/ - for (i=0; istop_state == 2) continue; - if (!gf_isom_get_sample_count(dest, tki->dst_tk)) { - gf_isom_remove_track(dest, tki->dst_tk); - continue; - } - if (gf_isom_has_time_offset(mp4, tki->tk)) { - gf_isom_set_cts_packing(dest, tki->dst_tk, GF_FALSE); - } - if (is_last_rap && tki->can_duplicate) { - gf_isom_set_last_sample_duration(dest, tki->dst_tk, gf_isom_get_sample_duration(mp4, tki->tk, tki->sample_count)); - } + if (!outName) { + strcat(szFile, ".mp4"); + } else { + strcpy(szFile, outName); + } + dst = gf_fs_load_destination(fs, szFile, NULL, NULL, &e); + if (!dst) { + fprintf(stderr, "Failed to load destination filter: %s\n", gf_error_to_string(e) ); + gf_fs_del(fs); + return e; + } + //link reframer to dst + gf_filter_set_source(dst, reframe, NULL); - /*rewrite edit list*/ - new_track_dur = gf_isom_get_track_duration(dest, tki->dst_tk); - count = gf_isom_get_edit_segment_count(mp4, tki->tk); - if (count>2) { - fprintf(stderr, "Warning: %d edit segments - not supported while splitting (max 2) - ignoring extra\n", count); - count=2; - } - for (j=0; jtk, j+1, &editTime, &segDur, &MediaTime, &mode); - if (!j && (mode!=GF_ISOM_EDIT_EMPTY) ) { - fprintf(stderr, "Warning: Edit list doesn't look like a track delay scheme - ignoring\n"); - break; - } - if (mode==GF_ISOM_EDIT_NORMAL) { - segDur = new_track_dur; - } - gf_isom_set_edit_segment(dest, tki->dst_tk, editTime, segDur, MediaTime, mode); - } - } - /*check chapters*/ - do_add = 1; - for (i=0; icur_file_time+file_split_dur) break; - max_dts-=cur_file_time; - chap_time = (u64) (max_dts*1000); - gf_isom_add_chapter(dest, 0, chap_time, name); - /*add prev*/ - if (do_add && i) { - gf_isom_get_chapter(mp4, 0, i, &chap_time, (const char **) &name); - gf_isom_add_chapter(dest, 0, 0, name); - do_add = 0; - } - } - cur_file_time += file_split_dur; - - if (conv_type==1) gf_media_make_isma(dest, 1, 0, 0); - else if (conv_type==2) gf_media_make_3gpp(dest); - if (InterleavingTime) { - gf_isom_make_interleave(dest, InterleavingTime); - } else { - gf_isom_set_storage_mode(dest, GF_ISOM_STORE_STREAMABLE); - } - gf_isom_clone_pl_indications(mp4, dest); - e = gf_isom_close(dest); - dest = NULL; - if (e) fprintf(stderr, "Error storing file %s\n", gf_error_to_string(e)); - if (is_last_rap || chunk_extraction) break; - cur_file++; + e = gf_fs_run(fs); + if (e>=GF_OK) { + e = gf_fs_get_last_connect_error(fs); + if (e>=GF_OK) + e = gf_fs_get_last_process_error(fs); } - gf_set_progress("Splitting", nb_samp, nb_samp); -err_exit: - if (dest) gf_isom_delete(dest); - gf_free(tks); + gf_fs_del(fs); + if (eAVCLevelIndication!=avc_dst->AVCLevelIndication) { + if (!force_cat && (avc_src->AVCLevelIndication!=avc_dst->AVCLevelIndication)) { dst_tk = 0; - } else if (avc_src->AVCProfileIndication!=avc_dst->AVCProfileIndication) { + } else if (!force_cat && (avc_src->AVCProfileIndication!=avc_dst->AVCProfileIndication)) { dst_tk = 0; } else { /*rewrite all samples if using different NALU size*/ if (avc_src->nal_unit_size > avc_dst->nal_unit_size) { - gf_media_avc_rewrite_samples(dest, dst_tk, 8*avc_dst->nal_unit_size, 8*avc_src->nal_unit_size); + gf_media_nal_rewrite_samples(dest, dst_tk, 8*avc_src->nal_unit_size); avc_dst->nal_unit_size = avc_src->nal_unit_size; } else if (avc_src->nal_unit_size < avc_dst->nal_unit_size) { - gf_media_avc_rewrite_samples(orig, src_track, 8*avc_src->nal_unit_size, 8*avc_dst->nal_unit_size); + gf_media_nal_rewrite_samples(orig, src_track, 8*avc_dst->nal_unit_size); } /*merge PS*/ @@ -1677,7 +1556,7 @@ static u32 merge_avc_config(GF_ISOFile *dest, u32 tk_id, GF_ISOFile *orig, u32 s dst_tk = gf_isom_get_track_by_id(dest, tk_id); gf_isom_set_nalu_extract_mode(orig, src_track, GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG); if (!force_cat) { - gf_isom_avc_set_inband_config(dest, dst_tk, 1); + gf_isom_avc_set_inband_config(dest, dst_tk, 1, GF_FALSE); } else { fprintf(stderr, "WARNING: Concatenating track ID %d even though sample descriptions do not match\n", tk_id); } @@ -1701,10 +1580,10 @@ static u32 merge_hevc_config(GF_ISOFile *dest, u32 tk_id, GF_ISOFile *orig, u32 else { /*rewrite all samples if using different NALU size*/ if (hevc_src->nal_unit_size > hevc_dst->nal_unit_size) { - gf_media_avc_rewrite_samples(dest, dst_tk, 8*hevc_dst->nal_unit_size, 8*hevc_src->nal_unit_size); + gf_media_nal_rewrite_samples(dest, dst_tk, 8*hevc_src->nal_unit_size); hevc_dst->nal_unit_size = hevc_src->nal_unit_size; } else if (hevc_src->nal_unit_size < hevc_dst->nal_unit_size) { - gf_media_avc_rewrite_samples(orig, src_track, 8*hevc_src->nal_unit_size, 8*hevc_dst->nal_unit_size); + gf_media_nal_rewrite_samples(orig, src_track, 8*hevc_dst->nal_unit_size); } /*merge PS*/ @@ -1731,7 +1610,7 @@ static u32 merge_hevc_config(GF_ISOFile *dest, u32 tk_id, GF_ISOFile *orig, u32 dst_tk = gf_isom_get_track_by_id(dest, tk_id); gf_isom_set_nalu_extract_mode(orig, src_track, GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG); if (!force_cat) { - gf_isom_hevc_set_inband_config(dest, dst_tk, 1); + gf_isom_hevc_set_inband_config(dest, dst_tk, 1, GF_FALSE); } else { fprintf(stderr, "WARNING: Concatenating track ID %d even though sample descriptions do not match\n", tk_id); } @@ -1740,7 +1619,9 @@ static u32 merge_hevc_config(GF_ISOFile *dest, u32 tk_id, GF_ISOFile *orig, u32 } #endif /*GPAC_DISABLE_HEVC */ -GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command) +GF_Err cat_playlist(GF_ISOFile *dest, char *playlistName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command); + +GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command, Bool is_pl) { u32 i, j, count, nb_tracks, nb_samp, nb_done; GF_ISOFile *orig; @@ -1752,18 +1633,19 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou u64 insert_dts; Bool is_isom; GF_ISOSample *samp; - Double aligned_to_DTS = 0; + GF_Fraction64 aligned_to_DTS_frac; + + if (is_pl) return cat_playlist(dest, fileName, import_flags, force_fps, frames_per_sample, tmp_dir, force_cat, align_timelines, allow_add_in_command); - if (strchr(fileName, '*')) return cat_multiple_files(dest, fileName, import_flags, force_fps, frames_per_sample, tmp_dir, force_cat, align_timelines, allow_add_in_command); + if (strchr(fileName, '*') || (strchr(fileName, '@')) ) + return cat_multiple_files(dest, fileName, import_flags, force_fps, frames_per_sample, tmp_dir, force_cat, align_timelines, allow_add_in_command); multi_cat = allow_add_in_command ? strchr(fileName, '+') : NULL; if (multi_cat) { multi_cat[0] = 0; multi_cat = &multi_cat[1]; } - opts = strchr(fileName, ':'); - if (opts && (opts[1]=='\\')) - opts = strchr(fileName, ':'); + opts = gf_url_colon_suffix(fileName); e = GF_OK; @@ -1772,7 +1654,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou if (!is_isom || opts) { orig = gf_isom_open("temp", GF_ISOM_WRITE_EDIT, tmp_dir); - e = import_file(orig, fileName, import_flags, force_fps, frames_per_sample); + e = import_file(orig, fileName, import_flags, force_fps, frames_per_sample, NULL, NULL, 0); if (e) return e; } else { /*we open the original file in edit mode since we may have to rewrite AVC samples*/ @@ -1783,7 +1665,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou char *sep = strchr(multi_cat, '+'); if (sep) sep[0] = 0; - e = import_file(orig, multi_cat, import_flags, force_fps, frames_per_sample); + e = import_file(orig, multi_cat, import_flags, force_fps, frames_per_sample, NULL, NULL, 0); if (e) { gf_isom_delete(orig); return e; @@ -1796,7 +1678,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou nb_samp = 0; nb_tracks = gf_isom_get_track_count(orig); for (i=0; i1)) { insert_dts = 2*gf_isom_get_sample_dts(dest, dst_tk, count) - gf_isom_get_sample_dts(dest, dst_tk, count-1); } else { @@ -2028,14 +1960,13 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou /*if not a new track, see if we can merge the edit list - this is a crude test that only checks we have the same edit types*/ - if (nb_edits && (nb_edits == gf_isom_get_edit_segment_count(dest, dst_tk)) ) { + if (nb_edits && (nb_edits == gf_isom_get_edits_count(dest, dst_tk)) ) { u64 editTime, segmentDuration, mediaTime, dst_editTime, dst_segmentDuration, dst_mediaTime; - u8 dst_editMode, editMode; - u32 j; + GF_ISOEditType dst_editMode, editMode; merge_edits = 1; for (j=0; jCTS_Offset = (u32) (samp->CTS_Offset * ts_scale); if (gf_isom_is_self_contained(orig, i+1, di)) { - e = gf_isom_add_sample(dest, dst_tk, di, samp); + e = gf_isom_add_sample(dest, dst_tk, di + dst_tk_sample_entry, samp); } else { u64 offset; GF_ISOSample *s = gf_isom_get_sample_info(orig, i+1, j+1, &di, &offset); - e = gf_isom_add_sample_reference(dest, dst_tk, di, samp, offset); + e = gf_isom_add_sample_reference(dest, dst_tk, di + dst_tk_sample_entry, samp, offset); gf_isom_sample_del(&s); } + if (samp->nb_pack) + j+= samp->nb_pack-1; + gf_isom_sample_del(&samp); if (e) goto err_exit; @@ -2072,8 +2008,9 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou } /*scene description and text: compute last sample duration based on original media duration*/ if (!use_ts_dur) { - insert_dts = gf_isom_get_media_duration(orig, i+1) - last_DTS; - gf_isom_set_last_sample_duration(dest, dst_tk, (u32) insert_dts); + u64 extend_dur = gf_isom_get_media_duration(orig, i+1) - last_DTS; + //extend the duration of the last sample, but don't insert any edit list entry + gf_isom_set_last_sample_duration(dest, dst_tk, (u32) (ts_scale*extend_dur) ); } if (new_track && insert_dts) { @@ -2084,54 +2021,54 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou /*convert from orig to dst time scale*/ rescale *= ts_scale; - gf_isom_set_edit_segment(dest, dst_tk, 0, (u64) (s64) (insert_dts*rescale), 0, GF_ISOM_EDIT_EMPTY); - gf_isom_set_edit_segment(dest, dst_tk, (u64) (s64) (insert_dts*rescale), (u64) (s64) (media_dur*rescale), 0, GF_ISOM_EDIT_NORMAL); + gf_isom_set_edit(dest, dst_tk, 0, (u64) (s64) (insert_dts*rescale), 0, GF_ISOM_EDIT_EMPTY); + gf_isom_set_edit(dest, dst_tk, (u64) (s64) (insert_dts*rescale), (u64) (s64) (media_dur*rescale), 0, GF_ISOM_EDIT_NORMAL); } else if (merge_edits) { /*convert from media time to track time*/ - Double rescale = (Float) gf_isom_get_timescale(dest); - rescale /= (Float) gf_isom_get_media_timescale(dest, dst_tk); - /*convert from orig to dst time scale*/ - rescale *= ts_scale; + u32 movts_dst = gf_isom_get_timescale(dest); + u32 trackts_dst = gf_isom_get_media_timescale(dest, dst_tk); + u32 trackts_orig = gf_isom_get_media_timescale(orig, i+1); /*get the first edit normal mode and add the new track dur*/ for (j=nb_edits; j>0; j--) { u64 editTime, segmentDuration, mediaTime; - u8 editMode; - gf_isom_get_edit_segment(dest, dst_tk, j, &editTime, &segmentDuration, &mediaTime, &editMode); + GF_ISOEditType editMode; + gf_isom_get_edit(dest, dst_tk, j, &editTime, &segmentDuration, &mediaTime, &editMode); if (editMode==GF_ISOM_EDIT_NORMAL) { Double prev_dur = (Double) (s64) dest_track_dur_before_cat; Double dur = (Double) (s64) gf_isom_get_media_duration(orig, i+1); - dur *= rescale; - prev_dur *= rescale; - /*safety test: some files have broken edit lists. If no more than 2 entries, check that the segment duration is less or equal to the movie duration*/ - if (prev_dur < segmentDuration) { - fprintf(stderr, "Warning: suspicious edit list entry found: duration %g sec but longest track duration before cat is %g - fixing it\n", (Double) (s64) segmentDuration/1000.0, prev_dur/1000); - segmentDuration = (u64) (s64) ( (Double) (s64) (dest_track_dur_before_cat - mediaTime) * rescale ); + if (prev_dur * movts_dst < segmentDuration * trackts_dst) { + fprintf(stderr, "Warning: suspicious edit list entry found: duration %g sec but longest track duration before cat is %g - fixing it\n", (Double) (s64) segmentDuration/movts_dst, prev_dur/trackts_dst); + segmentDuration = (dest_track_dur_before_cat - mediaTime) * movts_dst; + segmentDuration /= trackts_dst; } + //express original dur in new timescale + dur /= trackts_orig; + dur *= movts_dst; + segmentDuration += (u64) (s64) dur; - gf_isom_modify_edit_segment(dest, dst_tk, j, segmentDuration, mediaTime, editMode); + gf_isom_modify_edit(dest, dst_tk, j, segmentDuration, mediaTime, editMode); break; } } } else { u64 editTime, segmentDuration, mediaTime, edit_offset; Double t; - u8 editMode; - u32 j, count; + GF_ISOEditType editMode; - count = gf_isom_get_edit_segment_count(dest, dst_tk); + count = gf_isom_get_edits_count(dest, dst_tk); if (count) { - e = gf_isom_get_edit_segment(dest, dst_tk, count, &editTime, &segmentDuration, &mediaTime, &editMode); + e = gf_isom_get_edit(dest, dst_tk, count, &editTime, &segmentDuration, &mediaTime, &editMode); if (e) { fprintf(stderr, "Error: edit segment error on destination track %u could not be retrieved.\n", dst_tk); goto err_exit; } - } else if (gf_isom_get_edit_segment_count(orig, i+1)) { + } else if (gf_isom_get_edits_count(orig, i+1)) { /*fake empty edit segment*/ /*convert from media time to track time*/ Double rescale = (Float) gf_isom_get_timescale(dest); @@ -2139,7 +2076,8 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou segmentDuration = (u64) (dest_track_dur_before_cat * rescale); editTime = 0; mediaTime = 0; - gf_isom_set_edit_segment(dest, dst_tk, editTime, segmentDuration, mediaTime, GF_ISOM_EDIT_NORMAL); + if (segmentDuration) + gf_isom_set_edit(dest, dst_tk, editTime, segmentDuration, mediaTime, GF_ISOM_EDIT_NORMAL); } else { editTime = 0; segmentDuration = 0; @@ -2150,9 +2088,9 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou ts_scale /= (Float) gf_isom_get_timescale(orig); edit_offset = editTime + segmentDuration; - count = gf_isom_get_edit_segment_count(orig, i+1); + count = gf_isom_get_edits_count(orig, i+1); for (j=0; j 0)) { editMode = GF_ISOM_EDIT_NORMAL; } - gf_isom_set_edit_segment(dest, dst_tk, editTime, segmentDuration, mediaTime, editMode); + gf_isom_set_edit(dest, dst_tk, editTime, segmentDuration, mediaTime, editMode); } } + gf_media_update_bitrate(dest, dst_tk); } + for (i = 0; i < gf_isom_get_track_count(dest); ++i) { + if (gf_isom_get_media_type(dest, i+1) == GF_ISOM_MEDIA_TIMECODE) { + u32 video_ref = 0; + for (j = 0; j < gf_isom_get_track_count(dest); ++j) { + if (gf_isom_is_video_handler_type(gf_isom_get_media_type(dest, j+1))) { + video_ref = j+1; + break; + } + } + if (video_ref) { + u64 video_ref_dur = gf_isom_get_media_duration(dest, video_ref); + u32 last_sample_dur = gf_isom_get_sample_duration(dest, i+1, gf_isom_get_sample_count(dest, i+1)); + u64 dur = video_ref_dur - gf_isom_get_media_duration(dest, i+1) + last_sample_dur; + gf_isom_set_last_sample_duration(dest, i+1, (u32)dur); + } + } + } gf_set_progress("Appending", nb_samp, nb_samp); + /*check brands*/ + gf_isom_get_brand_info(orig, NULL, NULL, &j); + for (i=0; iszRad1, len_rad1)) return 0; if (strlen(cat_enum->szRad2) && !strstr(szName + len_rad1, cat_enum->szRad2) ) return 0; - strcpy(szFileName, szName); + strcpy(szFileName, szPath); strcat(szFileName, cat_enum->szOpt); - e = cat_isomedia_file(cat_enum->dest, szFileName, cat_enum->import_flags, cat_enum->force_fps, cat_enum->frames_per_sample, cat_enum->tmp_dir, cat_enum->force_cat, cat_enum->align_timelines, cat_enum->allow_add_in_command); + e = cat_isomedia_file(cat_enum->dest, szFileName, cat_enum->import_flags, cat_enum->force_fps, cat_enum->frames_per_sample, cat_enum->tmp_dir, cat_enum->force_cat, cat_enum->align_timelines, cat_enum->allow_add_in_command, GF_FALSE); if (e) return 1; return 0; } -GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command) +GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command) { CATEnum cat_enum; char *sep; @@ -2247,30 +2210,91 @@ GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Do cat_enum.align_timelines = align_timelines; cat_enum.allow_add_in_command = allow_add_in_command; + if (strlen(fileName) >= sizeof(cat_enum.szPath)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("File name %s is too long.\n", fileName)); + return GF_NOT_SUPPORTED; + } strcpy(cat_enum.szPath, fileName); sep = strrchr(cat_enum.szPath, GF_PATH_SEPARATOR); if (!sep) sep = strrchr(cat_enum.szPath, '/'); if (!sep) { strcpy(cat_enum.szPath, "."); + if (strlen(fileName) >= sizeof(cat_enum.szRad1)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("File name %s is too long.\n", fileName)); + return GF_NOT_SUPPORTED; + } strcpy(cat_enum.szRad1, fileName); } else { + if (strlen(sep + 1) >= sizeof(cat_enum.szRad1)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("File name %s is too long.\n", (sep + 1))); + return GF_NOT_SUPPORTED; + } strcpy(cat_enum.szRad1, sep+1); sep[0] = 0; } sep = strchr(cat_enum.szRad1, '*'); + if (!sep) sep = strchr(cat_enum.szRad1, '@'); + if (strlen(sep + 1) >= sizeof(cat_enum.szRad2)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("File name %s is too long.\n", (sep + 1))); + return GF_NOT_SUPPORTED; + } strcpy(cat_enum.szRad2, sep+1); sep[0] = 0; sep = strchr(cat_enum.szRad2, '%'); if (!sep) sep = strchr(cat_enum.szRad2, '#'); - if (!sep) sep = strchr(cat_enum.szRad2, ':'); + if (!sep) sep = gf_url_colon_suffix(cat_enum.szRad2); strcpy(cat_enum.szOpt, ""); if (sep) { + if (strlen(sep) >= sizeof(cat_enum.szOpt)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Invalid option: %s.\n", sep)); + return GF_NOT_SUPPORTED; + } strcpy(cat_enum.szOpt, sep); sep[0] = 0; } return gf_enum_directory(cat_enum.szPath, 0, cat_enumerate, &cat_enum, NULL); } +GF_Err cat_playlist(GF_ISOFile *dest, char *playlistName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command) +{ + GF_Err e; + FILE *pl = gf_fopen(playlistName, "r"); + if (!pl) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Failed to open playlist file %s\n", playlistName)); + return GF_URL_ERROR; + } + + e = GF_OK; + while (!feof(pl)) { + char szLine[10000]; + char *url; + u32 len; + szLine[0] = 0; + if (gf_fgets(szLine, 10000, pl) == NULL) break; + if (szLine[0]=='#') continue; + len = (u32) strlen(szLine); + while (len && strchr("\r\n \t", szLine[len-1])) { + szLine[len-1] = 0; + len--; + } + if (!len) continue; + + url = gf_url_concatenate(playlistName, szLine); + if (!url) url = gf_strdup(szLine); + + e = cat_isomedia_file(dest, url, import_flags, force_fps, frames_per_sample, tmp_dir, force_cat, align_timelines, allow_add_in_command, GF_FALSE); + + + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Failed to concatenate file %s\n", url)); + gf_free(url); + break; + } + gf_free(url); + } + gf_fclose(pl); + return e; +} #ifndef GPAC_DISABLE_SCENE_ENCODER /* @@ -2299,6 +2323,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log load.swf_flatten_limit = swf_flatten_angle; /*since we're encoding we must get MPEG4 nodes only*/ load.flags = GF_SM_LOAD_MPEG4_STRICT; + e = gf_sm_load_init(&load); if (e<0) { gf_sm_load_done(&load); @@ -2314,7 +2339,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log statsman = gf_sm_stats_new(); e = gf_sm_stats_for_scene(statsman, ctx); if (!e) { - GF_SceneStatistics *stats = gf_sm_stats_get(statsman); + const GF_SceneStatistics *stats = gf_sm_stats_get(statsman); /*LASeR*/ if (opts->auto_quant==1) { if (opts->resolution > (s32)stats->frac_res_2d) { @@ -2365,7 +2390,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log if ((stats->count_3f+stats->count_3d) && opts->resolution) { qp->position3DMin = stats->min_3d; qp->position3DMax = stats->max_3d; - qp->position3DQuant = opts->resolution; + qp->position3DNbBits = opts->resolution; qp->position3DQuant = 1; qp->textureCoordinateQuant = 1; } @@ -2402,7 +2427,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log } gf_isom_set_brand_info(mp4, GF_ISOM_BRAND_MP42, 1); - gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, 1); + gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, GF_TRUE); err_exit: #ifndef GPAC_DISABLE_SCENE_STATS @@ -2433,18 +2458,16 @@ static u32 GetNbBits(u32 MaxVal) GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCallback)(GF_ISOSample *)) { GF_Err e; - char *data; + u8 *data; u32 data_len; GF_BifsEncoder *bifsenc; GF_InitialObjectDescriptor *iod; u32 i, j, count; - GF_StreamContext *sc; - GF_ESD *esd; Bool encode_names, delete_bcfg; GF_BIFSConfig *bcfg; GF_AUContext *au; char szRad[GF_MAX_PATH], *ext; - char szName[1024]; + char szName[GF_MAX_PATH+100]; FILE *f; strcpy(szRad, bifsOutputFile); @@ -2461,20 +2484,21 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa if (!iod) { count = 0; for (i=0; istreams); i++) { - sc = gf_list_get(ctx->streams, i); + GF_StreamContext *sc = gf_list_get(ctx->streams, i); if (sc->streamType == GF_STREAM_OD) count++; } - if (!iod && count>1) return GF_NOT_SUPPORTED; + if (count>1) return GF_NOT_SUPPORTED; } count = gf_list_count(ctx->streams); for (i=0; istreams, i); - esd = NULL; + if (sc->streamType != GF_STREAM_SCENE) continue; - esd = NULL; if (iod) { for (j=0; jESDescriptors); j++) { esd = gf_list_get(iod->ESDescriptors, j); @@ -2500,6 +2524,7 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa esd->decoderConfig->decoderSpecificInfo = NULL; esd->ESID = sc->ESID; esd->decoderConfig->streamType = GF_STREAM_SCENE; + delete_esd = GF_TRUE; } if (!esd->decoderConfig) return GF_OUT_OF_MEM; @@ -2538,7 +2563,6 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa gf_bifs_encoder_new_stream(bifsenc, sc->ESID, bcfg, encode_names, 0); if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg); - /*setup MP4 track*/ if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); if (sc->timeScale) esd->slConfig->timestampResolution = sc->timeScale; if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000; @@ -2552,18 +2576,17 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(bifsenc, sc->ESID); for (j=1; jAUs); j++) { - char *data; - u32 data_len; au = gf_list_get(sc->AUs, j); e = gf_bifs_encode_au(bifsenc, sc->ESID, au->commands, &data, &data_len); if (data) { - sprintf(szName, "%s%02d.bifs", szRad, j); + sprintf(szName, "%s-%02d-%02d.bifs", szRad, sc->ESID, j); f = gf_fopen(szName, "wb"); - gf_fwrite(data, data_len, 1, f); + gf_fwrite(data, data_len, f); gf_fclose(f); gf_free(data); } } + if (delete_esd) gf_odf_desc_del((GF_Descriptor*)esd); } gf_bifs_encoder_del(bifsenc); return e; @@ -2574,12 +2597,12 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa #endif /*GPAC_DISABLE_BIFS_ENC*/ /** - * \param chunkFile BT chunk to be encoded - * \param bifs output file name for the BIFS data - * \param inputContext initial BT upon which the chunk is based (shall not be NULL) - * \param outputContext: file name to dump the context after applying the new chunk to the input context +\param chunkFile BT chunk to be encoded +\param bifs output file name for the BIFS data +\param inputContext initial BT upon which the chunk is based (shall not be NULL) +\param outputContext: file name to dump the context after applying the new chunk to the input context can be NULL, without .bt - * \param tmpdir can be NULL +\param tmpdir can be NULL */ GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *outputContext, const char *tmpdir) { @@ -2604,7 +2627,7 @@ GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *ou if (!e) e = gf_sm_load_run(&load); gf_sm_load_done(&load); if (e) { - fprintf(stderr, "Cannot load context %s - %s\n", inputContext, gf_error_to_string(e)); + fprintf(stderr, "Cannot load context %s: %s\n", inputContext, gf_error_to_string(e)); goto exit; } @@ -2621,7 +2644,7 @@ GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *ou if (!e) e = gf_sm_load_run(&load); gf_sm_load_done(&load); if (e) { - fprintf(stderr, "Cannot load chunk context %s - %s\n", chunkFile, gf_error_to_string(e)); + fprintf(stderr, "Cannot load scene commands chunk %s: %s\n", chunkFile, gf_error_to_string(e)); goto exit; } fprintf(stderr, "Context and chunks loaded\n"); @@ -2685,14 +2708,13 @@ void sax_node_start(void *sax_cbck, const char *node_name, const char *name_spac { char szCheck[100]; GF_List *imports = sax_cbck; - GF_XMLAttribute *att; u32 i=0; /*do not process hyperlinks*/ if (!strcmp(node_name, "a") || !strcmp(node_name, "Anchor")) return; for (i=0; iname, "xlink:href") && stricmp(att->name, "url")) continue; if (att->value[0]=='#') continue; if (!strnicmp(att->value, "od:", 3)) continue; @@ -2707,8 +2729,8 @@ static Bool wgt_enum_files(void *cbck, char *file_name, char *file_path, GF_File WGTEnum *wgt = (WGTEnum *)cbck; if (!strcmp(wgt->root_file, file_path)) return 0; - /*remove CVS stuff*/ - if (strstr(file_path, ".#")) return 0; + //remove hidden files + if (file_path[0] == '.') return 0; gf_list_add(wgt->imports, gf_strdup(file_path) ); return 0; } @@ -2781,10 +2803,10 @@ GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool ma mtype = GF_4CC(fcc[0],fcc[1],fcc[2],fcc[3]); } else { mtype = 0; - if (!stricmp(type, "svg")) mtype = ascii ? GF_4CC('s','v','g',' ') : GF_4CC('s','v','g','z'); - else if (!stricmp(type, "smil")) mtype = ascii ? GF_4CC('s','m','i','l') : GF_4CC('s','m','l','z'); - else if (!stricmp(type, "x3d")) mtype = ascii ? GF_4CC('x','3','d',' ') : GF_4CC('x','3','d','z') ; - else if (!stricmp(type, "xmt-a")) mtype = ascii ? GF_4CC('x','m','t','a') : GF_4CC('x','m','t','z'); + if (!stricmp(type, "svg")) mtype = ascii ? GF_META_TYPE_SVG : GF_META_TYPE_SVGZ; + else if (!stricmp(type, "smil")) mtype = ascii ? GF_META_TYPE_SMIL : GF_META_TYPE_SMLZ; + else if (!stricmp(type, "x3d")) mtype = ascii ? GF_META_TYPE_X3D : GF_META_TYPE_X3DZ ; + else if (!stricmp(type, "xmt-a")) mtype = ascii ? GF_META_TYPE_XMTA : GF_META_TYPE_XMTZ; } if (!mtype) { fprintf(stderr, "Missing 4CC code for meta name - please use ABCD:fileName\n"); @@ -2797,9 +2819,16 @@ GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool ma count = gf_list_count(imports); for (i=0; iname, "HDR")) { + fprintf(stderr, "Error parsing HDR XML file: root name is \"%s\", expecting \"HDR\"\n", root->name); + gf_xml_dom_del(parser); + return GF_NON_COMPLIANT_BITSTREAM; + } + + i = 0; + while ((stream = gf_list_enum(root->content, &i))) { + u32 id = 0, j; + GF_XMLAttribute* att = NULL; + GF_XMLNode *box = NULL; + + if (stream->type != GF_XML_NODE_TYPE) continue; + if (strcmp(stream->name, "Track")) continue; + + j = 0; + while ((att = gf_list_enum(stream->attributes, &j))) { + if (!strcmp(att->name, "id")) id = atoi(att->value); + else fprintf(stderr, "HDR XML: ignoring track attribute \"%s\"\n", att->name); + } + + j = 0; + while ((box = gf_list_enum(stream->content, &j))) { + u32 k; + + if (box->type != GF_XML_NODE_TYPE) continue; + + if (!strcmp(box->name, "mdcv")) { + k = 0; + while ((att = gf_list_enum(box->attributes, &k))) { + if (!strcmp(att->name, "display_primaries_0_x")) mdcv.display_primaries[0].x = atoi(att->value); + else if (!strcmp(att->name, "display_primaries_0_y")) mdcv.display_primaries[0].y = atoi(att->value); + else if (!strcmp(att->name, "display_primaries_1_x")) mdcv.display_primaries[1].x = atoi(att->value); + else if (!strcmp(att->name, "display_primaries_1_y")) mdcv.display_primaries[1].y = atoi(att->value); + else if (!strcmp(att->name, "display_primaries_2_x")) mdcv.display_primaries[2].x = atoi(att->value); + else if (!strcmp(att->name, "display_primaries_2_y")) mdcv.display_primaries[2].y = atoi(att->value); + else if (!strcmp(att->name, "white_point_x")) mdcv.white_point_x = atoi(att->value); + else if (!strcmp(att->name, "white_point_y")) mdcv.white_point_y = atoi(att->value); + else if (!strcmp(att->name, "max_display_mastering_luminance")) mdcv.max_display_mastering_luminance = atoi(att->value); + else if (!strcmp(att->name, "min_display_mastering_luminance")) mdcv.min_display_mastering_luminance = atoi(att->value); + else fprintf(stderr, "HDR XML: ignoring box \"%s\" attribute \"%s\"\n", box->name, att->name); + } + } else if (!strcmp(box->name, "clli")) { + k = 0; + while ((att = gf_list_enum(box->attributes, &k))) { + if (!strcmp(att->name, "max_content_light_level")) clli.max_content_light_level = atoi(att->value); + else if (!strcmp(att->name, "max_pic_average_light_level")) clli.max_pic_average_light_level = atoi(att->value); + else fprintf(stderr, "HDR XML: ignoring box \"%s\" attribute \"%s\"\n", box->name, att->name); + } + } else { + fprintf(stderr, "HDR XML: ignoring box element \"%s\"\n", box->name); + continue; + } + } + + e = gf_isom_set_high_dynamic_range_info(movie, id, 1, &mdcv, &clli); + if (e) { + fprintf(stderr, "HDR XML: error in gf_isom_set_high_dynamic_range_info()\n"); + break; + } + } + + gf_xml_dom_del(parser); + return e; +} + #else GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool make_wgt) { fprintf(stderr, "XML Not supported in this build of GPAC - cannot package file\n"); return NULL; } + +GF_Err parse_high_dynamc_range_xml_desc(GF_ISOFile* movie, char* file_name) +{ + fprintf(stderr, "XML Not supported in this build of GPAC - cannot process HDR parameter file\n"); + return GF_OK; +} #endif //#ifndef GPAC_DISABLE_CORE_TOOLS diff --git a/applications/mp4box/live.c b/applications/mp4box/live.c index da512be..06153b1 100644 --- a/applications/mp4box/live.c +++ b/applications/mp4box/live.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2012 + * Copyright (c) Telecom ParisTech 2000-2019 * All rights reserved * * Authors: Jean Le Feuvre @@ -26,23 +26,17 @@ */ -#include -#include +#include "mp4box.h" #ifndef GPAC_DISABLE_SENG #include #endif #ifndef GPAC_DISABLE_STREAMING -#include #include #endif #include -#ifndef GPAC_DISABLE_STREAMING -#include -#endif - #if defined(GPAC_DISABLE_ISOM) || defined(GPAC_DISABLE_ISOM_WRITE) #error "Cannot compile MP4Box if GPAC is not built with ISO File Format support" @@ -51,164 +45,16 @@ #if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) -void PrintStreamerUsage() -{ - fprintf(stderr, "File Streamer Options\n" - "\n" - "MP4Box can stream ISO files to RTP. The streamer currently doesn't support\n" - "data carrouselling and will therefore not handle BIFS and OD streams properly.\n" - "\n" - "-rtp enables streamer\n" - "-run-for=T runs for T seconds of the media then exits\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" - ); -} - -static void on_logs(void *cbk, GF_LOG_Level ll, GF_LOG_Tool lm, const char *fmt, va_list list) -{ - FILE *logs = (FILE*)cbk; - vfprintf(logs, fmt, list); - fflush(logs); -} - -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; - char *logs=NULL; - FILE *logfile=NULL; - u16 port = 7000; - u32 ttl = 1; - Bool loop = GF_TRUE; - GF_MemTrackerType mem_track = GF_MemTrackerNone; - Bool force_mpeg4 = GF_FALSE; - u32 path_mtu = 1450; - Double run_for = -1.0; - u32 i; - - for (i = 1; i < (u32) argc ; i++) { - char *arg = argv[i]; - - if (arg[0] != '-') { - if (inName) { - fprintf(stderr, "Error - 2 input names specified, please check usage\n"); - return 1; - } - inName = arg; - } - else if (!stricmp(arg, "-noloop")) loop = GF_FALSE; - else if (!stricmp(arg, "-mpeg4")) force_mpeg4 = GF_TRUE; - 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; - else if (!stricmp(arg, "-mem-track")) mem_track = GF_MemTrackerSimple; - else if (!stricmp(arg, "-mem-track-stack")) mem_track = GF_MemTrackerBackTrace; - else if (!strnicmp(arg, "-logs=", 6)) logs = arg+6; - else if (!strnicmp(arg, "-lf=", 4)) logfile = gf_fopen(arg+4, "wt"); - else if (!strnicmp(arg, "-run-for=", 9)) run_for = atof(arg+9); - } - gf_sys_init(mem_track); - if (logs) - gf_log_set_tools_levels(logs); - else - gf_log_set_tool_level(GF_LOG_RTP, GF_LOG_INFO); //set to debug to have packet list - if (logfile) { - gf_log_set_callback(logfile, on_logs); - } - if (!gf_isom_probe_file(inName)) { - fprintf(stderr, "File %s is not a valid ISO Media file and cannot be streamed\n", inName); - if (logfile) gf_fclose(logfile); - gf_sys_close(); - return 1; - } - file_streamer = gf_isom_streamer_new(inName, ip_dest, port, loop, force_mpeg4, path_mtu, ttl, ifce_addr); - if (!file_streamer) { - fprintf(stderr, "Cannot create file streamer\n"); - } else { - Bool run = GF_TRUE; - u32 check = 50; - fprintf(stderr, "Starting streaming %s to %s:%d\n", inName, ip_dest, port); - gf_isom_streamer_write_sdp(file_streamer, sdp_file); - - if (run_for==0) run=GF_FALSE; - - while (run) { - 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; - } - if ((run_for > 0) && (run_for < gf_isom_streamer_get_current_time(file_streamer)) ) - break; - } - gf_isom_streamer_del(file_streamer); - } - if (logfile) gf_fclose(logfile); - gf_sys_close(); - return 0; -} - - -void PrintLiveUsage() -{ - fprintf(stderr, - - "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" - "-no-rap disabled RAP sending - this also disables carousel generation. 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; + u8 *carousel_data; u32 carousel_size, carousel_alloc; u32 last_carousel_time; u64 carousel_ts, time_at_carousel_store; @@ -265,7 +111,7 @@ RTPChannel *next_carousel(LiveSession *sess, u32 *timeout) } -static void live_session_callback(void *calling_object, u16 ESID, char *data, u32 size, u64 ts) +static void live_session_callback(void *calling_object, u16 ESID, u8 *data, u32 size, u64 ts) { LiveSession *livesess = (LiveSession *) calling_object; RTPChannel *rtpch; @@ -310,7 +156,7 @@ static void live_session_callback(void *calling_object, u16 ESID, char *data, u3 static void live_session_send_carousel(LiveSession *livesess, RTPChannel *ch) { u32 now = gf_sys_clock(); - u64 ts=0; + u64 ts; if (ch) { if (ch->carousel_size) { ts = ch->carousel_ts + ch->timescale * ( (ch->adjust_carousel_time ? (u64)gf_sys_clock() : ch->time_at_carousel_store) - ch->init_time + ch->ts_delta)/1000; @@ -346,7 +192,7 @@ static void live_session_send_carousel(LiveSession *livesess, RTPChannel *ch) } } -static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 path_mtu, u32 ttl, char *ifce_addr, char *sdp_name) +static Bool 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); @@ -355,10 +201,16 @@ static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 pa char *sdp = gf_rtp_streamer_format_sdp_header("GPACSceneStreamer", ip, NULL, iod64); if (iod64) gf_free(iod64); +#ifdef GPAC_ENABLE_COVERAGE + if (gf_sys_is_cov_mode()) { + GF_Descriptor *desc = gf_seng_get_iod(livesess->seng); + if (desc) gf_odf_desc_del(desc); + } +#endif for (i=0; iseng, i, &ESID, &config, &config_len, &st, &oti, &ts); @@ -373,9 +225,9 @@ static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 pa 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); + rtpch->rtp = gf_rtp_streamer_new(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, + GP_RTP_PCK_SYSTEMS_CAROUSEL, config, config_len, + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, GF_FALSE); if (rtpch->rtp) { gf_rtp_streamer_disable_auto_rtcp(rtpch->rtp); @@ -383,18 +235,20 @@ static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 pa } 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); + rtpch->rtp = gf_rtp_streamer_new(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, GP_RTP_PCK_SIGNAL_RAP, config, config_len, 96, 0, 0, GF_FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GF_FALSE); 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); + if (!rtpch->rtp) + return GF_FALSE; + + gf_rtp_streamer_append_sdp(rtpch->rtp, ESID, 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) { @@ -403,6 +257,7 @@ static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 pa gf_fclose(out); gf_free(sdp); } + return GF_TRUE; } void live_session_shutdown(LiveSession *livesess) @@ -475,7 +330,7 @@ int live_session(int argc, char **argv) u32 i; char *filename = NULL; char *dst = NULL; - char *ifce_addr = NULL; + const char *ifce_addr = NULL; char *sdp_name = "session.sdp"; u16 dst_port = 7000; u32 load_type=0; @@ -483,7 +338,7 @@ int live_session(int argc, char **argv) u32 ttl = 1; u32 path_mtu = 1450; s32 next_time; - u64 last_src_modif, mod_time; + u64 last_src_modif, mod_time, runfor=0, start_time; char *src_name = NULL; Bool run, has_carousel, no_rap; Bool udp = 0; @@ -502,12 +357,15 @@ int live_session(int argc, char **argv) aggregate_au = 1; es_id = 0; no_rap = 0; - gf_sys_init(GF_MemTrackerNone); + gf_sys_init(GF_MemTrackerNone, NULL); memset(&livesess, 0, sizeof(LiveSession)); gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_INFO); + gf_sys_set_args(argc, (const char **) argv); + + for (i=1; i<(u32) argc; i++) { char *arg = argv[i]; if (arg[0] != '-') filename = arg; @@ -516,7 +374,6 @@ int live_session(int argc, char **argv) else if (!strnicmp(arg, "-sdp=", 5)) sdp_name = arg+5; else if (!strnicmp(arg, "-mtu=", 5)) path_mtu = atoi(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, "-no-rap", 7)) no_rap = 1; else if (!strnicmp(arg, "-dims", 5)) load_type = GF_SM_LOAD_DIMS; else if (!strnicmp(arg, "-src=", 5)) src_name = arg+5; @@ -528,12 +385,17 @@ int live_session(int argc, char **argv) sk_port = atoi(arg+5); udp = 0; } + else if (!stricmp(arg, "-run-for")) { + runfor = 1 + 1000 * atoi(argv[i+1]); + i++; + } } if (!filename) { fprintf(stderr, "Missing filename\n"); PrintLiveUsage(); return 1; } + ifce_addr = gf_opts_get_key("core", "ifce"); if (dst_port && dst) livesess.streams = gf_list_new(); @@ -542,7 +404,16 @@ int live_session(int argc, char **argv) fprintf(stderr, "Cannot create scene engine\n"); return 1; } - if (livesess.streams) live_session_setup(&livesess, dst, dst_port, path_mtu, ttl, ifce_addr, sdp_name); + if (livesess.streams) { + Bool res = live_session_setup(&livesess, dst, dst_port, path_mtu, ttl, (char *) ifce_addr, sdp_name); + if (!res) { + live_session_shutdown(&livesess); + if (update_buffer) gf_free(update_buffer); + if (sk) gf_sk_del(sk); + gf_sys_close(); + return e ? 1 : 0; + } + } has_carousel = 0; last_src_modif = src_name ? gf_file_modification_time(src_name) : 0; @@ -563,8 +434,7 @@ int live_session(int argc, char **argv) for (i=0; i<(u32) argc; i++) { char *arg = argv[i]; if (!strnicmp(arg, "-rap=", 5)) { - u32 period, id, j; - RTPChannel *ch; + u32 id, j; period = id = 0; if (strchr(arg, ':')) { sscanf(arg, "-rap=ESID=%u:%u", &id, &period); @@ -604,6 +474,21 @@ int live_session(int argc, char **argv) live_session_send_carousel(&livesess, NULL); + +#ifdef GPAC_ENABLE_COVERAGE + if (gf_sys_is_cov_mode()) { + 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; + + 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); + } +#endif + + start_time = gf_sys_clock_high_res(); check = 10; run = 1; while (run) { @@ -617,14 +502,12 @@ int live_session(int argc, char **argv) run=0; break; case 'U': - livesess.critical = 1; case 'u': { - GF_Err e; char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); szCom[0] = 0; - if (1 > scanf("%[^\t\n]", szCom)) { + if (1 > scanf("%8191[^\t\n]", szCom)) { fprintf(stderr, "No command entered properly, aborting.\n"); break; } @@ -634,19 +517,17 @@ int live_session(int argc, char **argv) if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); e = gf_seng_aggregate_context(livesess.seng, 0); if (e) fprintf(stderr, "Aggregating context failed: %s\n", gf_error_to_string(e)); - livesess.critical = 0; + livesess.critical = (c=='U') ? 1 : 0; update_context = 1; } break; case 'E': - livesess.critical = 1; case 'e': { - GF_Err e; char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); szCom[0] = 0; - if (1 > scanf("%[^\t\n]", szCom)) { + if (1 > scanf("%8191[^\t\n]", szCom)) { printf("No command entered properly, aborting.\n"); break; } @@ -654,7 +535,7 @@ int live_session(int argc, char **argv) while (getchar()!='\n') {} e = gf_seng_encode_from_string(livesess.seng, 0, 1, szCom, live_session_callback); if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); - livesess.critical = 0; + livesess.critical = (c=='E') ? 1 : 0; e = gf_seng_aggregate_context(livesess.seng, 0); if (e) fprintf(stderr, "Aggregating context failed: %s\n", gf_error_to_string(e)); @@ -665,7 +546,7 @@ int live_session(int argc, char **argv) { char rad[GF_MAX_PATH]; fprintf(stderr, "Enter output file name - \"std\" for stderr: "); - if (1 > scanf("%s", rad)) { + if (1 > scanf("%1023s", rad)) { fprintf(stderr, "No ouput file name entered, aborting.\n"); break; } @@ -696,7 +577,7 @@ int live_session(int argc, char **argv) if (!srcf) continue; /*checks if we have a broadcast config*/ - if (!fgets(flag_buf, 200, srcf)) + if (!gf_fgets(flag_buf, 200, srcf)) flag_buf[0] = '\0'; gf_fclose(srcf); @@ -712,7 +593,7 @@ int live_session(int argc, char **argv) if (flag) { flag += strlen("gpac_broadcast_config "); /*move to next word*/ - while (flag && (flag[0]==' ')) flag++; + while (flag[0]==' ') flag++; while (1) { char *sep = strchr(flag, ' '); @@ -750,13 +631,13 @@ int live_session(int argc, char **argv) /*process updates from socket source*/ if (sk) { - char buffer[2049]; + u8 buffer[2049]; u32 bytes_read; u32 update_length; u32 bytes_received; - e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read); + e = gf_sk_receive(sk, buffer, 2048, &bytes_read); if (e == GF_OK) { u32 hdr_length = 0; u8 cmd_type = buffer[0]; @@ -801,7 +682,7 @@ int live_session(int argc, char **argv) bytes_received = bytes_read-hdr_length; } while (bytes_received start_time+runfor)) + break; + + if (!has_carousel) { gf_sleep(10); continue; @@ -852,6 +737,16 @@ int live_session(int argc, char **argv) live_session_send_carousel(&livesess, ch); } +#ifdef GPAC_ENABLE_COVERAGE + if (gf_sys_is_cov_mode()) { +/* gf_seng_save_context(livesess.seng, NULL); + gf_seng_aggregate_context + gf_seng_encode_from_string + gf_seng_encode_from_file +*/ + } +#endif + exit: live_session_shutdown(&livesess); if (update_buffer) gf_free(update_buffer); @@ -864,98 +759,3 @@ exit: #endif /*!defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)*/ #endif /*defined(GPAC_DISABLE_ISOM) || defined(GPAC_DISABLE_ISOM_WRITE)*/ - -#ifndef GPAC_DISABLE_MPEG2TS - -u32 grab_live_m2ts(const char *grab_m2ts, const char *grab_ifce, const char *outName) -{ - char data[0x80000]; - u32 check = 50; - u64 nb_pck; - Bool first_run, is_rtp; - FILE *output; -#ifndef GPAC_DISABLE_STREAMING - u16 seq_num; - GF_RTPReorder *ch = NULL; -#endif - GF_Socket *sock; - GF_Err e = gf_m2ts_get_socket(grab_m2ts, grab_ifce, GF_M2TS_UDP_BUFFER_SIZE, &sock); - - if (e) { - fprintf(stderr, "Cannot open %s: %s\n", grab_m2ts, gf_error_to_string(e)); - return 1; - } - output = gf_fopen(outName, "wb"); - if (!output) { - fprintf(stderr, "Cannot open %s: check path and rights\n", outName); - gf_sk_del(sock); - return 1; - } - - fprintf(stderr, "Dumping %s stream to %s - press q to abort\n", grab_m2ts, outName); - - first_run = 1; - is_rtp = 0; - while (1) { - u32 size = 0; - - check--; - if (!check) { - if (gf_prompt_has_input()) { - char c = (char) gf_prompt_get_char(); - if (c=='q') break; - } - check = 50; - } - - /*m2ts chunks by chunks*/ - e = gf_sk_receive(sock, data, 0x40000, 0, &size); - if (!size || e) { - gf_sleep(1); - continue; - } - if (first_run) { - first_run = 0; - /*FIXME: we assume only simple RTP packaging (no CSRC nor extensions)*/ - if ((data[0] != 0x47) && ((data[1] & 0x7F) == 33) ) { - is_rtp = 1; -#ifndef GPAC_DISABLE_STREAMING - ch = gf_rtp_reorderer_new(100, 500); -#endif - } - } - /*process chunk*/ - if (is_rtp) { -#ifndef GPAC_DISABLE_STREAMING - char *pck; - seq_num = ((data[2] << 8) & 0xFF00) | (data[3] & 0xFF); - gf_rtp_reorderer_add(ch, (void *) data, size, seq_num); - - pck = (char *) gf_rtp_reorderer_get(ch, &size); - if (pck) { - fwrite(pck+12, size-12, 1, output); - gf_free(pck); - } -#else - fwrite(data+12, size-12, 1, output); -#endif - } else { - fwrite(data, size, 1, output); - } - } - nb_pck = gf_ftell(output); - nb_pck /= 188; - fprintf(stderr, "Captured "LLU" TS packets\n", nb_pck ); - gf_fclose(output); - gf_sk_del(sock); - -#ifndef GPAC_DISABLE_STREAMING - if (ch) - gf_rtp_reorderer_del(ch); -#endif - return 0; -} - -#endif /* GPAC_DISABLE_MPEG2TS */ - - diff --git a/applications/mp4box/main.c b/applications/mp4box/main.c index 5611fe5..7871248 100644 --- a/applications/mp4box/main.c +++ b/applications/mp4box/main.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2012 + * Copyright (c) Telecom ParisTech 2000-2020 * All rights reserved * * This file is part of GPAC / mp4box application @@ -24,13 +24,7 @@ */ -#include -#include -#include - -#ifndef GPAC_DISABLE_SMGR -#include -#endif +#include "mp4box.h" #ifdef GPAC_DISABLE_ISOM @@ -44,108 +38,28 @@ #endif #include +#include /*RTP packetizer flags*/ #ifndef GPAC_DISABLE_STREAMING #include #endif -#ifndef GPAC_DISABLE_MCRYPT -#include +#ifndef GPAC_DISABLE_CRYPTO +#include #endif #include +#include -#include - -#include +#include #define BUFFSIZE 8192 #define DEFAULT_INTERLEAVING_IN_SEC 0.5 -/*in fileimport.c*/ - -#ifndef GPAC_DISABLE_MEDIA_IMPORT -void convert_file_info(char *inName, u32 trackID); -#endif - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample); -GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u64 split_size_kb, char *inName, Double interleaving_time, Double chunk_start, Bool adjust_split_end, char *outName, const char *tmpdir); -GF_Err cat_isomedia_file(GF_ISOFile *mp4, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command); - -#if !defined(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_Err dump_isom_cover_art(GF_ISOFile *file, char *inName, Bool is_final_name); -GF_Err dump_isom_chapters(GF_ISOFile *file, char *inName, Bool is_final_name, Bool dump_ogg); -void dump_isom_udta(GF_ISOFile *file, char *inName, Bool is_final_name, u32 dump_udta_type, u32 dump_udta_track); -GF_Err set_file_udta(GF_ISOFile *dest, u32 tracknum, u32 udta_type, char *src, Bool is_box_array); -u32 id3_get_genre_tag(const char *name); - -/*in filedump.c*/ -#ifndef GPAC_DISABLE_SCENE_DUMP -GF_Err dump_isom_scene(char *file, char *inName, Bool is_final_name, GF_SceneDumpFormat dump_mode, Bool do_log); -//void gf_check_isom_files(char *conf_rules, char *inName); -#endif -#ifndef GPAC_DISABLE_SCENE_STATS -void dump_isom_scene_stats(char *file, char *inName, Bool is_final_name, u32 stat_level); -#endif -void PrintNode(const char *name, u32 graph_type); -void PrintBuiltInNodes(u32 graph_type); -void PrintBuiltInBoxes(); - -#ifndef GPAC_DISABLE_ISOM_DUMP -GF_Err dump_isom_xml(GF_ISOFile *file, char *inName, Bool is_final_name, Bool do_track_dump); -#endif - - -#ifndef GPAC_DISABLE_ISOM_HINTING -#ifndef GPAC_DISABLE_ISOM_DUMP -void dump_isom_rtp(GF_ISOFile *file, char *inName, Bool is_final_name); -#endif -void dump_isom_sdp(GF_ISOFile *file, char *inName, Bool is_final_name); -#endif - -void dump_isom_timestamps(GF_ISOFile *file, char *inName, Bool is_final_name); -void dump_isom_nal(GF_ISOFile *file, u32 trackID, char *inName, Bool is_final_name); - -#ifndef GPAC_DISABLE_ISOM_DUMP -void dump_isom_ismacryp(GF_ISOFile *file, char *inName, Bool is_final_name); -void dump_isom_timed_text(GF_ISOFile *file, u32 trackID, char *inName, Bool is_final_name, Bool is_convert, GF_TextDumpType dump_type); -#endif /*GPAC_DISABLE_ISOM_DUMP*/ - - -void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump); -void DumpMovieInfo(GF_ISOFile *file); -void PrintLanguages(); - -#ifndef GPAC_DISABLE_MPEG2TS -void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name, Bool prog_num); -#endif - - -#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) -void PrintStreamerUsage(); -int stream_file_rtp(int argc, char **argv); -int live_session(int argc, char **argv); -void PrintLiveUsage(); -#endif - -#if !defined(GPAC_DISABLE_STREAMING) -u32 grab_live_m2ts(const char *grab_m2ts, const char *ifce_name, const char *outName); -#endif int mp4boxTerminal(int argc, char **argv); -u32 quiet = 0; Bool dvbhdemux = GF_FALSE; Bool keep_sys_tracks = GF_FALSE; @@ -154,7 +68,8 @@ Bool keep_sys_tracks = GF_FALSE; u32 swf_flags = 0; Float swf_flatten_angle = 0; s32 laser_resolution = 0; - +static FILE *helpout = NULL; +static u32 help_flags = 0; typedef struct { u32 code; @@ -189,684 +104,1061 @@ u32 nb_itunes_tags = sizeof(itags) / sizeof(itunes_tag); void PrintVersion() { - fprintf(stderr, "MP4Box - GPAC version " GPAC_FULL_VERSION "\n" - "GPAC Copyright (c) Telecom ParisTech 2000-2012\n" + fprintf(stderr, "MP4Box - GPAC version %s\n" + "%s\n" "GPAC Configuration: " GPAC_CONFIGURATION "\n" - "Features: %s\n", gpac_features()); + "Features: %s %s\n", gf_gpac_version(), gf_gpac_copyright_cite(), gf_sys_features(GF_FALSE), gf_sys_features(GF_TRUE)); } -void PrintGeneralUsage() +GF_GPACArg m4b_gen_args[] = { - fprintf(stderr, "General Options:\n" #ifdef GPAC_MEMORY_TRACKING - " -mem-track: enables memory tracker\n" - " -mem-track-stack: enables memory tracker with stack dumping\n" -#endif - " -strict-error exits after the first error is reported\n" - " -inter time_in_ms interleaves file data (track chunks of time_in_ms)\n" - " * Note 1: Interleaving is 0.5s by default\n" - " * Note 2: Performs drift checking across 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" - " * 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" - " -out filename specifies output file name\n" - " * Note: By default input (MP4,3GP) file is overwritten\n" - " -tmp dirname specifies directory for temporary file creation\n" - " * Note: Default temp dir is OS-dependent\n" - " -for-test disables all creation/modif dates and GPAC versions in files\n" - " -co64 forces usage of 64-bit chunk offsets for ISOBMF files\n" - " -write-buffer SIZE specifies write buffer in bytes for ISOBMF files\n" - " -no-sys removes all MPEG-4 Systems info except IOD (profiles)\n" - " * Note: Set by default whith '-add' and '-cat'\n" - " -no-iod removes InitialObjectDescriptor from file\n" - " -isma rewrites the file as an ISMA 1.0 AV file\n" - " -ismax same as \'-isma\' and removes all clock references\n" - " -3gp rewrites as 3GPP(2) file (no more MPEG-4 Systems Info)\n" - " * Note 1: some tracks may be removed in the process\n" - " * Note 2: always on for *.3gp *.3g2 *.3gpp\n" - " -ipod rewrites the file for iPod\n" - " -psp rewrites the file for PSP devices\n" - " -brand ABCD[:v] sets major brand of file, with optional version\n" - " -ab ABCD adds given brand to file's alternate brand list\n" - " -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" - " -set-track-id id1:id2 changes the id of a track from id1 to id2\n" - " -swap-track-id id1:id2 swaps the IDs of the identified tracks\n" - " -rem trackID removes track from file\n" - " -rap trackID removes all non-RAP samples from track\n" - " -enable trackID enables track\n" - " -disable trackID disables track\n" - " -new forces creation of a new destination file\n" - " -timescale VAL sets movie timescale to VAL ticks per second (default is 600)\n" - " -lang [tkID=]LAN sets track language. LAN is the BCP-47 code (eng, en-UK, ...)\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" - " -split time_sec splits in files of time_sec max duration, starting each file at RAP.\n" - " * Note: this removes all MPEG-4 Systems media\n" - " -split-size size splits in files of max filesize kB. same as -splits.\n" - " * Note: this removes all MPEG-4 Systems media\n" - " -split-rap splits in files beginning at each RAP. same as -splitr.\n" - " * Note: this removes all MPEG-4 Systems media\n" - " -split-chunk S:E extracts a new file from Start to End (in seconds). same as -splitx\n" - " * Note: this removes all MPEG-4 Systems media\n" - " -splitz S:E same as -split-chunk, but adjust the end time to be before the last RAP sample\n" - " * Note: this removes all MPEG-4 Systems media\n" - " -group-add fmt creates a new grouping information in the file. Format is\n" - " a colon-separated list of following options:\n" - " refTrack=ID: ID of the track used as a group reference.\n" - " If not set, the track will belong to the same group as the previous trackID specified.\n" - " If 0 or no previous track specified, a new alternate group will be created\n" - " switchID=ID: ID of the switch group to create.\n" - " If 0, a new ID will be computed for you\n" - " If <0, disables SwitchGroup\n" - " criteria=string: list of space-separated 4CCs.\n" - " trackID=ID: ID of the track to add to this group.\n" - "\n" - " *WARNING* Options modify state as they are parsed:\n" - " trackID=1:criteria=lang:trackID=2\n" - " is different from:\n" - " criteria=lang:trackID=1:trackID=2\n" - "\n" - " -group-rem-track ID removes track from its group\n" - " -group-rem ID removes the track's group\n" - " -group-clean removes all group information from all tracks\n" - " -group-single puts all tracks in a single group\n" - " -ref id:XXXX:refID adds a reference of type 4CC from track ID to track refID\n" - " -keep-utc keeps UTC timing in the file after edit\n" - " -udta ID:[OPTS] sets udta for given track or movie if ID is 0. OPTS is a colon separated list of:\n" - " type=CODE where code is the 4CC code of the UDTA (not needed for box= option)\n" - " box=FILE where FILE is the location of the udta data, formatted as serialized boxes\n" -#ifndef GPAC_DISABLE_CORE_TOOLS - " box=base64,DATA where DATA is the base64 encoded udta data, formatted as serialized boxes\n" -#endif - " src=FILE where FILE is the location of the udta data (will be stored in a single box of type CODE)\n" -#ifndef GPAC_DISABLE_CORE_TOOLS - " src=base64,DATA where DATA is the base64 encoded udta data (will be stored in a single box of type CODE)\n" + GF_DEF_ARG("mem-track", NULL, "enable memory tracker", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("mem-track-stack", NULL, "enable memory tracker with stack dumping", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), #endif - " If no source is set, UDTA of type CODE will be removed\n" - "\n"); + GF_DEF_ARG("p", NULL, "use indicated profile for the global GPAC config. If not found, config file is created. If a file path is indicated, this will load profile from that file. Otherwise, this will create a directory of the specified name and store new config there. Reserved name `0` means a new profile, not stored to disk. Works using -p=NAME or -p NAME", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("inter", NULL, "interleave file, producing track chunks with given duration in ms. A value of 0 disables interleaving ", "0.5", NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("old-inter", NULL, "same as [-inter]() but wihout drift correction", NULL, NULL, GF_ARG_DOUBLE, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("tight", NULL, "tight interleaving (sample based) of the file. This reduces disk seek operations but increases file size", NULL, NULL, GF_ARG_DOUBLE, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("flat", NULL, "store file with all media data first, non-interleaved. This speeds up writing time when creating new files", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("frag", NULL, "fragment file, producing track fragments of given duration in ms. This disables interleaving", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("out", NULL, "specify output file name. By default input file is overwritten", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("tmp", NULL, "specify directory for temporary file creation", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("co64", NULL, "force usage of 64-bit chunk offsets for ISOBMF files", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("new", NULL, "force creation of a new destination file", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("newfs", NULL, "force creation of a new destination file without temp file but interleaving support", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("no-sys", NULL, "remove all MPEG-4 Systems info except IOD, kept for profiles. This is the default when creating regular AV content", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("no-iod", NULL, "remove MPEG-4 InitialObjectDescriptor from file", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("mfra", NULL, "insert movie fragment random offset when fragmenting file (ignored in dash mode)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("isma", NULL, "rewrite the file as an ISMA 1.0 file", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("ismax", NULL, "same as [-isma]() and remove all clock references", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("3gp", NULL, "rewrite as 3GPP(2) file (no more MPEG-4 Systems Info), always enabled if destination file extension is `.3gp`, `.3g2` or `.3gpp`. Some tracks may be removed in the process", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("ipod", NULL, "rewrite the file for iPod/old iTunes", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("psp", NULL, "rewrite the file for PSP devices", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("brand", NULL, "set major brand of file (`ABCD`) or brand with optional version (`ABCD:v`)", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("ab", NULL, "add given brand to file's alternate brand list", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("rb", NULL, "remove given brand to file's alternate brand list", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("cprt", NULL, "add copyright string to file", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("chap", NULL, "set chapter information from given file", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("chapqt", NULL, "set chapter information from given file, using QT signaling for text tracks", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("set-track-id `id1:id2`", NULL, "change id of track with id1 to id2", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("swap-track-id `id1:id2`", NULL, "swap the id between tracks with id1 to id2", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("rem", NULL, "remove given track from file", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("rap", NULL, "remove all non-RAP samples from given track", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("refonly", NULL, "remove all non-reference pictures from given track", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("enable", NULL, "enable given track", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("disable", NULL, "disable given track", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("timescale", NULL, "set movie timescale to given value (ticks per second)", "600", NULL, GF_ARG_INT, 0), + GF_DEF_ARG("lang `[tkID=]LAN`", NULL, "set language. LAN is the BCP-47 code (eng, en-UK, ...). If no track ID is given, sets language to all tracks", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("delay `tkID=TIME`", NULL, "set track start delay in ms", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("par `tkID=PAR`", NULL, "set visual track pixel aspect ratio. PAR is:\n" + " - N:D: set PAR to N:D in track, do not modify the bitstream\n" + " - wN:D: set PAR to N:D in track and try to modify the bitstream\n" + " - none: remove PAR info from track, do not modify the bitstream\n" + " - auto: retrieve PAR info from bitstream and set it in track\n" + " - force: force 1:1 PAR in track, do not modify the bitstream", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("clap `tkID=CLAP`", NULL, "set visual track clean aperture. CLAP is `Wn,Wd,Hn,Hd,HOn,HOd,VOn,VOd` or `none`\n" + "- n, d: numerator, denominator\n" + "- W, H, HO, VO: clap width, clap height, clap horizontal offset, clap vertical offset\n" + , NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("mx `tkID=MX`", NULL, "set track matrix, with MX is M1:M2:M3:M4:M5:M6:M7:M8:M9 in 16.16 fixed point intergers or hexa" + , NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("name `tkID=NAME`", NULL, "set track handler name to NAME (UTF-8 string)", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("itags `tag1[:tag2]`", NULL, "set iTunes tags to file, see [-tag-list]()", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("tag-list", NULL, "print the set of supported iTunes tags", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("split", NULL, "split in files of given max duration", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("split-size", "splits", "split in files of given max size (in kb)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("split-rap", "splitr", "split in files at each new RAP", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("split-chunk VAL", "splitx", "extract a new file from source. `VAL` can be formated as:\n" + "- `S:E`: `S` (number of seconds) to `E` with `E` a number (in seconds), `end` or `end-N`, N number of seconds before the end\n" + "- `S-E`: start and end dates, each formatted as `HH:MM:SS.ms` or `MM:SS.ms`", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("splitz `S:E`", NULL, "same as -split-chunk, but adjust the end time to be before the last RAP sample", NULL, NULL, GF_ARG_STRING, 0), + + GF_DEF_ARG("group-add", NULL, "create a new grouping information in the file. Format is a colon-separated list of following options:\n" + "- refTrack=ID: ID of the track used as a group reference. If not set, the track will belong to the same group as the " + "previous trackID specified. If 0 or no previous track specified, a new alternate group will be created\n" + "- switchID=ID: ID of the switch group to create. If 0, a new ID will be computed for you. If <0, disables SwitchGroup\n" + "- criteria=string: list of space-separated 4CCs\n" + "- trackID=ID: ID of the track to add to this group\n" + " \n" + "Warning: Options modify state as they are parsed, `trackID=1:criteria=lang:trackID=2` is different from `criteria=lang:trackID=1:trackID=2`" + "\n", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + + GF_DEF_ARG("group-rem-track", NULL, "remove given track from its group", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("group-rem", NULL, "remove the track's group\n", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("group-clean", NULL, "remove all group information from all tracks\n", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("ref `id:XXXX:refID`", NULL, "add a reference of type 4CC from track ID to track refID\n", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("keep-utc", NULL, "keep UTC timing in the file after edit\n", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("udta tkID:[OPTS]", NULL, "set udta for given track or movie if tkID is 0. OPTS is a colon separated list of:\n" + "- type=CODE: 4CC code of the UDTA (not needed for `box=` option)\n" + "- box=FILE: location of the udta data, formatted as serialized boxes\n" + "- box=base64,DATA: base64 encoded udta data, formatted as serialized boxes\n" + "- src=FILE: location of the udta data (will be stored in a single box of type CODE)\n" + "- src=base64,DATA: base64 encoded udta data (will be stored in a single box of type CODE)\n" + "Note: If no source is set, UDTA of type CODE will be removed\n", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("patch [tkID=]FILE", NULL, "apply box patch described in FILE, for given trackID if set\n", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("bo", NULL, "freeze the order of boxes in input file\n", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("init-seg", NULL, "use the given file as an init segment for dumping or for encryption\n", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("zmov", NULL, "compress movie box according to ISOBMFF box compression\n", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + + + {0} +}; + +void PrintGeneralUsage() +{ + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# General Options\n" + "MP4Box is a multimedia packager, with a vast number of functionalities: conversion, splitting, hinting, dumping, DASH-ing, encryption and others.\n" + "MP4Box provides a large set of options, classified by categories (see [-h]()). These options do not follow any particular ordering.\n" + "MP4Box performs in-place rewrite of IsoMedia files (the input file is overwritten). You can change this behaviour by using the [-out]() option.\n" + "MP4Box stores by default the file with 0.5 second interleaving and meta-data (`moov`...) at the beginning, making it suitable for HTTP streaming. This may however takes longer to store the file, use [-flat]() to change this behaviour.\n" + "MP4Box usually generates a temporary file when creating a new IsoMedia file. The location of this temporary file is OS-dependent, and it may happen that the drive/partition the temporary file is created on has not enough space or no write access. In such a case, you can specify a temporary file location with [-tmp]().\n" + "Note: Track operations identify tracks through their ID (usually refered as tkID in the help), not their order.\n" + "Option values:\n" + "Unless specified otherwise, an option of type `integer` expects a trackID value following it." + "An option of type `boolean` expects no following value." + " \n" + "# File Splitting and Concatenation\n" + "MP4Box can split IsoMedia files by size, duration or extract a given part of the file to new IsoMedia file(s). This process requires that at most one track in the input file has non random-access points (typically one video track at most). This process will also ignore all MPEG-4 Systems tracks and hint tracks, but will try to split private media tracks.\n" + "Note: The input file must have enough random access points in order to be split. This may not be the case with some video files where only the very first sample of the video track is a key frame (many 3GP files with H263 video are recorded that way). In order to split such files you will have to use a real video editor and re-encode the content.\n" + "Note: You can add media to a file and split it in the same pass. In this case, the destination file (the one which would be obtained without spliting) will not be stored.\n" + " \n" + "Options:\n" + ); + + while (m4b_gen_args[i].name) { + GF_GPACArg *arg = &m4b_gen_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-gen"); + } } + +GF_GPACArg m4b_dash_args[] = +{ + GF_DEF_ARG("mpd", NULL, "convert given HLS or smooth manifest (local or remote http) to MPD. \nWarning: This is not compatible with other DASH options and does not convert associated segments", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("dash", "-dash-strict", "create DASH from input files with given segment (subsegment for onDemand profile) duration in ms", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("dash-live", NULL, "generate a live DASH session using the given segment duration in ms; using `-dash-live=F`will also write the live context to `F`. MP4Box will run the live session until `q` is pressed or a fatal error occurs", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("ddbg-live", NULL, "same as [-dash-live]() without time regulation for debug purposes", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("frag", NULL, "specify the fragment duration in ms. If not set, this is the DASH duration (one fragment per segment)", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("out", NULL, "specify the output MPD file name", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("tmp", NULL, "specify directory for temporary file creation", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("profile", NULL, "specify the target DASH profile, and set default options to ensure conformance to the desired profile. Default profile is `full` in static mode, `live` in dynamic mode", NULL, "onDemand|live|main|simple|full|hbbtv1.5:live|dashavc264:live|dashavc264:onDemand", GF_ARG_STRING, 0), + GF_DEF_ARG("profile-ext", NULL, "specify a list of profile extensions, as used by DASH-IF and DVB. The string will be colon-concatenated with the profile used", NULL, NULL, GF_ARG_STRING, 0), + + GF_DEF_ARG("rap", NULL, "ensure that segments begin with random access points, segment durations might vary depending on the source encoding", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("frag-rap", NULL, "ensure that all fragments begin with random access points (duration might vary depending on the source encoding)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("segment-name", NULL, "set the segment name for generated segments. If not set (default), segments are concatenated in output file except in `live` profile where `dash_%%s`. Supported replacement strings are:\n" + "- $Number[%%0Nd]$ is replaced by the segment number, possibly prefixed with 0\n" + "- $RepresentationID$ is replaced by representation name\n" + "- $Time$ is replaced by segment start time\n" + "- $Bandwidth$ is replaced by representation bandwidth\n" + "- $Init=NAME$ is replaced by NAME for init segment, ignored otherwise\n" + "- $Index=NAME$ is replaced by NAME for index segments, ignored otherwise\n" + "- $Path=PATH$ is replaced by PATH when creating segments, ignored otherwise\n" + "- $Segment=NAME$ is replaced by NAME for media segments, ignored for init segments", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("segment-ext", NULL, "set the segment extension, `null` means no extension", "m4s", NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("init-segment-ext", NULL, "set the segment extension for init, index and bitstream switching segments, `null` means no extension\n", "mp4", NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("segment-timeline", NULL, "use `SegmentTimeline` when generating segments", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("segment-marker `MARK`", NULL, "add a box of type `MARK` (4CC) at the end of each DASH segment", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("insert-utc", NULL, "insert UTC clock at the beginning of each ISOBMF segment", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("base-url", NULL, "set Base url at MPD level. Can be used several times. \nWarning: this does not modify generated files location", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("mpd-title", NULL, "set MPD title", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("mpd-source", NULL, "set MPD source", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("mpd-info-url", NULL, "set MPD info url", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("cprt", NULL, "add copyright string to MPD", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("dash-ctx", NULL, "store/restore DASH timing from indicated file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("dynamic", NULL, "use dynamic MPD type instead of static", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("last-dynamic", NULL, "same as [-dynamic]() but close the period (insert lmsg brand if needed and update duration)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("mpd-duration", NULL, "set the duration in second of a live session (if `0`, you must use [-mpd-refresh]())", "0", NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("mpd-refresh", NULL, "specify MPD update time in seconds", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("time-shift", NULL, "specify MPD time shift buffer depth in seconds, `-1` to keep all files)", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("subdur", NULL, "specify maximum duration in ms of the input file to be dashed in LIVE or context mode. This does not change the segment duration, but stops dashing once segments produced exceeded the duration. If there is not enough samples to finish a segment, data is looped unless [-no-loop]() is used which triggers a period end", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("run-for", NULL, "run for given ms the dash-live session then exits", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("min-buffer", NULL, "specify MPD min buffer time in ms", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("ast-offset", NULL, "specify MPD AvailabilityStartTime offset in ms if positive, or availabilityTimeOffset of each representation if negative", "0", NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dash-scale", NULL, "specify that timing for [-dash]() and [-frag]() are expressed in given timexale (units per seconds)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("mem-frags", NULL, "fragmentation happens in memory rather than on disk before flushing to disk", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("pssh", NULL, "set pssh store mode\n" + "- v: initial movie\n" + "- f: movie fragments\n" + "- m: MPD\n" + "- mv, vm: in initial movie and MPD\n" + "- mf, fm: in movie fragments and MPD", NULL, "v|f|m|mv|vm|mf|fm", GF_ARG_INT, 0), + GF_DEF_ARG("sample-groups-traf", NULL, "store sample group descriptions in traf (duplicated for each traf). If not set, sample group descriptions are stored in the initial movie", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("mvex-after-traks", NULL, "store `mvex` box after `trak` boxes within the moov box. If not set, `mvex` is before", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("sdtp-traf", NULL, "use `sdtp` box in `traf` (Smooth-like)\n" + "- no: do not use sdtp\n" + "- sdtp: use sdtp box to indicate sample dependencies and don't write info in trun sample flags\n" + "- both: use sdtp box to indicate sample dependencies and also write info in trun sample flags\n", NULL, "no|sdtp|both", GF_ARG_INT, 0), + GF_DEF_ARG("no-cache", NULL, "disable file cache for dash inputs", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-loop", NULL, "disable looping content in live mode and uses period switch instead", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("hlsc", NULL, "insert UTC in variant playlists for live HLS", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("bound", NULL, "segmentation will always try to split before or at, but never after, the segment boundary", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("closest", NULL, "segmentation will use the closest frame to the segment boundary (before or after)", NULL, NULL, GF_ARG_BOOL, 0), + + GF_DEF_ARG("subsegs-per-sidx", NULL, "set the number of subsegments to be written in each SIDX box\n" + "- 0: a single SIDX box is used per segment\n" + "- -1: no SIDX box is used", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("ssix", NULL, "enable SubsegmentIndexBox describing 2 ranges, first one from moof to end of first I-frame, second one unmapped. This does not work with daisy chaining mode enabled", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("url-template", NULL, "use SegmentTemplate instead of explicit sources in segments. Ignored if segments are stored in the output file", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("daisy-chain", NULL, "use daisy-chain SIDX instead of hierarchical. Ignored if frags/sidx is 0", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("single-segment", NULL, "use a single segment for the whole file (OnDemand profile)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("single-file", NULL, "use a single file for the whole file (default)", "yes", NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("bs-switching", NULL, "set bitstream switching mode\n" + "- inband: use inband param set and a single init segment\n" + "- merge: try to merge param sets in a single sample description, fallback to `no`\n" + "- multi: use several sample description, one per quality\n" + "- no: use one init segment per quality\n" + "- single: to test with single input", "inband", "inband|merge|multi|no|single", GF_ARG_STRING, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("moof-sn", NULL, "set sequence number of first moof to given value", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("tfdt", NULL, "set TFDT of first traf to given value in SCALE units (cf -dash-scale)", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("no-frags-default", NULL, "disable default fragments flags in trex (required by some dash-if profiles and CMAF/smooth streaming compatibility)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("single-traf", NULL, "use a single track fragment per moof (smooth streaming and derived specs may require this)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("tfdt-traf", NULL, "use a tfdt per track fragment (when -single-traf is used)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("dash-ts-prog", NULL, "program_number to be considered in case of an MPTS input file", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("frag-rt", NULL, "when using fragments in live mode, flush fragments according to their timing", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("cp-location", NULL, "set ContentProtection element location\n" + "- as: sets ContentProtection in AdaptationSet element\n" + "- rep: sets ContentProtection in Representation element\n" + "- both: sets ContentProtection in both elements", NULL, "as|rep\both", GF_ARG_STRING, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("start-date", NULL, "for live mode, set start date (as xs:date, eg YYYY-MM-DDTHH:MM:SSZ). Default is current UTC\n" + "Warning: Do not use with multiple periods, nor when DASH duration is not a multiple of GOP size", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), + + GF_DEF_ARG("cues", NULL, "ignore dash duration and segment according to cue times in given XML file (tests/media/dash_cues for examples)", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("strict-cues", NULL, "throw error if something is wrong while parsing cues or applying cue-based segmentation", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + {0} +}; + void PrintDASHUsage() { - fprintf(stderr, "DASH Options:\n" - " -mpd m3u8 converts HLS manifest (local or remote http) to MPD \n" - " Note: not compatible with other DASH options (except -out and -tmp) and does not convert associated segments\n" - " -dash dur enables DASH-ing of the file(s) with a segment duration of DUR ms\n" - " Note: the duration of a fragment (subsegment) is set\n" - " using the -frag switch.\n" - " Note: for onDemand profile, sets duration of a subsegment\n" - " -dash-strict dur enables DASH-ing of the file(s) with a segment duration of DUR ms (old behaviour)\n" - " Note: the duration will be the closest to \'dur\', and will remain constant\n" - " -dash-live[=F] dur generates a live DASH session using dur segment duration, optionally writing live context to F\n" - " MP4Box will run the live session until \'q\' is pressed or a fatal error occurs.\n" - " -ddbg-live[=F] dur same as -dash-live without time regulation for debug purposes.\n" - " -frag time_in_ms Specifies a fragment duration of time_in_ms.\n" - " * Note: By default, this is the DASH duration\n" - " -out filename specifies output MPD file name.\n" - " -tmp dirname specifies directory for temporary file creation\n" - " * Note: Default temp dir is OS-dependent\n" - " -profile NAME specifies the target DASH profile: \"onDemand\",\n" - " \"live\", \"main\", \"simple\", \"full\",\n" - " \"hbbtv1.5:live\", \"dashavc264:live\", \"dashavc264:onDemand\"\n" - " * This will set default option values to ensure conformance to the desired profile\n" - " * Default profile is \"full\" in static mode, \"live\" in dynamic mode\n" - " -profile-ext STRING specifies a list of profile extensions, as used by DASH-IF and DVB.\n" - " The string will be colon-concatenated with the profile used\n" - "\n" - "Input media files to dash can use the following modifiers\n" - " \"#trackID=N\" only uses the track ID N from the source file\n" - " \"#video\" only uses the first video track from the source file\n" - " \"#audio\" only uses the first audio track from the source file\n" - " \":id=NAME\" sets the representation ID to NAME\n" - " \":dur=VALUE\" processes VALUE seconds from the media\n" - " If VALUE is longer than the media duration, the last media duration is lengthen.\n" - " \":period=NAME\" sets the representation's period to NAME. Multiple periods may be used\n" - " period appear in the MPD in the same order as specified with this option\n" - " \":BaseURL=NAME\" sets the BaseURL. Set multiple times for multiple BaseURLs\n" - " \":bandwidth=VALUE\" sets the representation's bandwidth to a given value\n" - " \":period_duration=VALUE\" increases the duration of this period by the given duration in seconds\n" - " only used when no input media is specified (remote period insertion), eg :period=X:xlink=Z:duration=Y.\n" - " \":xlink=VALUE\" sets the xlink value for the period containing this element\n" - " only the xlink declared on the first rep of a period will be used\n" - " \":role=VALUE\" sets the role of this representation (cf DASH spec).\n" - " media with different roles belong to different adaptation sets.\n" - " \":desc_p=VALUE\" adds a descriptor at the Period level. Value must be a properly formatted XML element.\n" - " \":desc_as=VALUE\" adds a descriptor at the AdaptationSet level. Value must be a properly formatted XML element.\n" - " two input files with different values will be in different AdaptationSet elements.\n" - " \":desc_as_c=VALUE\" adds a descriptor at the AdaptationSet level. Value must be a properly formatted XML element.\n" - " value is ignored while creating AdaptationSet elements.\n" - " \":desc_rep=VALUE\" adds a descriptor at the Representation level. Value must be a properly formatted XML element.\n" - " value is ignored while creating AdaptationSet elements.\n" - "\n" - " -rap segments begin with random access points\n" - " Note: segment duration may not be exactly what asked by\n" - " \"-dash\" since encoded video data is not modified\n" - " -frag-rap All fragments begin with random access points\n" - " Note: fragment duration may not be exactly what is asked by\n" - " \"-frag\" since encoded video data is not modified\n" - " -segment-name name sets the segment name for generated segments\n" - " If not set (default), segments are concatenated in output file\n" - " except in \"live\" profile where dash_%%s is used\n" - " -segment-ext name sets the segment extension. Default is m4s, \"null\" means no extension\n" - " -segment-timeline uses SegmentTimeline when generating segments.\n" - " -segment-marker MARK adds a box of type \'MARK\' at the end of each DASH segment. MARK shall be a 4CC identifier\n" - " -insert-utc inserts UTC clock at the begining of each ISOBMF segment\n" - " -base-url string sets Base url at MPD level. Can be used several times.\n" - " -mpd-title string sets MPD title.\n" - " -mpd-source string sets MPD source.\n" - " -mpd-info-url string sets MPD info url.\n" - " -cprt string adds copyright string to MPD\n" - " -dash-ctx FILE stores/restore DASH timing from FILE.\n" - " -dynamic uses dynamic MPD type instead of static.\n" - " -last-dynamic same as dynamic but closes the period (insert lmsg brand if needed and update duration).\n" - " -mpd-duration DUR sets the duration in second of a live session (0 by default). If 0, you must use -mpd-refresh.\n" - " -mpd-refresh TIME specifies MPD update time in seconds (double can be used).\n" - " -time-shift TIME specifies MPD time shift buffer depth in seconds (default 0). Specify -1 to keep all files\n" - " -subdur DUR specifies maximum duration in ms of the input file to be dashed in LIVE or context mode.\n" - " NOTE: This does not change the segment duration: dashing stops once segments produced exceeded the duration.\n" - " -dash-run-for TIME In case of dash live, runs for T ms of the media then exits\n" - " -min-buffer TIME specifies MPD min buffer time in milliseconds\n" - " -ast-offset TIME specifies MPD AvailabilityStartTime offset in ms if positive, or availabilityTimeOffset of each representation if negative. Default is 0 sec delay\n" - " -dash-scale SCALE specifies that timing for -dash and -frag are expressed in SCALE units per seconds\n" - " -mem-frags fragments will be produced in memory rather than on disk before flushing to disk\n" - " -pssh-moof stores PSSH boxes in first moof of each segments. By default PSSH are stored in movie box.\n" - " -sample-groups-traf stores sample group descriptions in traf (duplicated for each traf). If not used, sample group descriptions are stored in the movie box.\n" + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# DASH Options\n" + "Also see:\n" + "- the [dasher `gpac -h dash`](dasher) filter documentation\n" + "- [[online DASH Intro doc|DASH Introduction]].\n" + "\n" + "# Specifying input files\n" + "Input media files to dash can use the following modifiers\n" + "- #trackID=N: only use the track ID N from the source file\n" + "- #N: only use the track ID N from the source file (mapped to [-tkid](mp4dmx))\n" + "- #video: only use the first video track from the source file\n" + "- #audio: only use the first audio track from the source file\n" + "- :id=NAME: set the representation ID to NAME. Reserved value `NULL` disables representation ID for multiplexed inputs\n" + "- :dur=VALUE: process VALUE seconds from the media. If VALUE is longer than media duration, last sample duration is extended.\n" + "- :period=NAME: set the representation's period to NAME. Multiple periods may be used. Periods appear in the MPD in the same order as specified with this option\n" + "- :BaseURL=NAME: set the BaseURL. Set multiple times for multiple BaseURLs\nWarning: This does not modify generated files location (see segment template).\n" + "- :bandwidth=VALUE: set the representation's bandwidth to a given value\n" + "- :pdur=VALUE: increase the duration of this period by the given duration in seconds (alias for period_duration:VALUE). This is only used when no input media is specified (remote period insertion), eg `:period=X:xlink=Z:pdur=Y`\n" + "- :duration=VALUE: override target DASH segment duration for this input\n" + "- :xlink=VALUE: set the xlink value for the period containing this element. Only the xlink declared on the first rep of a period will be used\n" + "- :asID=VALUE: set the AdaptationSet ID to NAME\n" + "- :role=VALUE: set the role of this representation (cf DASH spec). Media with different roles belong to different adaptation sets.\n" + "- :desc_p=VALUE: add a descriptor at the Period level. Value must be a properly formatted XML element.\n" + "- :desc_as=VALUE: add a descriptor at the AdaptationSet level. Value must be a properly formatted XML element. Two input files with different values will be in different AdaptationSet elements.\n" + "- :desc_as_c=VALUE: add a descriptor at the AdaptationSet level. Value must be a properly formatted XML element. Value is ignored while creating AdaptationSet elements.\n" + "- :desc_rep=VALUE: add a descriptor at the Representation level. Value must be a properly formatted XML element. Value is ignored while creating AdaptationSet elements.\n" + "- :sscale: force movie timescale to match media timescale of the first track in the segment.\n" + "- :trackID=N: only use the track ID N from the source file\n" + "- @@f1[:args][@@fN:args]: set a filter chain to insert between the source and the dasher. Each filter in the chain is formatted as a regular filter, see [filter doc `gpac -h doc`](filters_general). If several filters are set, they will be chained in the given order.\n" + "\n" + "Note: `@@f` must be placed after all other options.\n" + "\n" + "# Options\n" + ); - "\n" - "Advanced Options, should not be needed when using -profile:\n" - " -subsegs-per-sidx N sets the number of subsegments to be written in each SIDX box\n" - " If 0, a single SIDX box is used per segment\n" - " If -1, no SIDX box is used\n" - " -url-template uses SegmentTemplate instead of explicit sources in segments.\n" - " Ignored if segments are stored in the output file.\n" - " -daisy-chain uses daisy-chain SIDX instead of hierarchical. Ignored if frags/sidx is 0.\n" - " -single-segment uses a single segment for the whole file (OnDemand profile). \n" - " -single-file uses a single file for the whole file (default). \n" - " -bs-switching MODE sets bitstream switching to \"inband\" (default), \"merge\", \"multi\", \"no\" or \"single\" to test with single input.\n" - " -moof-sn N sets sequence number of first moof to N\n" - " -tfdt N sets TFDT of first traf to N in SCALE units (cf -dash-scale)\n" - " -no-frags-default disables default flags in fragments\n" - " -single-traf uses a single track fragment per moof (smooth streaming and derived specs may require this)\n" - " -dash-ts-prog N program_number to be considered in case of an MPTS input file.\n" - " -frag-rt when using fragments in live mode, flush fragments according to their timing (only supported with a single input).\n" - " -cp-location=MODE sets ContentProtection element location. Possible values for mode are:\n" - " as: sets ContentProtection in AdaptationSet element\n" - " rep: sets ContentProtection in Representation element\n" - " both: sets ContentProtection in both elements\n" - " -start-date for live mode, sets start date (as xs:date, eg YYYY-MM-DDTHH:MM:SSZ. Default is now.\n" - " !! Do not use with multiple periods, nor when DASH duration is not a multiple of GOP size !!\n" - "\n"); + + while (m4b_dash_args[i].name) { + GF_GPACArg *arg = &m4b_dash_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-dash"); + } } -void PrintFormats() + +GF_GPACArg m4b_imp_args[] = { - fprintf(stderr, "Supported raw formats and file extensions:\n" - " NHNT .media .nhnt .info\n" - " NHML .nhml (opt: .media .info)\n" - " MPEG-1-2 Video .m1v .m2v\n" - " MPEG-4 Video .cmp .m4v\n" - " H263 Video .263 .h263\n" - " AVC/H264 Video .h264 .h26L .264 .26L .x264 .svc\n" - " HEVC Video .hevc .h265 .265 .hvc .shvc .lhvc .mhvc\n" - " JPEG Images .jpg .jpeg\n" - " JPEG-2000 Images .jp2\n" - " PNG Images .png\n" - " MPEG 1-2 Audio .mp3, .mp2, .m1a, .m2a\n" - " ADTS-AAC Audio .aac\n" - " Dolby (e)AC-3 Audio .ac3 .ec3\n" - " AMR(WB) Audio .amr .awb\n" - " EVRC Audio .evc\n" - " SMV Audio .smv\n" - "\n" - "Supported containers and file extensions:\n" - " AVI .avi\n" - " MPEG-2 PS .mpg .mpeg .vob .vcd .svcd\n" - " MPEG-2 TS .ts .m2t\n" - " QCP .qcp\n" - " OGG .ogg\n" - " ISO-Media files no extension checking\n" - "\n" - "Supported text formats:\n" - " SRT Subtitles .srt\n" - " SUB Subtitles .sub\n" - " VobSub .idx\n" - " GPAC Timed Text .ttxt\n" - " VTT .vtt\n" - " TTML .ttml\n" - " QuickTime TeXML Text .xml (cf QT documentation)\n" - "\n" - "Supported Scene formats:\n" - " MPEG-4 XMT-A .xmt .xmta .xmt.gz .xmta.gz\n" - " MPEG-4 BT .bt .bt.gz\n" - " MPEG-4 SAF .saf .lsr\n" - " VRML .wrl .wrl.gz\n" - " X3D-XML .x3d .x3d.gz\n" - " X3D-VRML .x3dv .x3dv.gz\n" - " MacroMedia Flash .swf (very limited import support only)\n" - "\n" - "Supported chapter formats:\n" - " Nero chapters .txt .chap\n" - "\n" - ); -} + GF_DEF_ARG("add", NULL, "add given file tracks to file. Multiple inputs can be specified using `+`, eg `-add url1+url2", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("cat", NULL, "concatenate given file samples to file, creating tracks if needed. Multiple inputs can be specified using `+`(eg `-cat url1+url2). \nNote: This aligns initial timestamp of the file to be concatenated", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("catx", NULL, "same as [-cat]() but new tracks can be imported before concatenation by specifying `+ADD_COMMAND` where `ADD_COMMAND` is a regular [-add]() syntax", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("catpl", NULL, "concatenate files listed in the given playlist file (one file per line, lines starting with # are comments). \nNote: Each listed file is concatenated as if called with -cat", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("unalign-cat", NULL, "do not attempt to align timestamps of samples inbetween tracks", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("force-cat", NULL, "skip media configuration check when concatenating file. \nWarning: THIS MAY BREAK THE CONCATENATED TRACK(S)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("keep-sys", NULL, "keep all MPEG-4 Systems info when using [-add]() and [-cat]() (only used when adding IsoMedia files)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dref", NULL, "keep media data in original file using `data referencing`. The resulting file only contains the meta-data of the presentation (frame sizes, timing, etc...) and references media data in the original file. This is extremely useful when developping content, since importing and storage of the MP4 file is much faster and the resulting file much smaller. \nNote: Data referencing may fail on some files because it requires the framed data (eg an IsoMedia sample) to be continuous in the original file, which is not always the case depending on the original interleaving or bitstream format (__AVC__ or __HEVC__ cannot use this option)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-drop", NULL, "force constant FPS when importing AVI video", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("packed", NULL, "force packed bitstream when importing raw MPEG-4 part 2 Advanced Simple Profile", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("sbr", NULL, "backward compatible signaling of AAC-SBR", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("sbrx", NULL, "non-backward compatible signaling of AAC-SBR", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ps", NULL, "backward compatible signaling of AAC-PS", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("psx", NULL, "non-backward compatible signaling of AAC-PS", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ovsbr", NULL, "oversample SBR import (SBR AAC, PS AAC and oversampled SBR cannot be detected at import time)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("fps", NULL, "force frame rate for video and SUB subtitles import to the given value, expressed as a number or as `timescale-increment`. \nNote: For raw H263 import, default FPS is `15`, otherwise `25`. This is ignored for ISOBMFF import, use `:rescale` option for that", "25", NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("mpeg4", NULL, "force MPEG-4 sample descriptions when possible. For AAC, forces MPEG-4 AAC signaling even if MPEG-2", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("agg", NULL, "aggregate N audio frames in 1 sample (3GP media only, maximum value is 15)", NULL, NULL, GF_ARG_INT, 0), + {0} +}; + + +static GF_GPACArg ImportFileOpts [] = { + GF_DEF_ARG("dur", NULL, "`X` import only the specified duration from the media. Value can be:\n" + " - positive float: specifies duration in seconds\n" + " - fraction: specifies duration as NUM/DEN fraction\n" + " - negative integer: specifies duration in number of coded frames", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("lang", NULL, "set imported media language code", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("delay", NULL, "set imported media initial delay in ms", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("par", NULL, "set visual pixel aspect ratio (see [-par](MP4B_GEN) )", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("clap", NULL, "set visual clean aperture (see [-clap](MP4B_GEN) )", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("mx", NULL, "set track matrix (see [-mx](MP4B_GEN) )", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("name", NULL, "set track handler name", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("ext", NULL, "override file extension when importing", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("hdlr", NULL, "set track handler type to the given code point (4CC)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("disable", NULL, "disable imported track(s)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("group", NULL, "add the track as part of the G alternate group. If G is 0, the first available GroupID will be picked", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("fps", NULL, "same as [-fps]()", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("rap", NULL, "`D` import only RAP samples", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("refs", NULL, "`D` import only reference pictures", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("trailing", NULL, "keep trailing 0-bytes in AVC/HEVC samples", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("agg", NULL, "`X` same as [-agg]()", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dref", NULL, "`X` same as [-dref]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("keep_refs", NULL, "keep track reference when importing a single track", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("nodrop", NULL, "same as [-nodrop]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("packed", NULL, "`X` same as [-packed]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("sbr", NULL, "same as [-sbr]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("sbrx", NULL, "same as [-sbrx]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ovsbr", NULL, "same as [-ovsbr]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ps", NULL, "same as [-ps]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("psx", NULL, "same as [-psx]()", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("asemode", NULL, "`X` set the mode to create the AudioSampleEntry. Value can be:\n" + " - v0-bs: use MPEG AudioSampleEntry v0 and the channel count from the bitstream (even if greater than 2) - default\n" + " - v0-2: use MPEG AudioSampleEntry v0 and the channel count is forced to 2\n" + " - v1: use MPEG AudioSampleEntry v1 and the channel count from the bitstream\n" + " - v1-qt: use QuickTime Sound Sample Description Version 1 and the channel count from the bitstream (even if greater than 2). This will also trigger using alis data references instead of url, even for non-audio tracks", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("audio_roll", NULL, "add a roll sample group with roll_distance `N`", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("mpeg4", NULL, "`X` same as [-mpeg4]() option", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("nosei", NULL, "discard all SEI messages during import", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("svc", NULL, "import SVC/LHVC with explicit signaling (no AVC base compatibility)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("nosvc", NULL, "discard SVC/LHVC data when importing", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("svcmode", NULL, "`D` set SVC/LHVC import mode. Value can be:\n" + " - split: each layer is in its own track\n" + " - merge: all layers are merged in a single track\n" + " - splitbase: all layers are merged in a track, and the AVC base in another\n" + " - splitnox: each layer is in its own track, and no extractors are written\n" + " - splitnoxib: each layer is in its own track, no extractors are written, using inband param set signaling", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("temporal", NULL, "`D` set HEVC/LHVC temporal sublayer import mode. Value can be:\n" + " - split: each sublayer is in its own track\n" + " - splitbase: all sublayers are merged in a track, and the HEVC base in another\n" + " - splitnox: each layer is in its own track, and no extractors are written", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("subsamples", NULL, "add SubSample information for AVC+SVC", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("deps", NULL, "import sample dependency information for AVC and HEVC", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ccst", NULL, "add default HEIF ccst box to visual sample entry", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("forcesync", NULL, "force non IDR samples with I slices to be marked as sync points (AVC GDR)\n" + "Warning: RESULTING FILE IS NOT COMPLIANT WITH THE SPEC but will fix seeking in most players", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("xps_inband", NULL, "`X` set xPS inband for AVC/H264 and HEVC (for reverse operation, re-import from raw media)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("xps_inbandx", NULL, "`X` same as xps_inband and also keep first xPS in sample desciption", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("au_delim", NULL, "keep AU delimiter NAL units in the imported file", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("max_lid", NULL, "set HEVC max layer ID to be imported to `N` (by default imports all layers)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("max_tid", NULL, "set HEVC max temporal ID to be imported to `N` (by default imports all temporal sublayers)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("tiles", NULL, "add HEVC tiles signaling and NALU maps without splitting the tiles into different tile tracks", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("split_tiles", NULL, "`D` split HEVC tiles into different tile tracks, one tile (or all tiles of one slice) per track", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("negctts", NULL, "use negative CTS-DTS offsets (ISO4 brand)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("chap", NULL, "specify the track is a chapter track", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("chapter", NULL, "add a single chapter (old nero format) with given name lasting the entire file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("chapfile", NULL, "add a chapter file (old nero format)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("layout", NULL, "specify the track layout as WxHxXxY\n" + " - if W (resp H) = 0: the max width (resp height) of the tracks in the file are used\n" + " - if Y=-1: the layout is moved to the bottom of the track area\n" + " - X and Y can be omitted: `:layout=WxH`", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("rescale", NULL, "force media timescale to TS !! changes the media duration", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("timescale", NULL, "set imported media timescale to TS", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("moovts", NULL, "set movie timescale to TS. A negative value picks the media timescale of the first track imported", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("noedit", NULL, "`X` do not set edit list when importing B-frames video tracks", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("rvc", NULL, "set RVC configuration for the media", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("fmt", NULL, "override format detection with given format (cf BT/XMTA doc)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("profile", NULL, "override AVC profile", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("level", NULL, "override AVC level", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("novpsext", NULL, "remove VPS extensions from HEVC VPS", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("keepav1t", NULL, "keep AV1 temporal delimiter OBU in samples, might help if source file had losses", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("font", NULL, "specify font name for text import (default `Serif`)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("size", NULL, "specify font size for text import (default `18`)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("text_layout", NULL, "specify the track text layout as WxHxXxY\n" + " - if W (resp H) = 0: the max width (resp height) of the tracks in the file are used\n" + " - if Y=-1: the layout is moved to the bottom of the track area\n" + " - X and Y can be omitted: `:layout=WxH`", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("swf-global", NULL, "all SWF defines are placed in first scene replace rather than when needed", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-no-ctrl", NULL, "use a single stream for movie control and dictionary (this will disable ActionScript)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-no-text", NULL, "remove all SWF text", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-no-font", NULL, "remove all embedded SWF Fonts (local playback host fonts used)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-no-line", NULL, "remove all lines from SWF shapes", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-no-grad", NULL, "remove all gradients from SWF shapes", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-quad", NULL, "use quadratic bezier curves instead of cubic ones", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-xlp", NULL, "support for lines transparency and scalability", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-ic2d", NULL, "use indexed curve 2D hardcoded proto", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-same-app", NULL, "appearance nodes are reused", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("swf-flatten", NULL, "complementary angle below which 2 lines are merged, `0` means no flattening", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("kind", NULL, "set kind for the track as `schemeURI=value`", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("txtflags", NULL, "set display flags (hexa number) of text track. Use `txtflags+=FLAGS` to add flags and `txtflags-=FLAGS` to remove flags", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("rate", NULL, "force average rate and max rate to VAL (in bps) in btrt box. If 0, removes btrt box", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("stz2", NULL, "use compact size table (for low-bitrates)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("bitdepth", NULL, "set bit depth to VAL for imported video content (default is 24)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("colr", NULL, "set color profile for imported video content (see ISO/IEC 23001-8). Value is formatted as:\n" + " - nclc,p,t,m: with p colour primary, t transfer characteristics and m matrix coef\n" + " - nclx,p,t,m,r: same as `nclx` with r full range flag\n" + " - prof,path: with path indicating the file containing the ICC color profile\n" + " - rICC,path: with path indicating the file containing the restricted ICC color profile", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("dv-profile", NULL, "set the Dolby Vision profile", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("tc", NULL, "inject a single QT timecode. Value is formated as:\n" + " - [d]FPS[/FPS_den],h,m,s,f[,framespertick]: optional drop flag, framerate (integer or fractional), hours, minutes, seconds and frame number\n" + " - : `d` is an optional flag used to indicate that the counter is in drop-frame format\n" + " - : the `framespertick` is optional and defaults to round(framerate); it indicates the number of frames per counter tick", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("lastsampdur", NULL, "set duration of the last sample. Value is formated as:\n" + " - no value: use the previous sample duration\n" + " - integer: indicate the duration in milliseconds\n" + " - N/D: indicate the duration as fractional second", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("fstat", NULL, "print filter session stats after import", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("fgraph", NULL, "print filter session graph after import", NULL, NULL, GF_ARG_BOOL, 0), + {"sopt:[OPTS]", NULL, "set `OPTS` as additional arguments to source filter. `OPTS` can be any usual filter argument, see [filter doc `gpac -h doc`](Filters)"}, + {"dopt:[OPTS]", NULL, "`X` set `OPTS` as additional arguments to [destination filter](mp4mx). OPTS can be any usual filter argument, see [filter doc `gpac -h doc`](Filters)"}, + {"@@f1[:args][@@fN:args]", NULL, "set a filter chain to insert before the muxer. Each filter in the chain is formatted as a regular filter, see [filter doc `gpac -h doc`](Filters). If several filters are set, they will be chained in the given order. The last filter shall not have any Filter ID specified"}, + {0} +}; void PrintImportUsage() { - fprintf(stderr, "Importing Options\n" - "\nFile importing syntax:\n" - " \"#video\" \"#audio\" base import for most AV files\n" - " \"#trackID=ID\" track import for IsoMedia and other files\n" - " \"#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" - " \":rap\" imports only RAP samples\n" - " \":trailing\" keeps trailing 0-bytes in AVC/HEVC samples\n" - " \":agg=VAL\" same as -agg 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" - " \":ovsbr\" same as -ovsbr option\n" - " \":ps\" same as -ps option\n" - " \":psx\" same as -psx option\n" - " \":mpeg4\" same as -mpeg4 option\n" - " \":nosei\" discard all SEI messages during import\n" - " \":svc\" import SVC/LHVC with explicit signaling (no AVC base compatibility)\n" - " \":nosvc\" discard SVC/LHVC data when importing\n" - " \":svcmode=MODE\" sets SVC/LHVC import mode:\n" - " \" split : each layer is in its own track\n" - " \" merge : all layers are merged in a single track\n" - " \" splitbase : all layers are merged in a track, and the AVC base in another\n" - " \" splitnox : each layer is in its own track, and no extractors are written\n" - " \":subsamples\" adds SubSample information for AVC+SVC\n" - " \":forcesync\" forces non IDR samples with I slices to be marked as sync points (AVC GDR)\n" - " !! RESULTING FILE IS NOT COMPLIANT WITH THE SPEC but will fix seeking in most players\n" - " \":xps_inband\" Sets xPS inband for AVC/H264 and HEVC (for reverse operation, re-import from raw media)\n" - " \":max_lid=N\" sets HEVC max layer ID to be imported to N. Default imports all.\n" - " \":max_tid=N\" sets HEVC max temporal ID to be imported to N. Default imports all.\n" - " \":tiles\" adds HEVC tiles signaling and NALU maps without splitting the tiles into different tile tracks.\n" - " \":split_tiles\" splits HEVC tiles into different tile tracks, one tile (or all tiles of one slice) per track.\n" - " \":negctts\" uses negative CTS-DTS offsets (ISO4 brand)\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" - " \":chapter=NAME\" adds a single chapter (old nero format) with given name lasting the entire file\n" - " This command can be used in -cat as well\n" - " \":chapfile=file\" adds a chapter file (old nero format)\n" - " This command can be used in -cat as well\n" - " \":layout=WxHxXxY\" specifies the track layout\n" - " - if W (resp H) = 0, the max width (resp height) of\n" - " the tracks in the file are used.\n" - " - if Y=-1, the layout is moved to the bottom of the\n" - " track area\n" - " - X and Y can be omitted (:layout=WxH)\n" - " \":rescale=TS\" forces media timescale to TS !! changes the media duration\n" - " \":timescale=TS\" sets import timescale to TS\n" - " \":noedit\" do not set edit list when importing B-frames video tracks\n" - " \":rvc=FILENAME\" sets TVC configuration for the media\n" - " \":fmt=FORMAT\" overrides format detection with given format (cf BT/XMTA doc)\n" - " \":profile=INT\" overrides AVC profile\n" - " \":level=INT\" overrides AVC level\n" - " \":novpsext\" removes VPS extensions from HEVC VPS\n" - - " \":font=name\" specifies font name for text import (default \"Serif\")\n" - " \":size=s\" specifies font size for text import (default 18)\n" - " \":text_layout=WxHxXxY\" specifies the track text layout\n" - " - if W (resp H) = 0, the max width (resp height) of\n" - " the tracks in the file are used.\n" - " - if Y=-1, the layout is moved to the bottom of the\n" - " track area\n" - " - X and Y can be omitted (:layout=WxH)\n" - - " \":swf-global\" all SWF defines are placed in first scene replace\n" - " * Note: By default SWF defines are sent when needed\n" - " \":swf-no-ctrl\" uses a single stream for movie control and dictionary\n" - " * Note: this will disable ActionScript\n" - " \":swf-no-text\" removes all SWF text\n" - " \":swf-no-font\" removes all embedded SWF Fonts (terminal fonts used)\n" - " \":swf-no-line\" removes all lines from SWF shapes\n" - " \":swf-no-grad\" removes all gradients from swf shapes\n" - " \":swf-quad\" uses quadratic bezier curves instead of cubic ones\n" - " \":swf-xlp\" support for lines transparency and scalability\n" - " \":swf-ic2d\" uses indexed curve 2D hardcoded proto\n" - " \":swf-same-app\" appearance nodes are reused\n" - " \":swf-flatten=ang\" complementary angle below which 2 lines are merged\n" - " * Note: angle \'0\' means no flattening\n" - " \":kind=schemeURI=value\" sets kind for the track\n" - " \":txtflags=flags\" sets display flags (hexa number) of text track\n" - " \":txtflags+=flags\" adds display flags (hexa number) to text track\n" - " \":txtflags-=flags\" removes display flags (hexa number) from text track\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" - " * Note: aligns initial timestamp of the file to be concatenated.\n" - " -catx file same as cat but new tracks can be imported before concatenation by specifying '+ADD_COMMAND'\n" - " where ADD_COMMAND is a regular -add syntax\n" - " -unalign-cat does not attempt to align timestamps of samples inbetween tracks\n" - " -force-cat skips media configuration check when concatenating file\n" - " !!! THIS MAY BREAK THE CONCATENATED TRACK(S) !!!\n" - " -keep-sys keeps all MPEG-4 Systems info when using '-add' / 'cat'\n" - " -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" - " -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" - ); + u32 i; + + gf_sys_format_help(helpout, help_flags, "# Importing Options\n" + "# File importing\n" + "Syntax is [-add]() / [-cat]() `filename[#FRAGMENT][:opt1...:optN=val]`\n" + "This process will create the destination file if not existing, and add the track(s) to it. If you wish to always create a new destination file, add [-new](MP4B_GEN).\n" + "The supported input media types depend on your installation, check [filters documentation](Filters) for more info.\n" + " \n" + "To select a desired media track from a source, a fragment identifier '#' can be specified, bfore any other options. The following syntax is used:\n" + "- `#video`: adds the first video track found in source\n" + "- `#audio`: adds the first audio track found in source\n" + "- `#auxv`: adds the first auxiliary video track found in source\n" + "- `#pict`: adds the first picture track found in source\n" + "- `#trackID=ID` or `#ID`: adds the specified track. For IsoMedia files, ID is the track ID. For other media files, ID is the value indicated by `MP4Box -info inputFile`\n" + "- `#pid=ID`: number of desired PID for MPEG-2 TS sources\n" + "- `#prog_id=ID`: number of desired program for MPEG-2 TS sources\n" + "- `#program=NAME`: name of desired program for MPEG-2 TS sources\n" + " \n" + "By default all imports are performed sequentially, and final interleaving is done at the end; this however requires a temporary file holding original ISOBMF file (if any) and added files before creating the final output. Since this can become quite large, it is possible to add media to a new file without temporary storage, using [-flat](MP4B_GEN) option, but this disables media interleaving.\n" + " \n" + "If you wish to create an interleaved new file with no temporary storage, use the [-newfs](MP4B_GEN) option. The interleaving might not be as precise as when using [-new]() since it is dependent on muxer input scheduling (each execution might lead to a slightly different result). Additionally in this mode: \n" + " - Some muxing options (marked with `X` below) will be activated for all inputs (e.g it is not possible to import one AVC track with `xps_inband` and another without).\n" + " - Some muxing options (marked as `D` below) cannot be used as they require temporary storage for file edition.\n" + " - Usage of [-cat]() is possible, but concatenated sources will not be interleaved in the output. If you wish to perforom more complex cat/add operations without temp file, use the [gpac application](Filters).\n" + " \n" + "Note: MP4Box cannot start importing from a random point in the input, it always import from the begining. If you wish to import from another point in the source, use the [gpac application](Filters).\n" + " \n" + "Note: When importing SRT or SUB files, MP4Box will choose default layout options to make the subtitle appear at the bottom of the video. You SHOULD NOT import such files before any video track is added to the destination file, otherwise the results will likelly not be useful (default SRT/SUB importing uses default serif font, fontSize 18 and display size 400x60). For more details, check [TTXT doc](Subtitling-with-GPAC).\n" + " \n" + "When importing several tracks/sources in one pass, all options will be applied if relevant to each source. These options are set for all imported streams. If you need to specify these options par stream, set per-file options using the syntax `-add stream[:opt1:...:optN]`. Allowed per-file options:\n\n" + ); + + i=0; + while (ImportFileOpts[i].name) { + GF_GPACArg *arg = &ImportFileOpts[i]; + i++; + gf_sys_print_arg(helpout, help_flags | GF_PRINTARG_NO_DASH, arg, "mp4box-import"); + } + + gf_sys_format_help(helpout, help_flags, "\n" + "Note: `sopt`, `dopt` and `@@f` must be placed after all other options.\n" + "# Global import options\n" + ); + + i=0; + while (m4b_imp_args[i].name) { + GF_GPACArg *arg = &m4b_imp_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-import"); + } } +GF_GPACArg m4b_senc_args[] = +{ + GF_DEF_ARG("mp4", NULL, "specify input file is for encoding", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("def", NULL, "encode DEF names in BIFS", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("sync", NULL, "force BIFS sync sample generation every given time in ms (cannot be used with [-shadow]() )", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("shadow", NULL, "force BIFS sync shadow sample generation every given time in ms (cannot be used with [-sync]() )", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("sclog", NULL, "generate scene codec log file if available", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ms", NULL, "import tracks from the given file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("ctx-in", NULL, "specify initial context (MP4/BT/XMT) file for chunk processing. Input file must be a commands-only file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("ctx-out", NULL, "specify storage of updated context (MP4/BT/XMT) file for chunk processing, optional", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("resolution", NULL, "resolution factor (-8 to 7, default 0) for LASeR encoding, and all coords are multiplied by `2^res` before truncation (LASeR encoding)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("coord-bits", NULL, "number of bits used for encoding truncated coordinates (0 to 31, default 12) (LASeR encoding)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("scale-bits", NULL, "extra bits used for encoding truncated scales (0 to 4, default 0) (LASeR encoding)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("auto-quant", NULL, "resolution is given as if using -resolution but coord-bits and scale-bits are infered (LASeR encoding)", NULL, NULL, GF_ARG_INT, 0), + {0} +}; + + void PrintEncodeUsage() { - fprintf(stderr, "MPEG-4 Scene Encoding Options\n" - " -mp4 specify input file is for encoding.\n" - " -def encode DEF names\n" - " -sync time_in_ms forces BIFS sync sample generation every time_in_ms\n" - " * Note: cannot be used with -shadow\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" - "\nChunk Processing\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" - "\n" - "LASeR Encoding options\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" - " (0 to 31, default 12)\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" - " but coord-bits and scale-bits are infered\n" - ); + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# MPEG-4 Scene Encoding Options\n" + "## General considerations\n" + "MP4Box supports encoding and decoding of of BT, XMT, VRML and (partially) X3D formats int MPEG-4 BIFS, and encoding and decoding of XSR and SVG into MPEG-4 LASeR\n" + "Any media track specified through a `MuxInfo` element will be imported in the resulting MP4 file.\n" + "See https://wiki.gpac.io/MPEG-4-BIFS-Textual-Format and related pages.\n" + "## Scene Random Access\n" + "MP4Box can encode BIFS or LASeR streams and insert random access points at a given frequency. This is useful when packaging content for broadcast, where users will not turn in the scene at the same time. In MPEG-4 terminology, this is called the __scene carousel__." + "## BIFS Chunk Processing\n" + "The BIFS chunk encoding mode alows encoding single BIFS access units from an initial context and a set of commands.\n" + "The generated AUs are raw BIFS (not SL-packetized), in files called FILE-ESID-AUIDX.bifs, with FILE the basename of the input file.\n" + "Commands with a timing of 0 in the input will modify the carousel version only (i.e. output context).\n" + "Commands with a timing different from 0 in the input will generate new AUs.\n" + " \n" + "Options:\n" + ); + + while (m4b_senc_args[i].name) { + GF_GPACArg *arg = &m4b_senc_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-senc"); + } } +GF_GPACArg m4b_crypt_args[] = +{ + GF_DEF_ARG("crypt", NULL, "encrypt the input file using the given `CryptFile`", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("decrypt", NULL, "decrypt the input file, potentially using the given `CryptFile`. If `CryptFile` is not given, will fail if the key management system is not supported", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("set-kms", NULL, "change ISMA/OMA KMS location for all tracks, or for a given one if `ID=kms_uri` is used", NULL, NULL, GF_ARG_STRING, 0), + {0} +}; + void PrintEncryptUsage() { - fprintf(stderr, "ISMA Encryption/Decryption Options\n" - " -crypt drm_file crypts a specific track using ISMA AES CTR 128\n" - " -decrypt [drm_file] decrypts a specific track using ISMA AES CTR 128\n" - " * Note: drm_file can be omitted if keys are in file\n" - " -set-kms kms_uri changes KMS location for all tracks or a given one.\n" - " * to address a track, use \'tkID=kms_uri\'\n" - "\n" - "DRM file syntax for GPAC ISMACryp:\n" - " File is XML and shall start with xml header\n" - " File root is an \"ISMACryp\" element\n" - " File is a list of \"cryptrack\" elements\n" - "\n" - "cryptrack 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" - "\nEncryption only attributes:\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" - " \"Clear\" all samples clean (not encrypted)\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" - " * If not set MP4Box will generate one for you\n" - "\n" - ); + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# Encryption/Decryption Options\n" + "MP4Box supports encryption and decryption of ISMA, OMA and CENC content, see [encryption filter `gpac -h cecrypt`](cecrypt).\n" + "It requires a specific XML file called `CryptFile`, whose syntax is available at https://wiki.gpac.io/Common-Encryption\n" + " \n" + "Options:\n" + ); + while (m4b_crypt_args[i].name) { + GF_GPACArg *arg = &m4b_crypt_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-crypt"); + } } +GF_GPACArg m4b_hint_args[] = +{ + GF_DEF_ARG("hint", NULL, "hint the file for RTP/RTSP", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("mtu", NULL, "specify RTP MTU (max size) in bytes (this includes 12 bytes RTP header)", "1450", NULL, GF_ARG_INT, 0), + GF_DEF_ARG("copy", NULL, "copy media data to hint track rather than reference (speeds up server but takes much more space)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("multi `[maxptime]`", NULL, "enable frame concatenation in RTP packets if possible (with max duration 100 ms or `maxptime` ms if given)", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("rate", NULL, "specify rtp rate in Hz when no default for payload", "90000", NULL, GF_ARG_INT, 0), + GF_DEF_ARG("mpeg4", NULL, "force MPEG-4 generic payload whenever possible", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("latm", NULL, "force MPG4-LATM transport for AAC streams", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("static", NULL, "enable static RTP payload IDs whenever possible (by default, dynamic payloads are always used)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("add-sdp", NULL, "add given SDP string to hint track (`tkID:string`) or movie (`string`)", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("no-offset", NULL, "signal no random offset for sequence number and timestamp (support will depend on server)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("unhint", NULL, "remove all hinting information from file", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("group-single", NULL, "put all tracks in a single hint group", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ocr", NULL, "force all MPEG-4 streams to be synchronized (MPEG-4 Systems only)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("rap", NULL, "signal random access points in RTP packets (MPEG-4 Systems)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ts", NULL, "signal AU Time Stamps in RTP packets (MPEG-4 Systems)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("size", NULL, "signal AU size in RTP packets (MPEG-4 Systems)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("idx", NULL, "signal AU sequence numbers in RTP packets (MPEG-4 Systems)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("iod", NULL, "prevent systems tracks embedding in IOD (MPEG-4 Systems), not compatible with [-isma]()", NULL, NULL, GF_ARG_BOOL, 0), + {0} +}; + void PrintHintUsage() { - fprintf(stderr, "Hinting Options\n" - " -hint hints the file for RTP/RTSP\n" - " -mtu size specifies RTP MTU (max size) in bytes. Default size is 1450\n" - " * Note: this includes the RTP header (12 bytes)\n" - " -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" - " * 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" - " * By default, dynamic payloads are always used\n" - "\n" - "MPEG-4 Generic Payload Options\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" - " * 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" - "\n"); + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# Hinting Options\n" + "IsoMedia hinting consists in creating special tracks in the file that contain transport protocol specific information and optionally multiplexing information. These tracks are then used by the server to create the actual packets being sent over the network, in other words they provide the server with hints on how to build packets, hence their names `hint tracks`.\n" + "MP4Box supports creation of hint tracks for RTSP servers supporting these such as QuickTime Streaming Server, DarwinStreaming Server or 3GPP-compliant RTSP servers.\n" + "Note: GPAC streaming tools [rtp output](rtpout) and [rtsp server](rtspout) do not use hint tracks, they use on-the-fly packetization " + "from any media sources, not just MP4\n" + " \n" + "Options:\n" + ); + while (m4b_hint_args[i].name) { + GF_GPACArg *arg = &m4b_hint_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-hint"); + } } + + +GF_GPACArg m4b_extr_args[] = +{ + GF_DEF_ARG("raw", NULL, "extract given track in raw format when supported. Use `tkID:output=FileName` to set output file name", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("raws", NULL, "extract each sample of the given track to a file. Use `tkID:N`to extract the Nth sample", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("nhnt", NULL, "extract given track to [NHNT](nhntr) format", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("nhml", NULL, "extract given track to [NHML](nhmlr) format. Use `tkID:full` for full NHML dump with all packet properties", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("webvtt-raw", NULL, "extract given track as raw media in WebVTT as metadata. Use `tkID:embedded` to include media data in the WebVTT file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("single", NULL, "extract given track to a new mp4 file", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("six", NULL, "extract given track as raw media in **experimental** XML streaming instructions", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("avi", NULL, "extract given track to an avi file", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("avi", NULL, "same as [-raw]() but defaults to QCP file for EVRC/SMV", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("aviraw", NULL, "extract AVI track in raw format; parameter can be `video`, `audio`or `audioN`", NULL, "video|audio", GF_ARG_STRING, 0), + GF_DEF_ARG("saf", NULL, "remux file to SAF multiplex", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dvbhdemux", NULL, "demux DVB-H file into IP Datagrams sent on the network", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("raw-layer", NULL, "same as [-raw]() but skips SVC/MVC/LHVC extractors when extracting", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("diod", NULL, "extract file IOD in raw format", NULL, NULL, GF_ARG_BOOL, 0), + {0} +}; + void PrintExtractUsage() { - fprintf(stderr, "Extracting Options:\n" - " -raw TrackID extracts track in raw format when supported\n" - " :output=FileName sets the output filename for this extraction \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" - " * Note: \"-nhml TrackID:full\" for full dump\n" - " -webvtt-raw TrackID extracts raw media track in WebVTT as metadata.\n" - " * Note: \"-webvtt-raw TrackID:embedded\" to include media data in the WebVTT file\n" - " -six TrackID extracts raw media track in experimental XML streaming instructions.\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" - " -raw-layer ID same as -raw but skips SVC/MVC extractors when extracting\n" - " -diod extracts file IOD in raw format when supported\n" - "\n" -#if !defined(GPAC_DISABLE_STREAMING) - " -grab-ts IP:port grabs TS over UDP or RTP at IP:port location to output TS file\n" - " -ifce IFCE indicates default ifce for grab operations\n" -#endif - "\n"); + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# Extracting Options\n" + "MP4Box can be used to extract media tracks from MP4 files. If you need to convert these tracks however, please check the [filters doc](Filters).\n" + " \n" + "Options:\n" + ); + while (m4b_extr_args[i].name) { + GF_GPACArg *arg = &m4b_extr_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract"); + } } + +GF_GPACArg m4b_dump_args[] = +{ + GF_DEF_ARG("stdb", NULL, "dump/write to stdout and assume stdout is opened in binary mode", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("stdb", NULL, "dump/write to stdout and try to reopen stdout in binary mode", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("tracks", NULL, "print the number of tracks on stdout", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("info", NULL, "print movie info (no parameter) or track info with specified ID", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("infon", NULL, "print track info for given track number, 1 being the first track in the file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("diso", NULL, "dump IsoMedia file boxes in XML output", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dxml", NULL, "dump IsoMedia file boxes and known track samples in XML output", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("disox", NULL, "dump IsoMedia file boxes except sample tables in XML output", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("keep-ods", NULL, "do not translate ISOM ODs and ESDs tags (debug purpose only)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("bt", NULL, "dump scene to BT format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("xmt", NULL, "dump scene to XMT format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("wrl", NULL, "dump scene to VRML format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("x3d", NULL, "dump scene to X3D XML format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("x3dc", NULL, "dump scene to X3D VRML format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("lsr", NULL, "dump scene to LASeR XML (XSR) format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("drtp", NULL, "dump rtp hint samples structure to XML output", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dts", NULL, "print sample timing, size and position in file to text output", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dtsx", NULL, "same as [-dts]() but does not print offset", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dtsc", NULL, "same as [-dts]() but analyse each sample for duplicated dts/cts (__slow !__)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dtsxc", NULL, "same as [-dtsc]() but does not print offset (__slow !__)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dnal", NULL, "print NAL sample info of given track", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dnalc", NULL, "print NAL sample info of given track, adding CRC for each nal", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dnald", NULL, "print NAL sample info of given track without DTS and CTS info", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dnalx", NULL, "print NAL sample info of given track without DTS and CTS info and adding CRC for each nal", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("sdp", NULL, "dump SDP description of hinted file", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dsap", NULL, "dump DASH SAP cues (see -cues) for a given track", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dsaps", NULL, "same as [-dsap]() but only print sample number", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dsapc", NULL, "same as [-dsap]() but only print CTS", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dsapd", NULL, "same as [-dsap]() but only print DTS, `-dsapp` to only print presentation time", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dsapp", NULL, "same as [-dsap]() but only print presentation time", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("dcr", NULL, "dump ISMACryp samples structure to XML output", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dump-cover", NULL, "extract cover art", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dump-chap", NULL, "extract chapter file as TTXT format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dump-chap-ogg", NULL, "extract chapter file as OGG format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dump-chap-zoom", NULL, "extract chapter file as zoom format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("dump-udta `[tkID:]4cc`", NULL, "extract udta for the given 4CC. If `tkID` is given, dumps from UDTA of the given track ID, otherwise moov is used", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("mergevtt", NULL, "merge vtt cues while dumping", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("ttxt", NULL, "convert input subtitle to GPAC TTXT format if no parameter. Otherwise, dump given text track to GPAC TTXT format", NULL, NULL, GF_ARG_INT, 0), + GF_DEF_ARG("srt", NULL, "convert input subtitle to SRT format if no parameter. Otherwise, dump given text track to SRT format", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("rip-mpd", NULL, "download manifest and segments of an MPD. Does not work with live sessions", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("stat", NULL, "generate node/field statistics for scene", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("stats", NULL, "generate node/field statistics per Access Unit", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("statx", NULL, "generate node/field statistics for scene after each AU", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("hash", NULL, "generate SHA-1 Hash of the input file", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("comp", NULL, "replace with compressed version all top level box types given as parameter, formated as `orig_4cc_1=comp_4cc_1[,orig_4cc_2=comp_4cc_2]`", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("bin", NULL, "convert input XML file using NHML bitstream syntax to binary", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("topcount", NULL, "print to stdout the number of top-level boxes matching box types given as parameter, formated as `4cc_1,4cc_2N`", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("topsize", NULL, "print to stdout the number of bytes of top-level boxes matching types given as parameter, formated as `4cc_1,4cc_2N` or `all` for all boxes", NULL, NULL, GF_ARG_STRING, 0), + {0} +}; + void PrintDumpUsage() { - fprintf(stderr, "Dumping Options\n" - " -stdb dumps/write to stdout and assumes stdout is opened in binary mode\n" - " -std dumps/write to stdout and try to reopen stdout in binary mode.\n" - " -info [trackID] prints movie info / track info if trackID specified\n" - " * Note: for non IsoMedia files, gets import options\n" - " -bt scene to bt format - removes unknown MPEG4 nodes\n" - " -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 dumps IsoMedia file boxes in XML output\n" - " -dxml dumps IsoMedia file boxes and known track samples in XML output\n" - " -drtp rtp hint samples structure to XML output\n" - " -dts prints sample timing to text output\n" - " -dnal trackID prints NAL sample info of given track\n" - " -sdp dumps SDP description of hinted file\n" - " -dcr ISMACryp samples structure to XML output\n" - " -dump-cover Extracts cover art\n" - " -dump-chap Extracts chapter file\n" - " -dump-chap-ogg Extracts chapter file as OGG format\n" - " -dump-udta [ID:]4cc Extracts udta for the given 4CC. If ID is given, dumps from UDTA of the given track ID, otherwise moov is used.\n" - "\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_DISABLE_ISOM_WRITE - " -srt Converts input subtitle to SRT format\n" -#endif - " -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" - "\n" - " -hash generates SHA-1 Hash of the input file\n" -#ifndef GPAC_DISABLE_CORE_TOOLS - " -bin converts input XML file using NHML bitstream syntax to binary\n" -#endif - "\n"); + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# File Dumping\n" + " \n" + "MP4Box has many dump functionalities, from simple track listing to more complete reporting of special tracks.\n" + " \n" + "Options:\n" + ); + while (m4b_dump_args[i].name) { + GF_GPACArg *arg = &m4b_dump_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract"); + } } +GF_GPACArg m4b_meta_args[] = +{ + GF_DEF_ARG("set-meta `ABCD[:tk=tkID]`", NULL, "set meta box type, with `ABCD` the four char meta type (NULL or 0 to remove meta)\n" + "- tk not set: use root (file) meta\n" + "- tkID == 0: use moov meta\n" + "- tkID != 0: use meta of given track", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("add-items", NULL, "add resource to meta, with parameter syntax `file_path[:opt1:optN]`\n" + "- file_path `this` or `self`: item is the file itself\n" + "- tk=tkID: meta location (file, moov, track)\n" + "- name=str: item name\n" + "- type=itype: item 4cc type (not needed if mime is provided)\n" + "- mime=mtype: item mime type\n" + "- encoding=enctype: item content-encoding type\n" + "- id=ID: item ID\n" + "- ref=4cc,id: reference of type 4cc to an other item", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("add-image", NULL, "add the given file (with parameters) as HEIF image item. Same syntax as [-add-item]()\n" + "- name=str: see [-add-item]()\n" + "- id=id: see [-add-item]()\n" + "- ref=4cc, id: see [-add-item]()\n" + "- primary: indicate that this item should be the primary item\n" + "- time=t: use the next sync sample after time t (float, in sec, default 0). A negative time imports ALL frames as items\n" + "- split_tiles: for an HEVC tiled image, each tile is stored as a separate item\n" + "- rotation=a: set the rotation angle for this image to 90*a degrees anti-clockwise\n" + "- hidden: indicate that this image item should be hidden\n" + "- icc_path: path to icc to add as colr\n" + "- alpha: indicate that the image is an alpha image (should use ref=auxl also)\n" + "- any other option will be passed as options to the media importer, see [-add]()", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("rem-item `item_ID[:tk=tkID]`", NULL, "remove resource from meta", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("set-primary `item_ID[:tk=tkID]`", NULL, "set item as primary for meta", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("set-xml `xml_file_path[:tk=tkID][:binary]`", NULL, "set meta XML data", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("rem-xml `[tk=tkID]`", NULL, "remove meta XML data", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("dump-xml `file_path[:tk=tkID]`", NULL, "dump meta XML to file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("dump-item `item_ID[:tk=tkID][:path=fileName]`", NULL, "dump item to file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("package", NULL, "package input XML file into an ISO container, all media referenced except hyperlinks are added to file", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("package", NULL, "package input XML file into an MPEG-U widget with ISO container, all files contained in the current folder are added to the widget package", NULL, NULL, GF_ARG_STRING, 0), + {0} +}; + void PrintMetaUsage() { - fprintf(stderr, "Meta handling Options\n" - " -set-meta args sets given meta type - syntax: \"ABCD[:tk=ID]\"\n" - " * ABCD: four char meta type (NULL or 0 to remove meta)\n" - " * [:tk=ID]: if not set use root (file) meta\n" - " 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" - " * syntax: file_path + options (\':\' separated):\n" - " file_path \"this\" or \"self\": item is the file itself\n" - " tk=ID: meta location (file, moov, track)\n" - " name=str: item name\n" - " type=itype: item 4cc type (not needed if mime is provided)\n" - " mime=mtype: item mime type\n" - " encoding=enctype: item content-encoding type\n" - " id=id: item ID\n" - " ref=4cc,id: reference of type 4cc to an other item\n" - " Image Item options\n" - " image-size=wxh sets the width and height of the image.\n" - " image-pasp=wxh sets the pixel aspect ratio property of the image.\n" - " image-rloc=wxh sets the location of this image within another image item.\n" - " image-irot=a sets the rotation angle for this image to 90*a degrees anti-clockwise.\n" - " image-hidden indicates that this image item should be hidden.\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" - " * all media referenced except hyperlinks are added to file\n" - " -mgt packages input XML file into an MPEG-U widget with ISO container.\n" - " * all files contained in the current folder are added to the widget package\n" - ); + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# Meta and HEIF Options\n" + "IsoMedia files can be used as generic meta-data containers, for examples storing XML information and sample images for a movie. The resulting file may not always contain a movie as is the case with some HEIF files or MPEG-21 files.\n" + " \n" + "These information can be stored at the file root level, as is the case for HEIF/IFF and MPEG-21 file formats, or at the moovie or track level for a regular movie." + " \n \n"); + while (m4b_meta_args[i].name) { + GF_GPACArg *arg = &m4b_meta_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract"); + } } +GF_GPACArg m4b_swf_args[] = +{ + GF_DEF_ARG("global", NULL, "all SWF defines are placed in first scene replace rather than when needed", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-ctrl", NULL, "use a single stream for movie control and dictionary (this will disable ActionScript)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-text", NULL, "remove all SWF text", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-font", NULL, "remove all embedded SWF Fonts (local playback host fonts used)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-line", NULL, "remove all lines from SWF shapes", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-grad", NULL, "remove all gradients from swf shapes", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("quad", NULL, "use quadratic bezier curves instead of cubic ones", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("xlp", NULL, "support for lines transparency and scalability", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("flatten", NULL, "complementary angle below which 2 lines are merged, value `0`means no flattening", NULL, NULL, GF_ARG_DOUBLE, 0), + {0} +}; + void PrintSWFUsage() { - fprintf(stderr, - "SWF Importer Options\n" + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# SWF Importer Options\n" "\n" "MP4Box can import simple Macromedia Flash files (\".SWF\")\n" "You can specify a SWF input file with \'-bt\', \'-xmt\' and \'-mp4\' options\n" + " \n" + "Options:\n" + ); + while (m4b_swf_args[i].name) { + GF_GPACArg *arg = &m4b_swf_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract"); + } +} + +GF_GPACArg m4b_liveenc_args[] = +{ + GF_DEF_ARG("dst", NULL, "destination IP", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("port", NULL, "destination port", "7000", NULL, GF_ARG_INT, 0), + GF_DEF_ARG("mtu", NULL, "path MTU for RTP packets", "1450", NULL, GF_ARG_INT, 0), + GF_DEF_ARG("ifce", NULL, "IP address of the physical interface to use", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("ttl", NULL, "time to live for multicast packets", "1", NULL, GF_ARG_INT, 0), + GF_DEF_ARG("sdp", NULL, "output SDP file", "session.sdp", NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("dims", NULL, "turn on DIMS mode for SVG input", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("no-rap", NULL, "disable RAP sending and carousel generation", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("src", NULL, "source of scene updates", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("rap", NULL, "duration in ms of base carousel; you can specify the RAP period of a single ESID (not in DIMS) using `ESID=X:time`", NULL, NULL, GF_ARG_INT, 0), + {0} +}; + +void PrintLiveUsage() +{ + u32 i=0; + gf_sys_format_help(helpout, help_flags, "# Live Scene Encoder Options\n" + "The options shall be specified as òpt_name=opt_val.\n" + "Options:\n" "\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" - " * 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" - " * Note: angle \'0\' means no flattening\n" - "\n" - ); + ); + while (m4b_liveenc_args[i].name) { + GF_GPACArg *arg = &m4b_liveenc_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-extract"); + } + + gf_sys_format_help(helpout, help_flags, " \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" + ); +} + +void PrintCoreUsage() +{ + gf_sys_format_help(helpout, help_flags, "# libgpac core options\n"); + gf_sys_print_core_help(helpout, 0, GF_ARGMODE_ALL, 0); } +GF_GPACArg m4b_usage_args[] = +{ + GF_DEF_ARG("h", NULL, "print help\n" + "- general: general options help\n" + "- hint: hinting options help\n" + "- dash: DASH segmenter help\n" + "- import: import options help\n" + "- encode: encode options help\n" + "- meta: meta handling options help\n" + "- extract: extraction options help\n" + "- dump: dump options help\n" + "- swf: Flash (SWF) options help\n" + "- crypt: ISMA E&A options help\n" + "- format: supported formats help\n" + "- live: BIFS streamer help\n" + "- core: libgpac core options\n" + "- all: print all the above help screens\n" + "- opts: print all options\n" + "- VAL: search for option named `VAL` (without `-` or `--`) in MP4Box, libgpac core and all filters\n" + , NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("hx", NULL, "look for given string in all possible options" + , NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("nodes", NULL, "list supported MPEG4 nodes", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("node", NULL, "get given MPEG4 node syntax and QP infolist", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("xnodes", NULL, "list supported X3D nodes", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("xnode", NULL, "get given X3D node syntax", NULL, NULL, GF_ARG_STRING, 0), + GF_DEF_ARG("snodes", NULL, "list supported SVG nodes", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("languages", NULL, "list supported ISO 639 languages", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("boxes", NULL, "list all supported ISOBMF boxes and their syntax", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("fstat", NULL, "print filter session statistics (import/export/encrypt/decrypt/dashing)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("fgraph", NULL, "print filter session graph (import/export/encrypt/decrypt/dashing)", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("v", NULL, "verbose mode", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("version", NULL, "get build version", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("-- INPUT", NULL, "escape option if INPUT starts with `-` character", NULL, NULL, GF_ARG_BOOL, 0), + {0} +}; + void PrintUsage() { - fprintf (stderr, "MP4Box [option] input [option]\n" - " -h general general options help\n" - " -h hint hinting options help\n" - " -h dash DASH segmenter help\n" - " -h import import options help\n" - " -h encode encode options help\n" - " -h meta meta handling options help\n" - " -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 file streamer help\n" - " -h live BIFS streamer help\n" - " -h all all options are printed\n" - "\n" - " -nodes lists supported MPEG4 nodes\n" - " -node NodeName gets MPEG4 node syntax and QP info\n" - " -xnodes lists supported X3D nodes\n" - " -xnode NodeName gets X3D node syntax\n" - " -snodes lists supported SVG nodes\n" - " -languages lists supported ISO 639 languages\n" - " -boxes lists all supported ISOBMF boxes and their syntax\n" - "\n" - " -quiet quiet mode\n" - " -noprog disables progress\n" - " -v verbose mode\n" - " -logs set log tools and levels, formatted as a ':'-separated list of toolX[:toolZ]@levelX\n" - " -log-file FILE sets output log file. Also works with -lf FILE\n" - " -log-clock or -lc logs time in micro sec since start time of GPAC before each log line.\n" - " -log-utc or -lu logs UTC time in ms before each log line.\n" - " -version gets build version\n" - " -- INPUT escape option if INPUT starts with - character\n" - "\n" - ); + u32 i=0; + gf_sys_format_help(helpout, help_flags, "MP4Box [option] input [option]\n" + " \n" + "# General Options:\n" + ); + while (m4b_usage_args[i].name) { + GF_GPACArg *arg = &m4b_usage_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, arg, "mp4box-general"); + } +} + +enum +{ + SEARCH_ARG_EXACT, + SEARCH_ARG_CLOSE, + SEARCH_DESC, +}; + +static Bool strstr_nocase(const char *text, const char *subtext, u32 subtext_len) +{ + if (!*text || !subtext || !subtext_len) + return GF_FALSE; + + while (*text) { + if (tolower(*text) == *subtext) { + if (!strnicmp(text, subtext, subtext_len)) + return GF_TRUE; + + } + text++; + } + return GF_FALSE; } +static u32 PrintHelpForArgs(char *arg_name, GF_GPACArg *args, u32 search_type) +{ + u32 res=0; + u32 i=0; + u32 alen = (u32) strlen(arg_name); + while (args[i].name) { + u32 flags=0; + GF_GPACArg *arg = &args[i]; + GF_GPACArg an_arg; + Bool do_match = GF_FALSE; + + if (args==ImportFileOpts) { + flags = GF_PRINTARG_COLON; + if (!strncmp(arg_name, arg->name, alen) && ((arg->name[alen]==0) || (arg->name[alen]=='='))) + do_match = GF_TRUE; + } + else if (!strcmp(arg_name, arg->name)) + do_match = GF_TRUE; + else if ((alen < (u32) strlen(arg->name)) && (arg->name[alen]==' ') && !strncmp(arg_name, arg->name, alen)) + do_match = GF_TRUE; + + if (arg_name[0] == '@') + do_match = GF_TRUE; + + if ((search_type==SEARCH_ARG_EXACT) && !do_match) { + i++; + continue; + } + if ((search_type==SEARCH_ARG_CLOSE) && !gf_sys_word_match(arg_name, arg->name)) { + i++; + continue; + } + if ((search_type==SEARCH_DESC) && !strstr_nocase(arg->description, arg_name, alen)) { + i++; + continue; + } + + an_arg = *arg; + if (search_type!=SEARCH_ARG_EXACT) { + an_arg.description = NULL; + an_arg.type = GF_ARG_BOOL; + } + gf_sys_print_arg(helpout, flags, &an_arg, ""); + res++; + i++; + } + return res; +} +static Bool PrintHelpArg(char *arg_name, u32 search_type, GF_FilterSession *fs) +{ + Bool first=GF_TRUE; + GF_GPACArg an_arg; + u32 i, count; + u32 res = 0; + u32 alen = (u32) strlen(arg_name); + res += PrintHelpForArgs(arg_name, m4b_gen_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_dash_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_imp_args, search_type); + res += PrintHelpForArgs(arg_name, ImportFileOpts, search_type); + res += PrintHelpForArgs(arg_name, m4b_senc_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_crypt_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_hint_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_extr_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_dump_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_meta_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_swf_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_liveenc_args, search_type); + res += PrintHelpForArgs(arg_name, m4b_usage_args, search_type); + res += PrintHelpForArgs(arg_name, (GF_GPACArg *) gf_sys_get_options(), search_type); + + if (!fs) return res; + + memset(&an_arg, 0, sizeof(GF_GPACArg)); + count = gf_fs_filters_registers_count(fs); + for (i=0; iargs) { + u32 len; + const GF_FilterArgs *arg = ®->args[j]; + if (!arg || !arg->arg_name) break; + j++; + if ((search_type==SEARCH_ARG_EXACT) && strcmp(arg->arg_name, arg_name)) continue; + + if ((search_type==SEARCH_ARG_CLOSE) && !gf_sys_word_match(arg->arg_name, arg_name)) continue; + + if (search_type==SEARCH_DESC) { + if (!strstr_nocase(arg->arg_desc, arg_name, alen)) continue; + } + + an_arg.name = arg->arg_name; + if (search_type==SEARCH_ARG_EXACT) { + an_arg.description = arg->arg_desc; + switch (arg->arg_type) { + case GF_PROP_BOOL: + an_arg.type = GF_ARG_BOOL; + break; + case GF_PROP_UINT: + case GF_PROP_SINT: + an_arg.type = GF_ARG_INT; + break; + case GF_PROP_DOUBLE: + an_arg.type = GF_ARG_DOUBLE; + break; + case GF_PROP_STRING_LIST: + case GF_PROP_UINT_LIST: + an_arg.type = GF_ARG_STRINGS; + break; + default: + an_arg.type = GF_ARG_STRING; + break; + } + if (first) { + first = GF_FALSE; + gf_sys_format_help(helpout, 0, "\nGlobal filter session arguments. Syntax is `--arg` or `--arg=VAL`. `[F]` indicates filter name. See `gpac -h` and `gpac -h F` for more info.\n"); + } + fprintf(helpout, "[%s]", reg->name); + len = (u32)strlen(reg->name); + while (len<10) { + len++; + fprintf(helpout, " "); + } + fprintf(helpout, " "); + } + + gf_sys_print_arg(helpout, GF_PRINTARG_ADD_DASH, &an_arg, "TEST"); + res++; + } + } + if (res) return GF_TRUE; + return GF_FALSE; +} + +static void PrintHelp(char *arg_name, Bool search_desc, Bool no_match) +{ + GF_FilterSession *fs; + Bool res; + + fs = gf_fs_new_defaults(0); + + if (arg_name[0]=='-') + arg_name++; + + if (search_desc) { + char *_arg_name = gf_strdup(arg_name); + strlwr(_arg_name); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Possible options mentionning `%s`:\n", arg_name)); + PrintHelpArg(_arg_name, SEARCH_DESC, fs); + gf_free(_arg_name); + } else { + res = no_match ? GF_FALSE : PrintHelpArg(arg_name, SEARCH_ARG_EXACT, fs); + if (!res) { + GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Option -%s unknown, please check usage.\n", arg_name)); + GF_LOG(GF_LOG_INFO, GF_LOG_APP, ("Possible options are:\n")); + + PrintHelpArg(arg_name, SEARCH_ARG_CLOSE, fs); + } + } + if (fs) + gf_fs_del(fs); +} void scene_coding_log(void *cbk, GF_LOG_Level log_level, GF_LOG_Tool log_tool, const char *fmt, va_list vlist) { @@ -908,7 +1200,7 @@ void SetupClockReferences(GF_ISOFile *file) /*base RTP payload type used (you can specify your own types if needed)*/ #define BASE_PAYT 96 -GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 base_flags, Bool copy_data, Bool interleave, Bool regular_iod, Bool single_group) +GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 base_flags, Bool copy_data, Bool interleave, Bool regular_iod, Bool single_group, Bool hint_no_offset) { GF_ESD *esd; GF_InitialObjectDescriptor *iod; @@ -969,6 +1261,18 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 media_prio = 2; } break; + case GF_ISOM_MEDIA_AUXV: + if (single_av) { + media_group = 2; + media_prio = 3; + } + break; + case GF_ISOM_MEDIA_PICT: + if (single_av) { + media_group = 2; + media_prio = 4; + } + break; case GF_ISOM_MEDIA_AUDIO: if (single_av) { media_group = 2; @@ -979,7 +1283,7 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 continue; default: /*no hinting of systems track on isma*/ - if (spec_type==GF_4CC('I','S','M','A')) continue; + if (spec_type==GF_ISOM_BRAND_ISMA) continue; } mtype = gf_isom_get_media_subtype(file, i+1, 1); if ((mtype==GF_ISOM_SUBTYPE_MPEG4) || (mtype==GF_ISOM_SUBTYPE_MPEG4_CRYP) ) mtype = gf_isom_get_mpeg4_subtype(file, i+1, 1); @@ -1030,6 +1334,10 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 } continue; } + + if (hint_no_offset) + gf_hinter_track_force_no_offsets(hinter); + bw = gf_hinter_track_get_bandwidth(hinter); tot_bw += bw; flags = gf_hinter_track_get_flags(hinter); @@ -1078,18 +1386,17 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 static void check_media_profile(GF_ISOFile *file, u32 track) { u8 PL; - GF_M4ADecSpecInfo dsi; GF_ESD *esd = gf_isom_get_esd(file, track, 1); if (!esd) return; switch (esd->decoderConfig->streamType) { case 0x04: PL = gf_isom_get_pl_indication(file, GF_ISOM_PL_VISUAL); - 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==GPAC_OTI_VIDEO_AVC) || (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_SVC)) { + if (esd->decoderConfig->objectTypeIndication==GF_CODECID_MPEG4_PART2) { + GF_M4VDecSpecInfo vdsi; + gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &vdsi); + if (vdsi.VideoPL > PL) gf_isom_set_pl_indication(file, GF_ISOM_PL_VISUAL, vdsi.VideoPL); + } else if ((esd->decoderConfig->objectTypeIndication==GF_CODECID_AVC) || (esd->decoderConfig->objectTypeIndication==GF_CODECID_SVC)) { 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); @@ -1098,12 +1405,15 @@ 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 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); + case GF_CODECID_AAC_MPEG2_MP: + case GF_CODECID_AAC_MPEG2_LCP: + case GF_CODECID_AAC_MPEG2_SSRP: + case GF_CODECID_AAC_MPEG4: + { + GF_M4ADecSpecInfo adsi; + gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &adsi); + if (adsi.audioPL > PL) gf_isom_set_pl_indication(file, GF_ISOM_PL_AUDIO, adsi.audioPL); + } break; default: if (!PL) gf_isom_set_pl_indication(file, GF_ISOM_PL_AUDIO, 0xFE); @@ -1127,6 +1437,8 @@ void remove_systems_tracks(GF_ISOFile *file) for (i=0; iact_type = act_type; - meta->mime_type[0] = 0; - meta->enc_type[0] = 0; - meta->szName[0] = 0; - meta->szPath[0] = 0; meta->trackID = 0; meta->root_meta = 1; if (!opts) return 0; while (1) { + char *next; + char *szSlot; if (!opts || !opts[0]) return ret; if (opts[0]==':') opts += 1; - strcpy(szSlot, opts); - next = strchr(szSlot, ':'); - /*use ':' as separator, but beware DOS paths...*/ - if (next && next[1]=='\\') next = strchr(szSlot+2, ':'); + + szSlot = opts; + next = gf_url_colon_suffix(opts); if (next) next[0] = 0; if (!strnicmp(szSlot, "tk=", 3)) { @@ -1289,37 +1585,40 @@ static Bool parse_meta_args(MetaAction *meta, MetaActionType act_type, char *opt } else if (!strnicmp(szSlot, "ref=", 4)) { char type[10]; - sscanf(szSlot, "ref=%u,%s", &meta->ref_item_id, type); + sscanf(szSlot, "ref=%9s,%u", type, &meta->ref_item_id); meta->ref_type = GF_4CC(type[0], type[1], type[2], type[3]); ret = 1; - } + } else if (!strnicmp(szSlot, "name=", 5)) { - strcpy(meta->szName, szSlot+5); + meta->szName = gf_strdup(szSlot+5); ret = 1; } else if (!strnicmp(szSlot, "path=", 5)) { - strcpy(meta->szPath, szSlot+5); + meta->szPath = gf_strdup(szSlot+5); ret = 1; } else if (!strnicmp(szSlot, "mime=", 5)) { - meta->item_type = GF_4CC('m','i','m','e'); - strcpy(meta->mime_type, szSlot+5); + meta->item_type = GF_META_ITEM_TYPE_MIME; + meta->mime_type = gf_strdup(szSlot+5); ret = 1; } else if (!strnicmp(szSlot, "encoding=", 9)) { - strcpy(meta->enc_type, szSlot+9); + meta->enc_type = gf_strdup(szSlot+9); ret = 1; } else if (!strnicmp(szSlot, "image-size=", 11)) { if (!meta->image_props) { GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; } + sscanf(szSlot+11, "%dx%d", &meta->image_props->width, &meta->image_props->height); ret = 1; } else if (!strnicmp(szSlot, "image-pasp=", 11)) { if (!meta->image_props) { GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; } sscanf(szSlot+11, "%dx%d", &meta->image_props->hSpacing, &meta->image_props->vSpacing); ret = 1; @@ -1327,47 +1626,71 @@ static Bool parse_meta_args(MetaAction *meta, MetaActionType act_type, char *opt else if (!strnicmp(szSlot, "image-rloc=", 11)) { if (!meta->image_props) { GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; } sscanf(szSlot+11, "%dx%d", &meta->image_props->hOffset, &meta->image_props->vOffset); ret = 1; } - else if (!strnicmp(szSlot, "image-irot=", 11)) { + else if (!strnicmp(szSlot, "rotation=", 9)) { if (!meta->image_props) { GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; } - meta->image_props->angle = atoi(szSlot+11); + meta->image_props->angle = atoi(szSlot+9); ret = 1; } - else if (!strnicmp(szSlot, "image-hidden", 12)) { + else if (!stricmp(szSlot, "hidden")) { if (!meta->image_props) { GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; } meta->image_props->hidden = GF_TRUE; ret = 1; } - else if (!strnicmp(szSlot, "tilemode=", 9)) { + else if (!stricmp(szSlot, "alpha")) { if (!meta->image_props) { GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; } - if (!strnicmp(szSlot + 9, "nobase", 6)) { - meta->image_props->tile_mode = TILE_ITEM_ALL_NO_BASE; - } else if (!strnicmp(szSlot + 9, "base", 4)) { - meta->image_props->tile_mode = TILE_ITEM_ALL_BASE; - } else if (!strnicmp(szSlot + 9, "grid", 4)) { - meta->image_props->tile_mode = TILE_ITEM_ALL_GRID; - } else { - meta->image_props->tile_mode = TILE_ITEM_SINGLE; - sscanf(szSlot + 9, "%d", &meta->image_props->single_tile_number); - } + meta->image_props->alpha = GF_TRUE; + ret = 1; } - else if (!strnicmp(szSlot, "dref", 4)) { + else if (!strnicmp(szSlot, "time=", 5)) { + if (!meta->image_props) { + GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; + } + meta->image_props->time = atof(szSlot+5); + ret = 1; + } + else if (!stricmp(szSlot, "split_tiles")) { + if (!meta->image_props) { + GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; + } + meta->image_props->tile_mode = TILE_ITEM_ALL_BASE; + ret = 1; + } + else if (!stricmp(szSlot, "dref")) { meta->use_dref = 1; ret = 1; } + else if (!stricmp(szSlot, "primary")) { + meta->primary = 1; + ret = 1; + } else if (!stricmp(szSlot, "binary")) { if (meta->act_type==META_ACTION_SET_XML) meta->act_type=META_ACTION_SET_BINARY_XML; ret = 1; } + else if (!strnicmp(szSlot, "icc_path=", 9)) { + if (!meta->image_props) { + GF_SAFEALLOC(meta->image_props, GF_ImageItemProperties); + if (!meta->image_props) return 0; + } + strcpy(meta->image_props->iccPath, szSlot+9); + ret = 1; + } else if (!strchr(szSlot, '=')) { switch (meta->act_type) { case META_ACTION_SET_TYPE: @@ -1379,7 +1702,12 @@ static Bool parse_meta_args(MetaAction *meta, MetaActionType act_type, char *opt case META_ACTION_ADD_IMAGE_ITEM: case META_ACTION_SET_XML: case META_ACTION_DUMP_XML: - strcpy(meta->szPath, szSlot); + if (!strncmp(szSlot, "dopt", 4) || !strncmp(szSlot, "sopt", 4) || !strncmp(szSlot, "@@", 2)) { + if (next) next[0]=':'; + next=NULL; + } + //cat as -add arg + gf_dynstrcat(&meta->szPath, szSlot, ":"); ret = 1; break; case META_ACTION_REM_ITEM: @@ -1392,12 +1720,13 @@ static Bool parse_meta_args(MetaAction *meta, MetaActionType act_type, char *opt break; } } + if (!next) break; opts += strlen(szSlot); + next[0] = ':'; } return ret; } -#endif - +#endif //GPAC_DISABLE_ISOM_WRITE typedef enum { TSEL_ACTION_SET_PARAM = 0, @@ -1408,24 +1737,25 @@ typedef enum { typedef struct { TSELActionType act_type; - u32 trackID; + GF_ISOTrackID trackID; - u32 refTrackID; + GF_ISOTrackID refTrackID; u32 criteria[30]; u32 nb_criteria; Bool is_switchGroup; u32 switchGroupID; } TSELAction; +#ifndef GPAC_DISABLE_ISOM_WRITE static Bool parse_tsel_args(TSELAction **__tsel_list, char *opts, u32 *nb_tsel_act, TSELActionType act) { - u32 refTrackID = 0; + GF_ISOTrackID refTrackID = 0; Bool has_switch_id; u32 switch_id = 0; u32 criteria[30]; u32 nb_criteria = 0; TSELAction *tsel_act; - char szSlot[1024], *next; + char szSlot[1024]; TSELAction *tsel_list; has_switch_id = 0; @@ -1433,12 +1763,11 @@ static Bool parse_tsel_args(TSELAction **__tsel_list, char *opts, u32 *nb_tsel_a if (!opts) return 0; while (1) { + char *next; if (!opts || !opts[0]) return 1; if (opts[0]==':') opts += 1; strcpy(szSlot, opts); - next = strchr(szSlot, ':'); - /*use ':' as separator, but beware DOS paths...*/ - if (next && next[1]=='\\') next = strchr(szSlot+2, ':'); + next = gf_url_colon_suffix(szSlot); if (next) next[0] = 0; @@ -1488,9 +1817,15 @@ static Bool parse_tsel_args(TSELAction **__tsel_list, char *opts, u32 *nb_tsel_a } return 1; } +#endif // GPAC_DISABLE_ISOM_WRITE + +#define CHECK_NEXT_ARG if (i+1==(u32)argc) {\ + fprintf(stderr, "Missing arg - please check usage\n"); return mp4box_cleanup(1);\ + } else { \ + has_next_arg = GF_TRUE;\ + } -#define CHECK_NEXT_ARG if (i+1==(u32)argc) { fprintf(stderr, "Missing arg - please check usage\n"); return mp4box_cleanup(1); } typedef enum { TRAC_ACTION_REM_TRACK = 0, @@ -1509,23 +1844,29 @@ typedef enum { TRAC_ACTION_SET_ID = 13, TRAC_ACTION_SET_UDTA = 14, TRAC_ACTION_SWAP_ID = 15, + TRAC_ACTION_REM_NON_REFS = 16, + TRAC_ACTION_SET_CLAP = 17, + TRAC_ACTION_SET_MX = 18, } TrackActionType; typedef struct { TrackActionType act_type; - u32 trackID; + GF_ISOTrackID trackID; char lang[10]; s32 delay_ms; const char *kms; const char *hdl_name; s32 par_num, par_den; + u8 force_par, rewrite_bs; u32 dump_type, sample_num; char *out_name; char *src_name; u32 udta_type; char *kind_scheme, *kind_value; u32 newTrackID; + s32 clap_wnum, clap_wden, clap_hnum, clap_hden, clap_honum, clap_hoden, clap_vonum, clap_voden; + s32 mx[9]; } TrackAction; enum @@ -1534,7 +1875,8 @@ enum GF_ISOM_CONV_TYPE_ISMA_EX, GF_ISOM_CONV_TYPE_3GPP, GF_ISOM_CONV_TYPE_IPOD, - GF_ISOM_CONV_TYPE_PSP + GF_ISOM_CONV_TYPE_PSP, + GF_ISOM_CONV_TYPE_MOV }; @@ -1542,21 +1884,8 @@ enum GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char *name, u32 *nb_dash_inputs) { GF_DashSegmenterInput *di; - char *sep; - // skip ./ and ../, and look for first . to figure out extension - if ((name[1]=='/') || (name[2]=='/') || (name[1]=='\\') || (name[2]=='\\') ) sep = strchr(name+3, '.'); - else { - char *s2 = strchr(name, ':'); - sep = strchr(name, '.'); - if (sep && s2 && (s2 - sep) < 0) { - sep = name; - } - } - - //then look for our opt separator : - sep = strchr(sep ? sep : name, ':'); - - if (sep && (sep[1]=='\\')) sep = strchr(sep+1, ':'); + char *other_opts = NULL; + char *sep = gf_url_colon_suffix(name); dash_inputs = gf_realloc(dash_inputs, sizeof(GF_DashSegmenterInput) * (*nb_dash_inputs + 1) ); memset(&dash_inputs[*nb_dash_inputs], 0, sizeof(GF_DashSegmenterInput) ); @@ -1567,7 +1896,7 @@ GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char * char *opts, *first_opt; opts = first_opt = sep; while (opts) { - sep = strchr(opts, ':'); + sep = gf_url_colon_suffix(opts); while (sep) { /* this is a real separator if it is followed by a keyword we are looking for */ if (!strnicmp(sep, ":id=", 4) || @@ -1577,28 +1906,38 @@ GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char * !strnicmp(sep, ":bandwidth=", 11) || !strnicmp(sep, ":role=", 6) || !strnicmp(sep, ":desc", 5) || - !strnicmp(sep, ":duration=", 10) || /*legacy*/!strnicmp(sep, ":period_duration=", 10) || - !strnicmp(sep, ":xlink=", 7)) { + !strnicmp(sep, ":sscale", 7) || + !strnicmp(sep, ":duration=", 10) || + !strnicmp(sep, ":period_duration=", 10) || + !strnicmp(sep, ":pdur=", 6) || + !strnicmp(sep, ":xlink=", 7) || + !strnicmp(sep, ":asID=", 6) || + !strnicmp(sep, ":sn=", 4) || + !strnicmp(sep, ":tpl=", 5) || + !strnicmp(sep, ":hls=", 5) || + !strnicmp(sep, ":trackID=", 9) || + !strnicmp(sep, ":@@", 3) + ) { break; } else { + char *nsep = gf_url_colon_suffix(sep+1); + if (nsep) nsep[0] = 0; + + gf_dynstrcat(&other_opts, sep, ":"); + + if (nsep) nsep[0] = ':'; + sep = strchr(sep+1, ':'); } } - if (sep && !strncmp(sep, "://", 3)) sep = strchr(sep+3, ':'); + if (sep && !strncmp(sep, "://", 3) && strnicmp(sep, ":@@", 3)) sep = gf_url_colon_suffix(sep+3); if (sep) sep[0] = 0; if (!strnicmp(opts, "id=", 3)) { - u32 i; di->representationID = gf_strdup(opts+3); - /* check to see if this representation Id has already been assigned */ - for (i=0; i<(*nb_dash_inputs)-1; i++) { - GF_DashSegmenterInput *other_di; - other_di = &dash_inputs[i]; - if (!strcmp(other_di->representationID, di->representationID)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("[DASH] Error: Duplicate Representation ID \"%s\" in command line\n", di->representationID)); - } - } - } else if (!strnicmp(opts, "dur=", 4)) di->media_duration = (Double)atof(opts+4); + /*we allow the same repID to be set to force muxed representations*/ + } + else if (!strnicmp(opts, "dur=", 4)) di->media_duration = (Double)atof(opts+4); else if (!strnicmp(opts, "period=", 7)) di->periodID = gf_strdup(opts+7); else if (!strnicmp(opts, "BaseURL=", 8)) { di->baseURL = (char **)gf_realloc(di->baseURL, (di->nb_baseURL+1)*sizeof(char *)); @@ -1643,10 +1982,19 @@ GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char * } else if (!strnicmp(opts, "xlink=", 6)) di->xlink = gf_strdup(opts+6); - else if (!strnicmp(opts, "period_duration=", 16)) { - di->period_duration = (Double) atof(opts+16); - } else if (!strnicmp(opts, "duration=", 9)) { - di->period_duration = (Double) atof(opts+9); /*legacy: use period_duration instead*/ + else if (!strnicmp(opts, "sscale", 6)) di->sscale = GF_TRUE; + else if (!strnicmp(opts, "pdur=", 5)) di->period_duration = (Double) atof(opts+5); + else if (!strnicmp(opts, "period_duration=", 16)) di->period_duration = (Double) atof(opts+16); + else if (!strnicmp(opts, "duration=", 9)) di->dash_duration = (Double) atof(opts+9); + else if (!strnicmp(opts, "asID=", 5)) di->asID = atoi(opts+5); + else if (!strnicmp(opts, "sn=", 3)) di->startNumber = atoi(opts+3); + else if (!strnicmp(opts, "tpl=", 4)) di->seg_template = gf_strdup(opts+4); + else if (!strnicmp(opts, "hls=", 4)) di->hls_pl = gf_strdup(opts+4); + else if (!strnicmp(opts, "trackID=", 8)) di->track_id = atoi(opts+8); + else if (!strnicmp(opts, "@@", 2)) { + di->filter_chain = gf_strdup(opts+2); + if (sep) sep[0] = ':'; + sep = NULL; } if (!sep) break; @@ -1656,6 +2004,8 @@ GF_DashSegmenterInput *set_dash_input(GF_DashSegmenterInput *dash_inputs, char * first_opt[0] = '\0'; } di->file_name = name; + di->source_opts = other_opts; + if (!di->representationID) { char szRep[100]; sprintf(szRep, "%d", *nb_dash_inputs); @@ -1669,9 +2019,9 @@ static GF_Err parse_track_action_params(char *string, TrackAction *action) { char *param = string; if (!action || !string) return GF_BAD_PARAM; - + while (param) { - param = strchr(param, ':'); + param = gf_url_colon_suffix(param); if (param) { *param = 0; param++; @@ -1719,11 +2069,11 @@ static u32 create_new_track_action(char *string, TrackAction **actions, u32 *nb_ } #ifndef GPAC_DISABLE_CORE_TOOLS -static GF_Err nhml_bs_to_bin(char *inName, char *outName, u32 dump_std) +static GF_Err xml_bs_to_bin(char *inName, char *outName, u32 dump_std) { GF_Err e; GF_XMLNode *root; - char *data = NULL; + u8 *data = NULL; u32 data_size; GF_DOMParser *dom = gf_xml_dom_new(); @@ -1739,7 +2089,7 @@ static GF_Err nhml_bs_to_bin(char *inName, char *outName, u32 dump_std) return GF_OK; } - e = gf_xml_parse_bit_sequence(root, &data, &data_size); + e = gf_xml_parse_bit_sequence(root, inName, &data, &data_size); gf_xml_dom_del(dom); if (e) { @@ -1748,7 +2098,7 @@ static GF_Err nhml_bs_to_bin(char *inName, char *outName, u32 dump_std) } if (dump_std) { - fwrite(data, 1, data_size, stdout); + gf_fwrite(data, data_size, stdout); } else { FILE *t; char szFile[GF_MAX_PATH]; @@ -1763,7 +2113,7 @@ static GF_Err nhml_bs_to_bin(char *inName, char *outName, u32 dump_std) fprintf(stderr, "Failed to open file %s\n", szFile); e = GF_IO_ERR; } else { - if (fwrite(data, 1, data_size, t) != data_size) { + if (gf_fwrite(data, data_size, t) != data_size) { fprintf(stderr, "Failed to write output to file %s\n", szFile); e = GF_IO_ERR; } @@ -1775,6 +2125,300 @@ static GF_Err nhml_bs_to_bin(char *inName, char *outName, u32 dump_std) } #endif /*GPAC_DISABLE_CORE_TOOLS*/ +static u64 do_size_top_boxes(char *inName, char *compress_top_boxes, u32 mode) +{ + FILE *in; + u64 top_size = 0; + Bool do_all = GF_FALSE; + GF_BitStream *bs_in; + if (!compress_top_boxes) return GF_BAD_PARAM; + if (!strcmp(compress_top_boxes, "all")) + do_all = GF_TRUE; + + in = gf_fopen(inName, "rb"); + if (!in) return GF_URL_ERROR; + bs_in = gf_bs_from_file(in, GF_BITSTREAM_READ); + while (gf_bs_available(bs_in)) { + const char *stype; + u32 hdr_size = 8; + u64 lsize = gf_bs_read_u32(bs_in); + u32 type = gf_bs_read_u32(bs_in); + + if (lsize==1) { + lsize = gf_bs_read_u64(bs_in); + hdr_size = 16; + } else if (lsize==0) { + lsize = gf_bs_available(bs_in) + 8; + } + stype = gf_4cc_to_str(type); + if (do_all || strstr(compress_top_boxes, stype)) { + //only count boxes + if (mode==2) { + top_size += 1; + } else { + top_size += lsize; + } + } + gf_bs_skip_bytes(bs_in, lsize - hdr_size); + } + gf_bs_del(bs_in); + gf_fclose(in); + return top_size; + +} + +static GF_Err do_compress_top_boxes(char *inName, char *outName, char *compress_top_boxes, u32 comp_top_box_version, Bool use_lzma) +{ + FILE *in, *out; + u8 *buf; + u32 buf_alloc, comp_size, start_offset; + s32 bytes_comp=0; + s32 bytes_uncomp=0; + GF_Err e = GF_OK; + u64 source_size, dst_size; + u32 orig_box_overhead; + u32 final_box_overhead; + u32 gzip_code = use_lzma ? GF_4CC('l','z','m','a') : GF_4CC('g','z','i','p') ; + u32 nb_added_box_bytes=0; + Bool has_mov = GF_FALSE; + u32 range_idx, nb_ranges=0; + Bool replace_all = !strcmp(compress_top_boxes, "*"); + Bool requires_byte_ranges=GF_FALSE; + GF_BitStream *bs_in, *bs_out; + u32 idx_size=0, nb_moof; + struct _ranges { + u32 size, csize; + } *ranges=NULL; + + if (!outName) { + fprintf(stderr, "Missing output file name\n"); + return GF_BAD_PARAM; + } + + in = gf_fopen(inName, "rb"); + if (!in) return GF_URL_ERROR; + out = gf_fopen(outName, "wb"); + if (!out) return GF_IO_ERR; + + buf_alloc = 4096; + buf = gf_malloc(buf_alloc); + + bs_in = gf_bs_from_file(in, GF_BITSTREAM_READ); + source_size = gf_bs_get_size(bs_in); + + bs_out = gf_bs_from_file(out, GF_BITSTREAM_WRITE); + + start_offset = 0; + nb_moof = 0; + if (comp_top_box_version==2) { + u32 i; + while (gf_bs_available(bs_in)) { + u32 size = gf_bs_read_u32(bs_in); + u32 type = gf_bs_read_u32(bs_in); + const char *b4cc = gf_4cc_to_str(type); + const char *replace = strstr(compress_top_boxes, b4cc); + + if (start_offset) { + Bool compress = (replace || replace_all) ? 1 : 0; + ranges = gf_realloc(ranges, sizeof(struct _ranges)*(nb_ranges+1)); + ranges[nb_ranges].csize = compress; + ranges[nb_ranges].size = size-8; + nb_ranges++; + } + if (!strcmp(b4cc, "ftyp") || !strcmp(b4cc, "styp")) { + if (!start_offset) start_offset = (u32) gf_bs_get_position(bs_in) + size-8; + } + if (!strcmp(b4cc, "sidx") || !strcmp(b4cc, "ssix")) { + requires_byte_ranges = GF_TRUE; + } + if (!strcmp(b4cc, "moof")) + nb_moof++; + + gf_bs_skip_bytes(bs_in, size-8); + } + + gf_bs_seek(bs_in, 0); + if (buf_allocbuf_alloc) nbytes=buf_alloc; + gf_bs_read_data(bs_in, buf, nbytes); + gf_bs_write_data(bs_out, buf, nbytes); + size-=nbytes; + } + continue; + } + orig_box_overhead += size; + + if (comp_top_box_version != 1) + size-=8; + + if (size>buf_alloc) { + buf_alloc = size; + buf = gf_realloc(buf, buf_alloc); + } + gf_bs_read_data(bs_in, buf, size); + + if (comp_top_box_version != 1) + replace+=5; + + comp_size = buf_alloc; + + if (use_lzma) { + e = gf_lz_compress_payload(&buf, size, &comp_size); + } else { + e = gf_gz_compress_payload(&buf, size, &comp_size); + } + if (e) break; + + if (comp_size>buf_alloc) { + buf_alloc = comp_size; + } + bytes_uncomp += size; + bytes_comp += comp_size; + if (comp_top_box_version==1) + nb_added_box_bytes +=8; + + //write size + gf_bs_write_u32(bs_out, comp_size+8); + //write type + if (comp_top_box_version==1) + gf_bs_write_u32(bs_out, gzip_code); + else + gf_bs_write_data(bs_out, replace, 4); + //write data + gf_bs_write_data(bs_out, buf, comp_size); + + final_box_overhead += 8+comp_size; + + if (ranges) { + assert(ranges[range_idx].size == size); + ranges[range_idx].csize = comp_size; + range_idx++; + } + } + dst_size = gf_bs_get_position(bs_out); + + if (comp_top_box_version==2) { + u32 i; + gf_bs_seek(bs_out, start_offset); + gf_bs_write_u32(bs_out, idx_size); + gf_bs_write_u32(bs_out, GF_4CC('c','m','a','p')); + gf_bs_write_u32(bs_out, gzip_code); + gf_bs_write_u32(bs_out, nb_ranges); + for (i=0; i0xFFFF ? 1 : 0; + gf_bs_write_int(bs_out, ranges[i].csize ? 1 : 0, 1); + gf_bs_write_int(bs_out, large_size ? 1 : 0, 1); + gf_bs_write_int(bs_out, 0, 6); + large_size = large_size ? 32 : 16; + + gf_bs_write_int(bs_out, ranges[i].size, large_size); + if (ranges[i].csize) + gf_bs_write_int(bs_out, ranges[i].csize, large_size); + } + final_box_overhead += idx_size; + nb_added_box_bytes += idx_size; + + } + gf_bs_del(bs_in); + gf_bs_del(bs_out); + gf_fclose(in); + gf_fclose(out); + if (e) { + fprintf(stderr, "Error compressing: %s\n", gf_error_to_string(e)); + return e; + } + + if (has_mov) { + u32 i, nb_tracks, nb_samples; + GF_ISOFile *mov; + Double rate, new_rate, duration; + + mov = gf_isom_open(inName, GF_ISOM_OPEN_READ, NULL); + duration = (Double) gf_isom_get_duration(mov); + duration /= gf_isom_get_timescale(mov); + + nb_samples = 0; + nb_tracks = gf_isom_get_track_count(mov); + for (i=0; irepresentationID) gf_free(di->representationID); if (di->periodID) gf_free(di->periodID); if (di->xlink) gf_free(di->xlink); + if (di->seg_template) gf_free(di->seg_template); + if (di->hls_pl) gf_free(di->hls_pl); + if (di->source_opts) gf_free(di->source_opts); + if (di->filter_chain) gf_free(di->filter_chain); if (di->roles) { for (j = 0; jnb_roles; j++) { @@ -2006,7 +2656,7 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) u32 i = *current_index; /*parse our args*/ { - arg = argv[i]; + char *arg = argv[i]; if (!stricmp(arg, "-itags")) { CHECK_NEXT_ARG itunes_tags = argv[i + 1]; @@ -2023,6 +2673,7 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) remove_hint = 1; } else if (!stricmp(arg, "-copy")) HintCopy = 1; + else if (!stricmp(arg, "-no-offset")) hint_no_offset = GF_TRUE; else if (!stricmp(arg, "-tight")) { FullInter = 1; open_edit = GF_TRUE; @@ -2030,12 +2681,12 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) } 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")) { + else if (!stricmp(arg, "-rap") || !stricmp(arg, "-refonly")) { if ((i + 1 < (u32)argc) && (argv[i + 1][0] != '-')) { if (sscanf(argv[i + 1], "%d", &trackID) == 1) { tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act + 1)); memset(&tracks[nb_track_act], 0, sizeof(TrackAction)); - tracks[nb_track_act].act_type = TRAC_ACTION_REM_NON_RAP; + tracks[nb_track_act].act_type = !stricmp(arg, "-rap") ? TRAC_ACTION_REM_NON_RAP : TRAC_ACTION_REM_NON_REFS; tracks[nb_track_act].trackID = trackID; nb_track_act++; i++; @@ -2048,6 +2699,9 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) else if (!stricmp(arg, "-frag-rap")) { frag_at_rap = 1; } + else if (!stricmp(arg, "-mfra")) { + use_mfra = GF_TRUE; + } 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; @@ -2132,10 +2786,15 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) else if (!stricmp(arg, "-iod")) regular_iod = 1; else if (!stricmp(arg, "-flat")) { open_edit = GF_TRUE; - do_flat = GF_TRUE; + do_flat = 1; } else if (!stricmp(arg, "-keep-utc")) keep_utc = GF_TRUE; - else if (!stricmp(arg, "-new")) force_new = GF_TRUE; + else if (!stricmp(arg, "-new")) force_new = 1; + else if (!stricmp(arg, "-newfs")) { + force_new = 2; + interleaving_time = 0.5; + do_flat = 1; + } else if (!stricmp(arg, "-timescale")) { CHECK_NEXT_ARG timescale = atoi(argv[i + 1]); @@ -2156,7 +2815,7 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) nb_add++; i++; } - else if (!stricmp(arg, "-cat") || !stricmp(arg, "-catx")) { + else if (!stricmp(arg, "-cat") || !stricmp(arg, "-catx") || !stricmp(arg, "-catpl")) { CHECK_NEXT_ARG nb_cat++; i++; @@ -2194,51 +2853,130 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) nb_track_act++; i++; } - else if (!stricmp(arg, "-set-track-id") || !stricmp(arg, "-swap-track-id")) { - char *sep; + else if (!stricmp(arg, "-set-track-id") || !stricmp(arg, "-swap-track-id")) { + char *sep; + CHECK_NEXT_ARG + tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act + 1)); + memset(&tracks[nb_track_act], 0, sizeof(TrackAction)); + tracks[nb_track_act].act_type = !stricmp(arg, "-set-track-id") ? TRAC_ACTION_SET_ID : TRAC_ACTION_SWAP_ID; + sep = strchr(argv[i + 1], ':'); + if (!sep) { + fprintf(stderr, "Bad format for -set-track-id - expecting \"id1:id2\" got \"%s\"\n", argv[i + 1]); + return 2; + } + *sep = 0; + tracks[nb_track_act].trackID = atoi(argv[i + 1]); + *sep = ':'; + sep++; + tracks[nb_track_act].newTrackID = atoi(sep); + open_edit = GF_TRUE; + nb_track_act++; + i++; + } + else if (!stricmp(arg, "-par")) { + char szTK[20], *ext; + CHECK_NEXT_ARG + tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act + 1)); + memset(&tracks[nb_track_act], 0, sizeof(TrackAction)); + + tracks[nb_track_act].act_type = TRAC_ACTION_SET_PAR; + assert(strlen(argv[i + 1]) + 1 <= sizeof(szTK)); + strncpy(szTK, argv[i + 1], sizeof(szTK)); + ext = strchr(szTK, '='); + if (!ext) { + fprintf(stderr, "Bad format for track par - expecting tkID=none or tkID=PAR_NUM:PAR_DEN got %s\n", argv[i + 1]); + return 2; + } + if (!stricmp(ext + 1, "none")) { + tracks[nb_track_act].par_num = tracks[nb_track_act].par_den = 0; + } + else if (!stricmp(ext + 1, "auto")) { + tracks[nb_track_act].par_num = tracks[nb_track_act].par_den = -1; + tracks[nb_track_act].force_par = 1; + } + else if (!stricmp(ext + 1, "force")) { + tracks[nb_track_act].par_num = tracks[nb_track_act].par_den = 1; + tracks[nb_track_act].force_par = 1; + } + else { + if (ext[1]=='w') { + tracks[nb_track_act].rewrite_bs = 1; + ext++; + } + sscanf(ext + 1, "%d", &tracks[nb_track_act].par_num); + ext = strchr(ext + 1, ':'); + if (!ext) { + fprintf(stderr, "Bad format for track par - expecting tkID=PAR_NUM:PAR_DEN got %s\n", argv[i + 1]); + return 2; + } + sscanf(ext + 1, "%d", &tracks[nb_track_act].par_den); + } + ext[0] = 0; + tracks[nb_track_act].trackID = atoi(szTK); + open_edit = GF_TRUE; + nb_track_act++; + i++; + } + else if (!stricmp(arg, "-clap")) { + char szTK[200], *ext; + TrackAction *tka; CHECK_NEXT_ARG tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act + 1)); memset(&tracks[nb_track_act], 0, sizeof(TrackAction)); - tracks[nb_track_act].act_type = !stricmp(arg, "-set-track-id") ? TRAC_ACTION_SET_ID : TRAC_ACTION_SWAP_ID; - sep = strchr(argv[i + 1], ':'); - if (!sep) { - fprintf(stderr, "Bad format for -set-track-id - expecting \"id1:id2\" got \"%s\"\n", argv[i + 1]); + + tracks[nb_track_act].act_type = TRAC_ACTION_SET_CLAP; + assert(strlen(argv[i + 1]) + 1 <= sizeof(szTK)); + strncpy(szTK, argv[i + 1], sizeof(szTK)); + ext = strchr(szTK, '='); + if (!ext) { + fprintf(stderr, "Bad format for track clap - expecting tkID=none or tkID=Wn,Wd,Hn,Hd,HOn,HOd,VOn,VOd got %s\n", argv[i + 1]); return 2; } - *sep = 0; - tracks[nb_track_act].trackID = atoi(argv[i + 1]); - *sep = ':'; - sep++; - tracks[nb_track_act].newTrackID = atoi(sep); + tka = &tracks[nb_track_act]; + if (!stricmp(ext + 1, "none")) { + tka->clap_wnum= tka->clap_wden = tka->clap_hnum = tka->clap_hden = tka->clap_honum = tka->clap_hoden = tka->clap_vonum = tka->clap_voden = 0; + } else { + if (sscanf(ext + 1, "%d,%d,%d,%d,%d,%d,%d,%d", &tka->clap_wnum, &tka->clap_wden, &tka->clap_hnum, &tka->clap_hden, &tka->clap_honum, &tka->clap_hoden, &tka->clap_vonum, &tka->clap_voden) != 8) { + + fprintf(stderr, "Bad format for track clap - expecting tkID=none or tkID=Wn,Wd,Hn,Hd,HOn,HOd,VOn,VOd got %s\n", argv[i + 1]); + return 2; + } + } + ext[0] = 0; + tracks[nb_track_act].trackID = atoi(szTK); open_edit = GF_TRUE; nb_track_act++; i++; } - else if (!stricmp(arg, "-par")) { - char szTK[20], *ext; + else if (!stricmp(arg, "-mx")) { + char szTK[200], *ext; + TrackAction *tka; CHECK_NEXT_ARG tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act + 1)); memset(&tracks[nb_track_act], 0, sizeof(TrackAction)); - tracks[nb_track_act].act_type = TRAC_ACTION_SET_PAR; + tracks[nb_track_act].act_type = TRAC_ACTION_SET_MX; assert(strlen(argv[i + 1]) + 1 <= sizeof(szTK)); strncpy(szTK, argv[i + 1], sizeof(szTK)); ext = strchr(szTK, '='); if (!ext) { - fprintf(stderr, "Bad format for track par - expecting ID=PAR_NUM:PAR_DEN got %s\n", argv[i + 1]); + fprintf(stderr, "Bad format for track matrix - expecting ID=none or ID=M1:M2:M3:M4:M5:M6:M7:M8:M9 got %s\n", argv[i + 1]); return 2; } + tka = &tracks[nb_track_act]; if (!stricmp(ext + 1, "none")) { - tracks[nb_track_act].par_num = tracks[nb_track_act].par_den = -1; - } - else { - sscanf(ext + 1, "%d", &tracks[nb_track_act].par_num); - ext = strchr(ext + 1, ':'); - if (!ext) { - fprintf(stderr, "Bad format for track par - expecting ID=PAR_NUM:PAR_DEN got %s\n", argv[i + 1]); + memset(tka->mx, 0, sizeof(s32)*9); + } else { + s32 res; + if (strstr(ext+1, "0x")) { + res = sscanf(ext + 1, "0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d:0x%d", &tka->mx[0], &tka->mx[1], &tka->mx[2], &tka->mx[3], &tka->mx[4], &tka->mx[5], &tka->mx[6], &tka->mx[7], &tka->mx[8]); + } else { + res = sscanf(ext + 1, "%d:%d:%d:%d:%d:%d:%d:%d:%d", &tka->mx[0], &tka->mx[1], &tka->mx[2], &tka->mx[3], &tka->mx[4], &tka->mx[5], &tka->mx[6], &tka->mx[7], &tka->mx[8]); + } + if (res != 9) { + fprintf(stderr, "Bad format for track matrix - expecting ID=none or ID=M1:M2:M3:M4:M5:M6:M7:M8:M9 got %s\n", argv[i + 1]); return 2; } - sscanf(ext + 1, "%d", &tracks[nb_track_act].par_den); } ext[0] = 0; tracks[nb_track_act].trackID = atoi(szTK); @@ -2246,6 +2984,27 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) nb_track_act++; i++; } + else if (!stricmp(arg, "-hdr")) { + CHECK_NEXT_ARG + high_dynamc_range_filename = argv[i + 1]; + i++; + } + else if (!stricmp(arg, "-bo")) { + freeze_box_order = GF_TRUE; + } + else if (!stricmp(arg, "-patch")) { + CHECK_NEXT_ARG + box_patch_filename = argv[i + 1]; + char *sep = strchr(box_patch_filename, '='); + if (sep) { + sep[0] = 0; + box_patch_trackID = atoi(box_patch_filename); + sep[0] = '='; + box_patch_filename = sep+1; + } + open_edit = GF_TRUE; + i++; + } else if (!stricmp(arg, "-lang")) { char szTK[20], *ext; CHECK_NEXT_ARG @@ -2254,7 +3013,8 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) tracks[nb_track_act].act_type = TRAC_ACTION_SET_LANGUAGE; tracks[nb_track_act].trackID = 0; - strcpy(szTK, argv[i + 1]); + strncpy(szTK, argv[i + 1], sizeof(szTK)-1); + szTK[sizeof(szTK)-1] = 0; ext = strchr(szTK, '='); if (!strnicmp(argv[i + 1], "all=", 4)) { strncpy(tracks[nb_track_act].lang, argv[i + 1] + 4, 10); @@ -2332,10 +3092,11 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act + 1)); memset(&tracks[nb_track_act], 0, sizeof(TrackAction)); - strcpy(szTK, argv[i + 1]); + strncpy(szTK, argv[i + 1], sizeof(szTK)-1); + szTK[sizeof(szTK)-1] = 0; ext = strchr(szTK, '='); if (!ext) { - fprintf(stderr, "Bad format for track delay - expecting ID=DLAY got %s\n", argv[i + 1]); + fprintf(stderr, "Bad format for track delay - expecting tkID=DLAY got %s\n", argv[i + 1]); return 2; } tracks[nb_track_act].act_type = TRAC_ACTION_SET_DELAY; @@ -2355,7 +3116,7 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) szTK = argv[i + 1]; ext = strchr(szTK, ':'); if (!ext) { - fprintf(stderr, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i + 1]); + fprintf(stderr, "Bad format for track reference - expecting tkID:XXXX:refID got %s\n", argv[i + 1]); return 2; } tracks[nb_track_act].act_type = TRAC_ACTION_REFERENCE; @@ -2365,7 +3126,7 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) szTK = ext + 1; ext = strchr(szTK, ':'); if (!ext) { - fprintf(stderr, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i + 1]); + fprintf(stderr, "Bad format for track reference - expecting tkID:XXXX:refID got %s\n", argv[i + 1]); return 2; } ext[0] = 0; @@ -2382,10 +3143,11 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act + 1)); memset(&tracks[nb_track_act], 0, sizeof(TrackAction)); - strcpy(szTK, argv[i + 1]); + strncpy(szTK, argv[i + 1], sizeof(szTK)-1); + szTK[sizeof(szTK)-1] = 0; ext = strchr(szTK, '='); if (!ext) { - fprintf(stderr, "Bad format for track name - expecting ID=name got %s\n", argv[i + 1]); + fprintf(stderr, "Bad format for track name - expecting tkID=name got %s\n", argv[i + 1]); return 2; } tracks[nb_track_act].act_type = TRAC_ACTION_SET_HANDLER_NAME; @@ -2408,22 +3170,23 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) 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 = GF_IMPORT_AUTO_FPS; + if (!strcmp(argv[i + 1], "auto")) { fprintf(stderr, "Warning, fps=auto option is deprecated\n"); } else if (strchr(argv[i + 1], '-')) { u32 ticks, dts_inc; sscanf(argv[i + 1], "%u-%u", &ticks, &dts_inc); if (!dts_inc) dts_inc = 1; - import_fps = ticks; - import_fps /= dts_inc; + import_fps.num = ticks; + import_fps.den = dts_inc; + } else { + import_fps.num = (s32) (1000 * atof(argv[i + 1])); + import_fps.den = 1000; } - 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-all") || !stricmp(arg, "-keepall")) import_flags |= GF_IMPORT_KEEP_ALL_TRACKS; #endif /*!defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_MEDIA_IMPORT*/ else if (!stricmp(arg, "-keep-sys") || !stricmp(arg, "-keepsys")) keep_sys_tracks = 1; else if (!stricmp(arg, "-ms")) { @@ -2437,8 +3200,8 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) else if (!stricmp(arg, "-saf")) { do_saf = GF_TRUE; } - else if (!stricmp(arg, "-log")) { - do_log = GF_TRUE; + else if (!stricmp(arg, "-sclog")) { + do_scene_log = GF_TRUE; } #ifndef GPAC_DISABLE_MPD else if (!stricmp(arg, "-mpd")) { @@ -2450,54 +3213,54 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) #endif #ifndef GPAC_DISABLE_SCENE_ENCODER - else if (!stricmp(arg, "-def")) opts.flags |= GF_SM_ENCODE_USE_NAMES; + else if (!stricmp(arg, "-def")) smenc_opts.flags |= GF_SM_ENCODE_USE_NAMES; else if (!stricmp(arg, "-sync")) { CHECK_NEXT_ARG - opts.flags |= GF_SM_ENCODE_RAP_INBAND; - opts.rap_freq = atoi(argv[i + 1]); + smenc_opts.flags |= GF_SM_ENCODE_RAP_INBAND; + smenc_opts.rap_freq = atoi(argv[i + 1]); i++; } else if (!stricmp(arg, "-shadow")) { CHECK_NEXT_ARG - opts.flags &= ~GF_SM_ENCODE_RAP_INBAND; - opts.flags |= GF_SM_ENCODE_RAP_SHADOW; - opts.rap_freq = atoi(argv[i + 1]); + smenc_opts.flags &= ~GF_SM_ENCODE_RAP_INBAND; + smenc_opts.flags |= GF_SM_ENCODE_RAP_SHADOW; + smenc_opts.rap_freq = atoi(argv[i + 1]); i++; } else if (!stricmp(arg, "-carousel")) { CHECK_NEXT_ARG - opts.flags &= ~(GF_SM_ENCODE_RAP_INBAND | GF_SM_ENCODE_RAP_SHADOW); - opts.rap_freq = atoi(argv[i + 1]); + smenc_opts.flags &= ~(GF_SM_ENCODE_RAP_INBAND | GF_SM_ENCODE_RAP_SHADOW); + smenc_opts.rap_freq = atoi(argv[i + 1]); i++; } /*LASeR options*/ else if (!stricmp(arg, "-resolution")) { CHECK_NEXT_ARG - opts.resolution = atoi(argv[i + 1]); + smenc_opts.resolution = atoi(argv[i + 1]); i++; } #ifndef GPAC_DISABLE_SCENE_STATS else if (!stricmp(arg, "-auto-quant")) { CHECK_NEXT_ARG - opts.resolution = atoi(argv[i + 1]); - opts.auto_quant = 1; + smenc_opts.resolution = atoi(argv[i + 1]); + smenc_opts.auto_quant = 1; i++; } #endif else if (!stricmp(arg, "-coord-bits")) { CHECK_NEXT_ARG - opts.coord_bits = atoi(argv[i + 1]); + smenc_opts.coord_bits = atoi(argv[i + 1]); i++; } else if (!stricmp(arg, "-scale-bits")) { CHECK_NEXT_ARG - opts.scale_bits = atoi(argv[i + 1]); + smenc_opts.scale_bits = atoi(argv[i + 1]); i++; } else if (!stricmp(arg, "-global-quant")) { CHECK_NEXT_ARG - opts.resolution = atoi(argv[i + 1]); - opts.auto_quant = 2; + smenc_opts.resolution = atoi(argv[i + 1]); + smenc_opts.auto_quant = 2; i++; } /*chunk encoding*/ @@ -2513,6 +3276,8 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) i++; } #endif /*GPAC_DISABLE_SCENE_ENCODER*/ + +#ifndef GPAC_DISABLE_ISOM_WRITE else if (!strcmp(arg, "-crypt")) { CHECK_NEXT_ARG crypt = 1; @@ -2558,7 +3323,7 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) else if (!stricmp(arg, "-split")) { CHECK_NEXT_ARG split_duration = atof(argv[i + 1]); - if (split_duration < 0) split_duration = 0;; + if (split_duration < 0) split_duration = 0; i++; split_size = 0; } @@ -2580,12 +3345,22 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) return 2; } if (strstr(argv[i + 1], "end")) { - sscanf(argv[i + 1], "%lf:end", &split_start); - split_duration = -2; + if (strstr(argv[i + 1], "end-")) { + Double dur_end=0; + sscanf(argv[i + 1], "%lf:end-%lf", &split_start, &dur_end); + split_duration = -2 - dur_end; + } else { + sscanf(argv[i + 1], "%lf:end", &split_start); + split_duration = -2; + } } else { - sscanf(argv[i + 1], "%lf:%lf", &split_start, &split_duration); - split_duration -= split_start; + if (strchr(argv[i + 1], '-')) { + split_range_str = argv[i + 1]; + } else { + sscanf(argv[i + 1], "%lf:%lf", &split_start, &split_duration); + split_duration -= split_start; + } } split_size = 0; if (!stricmp(arg, "-splitz")) adjust_split_end = 1; @@ -2652,7 +3427,7 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) nb_meta_act++; i++; } - else if (!stricmp(arg, "-group-add") || !stricmp(arg, "-group-rem-track") || !stricmp(arg, "-group-rem") || !stricmp(arg, "-group-clean")) { + else if (!stricmp(arg, "-group-add") || !stricmp(arg, "-group-rem-track") || !stricmp(arg, "-group-rem") ) { TSELActionType act_type; if (!stricmp(arg, "-group-rem")) { act_type = TSEL_ACTION_REMOVE_ALL_TSEL_IN_GROUP; @@ -2682,6 +3457,9 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) pack_file = argv[i + 1]; i++; } + else if (!stricmp(arg, "-zmov")) { + compress_moov = GF_TRUE; + } else if (!stricmp(arg, "-mgt")) { CHECK_NEXT_ARG pack_file = argv[i + 1]; @@ -2693,7 +3471,12 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) CHECK_NEXT_ARG major_brand = GF_4CC(b[0], b[1], b[2], b[3]); open_edit = GF_TRUE; - if (b[4] == ':') minor_version = atoi(b + 5); + if (b[4] == ':') { + if (!strncmp(b+5, "0x", 2)) + sscanf(b+5, "0x%x", &minor_version); + else + minor_version = atoi(b + 5); + } i++; } else if (!stricmp(arg, "-ab")) { @@ -2715,62 +3498,177 @@ u32 mp4box_parse_args_continue(int argc, char **argv, u32 *current_index) i++; } #endif -else if (!stricmp(arg, "-languages")) { - PrintLanguages(); - return 1; -} -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], "dash")) PrintDASHUsage(); - else if (!strcmp(argv[i + 1], "dump")) PrintDumpUsage(); - else if (!strcmp(argv[i + 1], "import")) PrintImportUsage(); - else if (!strcmp(argv[i + 1], "format")) PrintFormats(); - 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(); - else if (!strcmp(argv[i + 1], "swf")) PrintSWFUsage(); + else if (!stricmp(arg, "-languages")) { + PrintLanguages(); + return 1; + } + else if (!stricmp(arg, "-h")) { + gf_sys_set_args(argc, (const char**) argv); + + if (i + 1 == (u32)argc) PrintUsage(); + else if (!strcmp(argv[i + 1], "general")) PrintGeneralUsage(); + else if (!strcmp(argv[i + 1], "extract")) PrintExtractUsage(); + else if (!strcmp(argv[i + 1], "dash")) PrintDASHUsage(); + else if (!strcmp(argv[i + 1], "dump")) PrintDumpUsage(); + else if (!strcmp(argv[i + 1], "import")) PrintImportUsage(); + else if (!strcmp(argv[i + 1], "format")) fprintf(stderr, "deprectaed, see [filters documentation](Filters)\n"); + 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(); + else if (!strcmp(argv[i + 1], "swf")) PrintSWFUsage(); #if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) - else if (!strcmp(argv[i + 1], "rtp")) PrintStreamerUsage(); - else if (!strcmp(argv[i + 1], "live")) PrintLiveUsage(); + else if (!strcmp(argv[i + 1], "rtp")) fprintf(stderr, "RTP streaming deprecated in MP4Box, use gpac application\n"); + else if (!strcmp(argv[i + 1], "live")) PrintLiveUsage(); #endif - else if (!strcmp(argv[i + 1], "all")) { - PrintGeneralUsage(); - PrintExtractUsage(); - PrintDASHUsage(); - PrintDumpUsage(); - PrintImportUsage(); - PrintFormats(); - PrintHintUsage(); - PrintEncodeUsage(); - PrintEncryptUsage(); - PrintMetaUsage(); - PrintSWFUsage(); + else if (!strcmp(argv[i + 1], "core")) PrintCoreUsage(); + else if (!strcmp(argv[i + 1], "all")) { + PrintGeneralUsage(); + PrintExtractUsage(); + PrintDASHUsage(); + PrintDumpUsage(); + PrintImportUsage(); + PrintHintUsage(); + PrintEncodeUsage(); + PrintEncryptUsage(); + PrintMetaUsage(); + PrintSWFUsage(); #if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) - PrintStreamerUsage(); - PrintLiveUsage(); + PrintLiveUsage(); #endif + PrintCoreUsage(); + } else if (!strcmp(argv[i + 1], "opts")) { + PrintHelp("@", GF_FALSE, GF_FALSE); + } else { + PrintHelp(argv[i+1], GF_FALSE, GF_FALSE); + } + return 1; + } + else if (!stricmp(arg, "-hx")) { + if (i + 1 == (u32)argc) PrintUsage(); + else PrintHelp(argv[i+1], GF_TRUE, GF_FALSE); + return 1; + } + else if (!strcmp(arg, "-genmd")) { + help_flags = GF_PRINTARG_MD | GF_PRINTARG_IS_APP; + helpout = gf_fopen("mp4box-gen-opts.md", "w"); + + fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » General"); + fprintf(helpout, "\n"); + fprintf(helpout, "# Syntax\n"); + gf_sys_format_help(helpout, help_flags, "MP4Box [option] input [option] [other_dash_inputs]\n" + " \n" + ); + PrintGeneralUsage(); + PrintEncryptUsage(); + fprintf(helpout, "# Help Options\n"); + while (m4b_usage_args[i].name) { + GF_GPACArg *g_arg = &m4b_usage_args[i]; + i++; + gf_sys_print_arg(helpout, help_flags, g_arg, "mp4box-general"); + } + + gf_fclose(helpout); + + helpout = gf_fopen("mp4box-import-opts.md", "w"); + fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Media Import"); + fprintf(helpout, "\n"); + PrintImportUsage(); + gf_fclose(helpout); + + helpout = gf_fopen("mp4box-dash-opts.md", "w"); + fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Media DASH"); + fprintf(helpout, "\n"); + PrintDASHUsage(); + gf_fclose(helpout); + + helpout = gf_fopen("mp4box-dump-opts.md", "w"); + fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Media Dump and Export"); + fprintf(helpout, "\n"); + PrintExtractUsage(); + PrintDumpUsage(); + gf_fclose(helpout); + + helpout = gf_fopen("mp4box-meta-opts.md", "w"); + fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Meta and HEIF/IFF"); + fprintf(helpout, "\n"); + PrintMetaUsage(); + gf_fclose(helpout); + + + helpout = gf_fopen("mp4box-scene-opts.md", "w"); + fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Scene Description"); + fprintf(helpout, "\n"); + PrintEncodeUsage(); +#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) + PrintLiveUsage(); +#endif + PrintSWFUsage(); + gf_fclose(helpout); + + helpout = gf_fopen("mp4box-other-opts.md", "w"); + fprintf(helpout, "[**HOME**](Home) » [**MP4Box**](MP4Box) » Other Features"); + fprintf(helpout, "\n"); + PrintHintUsage(); + gf_fclose(helpout); + + gf_sys_close(); + return 1; + } else if (!strcmp(arg, "-genman")) { + help_flags = GF_PRINTARG_MAN; + helpout = gf_fopen("mp4box.1", "w"); + + + fprintf(helpout, ".TH MP4Box 1 2019 MP4Box GPAC\n"); + fprintf(helpout, ".\n.SH NAME\n.LP\nMP4Box \\- GPAC command-line media packager\n.SH SYNOPSIS\n.LP\n.B MP4Box\n.RI [options] \\ [file] \\ [options]\n.br\n.\n"); + + PrintGeneralUsage(); + PrintExtractUsage(); + PrintDASHUsage(); + PrintDumpUsage(); + PrintImportUsage(); + PrintHintUsage(); + PrintEncodeUsage(); + PrintEncryptUsage(); + PrintMetaUsage(); + PrintSWFUsage(); +#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) + PrintLiveUsage(); +#endif + + fprintf(helpout, ".SH EXAMPLES\n.TP\nBasic and advanced examples are available at https://wiki.gpac.io/MP4Box-Introduction\n"); + fprintf(helpout, ".SH MORE\n.LP\nAuthors: GPAC developers, see git repo history (-log)\n" + ".br\nFor bug reports, feature requests, more information and source code, visit http://github.com/gpac/gpac\n" + ".br\nbuild: %s\n" + ".br\nCopyright: %s\n.br\n" + ".SH SEE ALSO\n" + ".LP\ngpac(1), MP4Client(1)\n", gf_gpac_version(), gf_gpac_copyright()); + + gf_fclose(helpout); + gf_sys_close(); + return 1; + } + + else if (!stricmp(arg, "-v")) verbose++; + else if (!stricmp(arg, "-tag-list")) { + fprintf(stderr, "Supported iTunes tag modifiers:\n"); + for (i = 0; i < nb_itunes_tags; i++) { + fprintf(stderr, "\t%s\t%s\n", itags[i].name, itags[i].comment); + } + return 1; + } + else if (!live_scene) { + u32 res = gf_sys_is_gpac_arg(arg); + if (res==0) { + PrintHelp(arg, GF_FALSE, GF_TRUE); + return 2; + } else if (res==2) { + i++; + } + } } - else PrintUsage(); - return 1; -} -else if (!stricmp(arg, "-v")) verbose++; -else if (!stricmp(arg, "-tag-list")) { - fprintf(stderr, "Supported iTunes tag modifiers:\n"); - for (i = 0; i < nb_itunes_tags; i++) { - fprintf(stderr, "\t%s\t%s\n", itags[i].name, itags[i].comment); - } - return 1; -} -else if (!live_scene && !stream_rtp) { - fprintf(stderr, "Option %s unknown. Please check usage\n", arg); - return 2; -} -} -*current_index = i; -return 0; + *current_index = i; + return 0; } Bool mp4box_parse_args(int argc, char **argv) @@ -2778,7 +3676,7 @@ Bool mp4box_parse_args(int argc, char **argv) u32 i; /*parse our args*/ for (i = 1; i < (u32)argc; i++) { - arg = argv[i]; + char *arg = argv[i]; /*input file(s)*/ if ((arg[0] != '-') || !stricmp(arg, "--")) { char *arg_val = arg; @@ -2816,54 +3714,39 @@ Bool mp4box_parse_args(int argc, char **argv) return 1; } else if (!stricmp(arg, "-sdp")) print_sdp = 1; - else if (!stricmp(arg, "-quiet")) quiet = 2; else if (!strcmp(argv[i], "-mem-track")) continue; else if (!strcmp(argv[i], "-mem-track-stack")) continue; - - else if (!stricmp(arg, "-logs")) { - CHECK_NEXT_ARG - gf_logs = argv[i + 1]; - if (gf_logs) - gf_log_set_tools_levels(gf_logs); - i++; + else if (!strcmp(argv[i], "-p")) { + i++; + continue; } - else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) { - logfile = gf_fopen(argv[i + 1], "wt"); - gf_log_set_callback(logfile, on_gpac_log); + else if (!strncmp(argv[i], "-p=", 3)) continue; + else if (!stricmp(arg, "-logs") || !strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) { i++; } - else if (!strcmp(arg, "-lc") || !strcmp(arg, "-log-clock")) { - log_sys_clock = GF_TRUE; - } - else if (!strcmp(arg, "-lu") || !strcmp(arg, "-log-utc")) { - log_utc_time = GF_TRUE; - } - else if (!stricmp(arg, "-noprog")) quiet = 1; - else if (!stricmp(arg, "-info")) { + else if (!stricmp(arg, "-tracks")) get_nb_tracks = 1; + else if (!stricmp(arg, "-info") || !stricmp(arg, "-infon")) { print_info = 1; if ((i + 1<(u32)argc) && (sscanf(argv[i + 1], "%u", &info_track_id) == 1)) { char szTk[20]; sprintf(szTk, "%u", info_track_id); if (!strcmp(szTk, argv[i + 1])) i++; else info_track_id = 0; + + if (!stricmp(arg, "-infon")) print_info = 2; } else { info_track_id = 0; } } -#if !defined(GPAC_DISABLE_STREAMING) else if (!stricmp(arg, "-grab-ts")) { - CHECK_NEXT_ARG - grab_m2ts = argv[i + 1]; - i++; + fprintf(stderr, "Deprecated option - use gpac application\n"); + return mp4box_cleanup(2); } - else if (!stricmp(arg, "-ifce")) { - CHECK_NEXT_ARG - grab_ifce = argv[i + 1]; - i++; + else if (!stricmp(arg, "-atsc")) { + fprintf(stderr, "Deprecated option - use gpac application\n"); + return mp4box_cleanup(2); } - -#endif #if !defined(GPAC_DISABLE_CORE_TOOLS) else if (!stricmp(arg, "-wget")) { CHECK_NEXT_ARG @@ -2933,12 +3816,14 @@ Bool mp4box_parse_args(int argc, char **argv) else if (!stricmp(arg, "-avi")) { CHECK_NEXT_ARG track_dump_type = create_new_track_action(argv[i + 1], &tracks, &nb_track_act, GF_EXPORT_AVI); - i++; + if (tracks[nb_track_act-1].trackID) + i++; } #endif /*GPAC_DISABLE_MEDIA_EXPORT*/ #if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) else if (!stricmp(arg, "-rtp")) { - stream_rtp = GF_TRUE; + fprintf(stderr, "Deprecated option - use gpac application\n"); + return mp4box_cleanup(2); } else if (!stricmp(arg, "-live")) { live_scene = GF_TRUE; @@ -2958,29 +3843,36 @@ Bool mp4box_parse_args(int argc, char **argv) PrintNode(argv[i + 1], 1); return 1; } - else if (!stricmp(arg, "-nodes")) { - PrintBuiltInNodes(0); + else if (!stricmp(arg, "-nodes") || !stricmp(arg, "-nodex")) { + PrintBuiltInNodes(0, !stricmp(arg, "-nodex") ? GF_TRUE : GF_FALSE); return 1; } - else if (!stricmp(arg, "-xnodes")) { - PrintBuiltInNodes(1); + else if (!stricmp(arg, "-xnodes") || !stricmp(arg, "-xnodex")) { + PrintBuiltInNodes(1, !stricmp(arg, "-xnodex") ? GF_TRUE : GF_FALSE); return 1; } #endif #ifndef GPAC_DISABLE_SVG else if (!stricmp(arg, "-snodes")) { - PrintBuiltInNodes(2); + PrintBuiltInNodes(2, GF_FALSE); return 1; } #endif - else if (!stricmp(arg, "-boxes")) { - PrintBuiltInBoxes(); + else if (!stricmp(arg, "-boxcov")) { + gf_sys_set_args(argc, (const char **) argv); + PrintBuiltInBoxes(GF_TRUE); + return 1; + } else if (!stricmp(arg, "-boxes")) { + PrintBuiltInBoxes(GF_FALSE); return 1; } else if (!stricmp(arg, "-std")) dump_std = 2; else if (!stricmp(arg, "-stdb")) dump_std = 1; + else if (!stricmp(arg, "-fstat")) fs_dump_flags |= 1; + else if (!stricmp(arg, "-fgraph")) fs_dump_flags |= 1<<1; #if !defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_SCENE_DUMP) + else if (!stricmp(arg, "-keep-ods")) no_odf_conf = GF_TRUE; else if (!stricmp(arg, "-bt")) dump_mode = GF_SM_DUMP_BT; else if (!stricmp(arg, "-xmt")) dump_mode = GF_SM_DUMP_XMTA; else if (!stricmp(arg, "-wrl")) dump_mode = GF_SM_DUMP_VRML; @@ -2995,12 +3887,45 @@ Bool mp4box_parse_args(int argc, char **argv) else if (!stricmp(arg, "-statx")) stat_level = 3; else if (!stricmp(arg, "-diso")) dump_isom = 1; else if (!stricmp(arg, "-dxml")) dump_isom = 2; + else if (!stricmp(arg, "-disox")) dump_isom = 3; + else if (!stricmp(arg, "-mergevtt")) merge_vtt_cues = GF_TRUE; else if (!stricmp(arg, "-dump-cover")) dump_cart = 1; else if (!stricmp(arg, "-dump-chap")) dump_chap = 1; else if (!stricmp(arg, "-dump-chap-ogg")) dump_chap = 2; + else if (!stricmp(arg, "-dump-chap-zoom")) dump_chap = 3; else if (!stricmp(arg, "-hash")) do_hash = GF_TRUE; + else if (!strnicmp(arg, "-comp", 5)) { + CHECK_NEXT_ARG + + if (strchr(arg, 'x')) comp_top_box_version = 1; + else if (strchr(arg, 'f')) comp_top_box_version = 2; + + if (strchr(arg, 'l')) comp_lzma = GF_TRUE; + + compress_top_boxes = argv[i + 1]; + i++; + } + else if (!strnicmp(arg, "-topsize", 8)) { + CHECK_NEXT_ARG + size_top_box = 1; + compress_top_boxes = argv[i + 1]; + i++; + } + else if (!strnicmp(arg, "-topcount", 8)) { + CHECK_NEXT_ARG + size_top_box = 2; + compress_top_boxes = argv[i + 1]; + i++; + } + else if (!stricmp(arg, "-mpd-rip")) do_mpd_rip = GF_TRUE; + else if (!strcmp(arg, "-init-seg")) { + CHECK_NEXT_ARG + use_init_seg = argv[i + 1]; + i += 1; + } + #ifndef GPAC_DISABLE_CORE_TOOLS - else if (!stricmp(arg, "-bin")) do_bin_nhml = GF_TRUE; + else if (!stricmp(arg, "-bin")) do_bin_xml = GF_TRUE; #endif else if (!stricmp(arg, "-dump-udta")) { char *sep, *code; @@ -3015,7 +3940,20 @@ Bool mp4box_parse_args(int argc, char **argv) else { code = argv[i + 1]; } - dump_udta_type = GF_4CC(code[0], code[1], code[2], code[3]); + if (strlen(code) == 4) { + dump_udta_type = GF_4CC(code[0], code[1], code[2], code[3]); + } else if (strlen(code) == 8) { + // hex representation on 8 chars + u32 hex1, hex2, hex3, hex4; + if (sscanf(code, "%02x%02x%02x%02x", &hex1, &hex2, &hex3, &hex4) != 4) { + fprintf(stderr, "udta code is either a 4CC or 8 hex chars for non-printable 4CC\n"); + return mp4box_cleanup(1); + } + dump_udta_type = GF_4CC(hex1, hex2, hex3, hex4); + } else { + fprintf(stderr, "udta code is either a 4CC or 8 hex chars for non-printable 4CC\n"); + return mp4box_cleanup(1); + } i++; } else if (!stricmp(arg, "-dmp4")) { @@ -3032,9 +3970,31 @@ Bool mp4box_parse_args(int argc, char **argv) } } } - else if (!stricmp(arg, "-dnal")) { + else if (!stricmp(arg, "-dtsx")) { + dump_timestamps = 2; + } + else if (!stricmp(arg, "-dtsc")) { + dump_timestamps = 3; + } + else if (!stricmp(arg, "-dtsxc")) { + dump_timestamps = 4; + } + else if (!strnicmp(arg, "-dnal", 5)) { CHECK_NEXT_ARG dump_nal = atoi(argv[i + 1]); + if (arg[5] == 'c') dump_nal_type |= 1; + else if (arg[5] == 'd') dump_nal_type |= 2; + else if (arg[5] == 'x') dump_nal_type |= 2|1; + i++; + } + else if (!strnicmp(arg, "-dsap", 5)) { + CHECK_NEXT_ARG + dump_saps = atoi(argv[i + 1]); + if (!stricmp(arg, "-dsaps")) dump_saps_mode = 1; + else if (!stricmp(arg, "-dsapc")) dump_saps_mode = 2; + else if (!stricmp(arg, "-dsapd")) dump_saps_mode = 3; + else if (!stricmp(arg, "-dsapp")) dump_saps_mode = 4; + else dump_saps_mode = 0; i++; } else if (!stricmp(arg, "-dcr")) dump_cr = 1; @@ -3045,6 +4005,10 @@ Bool mp4box_parse_args(int argc, char **argv) if (!strcmp(szTk, argv[i + 1])) i++; else trackID = 0; } + else if ((i + 1<(u32)argc) && !strcmp(argv[i + 1], "*")) { + trackID = (u32)-1; + i++; + } else { trackID = 0; } @@ -3053,7 +4017,7 @@ Bool mp4box_parse_args(int argc, char **argv) fprintf(stderr, "Error: Read-Only version - subtitle conversion not available\n"); return 2; } -#endif +#endif //GPAC_DISABLE_ISOM_WRITE if (!stricmp(arg, "-ttxt")) dump_ttxt = GF_TRUE; else dump_srt = GF_TRUE; import_subtitle = 1; @@ -3122,16 +4086,14 @@ Bool mp4box_parse_args(int argc, char **argv) CHECK_NEXT_ARG tmpdir = argv[i + 1]; i++; } - else if (!stricmp(arg, "-for-test")) { - force_test_mode = GF_TRUE; - } else if (!stricmp(arg, "-co64")) { force_co64 = GF_TRUE; open_edit = GF_TRUE; } else if (!stricmp(arg, "-write-buffer")) { CHECK_NEXT_ARG - gf_isom_set_output_buffering(NULL, atoi(argv[i + 1])); + fprintf(stderr, "\tWARNING: \"-write-buffer\" deprecated and will soon be removed, use -bs-cache-size=%s\n", argv[i + 1]); + gf_opts_set_key("temp", "bs-cache-size", argv[i + 1]); i++; } else if (!stricmp(arg, "-cprt")) { @@ -3139,17 +4101,17 @@ Bool mp4box_parse_args(int argc, char **argv) i++; if (!dash_duration) open_edit = GF_TRUE; } - else if (!stricmp(arg, "-chap")) { - CHECK_NEXT_ARG chap_file = argv[i + 1]; + else if (!stricmp(arg, "-chap") || !stricmp(arg, "-chapqt")) { + CHECK_NEXT_ARG + chap_file = argv[i + 1]; i++; open_edit = GF_TRUE; - } - else if (!strcmp(arg, "-strict-error")) { - gf_log_set_strict_error(1); + if (!stricmp(arg, "-chapqt")) chap_qt = GF_TRUE; } else if (!stricmp(arg, "-inter") || !stricmp(arg, "-old-inter")) { CHECK_NEXT_ARG interleaving_time = atof(argv[i + 1]) / 1000; + if (!interleaving_time) do_flat = 2; open_edit = GF_TRUE; needSave = GF_TRUE; if (!stricmp(arg, "-old-inter")) old_interleave = 1; @@ -3160,7 +4122,7 @@ Bool mp4box_parse_args(int argc, char **argv) interleaving_time = atof(argv[i + 1]) / 1000; needSave = GF_TRUE; i++; - Frag = 1; + Frag = GF_TRUE; } else if (!stricmp(arg, "-dash")) { CHECK_NEXT_ARG @@ -3178,7 +4140,7 @@ Bool mp4box_parse_args(int argc, char **argv) fprintf(stderr, "\tERROR: \"-dash-dash_duration\": invalid parameter %s\n", argv[i + 1]); return 2; } - dash_duration_strict = GF_TRUE; + GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[DASH] -dash-strict is deprecated, will behave like -dash\n")); i++; } else if (!stricmp(arg, "-subdur")) { @@ -3210,16 +4172,36 @@ Bool mp4box_parse_args(int argc, char **argv) seg_name = argv[i + 1]; i++; } - else if (!stricmp(arg, "-dash-run-for")) { + else if (!stricmp(arg, "-run-for")) { CHECK_NEXT_ARG - dash_run_for = atoi(argv[i + 1]); + run_for = atoi(argv[i + 1]); i++; } + else if (!stricmp(arg, "-no-cache")) { + no_cache = GF_TRUE; + } + else if (!stricmp(arg, "-no-loop")) { + no_loop = GF_TRUE; + } + else if (!stricmp(arg, "-hlsc")) { + hls_clock = GF_TRUE; + } + else if (!stricmp(arg, "-bound")) { + dash_split_mode = GF_DASH_SPLIT_IN; + } + else if (!stricmp(arg, "-closest")) { + dash_split_mode = GF_DASH_SPLIT_CLOSEST; + } else if (!stricmp(arg, "-segment-ext")) { CHECK_NEXT_ARG seg_ext = argv[i + 1]; i++; } + else if (!stricmp(arg, "-init-segment-ext")) { + CHECK_NEXT_ARG + init_seg_ext = argv[i + 1]; + i++; + } else if (!stricmp(arg, "-bs-switching")) { CHECK_NEXT_ARG if (!stricmp(argv[i + 1], "no") || !stricmp(argv[i + 1], "off")) bitstream_switching_mode = GF_DASH_BSMODE_NONE; @@ -3243,7 +4225,7 @@ Bool mp4box_parse_args(int argc, char **argv) frag_real_time = GF_TRUE; } else if (!stricmp(arg, "-start-date")) { - dash_start_date = gf_net_parse_date(argv[i+1]); + dash_start_date = argv[i+1]; i++; } else if (!strnicmp(arg, "-cp-location=", 13)) { @@ -3305,6 +4287,9 @@ Bool mp4box_parse_args(int argc, char **argv) else if (!stricmp(arg, "-single-traf")) { single_traf_per_moof = 1; } + else if (!stricmp(arg, "-tfdt-traf")) { + tfdt_per_traf = 1; + } else if (!stricmp(arg, "-mpd-title")) { CHECK_NEXT_ARG dash_title = argv[i + 1]; i++; @@ -3330,6 +4315,9 @@ Bool mp4box_parse_args(int argc, char **argv) dash_ctx_file = argv[i + 1]; i++; } + else if (!stricmp(arg, "-ssix")) { + use_ssix = 1; + } else if (!stricmp(arg, "-daisy-chain")) { daisy_chain_sidx = 1; } @@ -3340,11 +4328,29 @@ Bool mp4box_parse_args(int argc, char **argv) single_file = 1; } else if (!stricmp(arg, "-pssh-moof")) { - pssh_in_moof = 1; + pssh_mode = GF_DASH_PSSH_MOOF; + } + else if (!strnicmp(arg, "-pssh=", 6)) { + if (!strcmp(arg+6, "f")) pssh_mode = GF_DASH_PSSH_MOOF; + else if (!strcmp(arg+6, "v")) pssh_mode = GF_DASH_PSSH_MOOV; + else if (!strcmp(arg+6, "m")) pssh_mode = GF_DASH_PSSH_MPD; + else if (!strcmp(arg+6, "mf") || !strcmp(arg+6, "fm")) pssh_mode = GF_DASH_PSSH_MOOF_MPD; + else if (!strcmp(arg+6, "mv") || !strcmp(arg+6, "vm")) pssh_mode = GF_DASH_PSSH_MOOV_MPD; + else pssh_mode = GF_DASH_PSSH_MOOV; } else if (!stricmp(arg, "-sample-groups-traf")) { samplegroups_in_traf = 1; } + else if (!stricmp(arg, "-mvex-after-traks")) { + mvex_after_traks = GF_TRUE; + } + else if (!stricmp(arg, "-sdtp-traf")) { + CHECK_NEXT_ARG + if (!stricmp(argv[i + 1], "both")) sdtp_in_traf = 2; + else if (!stricmp(argv[i + 1], "sdtp")) sdtp_in_traf = 1; + else sdtp_in_traf = 0; + i++; + } else if (!stricmp(arg, "-dash-profile") || !stricmp(arg, "-profile")) { CHECK_NEXT_ARG if (!stricmp(argv[i + 1], "live") || !stricmp(argv[i + 1], "simple")) dash_profile = GF_DASH_PROFILE_LIVE; @@ -3359,7 +4365,11 @@ Bool mp4box_parse_args(int argc, char **argv) dash_profile = GF_DASH_PROFILE_AVC264_ONDEMAND; } else if (!stricmp(argv[i + 1], "main")) dash_profile = GF_DASH_PROFILE_MAIN; - else dash_profile = GF_DASH_PROFILE_FULL; + else if (!stricmp(argv[i + 1], "full")) dash_profile = GF_DASH_PROFILE_FULL; + else { + fprintf(stderr, "\tWARNING: Unrecognized DASH profile \"%s\" - please check usage\n", argv[i + 1]); + return 2; + } i++; } else if (!stricmp(arg, "-profile-ext")) { @@ -3386,9 +4396,22 @@ Bool mp4box_parse_args(int argc, char **argv) segment_marker = GF_4CC(m[0], m[1], m[2], m[3]); i++; } + else if (!stricmp(arg, "-cues")) { + CHECK_NEXT_ARG + dash_cues = argv[i + 1]; + i++; + } + else if (!stricmp(arg, "-strict-cues")) { + strict_cues = GF_TRUE; + } else if (!stricmp(arg, "-insert-utc")) { insert_utc = GF_TRUE; } +#endif //GPAC_DISABLE_ISOM_WRITE + else if (!stricmp(arg, "-udp-write")) { + udp_dest = argv[i+1]; + i++; + } else { u32 ret = mp4box_parse_args_continue(argc, argv, &i); if (ret) return ret; @@ -3399,27 +4422,32 @@ Bool mp4box_parse_args(int argc, char **argv) int mp4boxMain(int argc, char **argv) { + u32 i, j; + const char *gpac_profile = "0"; + GF_Err e = GF_OK; nb_tsel_acts = nb_add = nb_cat = nb_track_act = nb_sdp_ex = max_ptime = nb_meta_act = rtp_rate = major_brand = nb_alt_brand_add = nb_alt_brand_rem = car_dur = minor_version = 0; - e = GF_OK; + split_duration = 0.0; split_start = -1.0; - interleaving_time = DEFAULT_INTERLEAVING_IN_SEC; + interleaving_time = 0; dash_duration = dash_subduration = 0.0; - dash_duration_strict = GF_FALSE; - import_fps = 0; + import_fps.num = import_fps.den = 0; import_flags = 0; split_size = 0; movie_time = 0; - dump_nal = 0; - FullInter = HintInter = encode = do_log = old_interleave = do_saf = do_hash = verbose = GF_FALSE; + dump_nal = dump_saps = dump_saps_mode = force_new = 0; + FullInter = HintInter = encode = do_scene_log = old_interleave = do_saf = do_hash = verbose = do_mpd_rip = merge_vtt_cues = get_nb_tracks = GF_FALSE; #ifndef GPAC_DISABLE_SCENE_DUMP dump_mode = GF_SM_DUMP_NONE; #endif - Frag = force_ocr = remove_sys_tracks = agg_samples = remove_hint = keep_sys_tracks = remove_root_od = single_group = clean_groups = GF_FALSE; - conv_type = HintIt = needSave = print_sdp = print_info = regular_iod = dump_std = open_edit = dump_rtp = dump_cr = dump_srt = dump_ttxt = force_new = dump_timestamps = dump_m2ts = dump_cart = import_subtitle = force_cat = pack_wgt = dash_live = GF_FALSE; + Frag = force_ocr = remove_sys_tracks = agg_samples = remove_hint = keep_sys_tracks = remove_root_od = single_group = clean_groups = compress_moov = GF_FALSE; + conv_type = HintIt = needSave = print_sdp = regular_iod = dump_std = open_edit = dump_rtp = dump_cr = dump_srt = dump_ttxt = dump_m2ts = dump_cart = import_subtitle = force_cat = pack_wgt = dash_live = GF_FALSE; no_fragments_defaults = GF_FALSE; - single_traf_per_moof = GF_FALSE, + single_traf_per_moof = hls_clock = GF_FALSE; + tfdt_per_traf = GF_FALSE; + dump_nal_type = 0; dump_isom = 0; + print_info = 0; /*align cat is the new default behaviour for -cat*/ align_cat = GF_TRUE; subsegs_per_sidx = 0; @@ -3429,18 +4457,19 @@ int mp4boxMain(int argc, char **argv) file = NULL; itunes_tags = pes_dump = NULL; seg_name = dash_ctx_file = NULL; + compress_top_boxes = NULL; initial_moof_sn = 0; initial_tfdt = 0; #ifndef GPAC_DISABLE_SCENE_ENCODER - memset(&opts, 0, sizeof(opts)); + memset(&smenc_opts, 0, sizeof(smenc_opts)); #endif trackID = stat_level = hint_flags = 0; program_number = 0; info_track_id = 0; - do_flat = GF_FALSE; - inName = outName = mediaSource = input_ctx = output_ctx = drm_file = avi2raw = cprt = chap_file = pack_file = raw_cat = NULL; + do_flat = 0; + inName = outName = mediaSource = input_ctx = output_ctx = drm_file = avi2raw = cprt = chap_file = pack_file = raw_cat = high_dynamc_range_filename = use_init_seg = box_patch_filename = NULL; #ifndef GPAC_DISABLE_SWF_IMPORT swf_flags = GF_SM_SWF_SPLIT_TIMELINE; @@ -3457,16 +4486,34 @@ int mp4boxMain(int argc, char **argv) #endif break; } + else if (!strcmp(argv[i], "-p")) { + if (i+1<(u32) argc) + gpac_profile = argv[i+1]; + else { + fprintf(stderr, "Bad argument for -p, expecting profile name but no more args\n"); + return 1; + } + } + else if (!strncmp(argv[i], "-p=", 3)) + gpac_profile = argv[i]+3; } +#ifdef _TWO_DIGIT_EXPONENT + _set_output_format(_TWO_DIGIT_EXPONENT); +#endif + /*init libgpac*/ - gf_sys_init(mem_track); + gf_sys_init(mem_track, gpac_profile); if (argc < 2) { - PrintUsage(); + fprintf(stderr, "Not enough arguments - check usage with -h\n" + "MP4Box - GPAC version %s\n" + "%s\n", gf_gpac_version(), gf_gpac_copyright_cite()); gf_sys_close(); return 0; } + helpout = stdout; + i = mp4box_parse_args(argc, argv); if (i) { return mp4box_cleanup(i - 1); @@ -3476,7 +4523,11 @@ int mp4boxMain(int argc, char **argv) inName = "std"; if (!inName) { - PrintUsage(); + if (has_next_arg) { + fprintf(stderr, "Broken argument specifier or file name missing - check usage with -h\n"); + } else { + PrintUsage(); + } return mp4box_cleanup(1); } if (!strcmp(inName, "std")) dump_std = 2; @@ -3489,8 +4540,9 @@ int mp4boxMain(int argc, char **argv) /*by default use single fragment per dash segment*/ if (dash_duration) interleaving_time = dash_duration; - else - do_flat = GF_TRUE; + else if (!do_flat) { + interleaving_time = DEFAULT_INTERLEAVING_IN_SEC; + } } if (dump_std) @@ -3513,12 +4565,26 @@ int mp4boxMain(int argc, char **argv) int ret = live_session(argc, argv); return mp4box_cleanup(ret); } - if (stream_rtp) { - int ret = stream_file_rtp(argc, argv); - return mp4box_cleanup(ret); - } #endif + GF_LOG_Level level = verbose ? GF_LOG_DEBUG : GF_LOG_INFO; + gf_log_set_tool_level(GF_LOG_CONTAINER, level); + gf_log_set_tool_level(GF_LOG_SCENE, level); + gf_log_set_tool_level(GF_LOG_PARSER, level); + gf_log_set_tool_level(GF_LOG_AUTHOR, level); + gf_log_set_tool_level(GF_LOG_CODING, level); + gf_log_set_tool_level(GF_LOG_DASH, level); +#ifdef GPAC_MEMORY_TRACKING + if (mem_track) + gf_log_set_tool_level(GF_LOG_MEMORY, level); +#endif + + e = gf_sys_set_args(argc, (const char **) argv); + if (e) { + fprintf(stderr, "Error assigning libgpac arguments: %s\n", gf_error_to_string(e) ); + return mp4box_cleanup(1); + } + if (raw_cat) { char chunk[4096]; FILE *fin, *fout; @@ -3536,8 +4602,8 @@ int mp4boxMain(int argc, char **argv) gf_fseek(fin, 0, SEEK_SET); done = 0; while (1) { - u32 nb_bytes = (u32) fread(chunk, 1, 4096, fin); - gf_fwrite(chunk, 1, nb_bytes, fout); + u32 nb_bytes = (u32) gf_fread(chunk, 4096, fin); + gf_fwrite(chunk, nb_bytes, fout); done += nb_bytes; fprintf(stderr, "Appending file %s - %02.2f done\r", raw_cat, 100.0*done/to_copy); if (done >= to_copy) break; @@ -3546,29 +4612,20 @@ int mp4boxMain(int argc, char **argv) gf_fclose(fout); return mp4box_cleanup(0); } -#if !defined(GPAC_DISABLE_STREAMING) - if (grab_m2ts) { - return grab_live_m2ts(grab_m2ts, grab_ifce, inName); + if (compress_top_boxes) { + if (size_top_box) { + u64 top_size = do_size_top_boxes(inName, compress_top_boxes, size_top_box); + fprintf(stdout, LLU"\n", top_size); + return mp4box_cleanup(e ? 1 : 0); + } else { + e = do_compress_top_boxes(inName, outName, compress_top_boxes, comp_top_box_version, comp_lzma); + return mp4box_cleanup(e ? 1 : 0); + } } -#endif - if (gf_logs) { - //gf_log_set_tools_levels(gf_logs); - } else { - GF_LOG_Level level = verbose ? GF_LOG_DEBUG : GF_LOG_INFO; - gf_log_set_tool_level(GF_LOG_CONTAINER, level); - gf_log_set_tool_level(GF_LOG_SCENE, level); - gf_log_set_tool_level(GF_LOG_PARSER, level); - gf_log_set_tool_level(GF_LOG_AUTHOR, level); - gf_log_set_tool_level(GF_LOG_CODING, level); -#ifdef GPAC_MEMORY_TRACKING - if (mem_track) - gf_log_set_tool_level(GF_LOG_MEMORY, level); -#endif - if (quiet) { - if (quiet==2) gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_QUIET); - gf_set_progress_callback(NULL, progress_quiet); - } + if (do_mpd_rip) { + e = rip_mpd(inName, outName); + return mp4box_cleanup(e ? 1 : 0); } #ifndef GPAC_DISABLE_CORE_TOOLS @@ -3576,11 +4633,31 @@ int mp4boxMain(int argc, char **argv) e = gf_dm_wget(do_wget, inName, 0, 0, NULL); if (e != GF_OK) { fprintf(stderr, "Cannot retrieve %s: %s\n", do_wget, gf_error_to_string(e) ); + return mp4box_cleanup(1); } - return mp4box_cleanup(1); + return mp4box_cleanup(0); } #endif + if (udp_dest) { + GF_Socket *sock = gf_sk_new(GF_SOCK_TYPE_UDP); + u16 port = 2345; + char *sep = strrchr(udp_dest, ':'); + if (sep) { + sep[0] = 0; + port = atoi(sep+1); + } + e = gf_sk_bind( sock, "127.0.0.1", 0, udp_dest, port, 0); + if (sep) sep[0] = ':'; + if (e) fprintf(stderr, "Failed to bind socket to %s: %s\n", udp_dest, gf_error_to_string(e) ); + else { + e = gf_sk_send(sock, (u8 *) inName, (u32)strlen(inName)); + if (e) fprintf(stderr, "Failed to send datagram: %s\n", gf_error_to_string(e) ); + } + gf_sk_del(sock); + return 0; + } + #ifndef GPAC_DISABLE_MPD if (do_mpd) { Bool remote = GF_FALSE; @@ -3604,10 +4681,11 @@ int mp4boxMain(int argc, char **argv) if (outName) strcpy(outfile, outName); else { - const char *sep = strrchr(inName, '/'); - char *ext = strstr(sep, ".m3u8"); + const char *sep = gf_file_basename(inName); + char *ext = gf_file_ext_start(sep); if (ext) ext[0] = 0; - sprintf(outfile, "%s.mpd", sep+1); + sprintf(outfile, "%s.mpd", sep); + if (ext) ext[0] = '.'; } } else { if (outName) @@ -3627,7 +4705,29 @@ int mp4boxMain(int argc, char **argv) fprintf(stderr, "[DASH] Error: MPD creation problem %s\n", gf_error_to_string(e)); mp4box_cleanup(1); } - e = gf_m3u8_to_mpd(remote ? "tmp_main.m3u8" : inName, mpd_base_url ? mpd_base_url : inName, outfile, 0, "video/mp2t", GF_TRUE, use_url_template, NULL, mpd, GF_TRUE); + FILE *f = gf_fopen(remote ? "tmp_main.m3u8" : inName, "r"); + u32 manif_type = 0; + if (f) { + char szDATA[1000]; + s32 read; + szDATA[999]=0; + read = (s32) gf_fread(szDATA, 999, f); + if (read<0) read = 0; + szDATA[read]=0; + gf_fclose(f); + if (strstr(szDATA, "SmoothStreamingMedia")) + manif_type = 2; + else if (strstr(szDATA, "#EXTM3U")) + manif_type = 1; + } + + if (manif_type==1) { + e = gf_m3u8_to_mpd(remote ? "tmp_main.m3u8" : inName, mpd_base_url ? mpd_base_url : inName, outfile, 0, "video/mp2t", GF_TRUE, use_url_template, segment_timeline, NULL, mpd, GF_TRUE, GF_TRUE); + } else if (manif_type==2) { + e = gf_mpd_smooth_to_mpd(remote ? "tmp_main.m3u8" : inName, mpd, mpd_base_url ? mpd_base_url : inName); + } else { + e = GF_NOT_SUPPORTED; + } if (!e) gf_mpd_write_file(mpd, outfile); @@ -3637,13 +4737,13 @@ int mp4boxMain(int argc, char **argv) gf_free(mpd_base_url); if (remote) { - gf_delete_file("tmp_main.m3u8"); + gf_file_delete("tmp_main.m3u8"); } if (e != GF_OK) { - fprintf(stderr, "Error converting M3U8 (%s) to MPD (%s): %s\n", inName, outfile, gf_error_to_string(e)); + fprintf(stderr, "Error converting %s (%s) to MPD (%s): %s\n", (manif_type==1) ? "HLS" : "Smooth", inName, outfile, gf_error_to_string(e)); return mp4box_cleanup(1); } else { - fprintf(stderr, "Done converting M3U8 (%s) to MPD (%s)\n", inName, outfile); + fprintf(stderr, "Done converting %s (%s) to MPD (%s)\n", (manif_type==1) ? "HLS" : "Smooth", inName, outfile); return mp4box_cleanup(0); } } @@ -3693,7 +4793,7 @@ int mp4boxMain(int argc, char **argv) if (e) { fprintf(stderr, "Error importing %s: %s\n", inName, gf_error_to_string(e)); gf_isom_delete(file); - gf_delete_file("ttxt_convert"); + gf_file_delete("ttxt_convert"); return mp4box_cleanup(1); } /* Prepare the export */ @@ -3711,7 +4811,7 @@ int mp4boxMain(int argc, char **argv) #endif /* Clean the importer */ gf_isom_delete(file); - gf_delete_file("ttxt_convert"); + gf_file_delete("ttxt_convert"); if (e) { fprintf(stderr, "Error converting %s: %s\n", inName, gf_error_to_string(e)); return mp4box_cleanup(1); @@ -3724,110 +4824,189 @@ int mp4boxMain(int argc, char **argv) } #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 = gf_fopen(inName, "rb"); - if (!test) { - open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; - if (!outName) outName = inName; + if (nb_add || nb_cat) { + u32 ipass, nb_pass = 1; + char *mux_args=NULL; + GF_FilterSession *fs = NULL; + if (nb_add) { + + GF_ISOOpenMode open_mode = GF_ISOM_OPEN_EDIT; + if (force_new) { + open_mode = (do_flat || (force_new==2)) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; } else { - gf_fclose(test); - if (! gf_isom_probe_file(inName) ) { + FILE *test = gf_fopen(inName, "rb"); + if (!test) { open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; if (!outName) outName = inName; + } else { + gf_fclose(test); + if (! gf_isom_probe_file(inName) ) { + open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; + if (!outName) outName = inName; + } } } + open_edit = do_flat ? GF_FALSE : GF_TRUE; + file = gf_isom_open(inName, open_mode, tmpdir); + if (!file) { + fprintf(stderr, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) ); + return mp4box_cleanup(1); + } + + if (freeze_box_order) + gf_isom_freeze_order(file); } - open_edit = GF_TRUE; - file = gf_isom_open(inName, open_mode, tmpdir); - if (!file) { - fprintf(stderr, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) ); - return mp4box_cleanup(1); + if (do_flat && interleaving_time) { + char szSubArg[100]; + gf_isom_set_storage_mode(file, GF_ISOM_STORE_FASTSTART); + do_flat = 2; + nb_pass = 2; + fs = gf_fs_new_defaults(0); + if (!fs) { + fprintf(stderr, "Error creating filter session\n"); + gf_isom_delete(file); + return mp4box_cleanup(1); + } + + //mux args + gf_dynstrcat(&mux_args, "mp4mx:importer:store=fstart", ":"); + + sprintf(szSubArg, "file=%p", file); + gf_dynstrcat(&mux_args, szSubArg, ":"); + sprintf(szSubArg, "cdur=%g", interleaving_time); + gf_dynstrcat(&mux_args, szSubArg, ":"); } - for (i=0; i<(u32) argc; i++) { - if (!strcmp(argv[i], "-add")) { - char *src = argv[i+1]; + for (ipass=0; ipass0) && (dash_duration > dash_subduration)) { fprintf(stderr, "Warning: -subdur parameter (%g s) should be greater than segment duration (%g s), using segment duration instead\n", dash_subduration, dash_duration); dash_subduration = dash_duration; @@ -3919,15 +5108,20 @@ int mp4boxMain(int argc, char **argv) fprintf(stderr, "Live DASH-ing - press 'q' to quit, 's' to save context and quit\n"); if (!dash_ctx_file && dash_live) { - dash_ctx = gf_cfg_new(NULL, NULL); + u32 r1; + u64 add = (u64) (intptr_t) &dasher; + add ^= gf_net_get_utc(); + r1 = (u32) add ^ (u32) (add/0xFFFFFFFF); + r1 ^= gf_rand(); + sprintf(szStateFile, "%s/dasher_%X.xml", gf_get_default_cache_directory(), r1 ); + dash_ctx_file = szStateFile; + dyn_state_file = GF_TRUE; } else if (dash_ctx_file) { if (force_new) - gf_delete_file(dash_ctx_file); - - dash_ctx = gf_cfg_force_new(NULL, dash_ctx_file); + gf_file_delete(dash_ctx_file); } - if (dash_profile==GF_DASH_PROFILE_UNKNOWN) + if (dash_profile==GF_DASH_PROFILE_AUTO) dash_profile = dash_mode ? GF_DASH_PROFILE_LIVE : GF_DASH_PROFILE_FULL; if (!dash_mode) { @@ -3946,24 +5140,24 @@ int mp4boxMain(int argc, char **argv) } /*setup dash*/ - dasher = gf_dasher_new(szMPD, dash_profile, tmpdir, dash_scale, dash_ctx); + dasher = gf_dasher_new(szMPD, dash_profile, tmpdir, dash_scale, dash_ctx_file); if (!dasher) { return mp4box_cleanup(1); - return GF_OUT_OF_MEM; } - e = gf_dasher_set_info(dasher, dash_title, cprt, dash_more_info, dash_source); + e = gf_dasher_set_info(dasher, dash_title, cprt, dash_more_info, dash_source, NULL); if (e) { fprintf(stderr, "DASH Error: %s\n", gf_error_to_string(e)); + gf_dasher_del(dasher); return mp4box_cleanup(1); } - if (dash_start_date) gf_dasher_set_start_date(dasher, dash_start_date); - - //e = gf_dasher_set_location(dasher, mpd_source); + gf_dasher_set_start_date(dasher, dash_start_date); + gf_dasher_set_location(dasher, dash_source); for (i=0; i < nb_mpd_base_urls; i++) { e = gf_dasher_add_base_url(dasher, mpd_base_urls[i]); if (e) { fprintf(stderr, "DASH Error: %s\n", gf_error_to_string(e)); + gf_dasher_del(dasher); return mp4box_cleanup(1); } } @@ -3972,47 +5166,60 @@ int mp4boxMain(int argc, char **argv) fprintf(stderr, "DASH Warning: using -segment-timeline with no -url-template. Forcing URL template.\n"); use_url_template = GF_TRUE; } - - e = gf_dasher_enable_url_template(dasher, (Bool) use_url_template, seg_name, seg_ext); + + e = gf_dasher_enable_url_template(dasher, (Bool) use_url_template, seg_name, seg_ext, init_seg_ext); if (!e) e = gf_dasher_enable_segment_timeline(dasher, segment_timeline); if (!e) e = gf_dasher_enable_single_segment(dasher, single_segment); if (!e) e = gf_dasher_enable_single_file(dasher, single_file); if (!e) e = gf_dasher_set_switch_mode(dasher, bitstream_switching_mode); - if (!e) e = gf_dasher_set_durations(dasher, dash_duration, dash_duration_strict, interleaving_time); + if (!e) e = gf_dasher_set_durations(dasher, dash_duration, interleaving_time, dash_subduration); if (!e) e = gf_dasher_enable_rap_splitting(dasher, seg_at_rap, frag_at_rap); if (!e) e = gf_dasher_set_segment_marker(dasher, segment_marker); - if (!e) e = gf_dasher_enable_sidx(dasher, (subsegs_per_sidx>=0) ? 1 : 0, (u32) subsegs_per_sidx, daisy_chain_sidx); + if (!e) e = gf_dasher_enable_sidx(dasher, (subsegs_per_sidx>=0) ? 1 : 0, (u32) subsegs_per_sidx, daisy_chain_sidx, use_ssix); if (!e) e = gf_dasher_set_dynamic_mode(dasher, dash_mode, mpd_update_time, time_shift_depth, mpd_live_duration); if (!e) e = gf_dasher_set_min_buffer(dasher, min_buffer); if (!e) e = gf_dasher_set_ast_offset(dasher, ast_offset_ms); if (!e) e = gf_dasher_enable_memory_fragmenting(dasher, memory_frags); if (!e) e = gf_dasher_set_initial_isobmf(dasher, initial_moof_sn, initial_tfdt); - if (!e) e = gf_dasher_configure_isobmf_default(dasher, no_fragments_defaults, pssh_in_moof, samplegroups_in_traf, single_traf_per_moof); + if (!e) e = gf_dasher_configure_isobmf_default(dasher, no_fragments_defaults, pssh_mode, samplegroups_in_traf, single_traf_per_moof, tfdt_per_traf, mvex_after_traks, sdtp_in_traf); if (!e) e = gf_dasher_enable_utc_ref(dasher, insert_utc); if (!e) e = gf_dasher_enable_real_time(dasher, frag_real_time); if (!e) e = gf_dasher_set_content_protection_location_mode(dasher, cp_location_mode); if (!e) e = gf_dasher_set_profile_extension(dasher, dash_profile_extension); + if (!e) e = gf_dasher_enable_cached_inputs(dasher, no_cache); + if (!e) e = gf_dasher_enable_loop_inputs(dasher, ! no_loop); + if (!e) e = gf_dasher_set_split_mode(dasher, dash_split_mode); + if (!e) e = gf_dasher_set_hls_clock(dasher, hls_clock); + if (!e && dash_cues) e = gf_dasher_set_cues(dasher, dash_cues, strict_cues); + if (!e && fs_dump_flags) e = gf_dasher_print_session_info(dasher, fs_dump_flags); for (i=0; i < nb_dash_inputs; i++) { if (!e) e = gf_dasher_add_input(dasher, &dash_inputs[i]); } if (e) { fprintf(stderr, "DASH Setup Error: %s\n", gf_error_to_string(e)); + gf_dasher_del(dasher); return mp4box_cleanup(1); } dash_cumulated_time=0; while (1) { - if (dash_run_for && (dash_cumulated_time>dash_run_for)) + if (run_for && (dash_cumulated_time >= run_for)) { + fprintf(stderr, "Done running, computing static MPD\n"); do_abort = 3; + } dash_prev_time=gf_sys_clock(); if (do_abort>=2) { e = gf_dasher_set_dynamic_mode(dasher, GF_DASH_DYNAMIC_LAST, 0, time_shift_depth, mpd_live_duration); } - if (!e) e = gf_dasher_process(dasher, dash_subduration); + if (!e) e = gf_dasher_process(dasher); + if (!dash_live && (e==GF_EOS) ) { + fprintf(stderr, "Nothing to dash, too early ...\n"); + e = GF_OK; + } if (do_abort) break; @@ -4029,7 +5236,12 @@ int mp4boxMain(int argc, char **argv) u64 ms_in_session=0; u32 slept = gf_sys_clock(); u32 sleep_for = gf_dasher_next_update_time(dasher, &ms_in_session); - fprintf(stderr, "Next generation scheduled in %u ms (DASH time "LLU" ms)\n", sleep_for, ms_in_session); + fprintf(stderr, "Next generation scheduled in %u ms (DASH time "LLU" ms)\r", sleep_for, ms_in_session); + if (run_for && (ms_in_session>=run_for)) { + dash_cumulated_time = 1+run_for; + continue; + } + while (1) { if (gf_prompt_has_input()) { char c = (char) gf_prompt_get_char(); @@ -4052,12 +5264,12 @@ int mp4boxMain(int argc, char **argv) } if (!sleep_for) break; - gf_sleep(1); + gf_sleep(sleep_for/10); sleep_for = gf_dasher_next_update_time(dasher, NULL); - if (sleep_for<1) { + if (sleep_for<=1) { dash_now_time=gf_sys_clock(); - fprintf(stderr, "Slept for %d ms before generation\n", dash_now_time - slept); dash_cumulated_time+=(dash_now_time-dash_prev_time); + fprintf(stderr, "Slept for %d ms before generation, dash cumulated time %d\n", dash_now_time - slept, dash_cumulated_time); break; } } @@ -4068,45 +5280,61 @@ int mp4boxMain(int argc, char **argv) gf_dasher_del(dasher); - if (dash_ctx) { - if (do_abort==3) { - if (!dash_ctx_file) { - char szName[1024]; - fprintf(stderr, "Enter file name to save dash context:\n"); - if (scanf("%s", szName) == 1) { - gf_cfg_set_filename(dash_ctx, szName); - gf_cfg_save(dash_ctx); - } - } + if (!run_for && dash_ctx_file && (do_abort==3) && (dyn_state_file) && !gf_sys_is_test_mode() ) { + char szName[1024]; + fprintf(stderr, "Enter file name to save dash context:\n"); + if (scanf("%1023s", szName) == 1) { + gf_file_move(dash_ctx_file, szName); } - gf_cfg_del(dash_ctx); } if (e) fprintf(stderr, "Error DASHing file: %s\n", gf_error_to_string(e)); if (file) gf_isom_delete(file); if (del_file) - gf_delete_file(inName); + gf_file_delete(inName); if (e) return mp4box_cleanup(1); goto exit; } - else if (!file + else if (!file && !do_hash #ifndef GPAC_DISABLE_MEDIA_EXPORT && !(track_dump_type & GF_EXPORT_AVI_NATIVE) #endif ) { FILE *st = gf_fopen(inName, "rb"); Bool file_exists = 0; + GF_ISOOpenMode omode; if (st) { file_exists = 1; gf_fclose(st); } switch (get_file_type_by_ext(inName)) { case 1: - file = gf_isom_open(inName, (u8) (open_edit ? GF_ISOM_OPEN_EDIT : ( ((dump_isom>0) || print_info) ? GF_ISOM_OPEN_READ_DUMP : GF_ISOM_OPEN_READ) ), tmpdir); + omode = (u8) (force_new ? GF_ISOM_WRITE_EDIT : (open_edit ? GF_ISOM_OPEN_EDIT : ( ((dump_isom>0) || print_info) ? GF_ISOM_OPEN_READ_DUMP : GF_ISOM_OPEN_READ) ) ); + + if (crypt) { + //keep fragment signaling in moov + omode = GF_ISOM_OPEN_READ; + if (use_init_seg) + file = gf_isom_open(use_init_seg, GF_ISOM_OPEN_READ, tmpdir); + } + if (!crypt && use_init_seg) { + file = gf_isom_open(use_init_seg, GF_ISOM_OPEN_READ_DUMP, tmpdir); + if (file) { + e = gf_isom_open_segment(file, inName, 0, 0, 0); + if (e) { + fprintf(stderr, "Error opening segment %s: %s\n", inName, gf_error_to_string(e) ); + gf_isom_delete(file); + file = NULL; + } + } + } + if (!file) + file = gf_isom_open(inName, omode, tmpdir); + if (!file && (gf_isom_last_error(NULL) == GF_ISOM_INCOMPLETE_FILE) && !open_edit) { u64 missing_bytes; - e = gf_isom_open_progressive(inName, 0, 0, &file, &missing_bytes); + e = gf_isom_open_progressive(inName, 0, 0, GF_FALSE, &file, &missing_bytes); fprintf(stderr, "Truncated file - missing "LLD" bytes\n", missing_bytes); } @@ -4121,6 +5349,8 @@ int mp4boxMain(int argc, char **argv) return mp4box_cleanup(1); } } + if (freeze_box_order) + gf_isom_freeze_order(file); break; /*allowed for bt<->xmt*/ case 2: @@ -4145,7 +5375,7 @@ int mp4boxMain(int argc, char **argv) else if (!open_edit && file_exists /* && !gf_isom_probe_file(inName) */ #ifndef GPAC_DISABLE_SCENE_DUMP && dump_mode == GF_SM_DUMP_NONE -#endif +#endif //GPAC_DISABLE_SCENE_DUMP ) { /*************************************************************************************************/ #ifndef GPAC_DISABLE_MEDIA_IMPORT @@ -4161,7 +5391,7 @@ int mp4boxMain(int argc, char **argv) if (e) { fprintf(stderr, "Error importing %s: %s\n", inName, gf_error_to_string(e)); gf_isom_delete(file); - gf_delete_file("ttxt_convert"); + gf_file_delete("ttxt_convert"); return mp4box_cleanup(1); } } @@ -4176,15 +5406,18 @@ int mp4boxMain(int argc, char **argv) dump_mpeg2_ts(inName, pes_dump, program_number); #endif #ifndef GPAC_DISABLE_CORE_TOOLS - } else if (do_bin_nhml) { - nhml_bs_to_bin(inName, outName, dump_std); + } else if (do_bin_xml) { + xml_bs_to_bin(inName, outName, dump_std); #endif } else if (do_hash) { hash_file(inName, dump_std); - } else { + } else if (print_info) { #ifndef GPAC_DISABLE_MEDIA_IMPORT convert_file_info(inName, info_track_id); #endif + } else { + fprintf(stderr, "Input %s is not an MP4 file, operation not allowed\n", inName); + return mp4box_cleanup(1); } goto exit; } @@ -4202,15 +5435,15 @@ int mp4boxMain(int argc, char **argv) } } - if (file && keep_utc && open_edit) { - gf_isom_keep_utc_times(file, 1); + if (high_dynamc_range_filename) { + e = parse_high_dynamc_range_xml_desc(file, high_dynamc_range_filename); + if (e) goto err_exit; } - if (file && force_test_mode) { - gf_isom_no_version_date_info(file, 1); + if (file && keep_utc && open_edit) { + gf_isom_keep_utc_times(file, 1); } - strcpy(outfile, outName ? outName : inName); { @@ -4225,6 +5458,8 @@ int mp4boxMain(int argc, char **argv) conv_type = GF_ISOM_CONV_TYPE_IPOD; else if (!stricmp(szExt, ".psp")) conv_type = GF_ISOM_CONV_TYPE_PSP; + else if (!stricmp(szExt, ".mov") || !stricmp(szExt, ".qt")) + conv_type = GF_ISOM_CONV_TYPE_MOV; //remove extension from outfile *szExt = 0; @@ -4233,7 +5468,7 @@ int mp4boxMain(int argc, char **argv) #ifndef GPAC_DISABLE_MEDIA_EXPORT if (track_dump_type & GF_EXPORT_AVI_NATIVE) { - char szFile[1024]; + char szFile[GF_MAX_PATH+24]; GF_MediaExporter mdump; memset(&mdump, 0, sizeof(mdump)); mdump.in_name = inName; @@ -4251,13 +5486,14 @@ int mp4boxMain(int argc, char **argv) mdump.out_name = szFile; } + mdump.print_stats_graph = fs_dump_flags; e = gf_media_export(&mdump); if (e) goto err_exit; goto exit; } - if (!open_edit && !gf_isom_probe_file(inName) && track_dump_type) { + if (!open_edit && track_dump_type && !gf_isom_probe_file(inName)) { GF_MediaExporter mdump; - char szFile[1024]; + char szFile[GF_MAX_PATH+24]; for (i=0; iact_type != TRAC_ACTION_RAW_EXTRACT) continue; @@ -4275,6 +5511,7 @@ int mp4boxMain(int argc, char **argv) } else { mdump.out_name = outfile; } + mdump.print_stats_graph = fs_dump_flags; e = gf_media_export(&mdump); if (e) goto err_exit; } @@ -4285,7 +5522,7 @@ int mp4boxMain(int argc, char **argv) #ifndef GPAC_DISABLE_SCENE_DUMP if (dump_mode != GF_SM_DUMP_NONE) { - e = dump_isom_scene(inName, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, dump_mode, do_log); + e = dump_isom_scene(inName, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, dump_mode, do_scene_log, no_odf_conf); if (e) goto err_exit; } #endif @@ -4297,23 +5534,38 @@ int mp4boxMain(int argc, char **argv) #ifndef GPAC_DISABLE_ISOM_HINTING if (!HintIt && print_sdp) dump_isom_sdp(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE); #endif + if (get_nb_tracks) { + fprintf(stdout, "%d\n", gf_isom_get_track_count(file)); + } if (print_info) { if (!file) { fprintf(stderr, "Cannot print info on a non ISOM file (%s)\n", inName); } else { - if (info_track_id) DumpTrackInfo(file, info_track_id, 1); + if (info_track_id) DumpTrackInfo(file, info_track_id, 1, (print_info==2) ? GF_TRUE : GF_FALSE); else DumpMovieInfo(file); } } #ifndef GPAC_DISABLE_ISOM_DUMP if (dump_isom) { - e = dump_isom_xml(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, (dump_isom==2) ? GF_TRUE : GF_FALSE); + e = dump_isom_xml(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, (dump_isom==2) ? GF_TRUE : GF_FALSE, merge_vtt_cues, use_init_seg ? GF_TRUE : GF_FALSE, (dump_isom==3) ? GF_TRUE : GF_FALSE); if (e) goto err_exit; } if (dump_cr) dump_isom_ismacryp(file, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE); - if ((dump_ttxt || dump_srt) && trackID) - dump_isom_timed_text(file, trackID, dump_std ? NULL : (outName ? outName : outfile), outName ? GF_TRUE : GF_FALSE, - GF_FALSE, dump_srt ? GF_TEXTDUMPTYPE_SRT : GF_TEXTDUMPTYPE_TTXT); + if ((dump_ttxt || dump_srt) && trackID) { + + if (trackID == (u32)-1) { + for (j=0; jtrackID==(u32) -1) { - u32 j; for (j=0; jtrackID) tk = gf_isom_get_track_by_id(file, meta->trackID); @@ -4437,17 +5696,17 @@ int mp4boxMain(int argc, char **argv) case META_ACTION_SET_TYPE: /*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); - gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_ISO2, 1); + gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_ISO2, GF_TRUE); needSave = GF_TRUE; break; case META_ACTION_ADD_ITEM: self_ref = !stricmp(meta->szPath, "NULL") || !stricmp(meta->szPath, "this") || !stricmp(meta->szPath, "self"); e = gf_isom_add_meta_item(file, meta->root_meta, tk, self_ref, self_ref ? NULL : meta->szPath, - strlen(meta->szName) ? meta->szName : NULL, + meta->szName, meta->item_id, meta->item_type, - strlen(meta->mime_type) ? meta->mime_type : NULL, - strlen(meta->enc_type) ? meta->enc_type : NULL, + meta->mime_type, + meta->enc_type, meta->use_dref ? meta->szPath : NULL, NULL, meta->image_props); if (meta->ref_type) { @@ -4456,30 +5715,41 @@ int mp4boxMain(int argc, char **argv) needSave = GF_TRUE; break; case META_ACTION_ADD_IMAGE_ITEM: - { - e = import_file(file, meta->szPath, 0, 0, 0); + { + u32 old_tk_count = gf_isom_get_track_count(file); + GF_Fraction _frac = {0,0}; + e = import_file(file, meta->szPath, 0, _frac, 0, NULL, NULL, 0); + if (e == GF_OK) { + u32 meta_type = gf_isom_get_meta_type(file, meta->root_meta, tk); + if (!meta_type) { + e = gf_isom_set_meta_type(file, meta->root_meta, tk, GF_META_ITEM_TYPE_PICT); + } else { + if (meta_type != GF_META_ITEM_TYPE_PICT) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Warning: file already has a root 'meta' box of type %s\n", gf_4cc_to_str(meta_type))); + e = GF_BAD_PARAM; + } + } if (e == GF_OK) { - if (!gf_isom_get_meta_type(file, meta->root_meta, tk)) { - e = gf_isom_set_meta_type(file, meta->root_meta, tk, GF_4CC('p','i','c','t')); + if (!meta->item_id) { + e = gf_isom_meta_get_next_item_id(file, meta->root_meta, tk, &meta->item_id); } if (e == GF_OK) { - if (!meta->item_id) { - e = gf_isom_meta_get_next_item_id(file, meta->root_meta, tk, &meta->item_id); - } - if (e == GF_OK) { - gf_isom_iff_create_image_item_from_track(file, meta->root_meta, tk, 1, - strlen(meta->szName) ? meta->szName : NULL, + e = gf_isom_iff_create_image_item_from_track(file, meta->root_meta, tk, 1, + meta->szName, meta->item_id, meta->image_props, NULL); - if (meta->ref_type) { - e = gf_isom_meta_add_item_ref(file, meta->root_meta, tk, meta->item_id, meta->ref_item_id, meta->ref_type, NULL); - } + if (e == GF_OK && meta->primary) { + e = gf_isom_set_meta_primary_item(file, meta->root_meta, tk, meta->item_id); + } + if (e == GF_OK && meta->ref_type) { + e = gf_isom_meta_add_item_ref(file, meta->root_meta, tk, meta->item_id, meta->ref_item_id, meta->ref_type, NULL); } } } - gf_isom_remove_track(file, 1); - needSave = GF_TRUE; } + gf_isom_remove_track(file, old_tk_count+1); + needSave = GF_TRUE; + } break; case META_ACTION_REM_ITEM: e = gf_isom_remove_meta_item(file, meta->root_meta, tk, meta->item_id); @@ -4491,7 +5761,7 @@ int mp4boxMain(int argc, char **argv) break; case META_ACTION_SET_XML: case META_ACTION_SET_BINARY_XML: - e = gf_isom_set_meta_xml(file, meta->root_meta, tk, meta->szPath, (meta->act_type==META_ACTION_SET_BINARY_XML) ? 1 : 0); + e = gf_isom_set_meta_xml(file, meta->root_meta, tk, meta->szPath, NULL, 0, (meta->act_type==META_ACTION_SET_BINARY_XML) ? 1 : 0); needSave = GF_TRUE; break; case META_ACTION_REM_XML: @@ -4509,7 +5779,8 @@ int mp4boxMain(int argc, char **argv) fprintf(stderr, "No meta box in input file\n"); } break; -#endif +#endif // GPAC_DISABLE_ISOM_WRITE + case META_ACTION_DUMP_XML: if (gf_isom_has_meta_xml(file, meta->root_meta, tk)) { e = gf_isom_extract_meta_xml(file, meta->root_meta, tk, meta->szPath, NULL); @@ -4538,7 +5809,7 @@ int mp4boxMain(int argc, char **argv) if (e) goto err_exit; needSave = GF_TRUE; } - + 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); + gf_isom_get_reference(file, j+1, GF_ISOM_REF_CHAP, k+1, &tk); if (tk==i+1) { is_chap = 1; break; @@ -4705,41 +5971,20 @@ int mp4boxMain(int argc, char **argv) break; } } - gf_isom_set_brand_info(file, major_brand, 1); - gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_MP42, 1); + gf_isom_set_brand_info(file, ipod_major_brand, 1); + gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_MP42, GF_TRUE); needSave = GF_TRUE; } -#ifndef GPAC_DISABLE_MCRYPT - if (crypt) { - if (!drm_file) { - fprintf(stderr, "Missing DRM file location - usage '-%s drm_file input_file\n", (crypt==1) ? "crypt" : "decrypt"); - e = GF_BAD_PARAM; - goto err_exit; - } - if (get_file_type_by_ext(inName) != GF_FILE_TYPE_ISO_MEDIA) { - fprintf(stderr, "MP4Box can crypt only ISOMedia File\n"); - e = GF_BAD_PARAM; - goto err_exit; - } - if (crypt == 1) { - e = gf_crypt_file(file, drm_file); - } else if (crypt ==2) { - e = gf_decrypt_file(file, drm_file); - } - if (e) goto err_exit; - needSave = GF_TRUE; - } -#endif /*GPAC_DISABLE_MCRYPT*/ } else if (outName) { strcpy(outfile, outName); } - - for (i=0; itrackID ? gf_isom_get_track_by_id(file, tka->trackID) : 0; - u32 timescale = gf_isom_get_timescale(file); + + timescale = gf_isom_get_timescale(file); switch (tka->act_type) { case TRAC_ACTION_REM_TRACK: e = gf_isom_remove_track(file, track); @@ -4781,26 +6026,26 @@ int mp4boxMain(int argc, char **argv) if (tka->delay_ms) { u64 tk_dur; - gf_isom_remove_edit_segments(file, track); + gf_isom_remove_edits(file, track); tk_dur = gf_isom_get_track_duration(file, track); - if (gf_isom_get_edit_segment_count(file, track)) + if (gf_isom_get_edits_count(file, track)) needSave = GF_TRUE; if (tka->delay_ms>0) { - gf_isom_append_edit_segment(file, track, (timescale*tka->delay_ms)/1000, 0, GF_ISOM_EDIT_EMPTY); - gf_isom_append_edit_segment(file, track, tk_dur, 0, GF_ISOM_EDIT_NORMAL); + gf_isom_append_edit(file, track, (timescale*tka->delay_ms)/1000, 0, GF_ISOM_EDIT_EMPTY); + gf_isom_append_edit(file, track, tk_dur, 0, GF_ISOM_EDIT_NORMAL); needSave = GF_TRUE; } else { u64 to_skip = (timescale*(-tka->delay_ms))/1000; if (to_skipdelay_ms)*gf_isom_get_media_timescale(file, track) / 1000; - gf_isom_append_edit_segment(file, track, tk_dur-to_skip, media_time, GF_ISOM_EDIT_NORMAL); + gf_isom_append_edit(file, track, tk_dur-to_skip, media_time, GF_ISOM_EDIT_NORMAL); needSave = GF_TRUE; } else { fprintf(stderr, "Warning: request negative delay longer than track duration - ignoring\n"); } } - } else if (gf_isom_get_edit_segment_count(file, track)) { - gf_isom_remove_edit_segments(file, track); + } else if (gf_isom_get_edits_count(file, track)) { + gf_isom_remove_edits(file, track); needSave = GF_TRUE; } break; @@ -4850,7 +6095,15 @@ int mp4boxMain(int argc, char **argv) } break; case TRAC_ACTION_SET_PAR: - e = gf_media_change_par(file, track, tka->par_num, tka->par_den); + e = gf_media_change_par(file, track, tka->par_num, tka->par_den, tka->force_par, tka->rewrite_bs); + needSave = GF_TRUE; + break; + case TRAC_ACTION_SET_CLAP: + e = gf_isom_set_clean_aperture(file, track, 1, tka->clap_wnum, tka->clap_wden, tka->clap_hnum, tka->clap_hden, tka->clap_honum, tka->clap_hoden, tka->clap_vonum, tka->clap_voden); + needSave = GF_TRUE; + break; + case TRAC_ACTION_SET_MX: + e = gf_isom_set_track_matrix(file, track, tka->mx); needSave = GF_TRUE; break; case TRAC_ACTION_SET_HANDLER_NAME: @@ -4859,13 +6112,13 @@ int mp4boxMain(int argc, char **argv) break; case TRAC_ACTION_ENABLE: if (!gf_isom_is_track_enabled(file, track)) { - e = gf_isom_set_track_enabled(file, track, 1); + e = gf_isom_set_track_enabled(file, track, GF_TRUE); needSave = GF_TRUE; } break; case TRAC_ACTION_DISABLE: if (gf_isom_is_track_enabled(file, track)) { - e = gf_isom_set_track_enabled(file, track, 0); + e = gf_isom_set_track_enabled(file, track, GF_FALSE); needSave = GF_TRUE; } break; @@ -4875,10 +6128,16 @@ int mp4boxMain(int argc, char **argv) break; case TRAC_ACTION_REM_NON_RAP: fprintf(stderr, "Removing non-rap samples from track %d\n", tka->trackID); - e = gf_media_remove_non_rap(file, track); + e = gf_media_remove_non_rap(file, track, GF_FALSE); + needSave = GF_TRUE; + break; + case TRAC_ACTION_REM_NON_REFS: + fprintf(stderr, "Removing non-reference samples from track %d\n", tka->trackID); + e = gf_media_remove_non_rap(file, track, GF_TRUE); needSave = GF_TRUE; break; case TRAC_ACTION_SET_UDTA: + fprintf(stderr, "Assigning udta box\n"); e = set_file_udta(file, track, tka->udta_type, tka->src_name, tka->sample_num ? GF_TRUE : GF_FALSE); if (e) goto err_exit; needSave = GF_TRUE; @@ -4894,7 +6153,7 @@ int mp4boxMain(int argc, char **argv) while (tags) { char *val; - char *sep = strchr(tags, ':'); + char *sep = gf_url_colon_suffix(tags); u32 tlen, itag = 0; if (sep) { while (sep) { @@ -4904,7 +6163,7 @@ int mp4boxMain(int argc, char **argv) if (itag>8; - _t[5]=t; - _t[4]=t>>8; - } - else if (sscanf(val, "%u", &n) == 1) { - _t[3]=n; - _t[2]=n>>8; + if (val) { + memset(_t, 0, sizeof(char) * 8); + tlen = (itag == GF_ISOM_ITUNE_DISK) ? 6 : 8; + if (sscanf(val, "%u/%u", &n, &t) == 2) { + _t[3] = n; + _t[2] = n >> 8; + _t[5] = t; + _t[4] = t >> 8; + } + else if (sscanf(val, "%u", &n) == 1) { + _t[3] = n; + _t[2] = n >> 8; + } + else tlen = 0; } - else tlen = 0; - if (tlen) gf_isom_apple_set_tag(file, itag, _t, tlen); + if (!val || tlen) gf_isom_apple_set_tag(file, itag, val ? (u8 *)_t : NULL, tlen); } break; case GF_ISOM_ITUNE_GAPLESS: case GF_ISOM_ITUNE_COMPILATION: { - char _t[1]; + u8 _t[1]; if (val && !stricmp(val, "yes")) _t[0] = 1; else _t[0] = 0; gf_isom_apple_set_tag(file, itag, _t, 1); } break; default: - gf_isom_apple_set_tag(file, itag, val, tlen); + gf_isom_apple_set_tag(file, itag, (u8 *)val, tlen); break; } needSave = GF_TRUE; @@ -5018,16 +6277,95 @@ int mp4boxMain(int argc, char **argv) needSave = GF_TRUE; } + if (cprt) { + e = gf_isom_set_copyright(file, "und", cprt); + needSave = GF_TRUE; + if (e) goto err_exit; + } + if (chap_file) { +#ifndef GPAC_DISABLE_MEDIA_IMPORT + e = gf_media_import_chapters(file, chap_file, import_fps, chap_qt); + needSave = GF_TRUE; +#else + fprintf(stderr, "Warning: GPAC compiled without Media Import, chapters can't be imported\n"); + e = GF_NOT_SUPPORTED; +#endif + if (e) goto err_exit; + } + + if (major_brand) { + gf_isom_set_brand_info(file, major_brand, minor_version); + needSave = GF_TRUE; + } + for (i=0; i len) { - fprintf(stderr, "Length allocated for conversion of wide char to UTF-8 not sufficient\n"); - return -1; - } - } - res = mp4boxMain(argc, argv); - for (i = 0; i < argc; i++) { - free(argv[i]); - } - free(argv); - return res; -} -#else -int main(int argc, char** argv) -{ - return mp4boxMain( argc, argv ); -} -#endif //win32 + +GF_MAIN_FUNC(mp4boxMain) #endif /*GPAC_DISABLE_ISOM*/ diff --git a/applications/mp4box/mp4box.h b/applications/mp4box/mp4box.h new file mode 100644 index 0000000..562d99d --- /dev/null +++ b/applications/mp4box/mp4box.h @@ -0,0 +1,145 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2000-2012 + * All rights reserved + * + * This file is part of GPAC / mp4box 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. + * + */ + +#ifndef _MP4BOX_H +#define _MP4BOX_H + +#include +#include +#include +#include +#include +#include + +#ifndef GPAC_DISABLE_SMGR +#include +#endif + + +typedef enum { + GF_FILE_TYPE_NOT_SUPPORTED = 0, + GF_FILE_TYPE_ISO_MEDIA = 1, + GF_FILE_TYPE_BT_WRL_X3DV = 2, + GF_FILE_TYPE_XMT_X3D = 3, + GF_FILE_TYPE_SVG = 4, + GF_FILE_TYPE_SWF = 5, + GF_FILE_TYPE_LSR_SAF = 6, +} GF_FileType; + + +#ifndef GPAC_DISABLE_MEDIA_IMPORT +void convert_file_info(char *inName, GF_ISOTrackID trackID); +#endif + +GF_Err parse_high_dynamc_range_xml_desc(GF_ISOFile* movie, char* file_name); + +#ifndef GPAC_DISABLE_ISOM_WRITE + +#ifndef GPAC_DISABLE_MEDIA_IMPORT +GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, GF_FilterSession *fsess, char **mux_args_if_first_pass, u32 tk_idx); +#else +GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, GF_FilterSession *fsess, Bool second_pass) { + return GF_NOT_SUPPORTED; +} +#endif +GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u64 split_size_kb, char *inName, Double interleaving_time, Double chunk_start, Bool adjust_split_end, char *outName, const char *tmpdir, Bool force_rap_split, const char *split_range_str); +GF_Err cat_isomedia_file(GF_ISOFile *mp4, char *fileName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command, Bool is_pl); + +#if !defined(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_Err dump_isom_cover_art(GF_ISOFile *file, char *inName, Bool is_final_name); +GF_Err dump_isom_chapters(GF_ISOFile *file, char *inName, Bool is_final_name, Bool dump_ogg); +GF_Err dump_isom_udta(GF_ISOFile *file, char *inName, Bool is_final_name, u32 dump_udta_type, u32 dump_udta_track); + +GF_Err set_file_udta(GF_ISOFile *dest, u32 tracknum, u32 udta_type, char *src, Bool is_box_array); +u32 id3_get_genre_tag(const char *name); + +/*in filedump.c*/ +#ifndef GPAC_DISABLE_SCENE_DUMP +GF_Err dump_isom_scene(char *file, char *inName, Bool is_final_name, GF_SceneDumpFormat dump_mode, Bool do_log, Bool no_odf_conv); +//void gf_check_isom_files(char *conf_rules, char *inName); +#endif +#ifndef GPAC_DISABLE_SCENE_STATS +void dump_isom_scene_stats(char *file, char *inName, Bool is_final_name, u32 stat_level); +#endif +void PrintNode(const char *name, u32 graph_type); +void PrintBuiltInNodes(u32 graph_type, Bool dump_all); +void PrintBuiltInBoxes(Bool do_cov); + +#ifndef GPAC_DISABLE_ISOM_DUMP +GF_Err dump_isom_xml(GF_ISOFile *file, char *inName, Bool is_final_name, Bool do_track_dump, Bool merge_vtt_cues, Bool skip_init, Bool skip_samples); +#endif + + +#ifndef GPAC_DISABLE_ISOM_HINTING +#ifndef GPAC_DISABLE_ISOM_DUMP +void dump_isom_rtp(GF_ISOFile *file, char *inName, Bool is_final_name); +#endif +void dump_isom_sdp(GF_ISOFile *file, char *inName, Bool is_final_name); +#endif + +void dump_isom_timestamps(GF_ISOFile *file, char *inName, Bool is_final_name, Bool skip_offset); +void dump_isom_nal(GF_ISOFile *file, GF_ISOTrackID trackID, char *inName, Bool is_final_name, u32 dump_flags); +void dump_isom_saps(GF_ISOFile *file, GF_ISOTrackID trackID, u32 dump_saps_mode, char *inName, Bool is_final_name); + +#ifndef GPAC_DISABLE_ISOM_DUMP +void dump_isom_ismacryp(GF_ISOFile *file, char *inName, Bool is_final_name); +void dump_isom_timed_text(GF_ISOFile *file, GF_ISOTrackID trackID, char *inName, Bool is_final_name, Bool is_convert, GF_TextDumpType dump_type); +#endif /*GPAC_DISABLE_ISOM_DUMP*/ + + +void DumpTrackInfo(GF_ISOFile *file, GF_ISOTrackID trackID, Bool full_dump, Bool is_track_num); +void DumpMovieInfo(GF_ISOFile *file); +void PrintLanguages(); + +#ifndef GPAC_DISABLE_MPEG2TS +void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name, Bool prog_num); +#endif + + +#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG) +void PrintStreamerUsage(); +int stream_file_rtp(int argc, char **argv); +int live_session(int argc, char **argv); +void PrintLiveUsage(); +#endif + +#if !defined(GPAC_DISABLE_STREAMING) +u32 grab_live_m2ts(const char *grab_m2ts, const char *outName); +#endif + +GF_Err rip_mpd(const char *mpd, const char *dst_file); + +GF_Err cat_playlist(GF_ISOFile *dest, char *playlistName, u32 import_flags, GF_Fraction force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat, Bool align_timelines, Bool allow_add_in_command); + +#endif // _MP4BOX_H + diff --git a/applications/mp4box/wrapper.c b/applications/mp4box/wrapper.c index d4a22c7..74e84e6 100644 --- a/applications/mp4box/wrapper.c +++ b/applications/mp4box/wrapper.c @@ -42,8 +42,6 @@ JNIEXPORT void JNICALL Java_com_enst_mp4box_mp4terminal_run(JNIEnv * env, jobjec jniLOGV("mp4terminal::command get back ok"); jniLOGV(sOriginalCommand); - int iNbArg = 0; - int i = 0; char** sConvertedCommandLine; sConvertedCommandLine = ConvertCommandLine( sOriginalCommand, &i ); diff --git a/applications/mp4client/Makefile b/applications/mp4client/Makefile index 9cb577e..caea206 100644 --- a/applications/mp4client/Makefile +++ b/applications/mp4client/Makefile @@ -2,21 +2,21 @@ include ../../config.mak vpath %.c $(SRC_PATH)/applications/mp4client -CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -I../../ +CFLAGS=-I"$(SRC_PATH)/include" $(OPTFLAGS) LINKFLAGS=$(GPAC_SH_FLAGS) -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif -ifeq ($(GPACREADONLY), yes) +ifeq ($(GPACREADONLY),yes) CFLAGS+=-DGPAC_READ_ONLY endif @@ -37,28 +37,33 @@ endif ifeq ($(STATICBUILD),yes) ##include static modules and other deps for libgpac include ../../static.mak -LINKFLAGS=-lgpac_static $(GPAC_SH_FLAGS) $(EXTRALIBS) +LINKFLAGS+=$(shell pkg-config ../../gpac.pc --libs --static | sed 's/-lgpac //' ) +LINKFLAGS+=$(GPAC_SH_FLAGS) $(EXTRALIBS) else LINKFLAGS+=-lgpac +ifeq ($(CONFIG_DARWIN),yes) +#LINKFLAGS+= -Wl,-rpath,'@loader_path' +else +LINKFLAGS+= -Wl,-rpath,'$$ORIGIN' -Wl,-rpath-link,../../bin/gcc +endif endif - #common obj -OBJS= main.o extract.o +OBJS= main.o ifeq ($(CONFIG_DARWIN),yes) OBJS+= carbon_events.o LDFLAGS += -framework Carbon endif -SRCS := $(OBJS:.o=.c) +SRCS := $(OBJS:.o=.c) all: $(PROG) MP4Client$(EXE): $(OBJS) $(CC) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc $(LINKFLAGS) $(LDFLAGS) -clean: +clean: rm -f $(OBJS) ../../bin/gcc/$(PROG) install: clean @@ -70,7 +75,7 @@ uninstall: dep: depend depend: - rm -f .depend + rm -f .depend $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend distclean: clean diff --git a/applications/mp4client/carbon_events.c b/applications/mp4client/carbon_events.c index a3ac7a4..5903d6b 100644 --- a/applications/mp4client/carbon_events.c +++ b/applications/mp4client/carbon_events.c @@ -28,7 +28,7 @@ #endif -void gf_sys_set_args(int argc, const char **argv); +int gf_sys_set_args(int argc, const char **argv); void send_open_url(const char *url); void RunApplicationEventLoop(void); diff --git a/applications/mp4client/extract.c b/applications/mp4client/extract.c deleted file mode 100644 index d9e7d6e..0000000 --- a/applications/mp4client/extract.c +++ /dev/null @@ -1,984 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2005-2012 - * All rights reserved - * - * This file is part of GPAC / command-line client - * - * 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 - -#ifdef WIN32 -#include -#else -typedef struct tagBITMAPFILEHEADER -{ - u16 bfType; - u32 bfSize; - u16 bfReserved1; - u16 bfReserved2; - u32 bfOffBits; -} BITMAPFILEHEADER; - -typedef struct tagBITMAPINFOHEADER { - u32 biSize; - s32 biWidth; - s32 biHeight; - u16 biPlanes; - u16 biBitCount; - u32 biCompression; - u32 biSizeImage; - s32 biXPelsPerMeter; - s32 biYPelsPerMeter; - u32 biClrUsed; - u32 biClrImportant; -} BITMAPINFOHEADER; - -#define BI_RGB 0L - -#endif - - -#include -#include -#include - - -enum -{ - DUMP_NONE = 0, - DUMP_AVI = 1, - DUMP_BMP = 2, - DUMP_PNG = 3, - DUMP_RAW = 4, - DUMP_SHA1 = 5, - - //DuMP flags - DUMP_DEPTH_ONLY = 1<<16, - DUMP_RGB_DEPTH = 1<<17, - DUMP_RGB_DEPTH_SHAPE = 1<<18 -}; - - -extern Bool is_connected; -extern GF_Terminal *term; -extern u64 Duration; -extern GF_Err last_error; -extern Bool no_prog; - - -static GFINLINE u8 colmask(s32 a, s32 n) -{ - s32 mask = (1 << n) - 1; - return (u8) (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask); -} - -static u32 put_pixel(FILE *fout, u32 type, u32 pf, char *ptr) -{ - u16 col; - switch (pf) { - case GF_PIXEL_RGB_32: - case GF_PIXEL_ARGB: - fputc(ptr[0], fout); - fputc(ptr[1], fout); - fputc(ptr[2], fout); - return 4; - - case GF_PIXEL_BGR_32: - case GF_PIXEL_RGBA: - fputc(ptr[2], fout); - fputc(ptr[1], fout); - fputc(ptr[0], fout); - return 4; - - case GF_PIXEL_RGB_24: - fputc(ptr[2], fout); - fputc(ptr[1], fout); - fputc(ptr[0], fout); - return 3; - - case GF_PIXEL_BGR_24: - fputc(ptr[2], fout); - fputc(ptr[1], fout); - fputc(ptr[0], fout); - return 3; - case GF_PIXEL_RGB_565: - col = * (u16 *)ptr; - fputc(colmask(col << 3, 3), fout); - fputc(colmask(col >> (5 - 2), 2), fout); - fputc(colmask(col >> (11 - 3), 3), fout); - return 2; - - case GF_PIXEL_RGB_555: - col = * (u16 *)ptr; - fputc(colmask(col << 3, 3), fout); - fputc(colmask(col >> (5 - 3), 3), fout); - fputc(colmask(col >> (10 - 3), 3), fout); - return 2; - /* this is used to write the byte depthbuffer in greyscale when dumping depth*/ - case GF_PIXEL_GREYSCALE: - /* bmp always needs 3 pixels */ - fputc(ptr[0], fout); - fputc(ptr[0], fout); - fputc(ptr[0], fout); - /* if printing the characters corresponding to the float depth buffer: */ - /* - { - u32 i=0; - while (ptr[i]!='\0') { - fputc(ptr[i], fout); - i++; - } - fputc('\b', fout); - } - */ - return 1; - - - case 0: - fputc(ptr[0], fout); - return 1; - } - return 0; -} - -void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - char str[GF_MAX_PATH]; - BITMAPFILEHEADER fh; - BITMAPINFOHEADER fi; - FILE *fout; - u32 j, i; - char *ptr; - - 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 = gf_fopen(str, "wb"); - if (!fout) return; - - memset(&fh, 0, sizeof(fh)); - fh.bfType = 19778; - fh.bfOffBits = 14 + 40; - - memset(&fi, 0, sizeof(char)*40); - fi.biSize = sizeof(char)*40; - fi.biWidth = fb->width; - fi.biHeight = fb->height; - fi.biPlanes = 1; - if (fb->pixel_format==GF_PIXEL_GREYSCALE) fi.biBitCount = 24; - else fi.biBitCount = 24; - fi.biCompression = BI_RGB; - fi.biSizeImage = fb->width * fb->height * 3; - - /*NOT ALIGNED!!*/ - gf_fwrite(&fh.bfType, 2, 1, fout); - gf_fwrite(&fh.bfSize, 4, 1, fout); - gf_fwrite(&fh.bfReserved1, 2, 1, fout); - gf_fwrite(&fh.bfReserved2, 2, 1, fout); - gf_fwrite(&fh.bfOffBits, 4, 1, fout); - - gf_fwrite(&fi, 1, 40, fout); - for (j=fb->height; j>0; j--) { - 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; - } - } - gf_fclose(fout); -} - -#include - -void write_png(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ -#ifndef GPAC_DISABLE_AV_PARSERS - char str[GF_MAX_PATH]; - FILE *fout; - u32 dst_size; - char *dst; - char *prev = strrchr(rad_name, '.'); - if (prev) prev[0] = '\0'; - sprintf(str, "%s_%d.png", rad_name, img_num); - if (prev) prev[0] = '.'; - - switch (fb->pixel_format) { - case GF_PIXEL_ARGB: - case GF_PIXEL_RGBA: - dst_size = fb->width*fb->height*4; - break; - default: - dst_size = fb->width*fb->height*3; - break; - } - dst = (char*)gf_malloc(sizeof(char)*dst_size); - - - fout = gf_fopen(str, "wb"); - if (fout) { - GF_Err e = gf_img_png_enc(fb->video_buffer, fb->width, fb->height, fb->pitch_y, fb->pixel_format, dst, &dst_size); - if (!e) { - gf_fwrite(dst, dst_size, 1, fout); - gf_fclose(fout); - } - } - - gf_free(dst); -#endif //GPAC_DISABLE_AV_PARSERS -} - - - -/*writes onto a file the content of the framebuffer in *fb interpreted as the byte depthbuffer */ -/*it's also possible to write a float depthbuffer by passing the floats to strings and writing chars in putpixel - see comments*/ -void write_depthfile(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - FILE *fout; - u32 i, j; - unsigned char *depth; - - depth = (unsigned char *) fb->video_buffer; - - fout = gf_fopen("dump_depth", "wb"); - if (!fout) return; - for (j=0; jheight; j++) { - for (i=0; iwidth; i++) { - -#ifdef GPAC_USE_TINYGL - fputc(depth[2*i+j*fb->width*sizeof(unsigned short)], fout); - fputc(depth[2*i+j*fb->width*sizeof(unsigned short) + 1], fout); -#else - fputc(depth[i+j*fb->width], fout); -#endif - } - } - gf_fclose(fout); -} - -void write_texture_file(GF_VideoSurface *fb, char *rad_name, u32 img_num, u32 dump_mode_flags) -{ - - FILE *fout; - u32 i, j; - unsigned char *buf; - - buf = (unsigned char *) fb->video_buffer; - - if (dump_mode_flags & DUMP_RGB_DEPTH_SHAPE) fout = gf_fopen("dump_rgbds", "wb"); - else if (dump_mode_flags & DUMP_RGB_DEPTH) fout = gf_fopen("dump_rgbd", "wb"); - else return; - - if (!fout) return; - for (j=0; jheight; j++) { - for (i=0; iwidth*4; i++) { - fputc(buf[i+j*fb->pitch_y], fout); - } - } - gf_fclose(fout); -} - - -void write_raw(GF_VideoSurface *fb, char *rad_name, u32 img_num) -{ - u32 j, i; - char *ptr, *prev; - char str[GF_MAX_PATH]; - FILE *fout; - prev = strrchr(rad_name, '.'); - if (prev) prev[0] = '\0'; - if (img_num<10) { - sprintf(str, "%s_00%d.raw", rad_name, img_num); - } else if (img_num<100) { - sprintf(str, "%s_0%d.raw", rad_name, img_num); - } else { - sprintf(str, "%s_%d.raw", rad_name, img_num); - } - - fout = gf_fopen(str, "wb"); - if (!fout) return; - - - for (j=0; jheight; j++) { - 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); - ptr += res; - } - } - gf_fclose(fout); -} - -void write_hash(FILE *sha_out, char *buf, u32 size) -{ - u8 hash[20]; - gf_sha1_csum((u8 *)buf, size, hash); - fwrite(hash, 1, 20, sha_out); -} - - -/* 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_mode_flags, u32 frameNum, char *conv_buf, void *avi_out, FILE *sha_out) -{ - GF_Err e; - u32 i, k; - - GF_VideoSurface fb; - u32 dump_mode = dump_mode_flags & 0x0000FFFF; - - /*lock it*/ - e = gf_sc_get_screen_buffer(term->compositor, &fb, 1); - if (e) fprintf(stderr, "Error grabbing depth buffer: %s\n", gf_error_to_string(e)); - else fprintf(stderr, "OK\n"); - /*export frame*/ - switch (dump_mode) { - case DUMP_AVI: - /*reverse frame*/ - for (k=0; k> 8/*(11 - 3)*/, 3); - dst[1] = colmask(src_16 >> 3/*(5 - 2)*/, 2); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - break; - case GF_PIXEL_RGB_555: - src_16 = * (u16 *)src; - dst[2] = colmask(src_16 >> 7/*(10 - 3)*/, 3); - dst[1] = colmask(src_16 >> 2/*(5 - 3)*/, 3); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - break; - /*for depth .avi*/ - case GF_PIXEL_GREYSCALE: - dst[0] = src[0]; - dst[1] = src[0]; - dst[2] = src[0]; - src+=1; - break; - } - dst += 3; - } - } -#ifndef GPAC_DISABLE_AVILIB - if (avi_out) { - if (AVI_write_frame(avi_out, conv_buf, fb.height*fb.width*3, 1) <0) - fprintf(stderr, "Error writing frame\n"); - } else -#endif - if (sha_out) { - write_hash(sha_out, conv_buf, fb.height*fb.width*3); - } - - /*in -depth -avi mode, do not release it yet*/ - if (dump_mode_flags & DUMP_DEPTH_ONLY) return; - break; - case DUMP_BMP: - write_bmp(&fb, rad_name, frameNum); - break; - case DUMP_PNG: - write_png(&fb, rad_name, frameNum); - break; - case DUMP_RAW: - write_raw(&fb, rad_name, frameNum); - break; - default: - write_depthfile(&fb, rad_name, frameNum); - break; - } - /*unlock it*/ - gf_sc_release_screen_buffer(term->compositor, &fb); -} - -void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_mode_flags, u32 frameNum, char *conv_buf, void *avi_out, FILE *sha_out) -{ - GF_Err e = GF_OK; - u32 i, k, out_size; - GF_VideoSurface fb; - - u32 dump_mode = dump_mode_flags & 0x0000FFFF; - u32 depth_dump_mode = 0; - - if (dump_mode_flags & DUMP_RGB_DEPTH_SHAPE) depth_dump_mode = 3; - else if (dump_mode_flags & DUMP_RGB_DEPTH) depth_dump_mode = 2; - else if (dump_mode_flags & DUMP_DEPTH_ONLY) depth_dump_mode = 1; - - /*lock it*/ - e = gf_sc_get_screen_buffer(term->compositor, &fb, depth_dump_mode); - if (e) fprintf(stderr, "Error grabbing frame buffer: %s\n", gf_error_to_string(e)); - - /*export frame*/ - switch (dump_mode) { - case DUMP_AVI: - case DUMP_SHA1: - /*reverse frame*/ - for (k=0; k> 8/*(11 - 3)*/, 3); - dst[1] = colmask(src_16 >> 3/*(5 - 2)*/, 2); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - dst+=3; - } - break; - case GF_PIXEL_RGB_555: - for (i=0; i> 7/*(10 - 3)*/, 3); - dst[1] = colmask(src_16 >> 2/*(5 - 3)*/, 3); - dst[0] = colmask(src_16 << 3, 3); - src+=2; - dst +=3; - } - break; - } - } - if (dump_mode_flags & (DUMP_RGB_DEPTH | DUMP_RGB_DEPTH_SHAPE)) { - out_size = fb.height*fb.width*4; - } else { - out_size = fb.height*fb.width*3; - } -#ifndef GPAC_DISABLE_AVILIB - if (avi_out) { - if (AVI_write_frame(avi_out, conv_buf, out_size, 1) <0) - fprintf(stderr, "Error writing frame\n"); - } else -#endif - if (sha_out) { - write_hash(sha_out, conv_buf, out_size); - } - break; - case DUMP_BMP: - write_bmp(&fb, rad_name, frameNum); - break; - case DUMP_PNG: - write_png(&fb, rad_name, frameNum); - break; - case DUMP_RAW: - write_raw(&fb, rad_name, frameNum); - break; - - default: - write_texture_file(&fb, rad_name, frameNum, dump_mode_flags); - break; - } - /*unlock it*/ - gf_sc_release_screen_buffer(term->compositor, &fb); -} - -#ifndef GPAC_DISABLE_AVILIB - -typedef struct -{ - GF_AudioListener al; - GF_Mutex *mx; - avi_t *avi; - u32 time_scale; - u64 max_dur, nb_bytes, audio_time; - u32 next_video_time, audio_time_init, flush_retry, nb_write, audio_clock_at_video_init; - u32 samplerate, bits_per_sample, nb_channel; -} AVI_AudioListener; - -void avi_audio_frame(void *udta, char *buffer, u32 buffer_size, u32 time, u32 delay) -{ - AVI_AudioListener *avil = (AVI_AudioListener *)udta; - - if (avil->audio_clock_at_video_init > time) - return; - - if (avil->audio_time >= avil->audio_time_init + avil->max_dur) - return; - - gf_mx_p(avil->mx); - - if (!avil->time_scale) { - AVI_set_audio(avil->avi, avil->nb_channel, avil->samplerate, avil->bits_per_sample, WAVE_FORMAT_PCM, 0); - avil->time_scale = avil->nb_channel*avil->bits_per_sample*avil->samplerate/8; - gf_term_set_option(term, GF_OPT_FORCE_AUDIO_CONFIG, 1); - } - - avil->nb_bytes+=buffer_size; - avil->flush_retry=0; - - if (avil->audio_time >= avil->audio_time_init) { - avil->nb_write++; - AVI_write_audio(avil->avi, buffer, buffer_size); - } - - - avil->audio_time = 1000*avil->nb_bytes/avil->time_scale; - - //we are behind video dump, force audio flush - if (avil->audio_time < avil->next_video_time) { - gf_term_step_clocks(term, 0); - } - gf_mx_v(avil->mx); -} - -void avi_audio_reconfig(void *udta, u32 samplerate, u32 bits_per_sample, u32 nb_channel, u32 channel_cfg) -{ - AVI_AudioListener *avil = (AVI_AudioListener *)udta; - - avil->nb_channel = nb_channel; - avil->samplerate = samplerate; - avil->bits_per_sample = bits_per_sample; -} -#endif - -Bool dump_file(char *url, char *out_url, u32 dump_mode_flags, Double fps, u32 width, u32 height, Float scale, u32 *times, u32 nb_times) -{ - GF_Err e; - Bool ret = 0; - u32 i = 0; - GF_VideoSurface fb; - char szPath[GF_MAX_PATH]; - char szOutPath[GF_MAX_PATH]; - char *prev=NULL; - u32 time, prev_time, nb_frames, init_time; - u64 dump_dur; - char *conv_buf = NULL; -#ifndef GPAC_DISABLE_AVILIB - avi_t *avi_out = NULL; - avi_t *depth_avi_out = NULL; - AVI_AudioListener avi_al; - char comp[5]; -#else - void *avi_out = NULL; - void *depth_avi_out = NULL; -#endif - GF_Mutex *avi_mx = NULL; - - FILE *sha_out = NULL; - FILE *sha_depth_out = NULL; - char szPath_depth[GF_MAX_PATH]; - u32 cur_time_idx; - u32 mode = dump_mode_flags & 0x0000FFFF; - - if (!out_url) out_url = url; - prev = strstr(url, "://"); - if (prev) { - prev = strrchr(url, '/'); - if (prev) prev++; - } - - if (!prev) prev = url; - strcpy(szPath, prev); - prev = gf_file_ext_start(szPath); - if (prev) *prev = 0; - - if (out_url) { - strcpy(szOutPath, out_url); - } else { - strcpy(szOutPath, szPath); - } - prev = gf_file_ext_start(szOutPath); - if (prev) *prev = 0; - - gf_term_set_simulation_frame_rate(term, (Double) fps); - - fprintf(stderr, "Opening URL %s\n", url); - /*connect and pause */ - gf_term_connect_from_time(term, url, 0, 2); - - while (!term->compositor->scene - || term->compositor->msg_type - || (gf_term_get_option(term, GF_OPT_PLAY_STATE) == GF_STATE_STEP_PAUSE) - ) { - if (last_error) return 1; - e = gf_term_process_flush(term); - if (e) { - fprintf(stderr, "Error initializing plalback: %s\n", gf_error_to_string(e)); - return 1; - } - } - - if (width && height) { - gf_term_set_size(term, width, height); - gf_term_process_flush(term); - } -#ifndef GPAC_USE_TINYGL - e = gf_sc_get_screen_buffer(term->compositor, &fb, 0); -#else - e = gf_sc_get_screen_buffer(term->compositor, &fb, 1); -#endif - if (e != GF_OK) { - fprintf(stderr, "Error grabbing screen buffer: %s\n", gf_error_to_string(e)); - return 1; - } - width = fb.width; - height = fb.height; - gf_sc_release_screen_buffer(term->compositor, &fb); - - if (scale != 1) { - width = (u32)(width * scale); - height = (u32)(height * scale); - gf_term_set_size(term, width, height); - gf_term_process_flush(term); - } - - /*we work in RGB24, and we must make sure the pitch is %4*/ - if ((width*3)%4) { - fprintf(stderr, "Adjusting width (%d) to have a stride multiple of 4\n", width); - while ((width*3)%4) width--; - - gf_term_set_size(term, width, height); - gf_term_process_flush(term); - - gf_sc_get_screen_buffer(term->compositor, &fb, 0); - width = fb.width; - height = fb.height; - gf_sc_release_screen_buffer(term->compositor, &fb); - } - - - strcpy(szPath_depth, szOutPath); - - if (mode==DUMP_AVI) { -#ifdef GPAC_DISABLE_AVILIB - fprintf(stderr, "AVILib is disabled in this build of GPAC\n"); - return 0; -#else - strcat(szOutPath, ".avi"); - avi_out = AVI_open_output_file(szOutPath); - if (!avi_out) { - fprintf(stderr, "Error creating AVI file %s\n", szOutPath); - return 1; - } -#endif - } - - if (mode==DUMP_SHA1) { - strcat(szOutPath, ".sha1"); - sha_out = gf_fopen(szOutPath, "wb"); - if (!sha_out) { - fprintf(stderr, "Error creating SHA file %s\n", szOutPath); - return 1; - } - } - - if (dump_mode_flags & DUMP_DEPTH_ONLY) { - if (mode==DUMP_AVI) { -#ifndef GPAC_DISABLE_AVILIB - strcat(szPath_depth, "_depth.avi"); - depth_avi_out = AVI_open_output_file(szPath_depth); - if (!depth_avi_out) { - fprintf(stderr, "Error creating depth AVI file %s\n", szPath_depth); - return 1; - } -#endif - } - if (mode==DUMP_SHA1) { - strcat(szPath_depth, "_depth.sha1"); - sha_depth_out = gf_fopen(szPath_depth, "wb"); - if (!sha_depth_out) { - fprintf(stderr, "Error creating depgth SHA file %s\n", szPath_depth); - return 1; - } - } - } - - - if (!fps) fps = GF_IMPORT_DEFAULT_FPS; - time = prev_time = 0; - nb_frames = 0; - - if (nb_times==2) { - prev_time = times[0]; - dump_dur = times[1] - times[0]; - } else if ((mode==DUMP_AVI) || (mode==DUMP_SHA1)) { - dump_dur = times[0] ? times[0] : Duration; - } else { - dump_dur = times[nb_times-1]; - dump_dur ++; - } - if (!dump_dur) { - fprintf(stderr, "Warning: file has no duration, defaulting to 1 sec\n"); - dump_dur = 1000; - } - - if (mode==DUMP_AVI) { - avi_mx = gf_mx_new("AVIMutex"); - -#ifndef GPAC_DISABLE_AVILIB - comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0; - AVI_set_video(avi_out, width, height, fps, comp); - - if (! (term->user->init_flags & GF_TERM_NO_AUDIO)) { - memset(&avi_al, 0, sizeof(avi_al)); - avi_al.al.udta = &avi_al; - avi_al.al.on_audio_frame = avi_audio_frame; - avi_al.al.on_audio_reconfig = avi_audio_reconfig; - avi_al.mx = avi_mx; - avi_al.avi = avi_out; - avi_al.max_dur=dump_dur; - - gf_sc_add_audio_listener(term->compositor, &avi_al.al); - } - - if (dump_mode_flags & DUMP_DEPTH_ONLY) - AVI_set_video(depth_avi_out, width, height, fps, comp); -#endif - } - - if ((mode==DUMP_AVI) || (mode==DUMP_SHA1)) { - - if (dump_mode_flags & (DUMP_RGB_DEPTH | DUMP_RGB_DEPTH_SHAPE) ) - conv_buf = gf_malloc(sizeof(char) * width * height * 4); - else - conv_buf = gf_malloc(sizeof(char) * width * height * 3); - } - - cur_time_idx = 0; - init_time = 0; - /*step to first frame*/ - if (prev_time) { - gf_term_step_clocks(term, prev_time); - init_time = prev_time; - prev_time=0; - } -#ifndef GPAC_DISABLE_AVILIB - avi_al.audio_time_init = avi_al.next_video_time = init_time; - avi_al.audio_clock_at_video_init = gf_term_get_clock(term); -#endif - - ret = 0; - while (time < dump_dur) { - u32 frame_start_time = gf_sys_clock(); - while ((gf_term_get_option(term, GF_OPT_PLAY_STATE) == GF_STATE_STEP_PAUSE)) { - e = gf_term_process_flush(term); - if (e) { - ret = 1; - break; - } - //if we can't flush a frame in 30 seconds consider this is an error - if (gf_sys_clock() - frame_start_time > 30000) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[MP4Client] Could not flush frame in 30 seconds for AVI dump, aborting dump\n")); - ret = 1; - break; - } - } - if (ret) - break; - - if ((mode==DUMP_AVI) || (mode==DUMP_SHA1)) { - - if (!no_prog) - fprintf(stderr, "Dumping %02d/100 %% - time %.02f sec\r", (u32) ((100.0*prev_time)/dump_dur), prev_time/1000.0 ); - - if (avi_mx) gf_mx_p(avi_mx); - - if (dump_mode_flags & DUMP_DEPTH_ONLY) { - - /*we'll dump both buffers at once*/ - gf_mx_p(term->compositor->mx); - dump_depth(term, szPath_depth, dump_mode_flags, i+1, conv_buf, depth_avi_out, sha_depth_out); - dump_frame(term, szOutPath, mode, i+1, conv_buf, avi_out, sha_out); - gf_mx_v(term->compositor->mx); - } else { - dump_frame(term, szOutPath, dump_mode_flags, i+1, conv_buf, avi_out, sha_out); - } - - if (avi_mx) gf_mx_v(avi_mx); - - } else { - if ( times[cur_time_idx] <= time) { - if (dump_mode_flags & (DUMP_DEPTH_ONLY | DUMP_RGB_DEPTH | DUMP_RGB_DEPTH_SHAPE) ) { - dump_depth(term, szOutPath, dump_mode_flags, cur_time_idx+1, NULL, NULL, NULL); - } else { - dump_frame(term, out_url, dump_mode_flags, cur_time_idx+1, NULL, NULL, NULL); - } - - cur_time_idx++; - if (cur_time_idx>=nb_times) - break; - } - } - - nb_frames++; - time = (u32) (nb_frames*1000/fps); -#ifndef GPAC_DISABLE_AVILIB - avi_al.next_video_time = init_time + time; -#endif - gf_term_step_clocks(term, time - prev_time); - prev_time = time; - - if (gf_prompt_has_input() && (gf_prompt_get_char()=='q')) { - fprintf(stderr, "Aborting dump\n"); - break; - } - } - -#ifndef GPAC_DISABLE_AVILIB - //flush audio dump - if (!ret && (mode==DUMP_AVI) && ! (term->user->init_flags & GF_TERM_NO_AUDIO)) { - avi_al.flush_retry=0; - while ((avi_al.flush_retry <1000) && (avi_al.audio_time < avi_al.audio_time_init + avi_al.max_dur)) { - gf_term_step_clocks(term, 0); - avi_al.flush_retry++; - gf_sleep(1); - } - if (avi_al.audio_time < avi_al.audio_time_init + avi_al.max_dur) { - GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("Failed to flush audio frames: audio time "LLU" - expected "LLU" - retry %d\n", avi_al.audio_time, avi_al.audio_time_init + avi_al.max_dur, avi_al.flush_retry)); - ret = 1; - } - } - - if (! (term->user->init_flags & GF_TERM_NO_AUDIO)) { - gf_sc_remove_audio_listener(term->compositor, &avi_al.al); - } - if (avi_out) AVI_close(avi_out); - if (depth_avi_out) AVI_close(depth_avi_out); - if (avi_mx) gf_mx_del(avi_mx); -#endif - - if (sha_out) gf_fclose(sha_out); - if (sha_depth_out) gf_fclose(sha_depth_out); - - if (conv_buf) { - gf_free(conv_buf); - fprintf(stderr, "Dumping done: %d frames at %g FPS\n", nb_frames, fps); - } - - return ret; -} - diff --git a/applications/mp4client/main.c b/applications/mp4client/main.c index 397bf6c..4a1b1d2 100644 --- a/applications/mp4client/main.c +++ b/applications/mp4client/main.c @@ -2,7 +2,7 @@ * GPAC - Multimedia Framework C SDK * * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2005-2012 + * Copyright (c) Telecom ParisTech 2005-2020 * All rights reserved * * This file is part of GPAC / command-line client @@ -31,18 +31,15 @@ #include #include #include -#include +#include + #include #include #include -#include /*ISO 639 languages*/ #include -//FIXME we need a plugin for playlists -#include - #ifndef WIN32 #include @@ -62,31 +59,33 @@ void carbon_uninit(); #endif //WIN32 /*local prototypes*/ -void PrintWorldInfo(GF_Terminal *term); -void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *URL); -void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name); +static void PrintWorldInfo(GF_Terminal *term); +static void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *URL); +static 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 void ViewODs(GF_Terminal *term, Bool show_timing); +static void MakeScreenshot(Bool for_coverage); +static void PrintAVInfo(Bool final); static u32 gui_mode = 0; +static int ret_val = 0; static Bool restart = GF_FALSE; static Bool reload = GF_FALSE; +Bool do_coverage = GF_FALSE; Bool no_prog = 0; +static FILE *helpout = NULL; +u32 help_flags = 0; + #if defined(__DARWIN__) || defined(__APPLE__) -//we keep no decoder thread because of JS_GC deadlocks between threads ... -static u32 threading_flags = GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_NO_DECODER_THREAD; #define VK_MOD GF_KEY_MOD_ALT #else -static u32 threading_flags = 0; #define VK_MOD GF_KEY_MOD_CTRL #endif + static Bool no_audio = GF_FALSE; -static Bool term_step = GF_FALSE; -static Bool no_regulation = GF_FALSE; static u32 bench_mode = 0; static u32 bench_mode_start = 0; static u32 bench_buffer = 0; @@ -105,16 +104,13 @@ static s32 request_next_playlist_item = GF_FALSE; FILE *playlist = NULL; static Bool readonly_playlist = GF_FALSE; -static GF_Config *cfg_file; static u32 display_rti = 0; static Bool Run; static Bool CanSeek = GF_FALSE; static char the_url[GF_MAX_PATH]; static char pl_path[GF_MAX_PATH]; static Bool no_mime_check = GF_TRUE; -static Bool be_quiet = GF_FALSE; -static u64 log_time_start = 0; -static Bool log_utc_time = GF_FALSE; +static u64 log_rti_time_start = 0; static Bool loop_at_end = GF_FALSE; static u32 forced_width=0; static u32 forced_height=0; @@ -126,45 +122,97 @@ u32 init_h = 0; u32 last_x, last_y; Bool right_down = GF_FALSE; -void dump_frame(GF_Terminal *term, char *rad_path, u32 dump_type, u32 frameNum); - -enum -{ - DUMP_NONE = 0, - DUMP_AVI = 1, - DUMP_BMP = 2, - DUMP_PNG = 3, - DUMP_RAW = 4, - DUMP_SHA1 = 5, - - //DuMP flags - DUMP_DEPTH_ONLY = 1<<16, - DUMP_RGB_DEPTH = 1<<17, - DUMP_RGB_DEPTH_SHAPE = 1<<18 -}; +Float scale = 1; -Bool dump_file(char *the_url, char *out_url, u32 dump_mode, Double fps, u32 width, u32 height, Float scale, u32 *times, u32 nb_times); +static Bool shell_visible = GF_TRUE; +#if defined(WIN32) && !defined(_WIN32_WCE) +static HWND console_hwnd = NULL; +static Bool owns_wnd = GF_FALSE; +#include +#include +static DWORD getParentPID(DWORD pid) +{ + DWORD ppid = 0; + HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (h) { + PROCESSENTRY32 pe = { 0 }; + pe.dwSize = sizeof(PROCESSENTRY32); + if (Process32First(h, &pe)) { + do { + if (pe.th32ProcessID == pid) { + ppid = pe.th32ParentProcessID; + break; + } + } while (Process32Next(h, &pe)); + } + CloseHandle(h); + } + return (ppid); +} -static Bool shell_visible = GF_TRUE; -void hide_shell(u32 cmd_type) +static void getProcessName(DWORD pid, PUCHAR fname, DWORD sz) +{ + HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); + if (h) { + GetModuleFileNameEx(h, NULL, fname, sz); + CloseHandle(h); + } +} +static void w32_hide_shell(u32 cmd_type) { -#if defined(WIN32) && !defined(_WIN32_WCE) typedef HWND (WINAPI *GetConsoleWindowT)(void); HMODULE hk32 = GetModuleHandle("kernel32.dll"); - GetConsoleWindowT GetConsoleWindow = (GetConsoleWindowT ) GetProcAddress(hk32,"GetConsoleWindow"); + if (!console_hwnd) { + char parentName[GF_MAX_PATH]; + DWORD dwProcessId = 0; + DWORD dwParentProcessId = 0; + DWORD dwParentParentProcessId = 0; + GetConsoleWindowT GetConsoleWindow = (GetConsoleWindowT)GetProcAddress(hk32, "GetConsoleWindow"); + console_hwnd = GetConsoleWindow(); + dwProcessId = GetCurrentProcessId(); + dwParentProcessId = getParentPID(dwProcessId); + if (dwParentProcessId) + dwParentParentProcessId = getParentPID(dwParentProcessId); + //get parent process name, check for explorer + parentName[0] = 0; + getProcessName(dwParentProcessId, parentName, GF_MAX_PATH); + if (strstr(parentName, "explorer")) { + owns_wnd = GF_TRUE; + } + //get parent parent process name, check for devenv (or any other ide name ...) + else if (dwParentParentProcessId) { + owns_wnd = GF_FALSE; + parentName[0] = 0; + getProcessName(dwParentParentProcessId, parentName, GF_MAX_PATH); + if (strstr(parentName, "devenv")) { + owns_wnd = GF_TRUE; + } + } else { + owns_wnd = GF_FALSE; + } + } + if (!owns_wnd || !console_hwnd) return; + if (cmd_type==0) { - ShowWindow( GetConsoleWindow(), SW_SHOW); + ShowWindow(console_hwnd, SW_SHOW); shell_visible = GF_TRUE; } else if (cmd_type==1) { - ShowWindow( GetConsoleWindow(), SW_HIDE); + ShowWindow(console_hwnd, SW_HIDE); shell_visible = GF_FALSE; } - else if (cmd_type==2) PostMessage(GetConsoleWindow(), WM_CLOSE, 0, 0); + else if (cmd_type == 2) { + PostMessage(GetConsoleWindow(), WM_CLOSE, 0, 0); + } +} + +#define hide_shell w32_hide_shell +#else + +#define hide_shell(_var) #endif -} void send_open_url(const char *url) @@ -176,198 +224,218 @@ void send_open_url(const char *url) gf_term_send_event(term, &evt); } -void PrintUsage() +GF_GPACArg mp4client_args[] = { - fprintf(stderr, "Usage MP4Client [options] [filename]\n" - "\t-c fileName: user-defined configuration file. Also works with -cfg\n" #ifdef GPAC_MEMORY_TRACKING - "\t-mem-track: enables memory tracker\n" - "\t-mem-track-stack: enables memory tracker with stack dumping\n" -#endif - "\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-quiet: removes script message, buffering and downloading status\n" - "\t-strict-error: exit when the player reports its first error\n" - "\t-opt option: Overrides an option in the configuration file. String format is section:key=value. \n" - "\t \"section:key=null\" removes the key\n" - "\t \"section:*=null\" removes the section\n" - "\t-conf option: Same as -opt but does not start player.\n" - "\t-log-file file: sets output log file. Also works with -lf\n" - "\t-logs log_args: sets log tools and levels, formatted as a ':'-separated list of toolX[:toolZ]@levelX\n" - "\t levelX can be one of:\n" - "\t \"quiet\" : skip logs\n" - "\t \"error\" : logs only error messages\n" - "\t \"warning\" : logs error+warning messages\n" - "\t \"info\" : logs error+warning+info messages\n" - "\t \"debug\" : logs all messages\n" - "\t toolX can be one of:\n" - "\t \"core\" : libgpac core\n" - "\t \"coding\" : bitstream formats (audio, video, scene)\n" - "\t \"container\" : container formats (ISO File, MPEG-2 TS, AVI, ...)\n" - "\t \"network\" : network data exept RTP trafic\n" - "\t \"rtp\" : rtp trafic\n" - "\t \"author\" : authoring tools (hint, import, export)\n" - "\t \"sync\" : terminal sync layer\n" - "\t \"codec\" : terminal codec messages\n" - "\t \"parser\" : scene parsers (svg, xmt, bt) and other\n" - "\t \"media\" : terminal media object management\n" - "\t \"scene\" : scene graph and scene manager\n" - "\t \"script\" : scripting engine messages\n" - "\t \"interact\" : interaction engine (events, scripts, etc)\n" - "\t \"smil\" : SMIL timing engine\n" - "\t \"compose\" : composition engine (2D, 3D, etc)\n" - "\t \"mmio\" : Audio/Video HW I/O management\n" - "\t \"rti\" : various run-time stats\n" - "\t \"cache\" : HTTP cache subsystem\n" - "\t \"audio\" : Audio renderer and mixers\n" -#ifdef GPAC_MEMORY_TRACKING - "\t \"mem\" : GPAC memory tracker\n" -#endif -#ifndef GPAC_DISABLE_DASH_CLIENT - "\t \"dash\" : HTTP streaming logs\n" + GF_DEF_ARG("mem-track", NULL, "enable memory tracker", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("mem-track-stack", NULL, "enable memory tracker with stack dumping", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), #endif - "\t \"module\" : GPAC modules debugging\n" - "\t \"mutex\" : mutex\n" - "\t \"all\" : all tools logged - other tools can be specified afterwards.\n" - "\n" - "\t-log-clock or -lc : logs time in micro sec since start time of GPAC before each log line.\n" - "\t-log-utc or -lu : logs UTC time in ms before each log line.\n" - "\t-ifce IPIFCE : Sets default Multicast interface\n" - "\t-size WxH: specifies visual size (default: scene size)\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-compositor-thread: disables compositor thread (iOS and Android mode)\n" - "\t-no-audio: disables audio \n" - "\t-no-wnd: uses windowless mode (Win32 only)\n" - "\t-no-back: uses transparent background for output window when no background is specified (Win32 only)\n" - "\t-align vh: specifies v and h alignment for windowless mode\n" - "\t possible v values: t(op), m(iddle), b(ottom)\n" - "\t possible h values: l(eft), m(iddle), r(ight)\n" - "\t default alignment is top-left\n" - "\t default alignment is top-left\n" - "\t-pause: pauses at first frame\n" - "\t-play-from T: starts from T seconds in media\n" - "\t-speed S: starts with speed S\n" - "\t-loop: loops presentation\n" - "\t-no-regulation: disables framerate regulation\n" - "\t-bench: disable a/v output and bench source decoding (as fast as possible)\n" - "\t-vbench: disable audio output, video sync bench source decoding/display (as fast as possible)\n" - "\t-sbench: disable all decoders and bench systems layer (as fast as possible)\n" - "\t-fs: starts in fullscreen mode\n" - "\t-views v1:.:vN: creates an auto-stereo scene of N views. vN can be any type of URL supported by GPAC.\n" - "\t in this mode, URL argument of GPAC is ignored, GUI as well.\n" - "\t this is equivalent as using views://v1:.:N as an URL.\n" - "\n" - "\t-exit: automatically exits when presentation is over\n" - "\t-run-for TIME: runs for TIME seconds and exits\n" - "\t-service ID: auto-tune to given service ID in a multiplex\n" - "\t-noprog: disable progress report\n" - "\t-no-save: disable saving config file on exit\n" - "\t-no-addon: disable automatic loading of media addons declared in source URL\n" - "\t-gui: starts in GUI mode. The GUI is indicated in GPAC config, section General, by the key [StartupFile]\n" - "\t-ntp-shift T: shifts NTP clock of T (signed int) milliseconds\n" - "\n" - "Dumper Options (times is a formated as start-end, with start being sec, h:m:s:f/fps or h:m:s:ms):\n" - "\t-bmp [times]: dumps given frames to bmp\n" - "\t-png [times]: dumps given frames to png\n" - "\t-raw [times]: dumps given frames to raw\n" - "\t-avi [times]: dumps given file to raw avi\n" - "\t-sha [times]: dumps given file to raw SHA-1 (1 hash per frame)\n" - "\r-out filename: name of the output file\n" - "\t-rgbds: dumps the RGBDS pixel format texture\n" - "\t with -avi [times]: dumps an rgbds-format .avi\n" - "\t-rgbd: dumps the RGBD pixel format texture\n" - "\t with -avi [times]: dumps an rgbd-format .avi\n" - "\t-depth: dumps depthmap (z-buffer) frames\n" - "\t with -avi [times]: dumps depthmap in grayscale .avi\n" - "\t with -bmp: dumps depthmap in grayscale .bmp\n" - "\t with -png: dumps depthmap in grayscale .png\n" - "\t-fps FPS: specifies frame rate for AVI dumping (default: %f)\n" - "\t-scale s: scales the visual size (default: 1)\n" - "\t-fill: uses fill aspect ratio for dumping (default: none)\n" - "\t-show: shows window while dumping (default: no)\n" - "\n" - "\t-uncache: Revert all cached items to their original name and location. Does not start player.\n" - "\n" - "\t-help: shows this screen\n" - "\n" - "MP4Client - GPAC command line player and dumper - version "GPAC_FULL_VERSION"\n" - "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n" - "GPAC Configuration: " GPAC_CONFIGURATION "\n" - "Features: %s\n", - GF_IMPORT_DEFAULT_FPS, - gpac_features() - ); + GF_DEF_ARG("rti", NULL, "log run-time info (FPS, CPU, Mem usage) to given file", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("rtix", NULL, "same as -rti but driven by GPAC logs", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("size", NULL, "specify visual size WxH. If not set, scene size or video size is used", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("rti-refresh", NULL, "set refresh time in ms between two runt-time counters queries (default is 200)", NULL, NULL, GF_ARG_INT, 0), + + GF_DEF_ARG("no-thread", NULL, "disable thread usage (except for depending on driver audio)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("no-audio", NULL, "disable audio", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + +#ifdef GPAC_CONFIG_WIN32 + GF_DEF_ARG("no-wnd", NULL, "use windowless mode (Win32 only)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERIMENTAL), + GF_DEF_ARG("no-back", NULL, "use transparent background for output window when no background is specified (Win32 only)", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERIMENTAL), + GF_DEF_ARG("align", NULL, "specify v and h alignment for windowless mode\n" + "- tl: top/left\n" + "- tm: top/horizontal middle\n" + "- tr: top/right\n" + "- ml: vertical middle/left\n" + "- mm: vertical middle/horizontal middle\n" + "- mr: vertical middle/right\n" + "- bl: bottom/left\n" + "- bm: bottom/horizontal middle\n" + "- br: bottom/right", "tl", "tl|tm|tr|ml|mm|mr|bl|bm|br", GF_ARG_INT, GF_ARG_HINT_EXPERIMENTAL), +#endif // GPAC_CONFIG_WIN32 + + GF_DEF_ARG("pause", NULL, "pause at first frame", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("play-from", NULL, "start playback from given time in seconds in media", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("speed", NULL, "start playback wit given speed", NULL, NULL, GF_ARG_DOUBLE, 0), + GF_DEF_ARG("loop", NULL, "loop playback", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("fs", NULL, "start in fullscreen mode", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("exit", NULL, "exit when presentation is over", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("run-for", NULL, "run for indicated time in seconds and exits", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("service", NULL, "auto-tune to given service ID in a multiplex", NULL, NULL, GF_ARG_INT, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("no-save", NULL, "do not save configuration file on exit", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("no-addon", NULL, "disable automatic loading of media addons declared in source URL", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("gui", NULL, "start in GUI mode. The GUI is indicated in the [configuration](core_config) file __[General]StartupFile__", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("p", NULL, "use indicated profile for the global GPAC config. If not found, config file is created. If a file path is indicated, this will load profile from that file. Otherwise, this will create a directory of the specified name and store new config there. Reserved name `0` means a new profile, not stored to disk. Works using -p=NAME or -p NAME", NULL, NULL, GF_ARG_STRING, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("stats", NULL, "dump filter session stats after playback", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("graph", NULL, "dump filter session graph after playback", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_EXPERT), + GF_DEF_ARG("nk", NULL, "disable keyboard interaction", NULL, NULL, GF_ARG_BOOL, GF_ARG_HINT_ADVANCED), + GF_DEF_ARG("h", "help", "show this help. Use `-hx` to show expert help", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("hc", NULL, "show libgpac core options", NULL, NULL, GF_ARG_BOOL, 0), + GF_DEF_ARG("hr", NULL, "show runtime options when keybard interaction is enabled", NULL, NULL, GF_ARG_BOOL, 0), + {0} +}; + + +void PrintUsage(Bool show_all) +{ + u32 i=0; + + if (help_flags & GF_PRINTARG_MAN) { + fprintf(helpout, ".SH \"DESCRIPTION\"\n.LP\nMP4Client is GPAC command-line media player. It supports all GPAC playback features (2D and 3D support, local playback, RTP streaming, HTTP faststart, many audio and video codecs ...).\n.br\nSpecific URLs shortcuts are available, see gpac -h compositor\n.\n.\n.SH OPTIONS\n"); + } else { + gf_sys_format_help(helpout, help_flags, "Usage: MP4Client [options] [filename]\n" + "# General\n" + "The player accepts any URL supported by GPAC.\n" + "Specific URLs shortcuts are available, see [GPAC Compositor (gpac -h compositor)](compositor)\n" + "Version: %s\n" + "%s\n" + "For more info on GPAC configuration, use `gpac ` [-h](GPAC) `bin` \n \n" + "# Options \n \n", + (help_flags == GF_PRINTARG_MD) ? GPAC_VERSION : gf_gpac_version(), + gf_gpac_copyright_cite() + ); + } + + while (mp4client_args[i].name) { + GF_GPACArg *arg = &mp4client_args[i]; + i++; + if (!show_all && (arg->flags & (GF_ARG_HINT_EXPERIMENTAL|GF_ARG_HINT_EXPERT) )) + continue; + gf_sys_print_arg(helpout, help_flags, arg, "mp4client"); + } +} + +typedef enum +{ + MP4C_QUIT = 0, + MP4C_KILL, + MP4C_RELOAD, + MP4C_OPEN, + MP4C_OPEN_PL, + MP4C_PL_NEXT, + MP4C_PL_JUMP, + MP4C_DISCONNECT, + MP4C_SELECT, + MP4C_PAUSE_RESUME, + MP4C_STEP, + MP4C_SEEK, + MP4C_SEEK_TIME, + MP4C_TIME, + MP4C_UPDATE, + MP4C_EVALJS, + MP4C_SCREENSHOT, + MP4C_WORLDINFO, + MP4C_ODLIST, + MP4C_ODINFO_ID, + MP4C_ODINFO_NUM, + MP4C_ODTIME, + MP4C_ODBUF, + MP4C_DUMPSCENE, + MP4C_STRESSMODE, + MP4C_NAVMODE, + MP4C_LASTVP, + MP4C_OGL2D, + MP4C_AR_4_3, + MP4C_AR_16_9, + MP4C_AR_NONE, + MP4C_AR_ORIG, + MP4C_LOGS, + MP4C_RELOAD_OPTS, + MP4C_DISP_RTI, + MP4C_DISP_FPS, + MP4C_DISP_STATS, + MP4C_DISP_GRAPH, + MP4C_HELP, + MP4C_DOWNRATE, + MP4C_VMEM_CACHE, + +} MP4C_Command; + +struct _mp4c_key +{ + u8 char_code; + MP4C_Command cmd_type; + const char *cmd_help; + u32 flags; +} MP4C_Keys[] = { + {'q', MP4C_QUIT, "quit", 0}, + {'X', MP4C_KILL, "kill", 0}, + {'r', MP4C_KILL, "reload current presentation", 0}, + {'o', MP4C_OPEN, "connect to the specified URL", 0}, + {'O', MP4C_OPEN_PL, "connect to the specified playlist", 0}, + {'N', MP4C_PL_NEXT, "switch to the next URL in the playlist. Also works with `\\n`", 0}, + {'P', MP4C_PL_JUMP, "jump to a given number ahead in the playlist", 0}, + {'D', MP4C_DISCONNECT, "disconnect the current presentation", 0}, + {'G', MP4C_SELECT, "select object or service ID", 0}, + {'p', MP4C_PAUSE_RESUME, "play/pause the presentation", 0}, + {'s', MP4C_STEP, "step one frame ahead", 0}, + {'z', MP4C_SEEK, "seek into presentation by percentage", 0}, + {'T', MP4C_SEEK_TIME, "seek into presentation by time", 0}, + {'t', MP4C_TIME, "print current timing", 0}, + {'u', MP4C_UPDATE, "send a command (BIFS or LASeR) to the main scene", 0}, + {'e', MP4C_EVALJS, "evaluate JavaScript code in the main scene", 0}, + {'Z', MP4C_SCREENSHOT, "dump current output frame to PNG", 0}, + {'w', MP4C_WORLDINFO, "view world info", 0}, + { 'v', MP4C_ODLIST, "view list of active media objects in scene", 0}, + { 'i', MP4C_ODINFO_ID, "view Object Descriptor info (by ID)", 0}, + { 'j', MP4C_ODINFO_NUM, "view Object Descriptor info (by number)", 0}, + { 'b', MP4C_ODTIME, "view media objects timing and buffering info", 0}, + { 'm', MP4C_ODBUF, "view media objects buffering and memory info", 0}, + { 'd', MP4C_DUMPSCENE, "dump scene graph", 0}, + { 'k', MP4C_STRESSMODE, "turn stress mode on/off", 0}, + { 'n', MP4C_NAVMODE, "change navigation mode", 0}, + { 'x', MP4C_LASTVP, "reset to last active viewpoint", 0}, + { '3', MP4C_OGL2D, "switch OpenGL on or off for 2D scenes", 0}, + { '4', MP4C_AR_4_3, "force 4/3 Aspect Ratio", 0}, + { '5', MP4C_AR_16_9, "force 16/9 Aspect Ratio", 0}, + { '6', MP4C_AR_NONE, "force no Aspect Ratio (always fill screen)", 0}, + { '7', MP4C_AR_ORIG, "force original Aspect Ratio (default)", 0}, + { 'H', MP4C_DOWNRATE, "set HTTP max download rate", 0}, + { 'E', MP4C_RELOAD_OPTS, "force reload of compositor options", 0}, + + { 'L', MP4C_LOGS, "change to new log tool/level. CF MP4Client usage for possible values", 0}, + { 'R', MP4C_DISP_RTI, "toggle run-time info display in window title bar on/off", 0}, + { 'F', MP4C_DISP_FPS, "toggle displaying of FPS in stderr on/off", 0}, + { 'f', MP4C_DISP_STATS, "print filter session stats", 0}, + { 'g', MP4C_DISP_GRAPH, "print filter session graph", 0}, + + { 'h', MP4C_HELP, "print this message", 0}, + //below this, only experimental features + { 'M', MP4C_VMEM_CACHE, "specify video cache memory for 2D objects", 1}, + {0} +}; + +MP4C_Command get_cmd(u8 char_code) +{ + u32 i=0; + while (MP4C_Keys[i].char_code) { + if (MP4C_Keys[i].char_code == char_code) + return MP4C_Keys[i].cmd_type; + i++; + } + return 0; } void PrintHelp() { - fprintf(stderr, "MP4Client command keys:\n" - "\tq: quit\n" - "\tX: kill\n" - "\to: connect to the specified URL\n" - "\tO: connect to the specified playlist\n" - "\tN: switch to the next URL in the playlist. Also works with \\n\n" - "\tP: jumps to a given number ahead in the playlist\n" - "\tr: reload current presentation\n" - "\tD: disconnects the current presentation\n" - "\tG: selects object or service ID\n" - "\n" - "\tp: play/pause the presentation\n" - "\ts: step one frame ahead\n" - "\tz: seek into presentation by percentage\n" - "\tT: seek into presentation by time\n" - "\tt: print current timing\n" - "\n" - "\tu: sends a command (BIFS or LASeR) to the main scene\n" - "\te: evaluates JavaScript code\n" - "\tZ: dumps output video to PNG\n" - "\n" - "\tw: view world info\n" - "\tv: view Object Descriptor list\n" - "\ti: view Object Descriptor info (by ID)\n" - "\tj: view Object Descriptor info (by number)\n" - "\tb: view media objects timing and buffering info\n" - "\tm: view media objects buffering and memory info\n" - "\td: dumps scene graph\n" - "\n" - "\tk: turns stress mode on/off\n" - "\tn: changes navigation mode\n" - "\tx: reset to last active viewpoint\n" - "\n" - "\t3: switch OpenGL on or off for 2D scenes\n" - "\n" - "\t4: forces 4/3 Aspect Ratio\n" - "\t5: forces 16/9 Aspect Ratio\n" - "\t6: forces no Aspect Ratio (always fill screen)\n" - "\t7: forces original Aspect Ratio (default)\n" - "\n" - "\tL: changes to new log level. CF MP4Client usage for possible values\n" - "\tT: select new tools to log. CF MP4Client usage for possible values\n" - "\n" - "\tl: list available modules\n" - "\tc: prints some GPAC configuration info\n" - "\tE: forces reload of GPAC configuration\n" - "\n" - "\tR: toggles run-time info display in window title bar on/off\n" - "\tF: toggle displaying of FPS in stderr on/off\n" - "\tg: print GPAC allocated memory\n" - "\th: print this message\n" - "\n" - "\tEXPERIMENTAL/UNSTABLE OPTIONS\n" - "\tC: Enable Streaming Cache\n" - "\tS: Stops Streaming Cache and save to file\n" - "\tA: Aborts Streaming Cache\n" - "\tM: specifies video cache memory for 2D objects\n" - "\n" - "MP4Client - GPAC command line player - version %s\n" - "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n", - - GPAC_FULL_VERSION - ); + u32 i=0; + + gf_sys_format_help(helpout, help_flags, "# MP4Client runtime commands\n" + "## Prompt Interaction\n" + "The following keys are used for prompt interaction:\n"); + + while (MP4C_Keys[i].char_code) { + struct _mp4c_key *k = &MP4C_Keys[i]; + i++; + gf_sys_format_help(helpout, help_flags|GF_PRINTARG_HIGHLIGHT_FIRST, "%c: %s%s\n", k->char_code, k->cmd_help, k->flags ? " **! experimental !**" : ""); + } + + gf_sys_format_help(helpout, help_flags, "\n" + "## Content interaction\n" + "It is possible to interact with content (interactive or not) using mouse and keyboard.\n" + "The following commands are available:\n" + "TODO\n" + "\n" + ); } @@ -381,8 +449,6 @@ static void PrintTime(u64 time) fprintf(stderr, "%02d:%02d:%02d.%03d", h, m, s, ms); } -void PrintAVInfo(Bool final); - static u32 rti_update_time_ms = 200; static FILE *rti_logs = NULL; @@ -392,6 +458,7 @@ static void UpdateRTInfo(const char *legend) GF_SystemRTInfo rti; /*refresh every second*/ + if (!Run) return; if (!display_rti && !rti_logs) return; if (!gf_sys_get_rti(rti_update_time_ms, &rti, 0) && !legend) return; @@ -432,43 +499,46 @@ static void UpdateRTInfo(const char *legend) } } +#include +#define MP4CLIENT_CAPTION "GPAC MP4Client "GPAC_VERSION "-rev" GPAC_GIT_REVISION + static void ResetCaption() { GF_Event event; if (display_rti) return; event.type = GF_EVENT_SET_CAPTION; + event.caption.caption = NULL; + if (is_connected) { char szName[1024]; - NetInfoCommand com; + GF_TermURLInfo urli; - event.caption.caption = NULL; /*get any service info*/ - if (!startup_file && gf_term_get_service_info(term, gf_term_get_root_object(term), &com) == GF_OK) { + if (!startup_file && gf_term_get_service_info(term, gf_term_get_root_object(term), &urli) == GF_OK) { strcpy(szName, ""); - if (com.track_info) { + if (urli.track_num) { char szBuf[10]; - sprintf(szBuf, "%02d ", (u32) (com.track_info>>16) ); + sprintf(szBuf, "%02d ", (u32) urli.track_num ); strcat(szName, szBuf); } - if (com.artist) { - strcat(szName, com.artist); + if (urli.artist) { + strcat(szName, urli.artist); strcat(szName, " "); } - if (com.name) { - strcat(szName, com.name); + if (urli.name) { + strcat(szName, urli.name); strcat(szName, " "); } - if (com.album) { + if (urli.album) { strcat(szName, "("); - strcat(szName, com.album); + strcat(szName, urli.album); strcat(szName, ")"); } - if (com.provider) { + if (urli.provider) { strcat(szName, "("); - strcat(szName, com.provider); + strcat(szName, urli.provider); strcat(szName, ")"); } - if (strlen(szName)) event.caption.caption = szName; } if (!event.caption.caption) { @@ -477,7 +547,7 @@ static void ResetCaption() event.caption.caption = str ? str+1 : the_url; } } else { - event.caption.caption = "GPAC MP4Client " GPAC_FULL_VERSION; + event.caption.caption = MP4CLIENT_CAPTION; } gf_term_user_event(term, &event); } @@ -504,6 +574,12 @@ void switch_bench(u32 is_on) gf_term_set_option(term, GF_OPT_VIDEO_BENCH, is_on); } +#ifdef GPAC_ENABLE_COVERAGE +#define getch() 0 +#define read_line_input(_line, _maxSize, _showContent) GF_FALSE + +#else + #ifndef WIN32 #include int getch() { @@ -536,7 +612,7 @@ int getch() { * @param maxSize the maximum size of the line to read * @param showContent boolean indicating if the line read should be printed on stderr or not */ -static const char * read_line_input(char * line, int maxSize, Bool showContent) { +static Bool read_line_input(char * line, int maxSize, Bool showContent) { char read; int i = 0; if (fflush( stderr )) @@ -544,7 +620,7 @@ static const char * read_line_input(char * line, int maxSize, Bool showContent) do { line[i] = '\0'; if (i >= maxSize - 1) - return line; + return GF_FALSE; read = getch(); if (read == 8 || read == 127) { if (i > 0) { @@ -558,9 +634,10 @@ static const char * read_line_input(char * line, int maxSize, Bool showContent) fflush(stderr); } while (read != '\n'); if (!read) - return 0; - return line; + return GF_FALSE; + return GF_TRUE; } +#endif //!GPAC_ENABLE_COVERAGE static void do_set_speed(Fixed desired_speed) { @@ -579,6 +656,8 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) if (gui_mode==1) { if (evt->type==GF_EVENT_QUIT) { Run = 0; + if (evt->message.error>0) + ret_val = evt->message.error; } else if (evt->type==GF_EVENT_KEYDOWN) { switch (evt->key.key_code) { case GF_KEY_C: @@ -620,8 +699,9 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CONSOLE, ("%s %s: %s\n", servName, evt->message.message, gf_error_to_string(evt->message.error))); } - } else if (!be_quiet) + } else { GF_LOG(GF_LOG_INFO, GF_LOG_CONSOLE, ("%s %s\n", servName, evt->message.message)); + } } break; case GF_EVENT_PROGRESS: @@ -682,7 +762,6 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } 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) { @@ -814,6 +893,10 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) if (playback_speed != FIX_ONE) gf_term_set_speed(term, playback_speed); + if (do_coverage) { + gf_term_switch_quality(term, 1); + } + } else if (is_connected) { fprintf(stderr, "Service %s\n", is_connected ? "Disconnected" : "Connection Failed"); is_connected = 0; @@ -826,7 +909,13 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) break; case GF_EVENT_EOS: eos_seen = GF_TRUE; - if (!playlist && loop_at_end) restart = 1; + if (playlist) { + if (Duration>1500) + request_next_playlist_item = GF_TRUE; + } + else if (loop_at_end) { + restart = 1; + } break; case GF_EVENT_SIZE: if (user.init_flags & GF_TERM_WINDOWLESS) { @@ -839,23 +928,28 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } break; case GF_EVENT_SCENE_SIZE: - if (forced_width && forced_height) { + + if ((forced_width && forced_height) || scale) { GF_Event size; - size.type = GF_EVENT_SIZE; - size.size.width = forced_width; - size.size.height = forced_height; - gf_term_user_event(term, &size); + u32 nw = forced_width ? forced_width : evt->size.width; + u32 nh = forced_height ? forced_height : evt->size.height; + + if (scale != 1) { + nw = (u32)(nw * scale); + nh = (u32)(nh * scale); + } + if ((nw != evt->size.width) || (nh != evt->size.height)) { + size.type = GF_EVENT_SIZE; + size.size.width = nw; + size.size.height = nh; + gf_term_user_event(term, &size); + } } break; case GF_EVENT_METADATA: ResetCaption(); break; - - case GF_EVENT_RELOAD: - if (is_connected) - reload = 1; - break; case GF_EVENT_DROPFILE: { u32 i, pos; @@ -867,9 +961,9 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) readonly_playlist = 0; if (!playlist) { readonly_playlist = 0; - playlist = gf_temp_file_new(NULL); + playlist = gf_file_temp(NULL); } - pos = ftell(playlist); + pos = (u32) gf_ftell(playlist); i=0; while (iopen_file.nb_files) { if (evt->open_file.files[i] != NULL) { @@ -877,14 +971,16 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } i++; } - fseek(playlist, pos, SEEK_SET); + gf_fseek(playlist, pos, SEEK_SET); request_next_playlist_item = 1; } return 1; case GF_EVENT_QUIT: - if (evt->message.error) { + if (evt->message.error<0) { fprintf(stderr, "A fatal error was encoutered: %s (%s) - exiting ...\n", evt->message.message ? evt->message.message : "no details", gf_error_to_string(evt->message.error) ); + } else { + ret_val = evt->message.error; } Run = 0; break; @@ -896,11 +992,13 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } break; case GF_EVENT_NAVIGATE_INFO: - if (evt->navigate.to_url) fprintf(stderr, "Go to URL: \"%s\"\r", evt->navigate.to_url); + if (evt->navigate.to_url) + fprintf(stderr, "Go to URL: \"%s\"\r", evt->navigate.to_url); break; case GF_EVENT_NAVIGATE: if (gf_term_is_supported_url(term, evt->navigate.to_url, 1, no_mime_check)) { - strcpy(the_url, evt->navigate.to_url); + strncpy(the_url, evt->navigate.to_url, sizeof(the_url)-1); + the_url[sizeof(the_url) - 1] = 0; fprintf(stderr, "Navigating to URL %s\n", the_url); gf_term_navigate_to(term, evt->navigate.to_url); return 1; @@ -913,20 +1011,23 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) break; case GF_EVENT_AUTHORIZATION: { - int maxTries = 1; + u32 nb_retry = 4; assert( evt->type == GF_EVENT_AUTHORIZATION); assert( evt->auth.user); assert( evt->auth.password); assert( evt->auth.site_url); - while ((!strlen(evt->auth.user) || !strlen(evt->auth.password)) && (maxTries--) >= 0) { + while ((!strlen(evt->auth.user) || !strlen(evt->auth.password)) && (nb_retry > 0) ) { + nb_retry--; fprintf(stderr, "**** Authorization required for site %s ****\n", evt->auth.site_url); fprintf(stderr, "login : "); - read_line_input(evt->auth.user, 50, 1); + if (!read_line_input(evt->auth.user, 50, 1)) + continue; fprintf(stderr, "\npassword: "); - read_line_input(evt->auth.password, 50, 0); + if (!read_line_input(evt->auth.password, 50, 0)) + continue; fprintf(stderr, "*********\n"); } - if (maxTries < 0) { + if (nb_retry == 0) { fprintf(stderr, "**** No User or password has been filled, aborting ***\n"); return 0; } @@ -943,12 +1044,12 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } -void list_modules(GF_ModuleManager *modules) +void list_modules() { u32 i; fprintf(stderr, "\rAvailable modules:\n"); - for (i=0; i #endif -static void progress_quiet(const void *cbck, const char *title, u64 done, u64 total) { } - int mp4client_main(int argc, char **argv) { char c; + MP4C_Command cmdtype; const char *str; - int ret_val = 0; - u32 i, times[100], nb_times, dump_mode; + GF_Err e; + u32 i, ll; u32 simulation_time_in_ms = 0; u32 initial_service_id = 0; Bool auto_exit = GF_FALSE; - Bool logs_set = GF_FALSE; Bool start_fs = GF_FALSE; Bool use_rtix = GF_FALSE; Bool pause_at_first = GF_FALSE; Bool no_cfg_save = GF_FALSE; - Bool is_cfg_only = GF_FALSE; - + Bool print_stats = GF_FALSE; + Bool print_graph = GF_FALSE; + Bool no_keyboard = GF_FALSE; Double play_from = 0; #ifdef GPAC_MEMORY_TRACKING GF_MemTrackerType mem_track = GF_MemTrackerNone; #endif - Double fps = GF_IMPORT_DEFAULT_FPS; - Bool fill_ar, visible, do_uncache; - char *url_arg, *out_arg, *the_cfg, *rti_file, *views, *default_com; + Bool has_command; + char *url_arg, *gpac_profile, *rti_file; FILE *logfile = NULL; - Float scale = 1; #ifndef WIN32 dlopen(NULL, RTLD_NOW|RTLD_GLOBAL); #endif + helpout = stdout; + /*by default use current dir*/ strcpy(the_url, "."); memset(&user, 0, sizeof(GF_User)); - dump_mode = DUMP_NONE; - fill_ar = visible = do_uncache = GF_FALSE; - url_arg = out_arg = the_cfg = rti_file = views = default_com = NULL; - nb_times = 0; - times[0] = 0; + has_command = GF_FALSE; + url_arg = gpac_profile = rti_file = NULL; - /*first locate config file if specified*/ + /*first identify profile and mem tracking */ for (i=1; i<(u32) argc; i++) { char *arg = argv[i]; - if (!strcmp(arg, "-c") || !strcmp(arg, "-cfg")) { - the_cfg = argv[i+1]; + if (!strcmp(arg, "-p")) { + gpac_profile = argv[i+1]; i++; - } - else if (!strcmp(arg, "-mem-track") || !strcmp(arg, "-mem-track-stack")) { + } else if (!strncmp(arg, "-p=", 3)) { + gpac_profile = argv[i]+3; + } else if (!strcmp(arg, "-mem-track") || !strcmp(arg, "-mem-track-stack")) { #ifdef GPAC_MEMORY_TRACKING mem_track = !strcmp(arg, "-mem-track-stack") ? GF_MemTrackerBackTrace : GF_MemTrackerSimple; #else @@ -1238,162 +1183,139 @@ int mp4client_main(int argc, char **argv) } else if (!strcmp(arg, "-guid")) { gui_mode = 2; } else if (!strcmp(arg, "-h") || !strcmp(arg, "-help")) { - PrintUsage(); + PrintUsage(GF_FALSE); + return 0; + } else if (!strcmp(arg, "-hx")) { + PrintUsage(GF_TRUE); + return 0; + } else if (!strcmp(arg, "-hr")) { + PrintHelp(); + return 0; + } else if (!strcmp(arg, "-hc")) { + fprintf(helpout, "libgpac options:\n"); + gf_sys_print_core_help(helpout, help_flags, GF_ARGMODE_ALL, 0); return 0; } } #ifdef GPAC_MEMORY_TRACKING - gf_sys_init(mem_track); + gf_sys_init(mem_track, gpac_profile); #else - gf_sys_init(GF_MemTrackerNone); + gf_sys_init(GF_MemTrackerNone, gpac_profile); #endif - gf_sys_set_args(argc, (const char **) argv); - cfg_file = gf_cfg_init(the_cfg, NULL); - if (!cfg_file) { - fprintf(stderr, "Error: Configuration File not found\n"); - return 1; - } - /*if logs are specified, use them*/ - if (gf_log_set_tools_levels( gf_cfg_get_key(cfg_file, "General", "Logs") ) != GF_OK) { - return 1; - } + gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING); + //we by default want 2 additional threads: + //main thread might get locked on vsync + //second thread might be busy decoding audio/video + //third thread will then be able to refill all buffers/perform networks tasks + gf_opts_set_key("temp", "threads", "2"); - if( gf_cfg_get_key(cfg_file, "General", "Logs") != NULL ) { - logs_set = GF_TRUE; + e = gf_sys_set_args(argc, (const char **) argv); + if (e) { + fprintf(stderr, "Error assigning libgpac arguments: %s\n", gf_error_to_string(e) ); + gf_sys_close(); + return 1; } if (!gui_mode) { - str = gf_cfg_get_key(cfg_file, "General", "ForceGUI"); + str = gf_opts_get_key("General", "ForceGUI"); if (str && !strcmp(str, "yes")) gui_mode = 1; } for (i=1; i<(u32) argc; i++) { char *arg = argv[i]; - if (!strcmp(arg, "-rti")) { + if (!strcmp(arg, "-genmd")) { + help_flags = GF_PRINTARG_MD; + helpout = gf_fopen("mp4client.md", "w"); + + fprintf(helpout, "[**HOME**](Home) » MP4Client \n"); + fprintf(helpout, "\n"); + PrintUsage(GF_TRUE); + PrintHelp(); + gf_fclose(helpout); + gf_sys_close(); + return 0; + } else if (!strcmp(arg, "-genman")) { + help_flags = GF_PRINTARG_MAN; + helpout = gf_fopen("mp4client.1", "w"); + + + fprintf(helpout, ".TH MP4Client 1 2019 MP4Client GPAC\n"); + fprintf(helpout, ".\n.SH NAME\n.LP\nMP4Client \\- GPAC command-line media player\n.SH SYNOPSIS\n.LP\n.B MP4Client\n.RI [options] \\ [file]\n.br\n.\n"); + + PrintUsage(GF_TRUE); + PrintHelp(); + + fprintf(helpout, ".SH EXAMPLES\n.TP\nBasic and advanced examples are available at https://wiki.gpac.io/mp4client\n"); + fprintf(helpout, ".SH MORE\n.LP\nAuthors: GPAC developers, see git repo history (-log)\n" + ".br\nFor bug reports, feature requests, more information and source code, visit http://github.com/gpac/gpac\n" + ".br\nbuild: %s\n" + ".br\nCopyright: %s\n.br\n" + ".SH SEE ALSO\n" + ".LP\ngpac(1), MP4Box(1)\n", gf_gpac_version(), gf_gpac_copyright()); + + gf_fclose(helpout); + gf_sys_close(); + return 0; + } else if (!strcmp(arg, "-rti")) { rti_file = argv[i+1]; i++; } else if (!strcmp(arg, "-rtix")) { rti_file = argv[i+1]; i++; use_rtix = GF_TRUE; + } else if (!strcmp(arg, "-rti-refresh")) { + rti_update_time_ms = atoi(argv[i+1]); + i++; } else if (!stricmp(arg, "-size")) { /*usage of %ud breaks sscanf on MSVC*/ if (sscanf(argv[i+1], "%dx%d", &forced_width, &forced_height) != 2) { forced_width = forced_height = 0; } i++; - } else if (!strcmp(arg, "-quiet")) { - be_quiet = 1; - } else if (!strcmp(arg, "-strict-error")) { - gf_log_set_strict_error(1); - } else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) { - logfile = gf_fopen(argv[i+1], "wt"); - gf_log_set_callback(logfile, on_gpac_log); - i++; - } else if (!strcmp(arg, "-logs") ) { - if (gf_log_set_tools_levels(argv[i+1]) != GF_OK) { - return 1; - } - logs_set = GF_TRUE; - i++; - } else if (!strcmp(arg, "-log-clock") || !strcmp(arg, "-lc")) { - log_time_start = 1; - } else if (!strcmp(arg, "-log-utc") || !strcmp(arg, "-lu")) { - log_utc_time = 1; } -#if defined(__DARWIN__) || defined(__APPLE__) - else if (!strcmp(arg, "-thread")) threading_flags = 0; -#else - else if (!strcmp(arg, "-no-thread")) threading_flags = GF_TERM_NO_DECODER_THREAD | GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_WINDOW_NO_THREAD; -#endif - else if (!strcmp(arg, "-no-compositor-thread")) threading_flags |= GF_TERM_NO_COMPOSITOR_THREAD; - 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, "-opt")) { - set_cfg_option(argv[i+1]); - i++; - } else if (!strcmp(arg, "-conf")) { - set_cfg_option(argv[i+1]); - is_cfg_only=GF_TRUE; - i++; - } - else if (!strcmp(arg, "-ifce")) { - gf_cfg_set_key(cfg_file, "Network", "DefaultMCastInterface", argv[i+1]); + //libgpac opts using an argument + else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf") || !strcmp(arg, "-logs") || !strcmp(arg, "-cfg") || !strcmp(arg, "-ifce") ) { i++; } - else if (!stricmp(arg, "-help")) { - PrintUsage(); - return 1; + + else if (!strcmp(arg, "-no-thread")) { + gf_opts_set_key("temp", "threads", "0"); } - else if (!stricmp(arg, "-noprog")) { - no_prog=1; - gf_set_progress_callback(NULL, progress_quiet); + else if (!strcmp(arg, "-no-audio")) { + no_audio = GF_TRUE; } + else if (!strcmp(arg, "-fs")) start_fs = 1; else if (!stricmp(arg, "-no-save") || !stricmp(arg, "--no-save") /*old versions used --n-save ...*/) { no_cfg_save=1; } - else if (!stricmp(arg, "-ntp-shift")) { - s32 shift = atoi(argv[i+1]); - i++; - gf_net_set_ntp_shift(shift); - } else if (!stricmp(arg, "-run-for")) { - simulation_time_in_ms = atoi(argv[i+1]) * 1000; + simulation_time_in_ms = (u32) (atof(argv[i+1]) * 1000); if (!simulation_time_in_ms) simulation_time_in_ms = 1; /*1ms*/ i++; - } - - else if (!strcmp(arg, "-out")) { - out_arg = argv[i+1]; - i++; - } - else if (!stricmp(arg, "-fps")) { - fps = atof(argv[i+1]); - i++; - } else if (!strcmp(arg, "-avi") || !strcmp(arg, "-sha")) { - dump_mode &= 0xFFFF0000; - - if (!strcmp(arg, "-sha")) dump_mode |= DUMP_SHA1; - else dump_mode |= DUMP_AVI; - - if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) { - if (!strcmp(arg, "-avi") && (nb_times!=2) ) { - fprintf(stderr, "Only one time arg found for -avi - check usage\n"); - return 1; - } - i++; - } - } else if (!strcmp(arg, "-rgbds")) { /*get dump in rgbds pixel format*/ - dump_mode |= DUMP_RGB_DEPTH_SHAPE; - } else if (!strcmp(arg, "-rgbd")) { /*get dump in rgbd pixel format*/ - dump_mode |= DUMP_RGB_DEPTH; - } else if (!strcmp(arg, "-depth")) { - dump_mode |= DUMP_DEPTH_ONLY; - } else if (!strcmp(arg, "-bmp")) { - dump_mode &= 0xFFFF0000; - dump_mode |= DUMP_BMP; - if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++; - } else if (!strcmp(arg, "-png")) { - dump_mode &= 0xFFFF0000; - dump_mode |= DUMP_PNG; - if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++; - } else if (!strcmp(arg, "-raw")) { - dump_mode &= 0xFFFF0000; - dump_mode |= DUMP_RAW; - if ((url_arg || (i+2<(u32)argc)) && get_time_list(argv[i+1], times, &nb_times)) i++; } else if (!stricmp(arg, "-scale")) { sscanf(argv[i+1], "%f", &scale); i++; } - + /* already parsed */ + else if (!strcmp(arg, "-nk")) { + no_keyboard = GF_TRUE; + } + /* already parsed */ + else if (!strcmp(arg, "-p")) { + i++; + } + /* already parsed */ + else if (!strcmp(arg, "-mem-track") || !strcmp(arg, "-mem-track-stack") || !strcmp(arg, "-gui") || !strcmp(arg, "-guid") + || !strncmp(arg, "-p=", 3) + ) { + } + /*arguments only used in non-gui mode*/ - if (!gui_mode) { + else if (!gui_mode) { if (arg[0] != '-') { if (url_arg) { fprintf(stderr, "Several input URLs provided (\"%s\", \"%s\"). Check your command-line.\n", url_arg, arg); @@ -1426,57 +1348,40 @@ int mp4client_main(int argc, char **argv) if (argv[i+1][1]=='m') align_mode |= 1; else if (argv[i+1][1]=='r') align_mode |= 2; i++; - } else if (!strcmp(arg, "-fill")) { - fill_ar = GF_TRUE; - } else if (!strcmp(arg, "-show")) { - visible = 1; - } else if (!strcmp(arg, "-uncache")) { - do_uncache = GF_TRUE; } else if (!strcmp(arg, "-exit")) auto_exit = GF_TRUE; - else if (!stricmp(arg, "-views")) { - views = argv[i+1]; - i++; - } else if (!stricmp(arg, "-com")) { - default_com = argv[i+1]; + has_command = GF_TRUE; i++; } else if (!stricmp(arg, "-service")) { initial_service_id = atoi(argv[i+1]); i++; + } else if (!stricmp(arg, "-stats")) { + print_stats=GF_TRUE; + } else if (!stricmp(arg, "-graph")) { + print_graph=GF_TRUE; + } else if (!stricmp(arg, "-cov")) { + do_coverage = GF_TRUE; + print_stats = GF_TRUE; + print_graph = GF_TRUE; + } else { + u32 res = gf_sys_is_gpac_arg(arg); + if (!res) { + fprintf(stderr, "Unrecognized option %s\n", arg); + } else if (res==2) { + i++; + } } + } else if (gf_sys_is_gpac_arg(arg)==2) { + i++; } - } - if (is_cfg_only) { - gf_cfg_del(cfg_file); - fprintf(stderr, "GPAC Config updated\n"); - return 0; - } - if (do_uncache) { - const char *cache_dir = gf_cfg_get_key(cfg_file, "General", "CacheDirectory"); - do_flatten_cache(cache_dir); - fprintf(stderr, "GPAC Cache dir %s flattened\n", cache_dir); - gf_cfg_del(cfg_file); - return 0; - } + } - if (dump_mode && !url_arg ) { - FILE *test; - url_arg = (char *)gf_cfg_get_key(cfg_file, "General", "StartupFile"); - test = url_arg ? gf_fopen(url_arg, "rt") : NULL; - if (!test) url_arg = NULL; - else gf_fclose(test); - - if (!url_arg) { - fprintf(stderr, "Missing argument for dump\n"); - PrintUsage(); - if (logfile) gf_fclose(logfile); - return 1; - } - } + //will run switch helpout to stderr + helpout = stderr; - if (!gui_mode && !url_arg && (gf_cfg_get_key(cfg_file, "General", "StartupFile") != NULL)) { + if (!gui_mode && !url_arg && (gf_opts_get_key("General", "StartupFile") != NULL)) { gui_mode=1; } @@ -1486,7 +1391,7 @@ int mp4client_main(int argc, char **argv) TCHAR buffer[1024]; DWORD res = GetCurrentDirectory(1024, buffer); buffer[res] = 0; - opt = gf_cfg_get_key(cfg_file, "General", "ModulesDirectory"); + opt = gf_opts_get_key("core", "mod-dirs"); if (strstr(opt, buffer)) { gui_mode=1; } else { @@ -1499,27 +1404,14 @@ int mp4client_main(int argc, char **argv) hide_shell(1); } if (gui_mode) { - no_prog=1; - gf_set_progress_callback(NULL, progress_quiet); + gf_sys_set_cfg_option("core:noprog=yes"); } - if (!url_arg && simulation_time_in_ms) - simulation_time_in_ms += gf_sys_clock(); - #if defined(__DARWIN__) || defined(__APPLE__) carbon_init(); #endif - if (dump_mode) rti_file = NULL; - - if (!logs_set) { - gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING); - } - //only override default log callback when needed - if (rti_file || logfile || log_utc_time || log_time_start) - gf_log_set_callback(NULL, on_gpac_log); - if (rti_file) init_rti_logs(rti_file, url_arg, use_rtix); { @@ -1529,74 +1421,37 @@ int mp4client_main(int argc, char **argv) } - /*setup dumping options*/ - if (dump_mode) { - user.init_flags |= GF_TERM_NO_DECODER_THREAD | GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_NO_REGULATION; - if (!visible) - user.init_flags |= GF_TERM_INIT_HIDE; - - gf_cfg_set_key(cfg_file, "Audio", "DriverName", "Raw Audio Output"); - no_cfg_save=GF_TRUE; - } else { - init_w = forced_width; - init_h = forced_height; - } - - user.modules = gf_modules_new(NULL, cfg_file); - if (user.modules) i = gf_modules_get_count(user.modules); - if (!i || !user.modules) { - fprintf(stderr, "Error: no modules found - exiting\n"); - if (user.modules) gf_modules_del(user.modules); - gf_cfg_del(cfg_file); - gf_sys_close(); - if (logfile) gf_fclose(logfile); - return 1; - } - fprintf(stderr, "Modules Found : %d \n", i); + init_w = forced_width; + init_h = forced_height; - user.config = cfg_file; user.EventProc = GPAC_EventProc; /*dummy in this case (global vars) but MUST be non-NULL*/ - user.opaque = user.modules; - if (threading_flags) user.init_flags |= threading_flags; - if (no_audio) user.init_flags |= GF_TERM_NO_AUDIO; - if (no_regulation) user.init_flags |= GF_TERM_NO_REGULATION; - - if (threading_flags & (GF_TERM_NO_DECODER_THREAD|GF_TERM_NO_COMPOSITOR_THREAD) ) term_step = GF_TRUE; + user.opaque = &user; - //in dump mode we don't want to rely on system clock but on the number of samples being consumed - if (dump_mode) user.init_flags |= GF_TERM_USE_AUDIO_HW_CLOCK; + if (no_audio) user.init_flags |= GF_TERM_NO_AUDIO; if (bench_mode) { - gf_cfg_discard_changes(user.config); + gf_opts_discard_changes(); auto_exit = GF_TRUE; - gf_cfg_set_key(user.config, "Audio", "DriverName", "Raw Audio Output"); - if (bench_mode!=2) { - gf_cfg_set_key(user.config, "Video", "DriverName", "Raw Video Output"); - gf_cfg_set_key(user.config, "RAWVideo", "RawOutput", "null"); - gf_cfg_set_key(user.config, "Compositor", "OpenGLMode", "disable"); - } else { - gf_cfg_set_key(user.config, "Video", "DisableVSync", "yes"); - } + if (bench_mode!=2) user.init_flags |= GF_TERM_NO_VIDEO; } - { + if (forced_width && forced_height) { char dim[50]; sprintf(dim, "%d", forced_width); - gf_cfg_set_key(user.config, "Compositor", "DefaultWidth", forced_width ? dim : NULL); + gf_opts_set_key("Temp", "DefaultWidth", dim); sprintf(dim, "%d", forced_height); - gf_cfg_set_key(user.config, "Compositor", "DefaultHeight", forced_height ? dim : NULL); + gf_opts_set_key("Temp", "DefaultHeight", dim); } fprintf(stderr, "Loading GPAC Terminal\n"); i = gf_sys_clock(); + term = gf_term_new(&user); if (!term) { fprintf(stderr, "\nInit error - check you have at least one video out and one rasterizer...\nFound modules:\n"); - list_modules(user.modules); - gf_modules_del(user.modules); - gf_cfg_discard_changes(cfg_file); - gf_cfg_del(cfg_file); + list_modules(); + gf_opts_discard_changes(); gf_sys_close(); if (logfile) gf_fclose(logfile); return 1; @@ -1609,68 +1464,54 @@ int mp4client_main(int argc, char **argv) if (bench_mode==1) bench_mode=2; } - if (dump_mode) { -// gf_term_set_option(term, GF_OPT_VISIBLE, 0); - if (fill_ar) gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); - } else { - /*check video output*/ - str = gf_cfg_get_key(cfg_file, "Video", "DriverName"); - if (!bench_mode && !strcmp(str, "Raw Video Output")) fprintf(stderr, "WARNING: using raw output video (memory only) - no display used\n"); - /*check audio output*/ - str = gf_cfg_get_key(cfg_file, "Audio", "DriverName"); - if (!str || !strcmp(str, "No Audio Output Available")) fprintf(stderr, "WARNING: no audio output available - make sure no other program is locking the sound card\n"); + str = gf_opts_get_key("General", "NoMIMETypeFetch"); + no_mime_check = (str && !stricmp(str, "yes")) ? 1 : 0; - str = gf_cfg_get_key(cfg_file, "General", "NoMIMETypeFetch"); - no_mime_check = (str && !stricmp(str, "yes")) ? 1 : 0; - } - - str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Enabled"); - if (str && !strcmp(str, "yes")) { - str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Name"); + if (gf_opts_get_bool("core", "proxy-on")) { + str = gf_opts_get_key("core", "proxy-name"); if (str) fprintf(stderr, "HTTP Proxy %s enabled\n", str); } if (rti_file) { - str = gf_cfg_get_key(cfg_file, "General", "RTIRefreshPeriod"); - if (str) { - rti_update_time_ms = atoi(str); - } else { - gf_cfg_set_key(cfg_file, "General", "RTIRefreshPeriod", "200"); - } UpdateRTInfo("At GPAC load time\n"); } Run = 1; - if (dump_mode) { - if (!nb_times) { - times[0] = 0; - nb_times++; - } - ret_val = dump_file(url_arg, out_arg, dump_mode, fps, forced_width, forced_height, scale, times, nb_times); - Run = 0; - } - else if (views) { + if (url_arg && !strcmp(url_arg, "NOGUI")) { + url_arg = NULL; } /*connect if requested*/ else if (!gui_mode && url_arg) { char *ext; - strcpy(the_url, url_arg); + if (strlen(url_arg) >= sizeof(the_url)) { + fprintf(stderr, "Input url %s is too long, truncating to %d chars.\n", url_arg, (int)(sizeof(the_url) - 1)); + strncpy(the_url, url_arg, sizeof(the_url)-1); + the_url[sizeof(the_url) - 1] = 0; + } + else { + strcpy(the_url, url_arg); + } ext = strrchr(the_url, '.'); if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls"))) { - GF_Err e = GF_OK; + e = GF_OK; fprintf(stderr, "Opening Playlist %s\n", the_url); strcpy(pl_path, the_url); /*this is not clean, we need to have a plugin handle playlist for ourselves*/ if (!strncmp("http:", the_url, 5)) { +#ifdef FILTER_FIXME GF_DownloadSession *sess = gf_dm_sess_new(term->downloader, the_url, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, &e); if (sess) { e = gf_dm_sess_process(sess); - if (!e) strcpy(the_url, gf_dm_sess_get_cache_name(sess)); + if (!e) { + strncpy(the_url, gf_dm_sess_get_cache_name(sess), sizeof(the_url) - 1); + the_url[sizeof(the_url) - 1] = 0; + } gf_dm_sess_del(sess); } +#endif } playlist = e ? NULL : gf_fopen(the_url, "rt"); @@ -1689,9 +1530,10 @@ int mp4client_main(int argc, char **argv) } } else { fprintf(stderr, "Hit 'h' for help\n\n"); - str = gf_cfg_get_key(cfg_file, "General", "StartupFile"); + str = gf_opts_get_key("General", "StartupFile"); if (str) { - strcpy(the_url, "MP4Client "GPAC_FULL_VERSION); + snprintf(the_url, sizeof(the_url)-1, "MP4Client %s", gf_gpac_version() ); + the_url[sizeof(the_url) - 1] = 0; gf_term_connect(term, str); startup_file = 1; is_connected = 1; @@ -1701,25 +1543,23 @@ int mp4client_main(int argc, char **argv) if (start_fs) gf_term_set_option(term, GF_OPT_FULLSCREEN, 1); - if (views) { - char szTemp[4046]; - sprintf(szTemp, "views://%s", views); - gf_term_connect(term, szTemp); - } if (bench_mode) { rti_update_time_ms = 500; bench_mode_start = gf_sys_clock(); } + if (simulation_time_in_ms) + simulation_time_in_ms += gf_sys_clock(); + while (Run) { /*we don't want getchar to block*/ - if ((gui_mode==1) || !gf_prompt_has_input()) { + if ((gui_mode==1) || (no_keyboard || !gf_prompt_has_input()) ) { if (reload) { reload = 0; gf_term_disconnect(term); - gf_term_connect(term, startup_file ? gf_cfg_get_key(cfg_file, "General", "StartupFile") : the_url); + gf_term_connect(term, startup_file ? gf_opts_get_key("General", "StartupFile") : the_url); } if (restart && gf_term_get_option(term, GF_OPT_IS_OVER)) { restart = 0; @@ -1731,9 +1571,14 @@ int mp4client_main(int argc, char **argv) goto force_input; } - if (default_com && is_connected) { - gf_term_scene_update(term, NULL, default_com); - default_com = NULL; + if (has_command && is_connected) { + has_command = GF_FALSE; + for (i=0; i<(u32)argc; i++) { + if (!strcmp(argv[i], "-com")) { + gf_term_scene_update(term, NULL, argv[i+1]); + i++; + } + } } if (initial_service_id && is_connected) { GF_ObjectManager *root_od = gf_term_get_root_object(term); @@ -1744,11 +1589,10 @@ int mp4client_main(int argc, char **argv) } if (!use_rtix || display_rti) UpdateRTInfo(NULL); - if (term_step) { - gf_term_process_step(term); - } else { - gf_sleep(rti_update_time_ms); - } + + + gf_term_process_step(term); + if (auto_exit && eos_seen && gf_term_get_option(term, GF_OPT_IS_OVER)) { Run = GF_FALSE; } @@ -1761,11 +1605,15 @@ int mp4client_main(int argc, char **argv) } continue; } + c = gf_prompt_get_char(); force_input: - switch (c) { - case 'q': + if (c=='\n') cmdtype=MP4C_PL_NEXT; + else cmdtype = get_cmd(c); + + switch (cmdtype) { + case MP4C_QUIT: { GF_Event evt; memset(&evt, 0, sizeof(GF_Event)); @@ -1774,32 +1622,31 @@ force_input: } // Run = 0; break; - case 'X': + case MP4C_KILL: exit(0); break; - case 'Q': - break; - case 'o': + + case MP4C_OPEN: startup_file = 0; gf_term_disconnect(term); fprintf(stderr, "Enter the absolute URL\n"); - if (1 > scanf("%s", the_url)) { + if (1 > scanf("%1023s", the_url)) { fprintf(stderr, "Cannot read absolute URL, aborting\n"); break; } if (rti_file) init_rti_logs(rti_file, the_url, use_rtix); gf_term_connect(term, the_url); break; - case 'O': + case MP4C_OPEN_PL: gf_term_disconnect(term); fprintf(stderr, "Enter the absolute URL to the playlist\n"); - if (1 > scanf("%s", the_url)) { + if (1 > scanf("%1023s", the_url)) { fprintf(stderr, "Cannot read the absolute URL, aborting.\n"); break; } playlist = gf_fopen(the_url, "rt"); if (playlist) { - if (1 > fscanf(playlist, "%s", the_url)) { + if (1 > fscanf(playlist, "%1023s", the_url)) { fprintf(stderr, "Cannot read any URL from playlist, aborting.\n"); gf_fclose( playlist); break; @@ -1808,16 +1655,15 @@ force_input: gf_term_connect(term, the_url); } break; - case '\n': - case 'N': + case MP4C_PL_NEXT: if (playlist) { int res; gf_term_disconnect(term); - res = fscanf(playlist, "%s", the_url); + res = fscanf(playlist, "%1023s", the_url); if ((res == EOF) && loop_at_end) { - fseek(playlist, 0, SEEK_SET); - res = fscanf(playlist, "%s", the_url); + gf_fseek(playlist, 0, SEEK_SET); + res = fscanf(playlist, "%1023s", the_url); } if (res == EOF) { fprintf(stderr, "No more items - exiting\n"); @@ -1830,7 +1676,7 @@ force_input: } } break; - case 'P': + case MP4C_PL_JUMP: if (playlist) { u32 count; gf_term_disconnect(term); @@ -1839,7 +1685,7 @@ force_input: break; } while (count) { - if (fscanf(playlist, "%s", the_url)) { + if (fscanf(playlist, "%1023s", the_url)) { fprintf(stderr, "Failed to read line, aborting\n"); break; } @@ -1849,23 +1695,23 @@ force_input: gf_term_connect(term, the_url); } break; - case 'r': + case MP4C_RELOAD: if (is_connected) reload = 1; break; - case 'D': + case MP4C_DISCONNECT: if (is_connected) gf_term_disconnect(term); break; - case 'p': + case MP4C_PAUSE_RESUME: if (is_connected) { Bool is_pause = gf_term_get_option(term, GF_OPT_PLAY_STATE); fprintf(stderr, "[Status: %s]\n", is_pause ? "Playing" : "Paused"); gf_term_set_option(term, GF_OPT_PLAY_STATE, is_pause ? GF_STATE_PLAYING : GF_STATE_PAUSED); } break; - case 's': + case MP4C_STEP: if (is_connected) { gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); fprintf(stderr, "Step time: "); @@ -1874,8 +1720,8 @@ force_input: } break; - case 'z': - case 'T': + case MP4C_SEEK: + case MP4C_SEEK_TIME: if (!CanSeek || (Duration<=2000)) { fprintf(stderr, "scene not seekable\n"); } else { @@ -1884,7 +1730,7 @@ force_input: fprintf(stderr, "Duration: "); PrintTime(Duration); res = gf_term_get_time_in_ms(term); - if (c=='z') { + if (cmdtype==MP4C_SEEK) { res *= 100; res /= (s64)Duration; fprintf(stderr, " (current %.2f %%)\nEnter Seek percentage:\n", res); @@ -1920,7 +1766,7 @@ force_input: } break; - case 't': + case MP4C_TIME: { if (is_connected) { fprintf(stderr, "Current Time: "); @@ -1931,13 +1777,13 @@ force_input: } } break; - case 'w': + case MP4C_WORLDINFO: if (is_connected) PrintWorldInfo(term); break; - case 'v': + case MP4C_ODLIST: if (is_connected) PrintODList(term, NULL, 0, 0, "Root"); break; - case 'i': + case MP4C_ODINFO_ID: if (is_connected) { u32 ID; fprintf(stderr, "Enter OD ID (0 for main OD): "); @@ -1946,12 +1792,12 @@ force_input: ViewOD(term, ID, (u32)-1, NULL); } else { char str_url[GF_MAX_PATH]; - if (scanf("%s", str_url) == 1) + if (scanf("%1023s", str_url) == 1) ViewOD(term, 0, (u32)-1, str_url); } } break; - case 'j': + case MP4C_ODINFO_NUM: if (is_connected) { u32 num; do { @@ -1961,31 +1807,26 @@ force_input: ViewOD(term, (u32)-1, num, NULL); } break; - case 'b': + case MP4C_ODTIME: if (is_connected) ViewODs(term, 1); break; - case 'm': + case MP4C_ODBUF: if (is_connected) ViewODs(term, 0); break; - case 'l': - list_modules(user.modules); - break; - - case 'n': + case MP4C_NAVMODE: if (is_connected) set_navigation(); break; - case 'x': + case MP4C_LASTVP: if (is_connected) gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 0); break; - case 'd': + case MP4C_DUMPSCENE: if (is_connected) { GF_ObjectManager *odm = NULL; char radname[GF_MAX_PATH], *sExt; - GF_Err e; - u32 i, count, odid; + u32 count, odid; Bool xml_dump, std_out; radname[0] = 0; do { @@ -2000,7 +1841,7 @@ force_input: GF_MediaInfo info; odm = gf_term_get_object(term, root_odm, i); if (gf_term_get_object_info(term, odm, &info) == GF_OK) { - if (info.od->objectDescriptorID==odid) break; + if (info.ODID==odid) break; } odm = NULL; } @@ -2008,7 +1849,7 @@ force_input: do { fprintf(stderr, "Enter file radical name (+\'.x\' for XML dumping) - \"std\" for stderr: "); fflush(stderr); - } while( 1 > scanf("%s", radname)); + } while( 1 > scanf("%1023s", radname)); sExt = strrchr(radname, '.'); xml_dump = 0; if (sExt) { @@ -2021,10 +1862,7 @@ force_input: } break; - case 'c': - PrintGPACConfig(); - break; - case '3': + case MP4C_OGL2D: { Bool use_3d = !gf_term_get_option(term, GF_OPT_USE_OPENGL); if (gf_term_set_option(term, GF_OPT_USE_OPENGL, use_3d)==GF_OK) { @@ -2032,7 +1870,7 @@ force_input: } } break; - case 'k': + case MP4C_STRESSMODE: { Bool opt = gf_term_get_option(term, GF_OPT_STRESS_MODE); opt = !opt; @@ -2040,70 +1878,45 @@ force_input: gf_term_set_option(term, GF_OPT_STRESS_MODE, opt); } break; - case '4': + case MP4C_AR_4_3: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); break; - case '5': + case MP4C_AR_16_9: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); break; - case '6': + case MP4C_AR_NONE: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); break; - case '7': + case MP4C_AR_ORIG: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); break; - case 'C': - switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) { - case GF_MEDIA_CACHE_DISABLED: - gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_ENABLED); - break; - case GF_MEDIA_CACHE_ENABLED: - gf_term_set_option(term, GF_OPT_MEDIA_CACHE, GF_MEDIA_CACHE_DISABLED); - break; - case GF_MEDIA_CACHE_RUNNING: - fprintf(stderr, "Streaming Cache is running - please stop it first\n"); - continue; - } - switch (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)) { - case GF_MEDIA_CACHE_ENABLED: - fprintf(stderr, "Streaming Cache Enabled\n"); - break; - case GF_MEDIA_CACHE_DISABLED: - fprintf(stderr, "Streaming Cache Disabled\n"); - break; - case GF_MEDIA_CACHE_RUNNING: - fprintf(stderr, "Streaming Cache Running\n"); - break; - } - break; - case 'S': - case 'A': - if (gf_term_get_option(term, GF_OPT_MEDIA_CACHE)==GF_MEDIA_CACHE_RUNNING) { - gf_term_set_option(term, GF_OPT_MEDIA_CACHE, (c=='S') ? GF_MEDIA_CACHE_DISABLED : GF_MEDIA_CACHE_DISCARD); - fprintf(stderr, "Streaming Cache stopped\n"); - } else { - fprintf(stderr, "Streaming Cache not running\n"); - } - break; - case 'R': + case MP4C_DISP_RTI: display_rti = !display_rti; ResetCaption(); break; - case 'F': + case MP4C_DISP_FPS: if (display_rti) display_rti = 0; else display_rti = 2; ResetCaption(); break; - - case 'u': + case MP4C_DISP_STATS: + case MP4C_DISP_GRAPH: + ll = gf_log_get_tool_level(GF_LOG_APP); + gf_log_set_tool_level(GF_LOG_APP, GF_LOG_INFO); + if (cmdtype==MP4C_DISP_STATS) + gf_term_print_stats(term); + else + gf_term_print_graph(term); + gf_log_set_tool_level(GF_LOG_APP, ll); + break; + case MP4C_UPDATE: { - GF_Err e; char szCom[8192]; fprintf(stderr, "Enter command to send:\n"); - fflush(stdin); +// fflush(stdin); szCom[0] = 0; - if (1 > scanf("%[^\t\n]", szCom)) { + if (1 > scanf("%8191[^\t\n]", szCom)) { fprintf(stderr, "Cannot read command to send, aborting.\n"); break; } @@ -2111,14 +1924,13 @@ force_input: if (e) fprintf(stderr, "Processing command failed: %s\n", gf_error_to_string(e)); } break; - case 'e': + case MP4C_EVALJS: { - GF_Err e; char jsCode[8192]; fprintf(stderr, "Enter JavaScript code to evaluate:\n"); - fflush(stdin); +// fflush(stdin); jsCode[0] = 0; - if (1 > scanf("%[^\t\n]", jsCode)) { + if (1 > scanf("%8191[^\t\n]", jsCode)) { fprintf(stderr, "Cannot read code to evaluate, aborting.\n"); break; } @@ -2127,13 +1939,13 @@ force_input: } break; - case 'L': + case MP4C_LOGS: { char szLog[1024], *cur_logs; cur_logs = gf_log_get_tools_levels(); fprintf(stderr, "Enter new log level (current tools %s):\n", cur_logs); gf_free(cur_logs); - if (scanf("%s", szLog) < 1) { + if (scanf("%1023s", szLog) < 1) { fprintf(stderr, "Cannot read new log level, aborting.\n"); break; } @@ -2141,14 +1953,7 @@ force_input: } break; - case 'g': - { - GF_SystemRTInfo rti; - gf_sys_get_rti(rti_update_time_ms, &rti, 0); - fprintf(stderr, "GPAC allocated memory "LLD"\n", rti.gpac_memory); - } - break; - case 'M': + case MP4C_VMEM_CACHE: { u32 size; do { @@ -2158,7 +1963,7 @@ force_input: } break; - case 'H': + case MP4C_DOWNRATE: { u32 http_bitrate = gf_term_get_option(term, GF_OPT_HTTP_MAX_RATE); do { @@ -2169,102 +1974,24 @@ force_input: } break; - case 'E': + case MP4C_RELOAD_OPTS: gf_term_set_option(term, GF_OPT_RELOAD_CONFIG, 1); break; - case 'B': - switch_bench(!bench_mode); - break; - - case 'Y': - { - char szOpt[8192]; - fprintf(stderr, "Enter option to set (Section:Name=Value):\n"); - fflush(stdin); - szOpt[0] = 0; - if (1 > scanf("%[^\t\n]", szOpt)) { - fprintf(stderr, "Cannot read option\n"); - break; - } - set_cfg_option(szOpt); - } - break; - /*extract to PNG*/ - case 'Z': - { - char szFileName[100]; - u32 nb_pass, nb_views, offscreen_view = 0; - GF_VideoSurface fb; - GF_Err e; - nb_pass = 1; - nb_views = gf_term_get_option(term, GF_OPT_NUM_STEREO_VIEWS); - if (nb_views>1) { - fprintf(stderr, "Auto-stereo mode detected - type number of view to dump (0 is main output, 1 to %d offscreen view, %d for all offscreen, %d for all offscreen and main)\n", nb_views, nb_views+1, nb_views+2); - if (scanf("%d", &offscreen_view) != 1) { - offscreen_view = 0; - } - if (offscreen_view==nb_views+1) { - offscreen_view = 1; - nb_pass = nb_views; - } - else if (offscreen_view==nb_views+2) { - offscreen_view = 0; - nb_pass = nb_views+1; - } - } - while (nb_pass) { - nb_pass--; - if (offscreen_view) { - sprintf(szFileName, "view%d_dump.png", offscreen_view); - e = gf_term_get_offscreen_buffer(term, &fb, offscreen_view-1, 0); - } else { - sprintf(szFileName, "gpac_video_dump_"LLU".png", gf_net_get_utc() ); - e = gf_term_get_screen_buffer(term, &fb); - } - offscreen_view++; - if (e) { - fprintf(stderr, "Error dumping screen buffer %s\n", gf_error_to_string(e) ); - nb_pass = 0; - } else { -#ifndef GPAC_DISABLE_AV_PARSERS - u32 dst_size = fb.width*fb.height*4; - char *dst = (char*)gf_malloc(sizeof(char)*dst_size); - - e = gf_img_png_enc(fb.video_buffer, fb.width, fb.height, fb.pitch_y, fb.pixel_format, dst, &dst_size); - if (e) { - fprintf(stderr, "Error encoding PNG %s\n", gf_error_to_string(e) ); - nb_pass = 0; - } else { - FILE *png = gf_fopen(szFileName, "wb"); - if (!png) { - fprintf(stderr, "Error writing file %s\n", szFileName); - nb_pass = 0; - } else { - gf_fwrite(dst, dst_size, 1, png); - gf_fclose(png); - fprintf(stderr, "Dump to %s\n", szFileName); - } - } - if (dst) gf_free(dst); - gf_term_release_screen_buffer(term, &fb); -#endif //GPAC_DISABLE_AV_PARSERS - } - } - fprintf(stderr, "Done: %s\n", szFileName); - } - break; + case MP4C_SCREENSHOT: + MakeScreenshot(GF_FALSE); + break; - case 'G': + case MP4C_SELECT: { GF_ObjectManager *root_od, *odm; u32 index; char szOpt[8192]; fprintf(stderr, "Enter 0-based index of object to select or service ID:\n"); - fflush(stdin); +// fflush(stdin); szOpt[0] = 0; - if (1 > scanf("%[^\t\n]", szOpt)) { + if (1 > scanf("%8191[^\t\n]", szOpt)) { fprintf(stderr, "Cannot read OD ID\n"); break; } @@ -2272,18 +1999,22 @@ force_input: odm = NULL; root_od = gf_term_get_root_object(term); if (root_od) { - odm = gf_term_get_object(term, root_od, index); - if (odm) { - gf_term_select_object(term, odm); - } else { - fprintf(stderr, "Cannot find object at index %d - trying with serviceID\n", index); + if ( gf_term_find_service(term, root_od, index)) { gf_term_select_service(term, root_od, index); + } else { + fprintf(stderr, "Cannot find service %d - trying with object index\n", index); + odm = gf_term_get_object(term, root_od, index); + if (odm) { + gf_term_select_object(term, odm); + } else { + fprintf(stderr, "Cannot find object at index %d\n", index); + } } } } break; - case 'h': + case MP4C_HELP: PrintHelp(); break; default: @@ -2300,28 +2031,142 @@ force_input: gf_log_set_strict_error(0); } + if (print_graph || print_stats) { + ll = gf_log_get_tool_level(GF_LOG_APP); + gf_log_set_tool_level(GF_LOG_APP, GF_LOG_INFO); + if (print_graph) + gf_term_print_graph(term); + if (print_stats) + gf_term_print_stats(term); + gf_log_set_tool_level(GF_LOG_APP, ll); + } + +#ifdef GPAC_ENABLE_COVERAGE + if (do_coverage) { + u32 w, h, k, nb_drawn; + GF_Event evt; + Bool is_bound; + const char *outName; + GF_ObjectManager *root_odm, *odm; + PrintAVInfo(GF_TRUE); + PrintODList(term, NULL, 0, 0, "Root"); + ViewODs(term, GF_TRUE); + ViewODs(term, GF_FALSE); + ViewOD(term, 0, (u32) -1, NULL); + ViewOD(term, 0, 1, NULL); + PrintUsage(0); + PrintHelp(); + PrintWorldInfo(term); + gf_term_dump_scene(term, NULL, NULL, GF_FALSE, 0, NULL); + gf_term_get_current_service_id(term); + gf_term_toggle_addons(term, GF_FALSE); + set_navigation(); + get_cmd('v'); + + gf_term_play_from_time(term, 0, 0); + + memset(&evt, 0, sizeof(GF_Event)); + evt.type = GF_EVENT_MOUSEUP; + evt.mouse.x = 20; + evt.mouse.y = 20; + gf_term_send_event(term, &evt); + + gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); + //exercise step clocks + gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); + root_odm = gf_term_get_root_object(term); + gf_term_find_service(term, root_odm, 0); + gf_term_select_service(term, root_odm, 0); + odm = gf_term_get_object(term, root_odm, 0); + gf_term_select_object(term, odm ); + gf_term_object_subscene_type(term, odm); + gf_term_get_visual_output_size(term, &w, &h); + + gf_term_is_type_supported(term, "video/mp4"); + gf_term_get_url(term); + gf_term_get_simulation_frame_rate(term, &nb_drawn); + + gf_term_get_text_selection(term, GF_TRUE); + gf_term_paste_text(term, "test", GF_TRUE); + + gf_term_set_option(term, GF_OPT_AUDIO_MUTE, 1); + + + MakeScreenshot(GF_TRUE); + + gf_term_scene_update(term, NULL, "REPLACE DYN_TRANS.translation BY 10 10"); + gf_term_add_object(term, NULL, GF_TRUE); + + gf_term_get_viewpoint(term, 1, &outName, &is_bound); + gf_term_set_viewpoint(term, 1, "testvp"); + + for (k=GF_NAVIGATE_WALK; k<=GF_NAVIGATE_VR; k++) { + gf_term_set_option(term, GF_OPT_NAVIGATION, k); + memset(&evt, 0, sizeof(GF_Event)); + evt.type = GF_EVENT_MOUSEDOWN; + evt.mouse.x = 100; + evt.mouse.y = 100; + gf_term_user_event(term, &evt); + evt.type = GF_EVENT_MOUSEMOVE; + evt.mouse.x += 10; + gf_term_user_event(term, &evt); + evt.mouse.y += 10; + gf_term_user_event(term, &evt); + + evt.type = GF_EVENT_KEYDOWN; + evt.key.key_code = GF_KEY_CONTROL; + gf_term_user_event(term, &evt); + + evt.type = GF_EVENT_MOUSEMOVE; + evt.mouse.x = 120; + evt.mouse.y = 110; + gf_term_user_event(term, &evt); + + evt.type = GF_EVENT_KEYUP; + evt.key.key_code = GF_KEY_CONTROL; + gf_term_user_event(term, &evt); + + evt.type = GF_EVENT_KEYDOWN; + evt.key.key_code = GF_KEY_J; + gf_term_user_event(term, &evt); + + } + gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 0); + + gf_term_connect_with_path(term, "logo.jpg", "./media/auxiliary_files/"); + gf_term_navigate_to(term, "./media/auxiliary_files/logo.jpg"); + send_open_url("./media/auxiliary_files/logo.jpg"); + switch_bench(1); + do_set_speed(1.0); + hide_shell(0); + list_modules(); + } +#endif i = gf_sys_clock(); gf_term_disconnect(term); if (rti_file) UpdateRTInfo("Disconnected\n"); - fprintf(stderr, "Deleting terminal... "); if (playlist) gf_fclose(playlist); #if defined(__DARWIN__) || defined(__APPLE__) carbon_uninit(); #endif + //special condition for immediate exit without terminal deletion + if (ret_val==3) { + fprintf(stderr, "Exit forced, no cleanup\n"); + exit(0); + } + + fprintf(stderr, "Deleting terminal... "); gf_term_del(term); fprintf(stderr, "done (in %d ms) - ran for %d ms\n", gf_sys_clock() - i, gf_sys_clock()); fprintf(stderr, "GPAC cleanup ...\n"); - gf_modules_del(user.modules); if (no_cfg_save) - gf_cfg_discard_changes(cfg_file); - - gf_cfg_del(cfg_file); + gf_opts_discard_changes(); gf_sys_close(); @@ -2343,49 +2188,90 @@ force_input: return ret_val; } -#if defined(WIN32) && !defined(NO_WMAIN) -int wmain(int argc, wchar_t** wargv) -{ - int i; - int res; - size_t len; - size_t res_len; - char **argv; - argv = (char **)malloc(argc*sizeof(wchar_t *)); - for (i = 0; i < argc; i++) { - wchar_t *src_str = wargv[i]; - len = UTF8_MAX_BYTES_PER_CHAR * gf_utf8_wcslen(wargv[i]); - argv[i] = (char *)malloc(len + 1); - res_len = gf_utf8_wcstombs(argv[i], len, &src_str); - argv[i][res_len] = 0; - if (res_len > len) { - fprintf(stderr, "Length allocated for conversion of wide char to UTF-8 not sufficient\n"); - return -1; - } - } - res = mp4client_main(argc, argv); - for (i = 0; i < argc; i++) { - free(argv[i]); - } - free(argv); - return res; -} -#else -int main(int argc, char** argv) +GF_MAIN_FUNC(mp4client_main) + + +static void MakeScreenshot(Bool for_coverage) { - return mp4client_main(argc, argv); + char szFileName[100]; + u32 nb_pass, nb_views, offscreen_view = 0; + GF_VideoSurface fb; + GF_Err e; + nb_pass = 1; + nb_views = gf_term_get_option(term, GF_OPT_NUM_STEREO_VIEWS); + if (nb_views>1) { + fprintf(stderr, "Auto-stereo mode detected - type number of view to dump (0 is main output, 1 to %d offscreen view, %d for all offscreen, %d for all offscreen and main)\n", nb_views, nb_views+1, nb_views+2); + if (!for_coverage) { + if (scanf("%d", &offscreen_view) != 1) { + offscreen_view = 0; + } + } + if (offscreen_view==nb_views+1) { + offscreen_view = 1; + nb_pass = nb_views; + } + else if (offscreen_view==nb_views+2) { + offscreen_view = 0; + nb_pass = nb_views+1; + } + } + if (for_coverage && !offscreen_view) { + if (gf_term_get_offscreen_buffer(term, &fb, 0, 0)==GF_OK) + gf_term_release_screen_buffer(term, &fb); + } + while (nb_pass) { + nb_pass--; + if (offscreen_view) { + sprintf(szFileName, "view%d_dump.png", offscreen_view); + e = gf_term_get_offscreen_buffer(term, &fb, offscreen_view-1, 0); + } else { + sprintf(szFileName, "gpac_video_dump_"LLU".png", gf_net_get_utc() ); + e = gf_term_get_screen_buffer(term, &fb); + } + offscreen_view++; + if (e) { + fprintf(stderr, "Error dumping screen buffer %s\n", gf_error_to_string(e) ); + nb_pass = 0; + } else { +#ifndef GPAC_DISABLE_AV_PARSERS + u32 dst_size = fb.width*fb.height*4; + char *dst = (char*)gf_malloc(sizeof(char)*dst_size); + + e = gf_img_png_enc(fb.video_buffer, fb.width, fb.height, fb.pitch_y, fb.pixel_format, dst, &dst_size); + if (e) { + fprintf(stderr, "Error encoding PNG %s\n", gf_error_to_string(e) ); + nb_pass = 0; + } else { + FILE *png = gf_fopen(szFileName, "wb"); + if (!png) { + fprintf(stderr, "Error writing file %s\n", szFileName); + nb_pass = 0; + } else { + gf_fwrite(dst, dst_size, png); + gf_fclose(png); + fprintf(stderr, "Dump to %s\n", szFileName); + } + } + if (dst) gf_free(dst); + gf_term_release_screen_buffer(term, &fb); + + if (for_coverage) gf_file_delete(szFileName); +#endif //GPAC_DISABLE_AV_PARSERS + } + } + fprintf(stderr, "Done: %s\n", szFileName); } -#endif //win32 + static GF_ObjectManager *video_odm = NULL; static GF_ObjectManager *audio_odm = NULL; static GF_ObjectManager *scene_odm = NULL; static u32 last_odm_count = 0; -void PrintAVInfo(Bool final) + +static void PrintAVInfo(Bool final) { GF_MediaInfo a_odi, v_odi, s_odi; - Double avg_dec_time=0; - u32 tot_time=0; - Bool print_codecs = final; + Double avg_dec_time; + u32 tot_time; if (scene_odm) { GF_ObjectManager *root_odm = gf_term_get_root_object(term); @@ -2397,7 +2283,7 @@ void PrintAVInfo(Bool final) } if (!video_odm && !audio_odm && !scene_odm) { u32 count, i; - GF_ObjectManager *root_odm = root_odm = gf_term_get_root_object(term); + GF_ObjectManager *root_odm = gf_term_get_root_object(term); if (!root_odm) return; if (gf_term_get_object_info(term, root_odm, &v_odi)==GF_OK) { @@ -2437,12 +2323,12 @@ void PrintAVInfo(Bool final) } else { memset(&v_odi, 0, sizeof(v_odi)); } - if (print_codecs && audio_odm) { + if (audio_odm) { gf_term_get_object_info(term, audio_odm, &a_odi); } else { memset(&a_odi, 0, sizeof(a_odi)); } - if ((print_codecs || !video_odm) && scene_odm) { + if (!video_odm && scene_odm) { gf_term_get_object_info(term, scene_odm, &s_odi); } else { memset(&s_odi, 0, sizeof(s_odi)); @@ -2460,54 +2346,51 @@ void PrintAVInfo(Bool final) fprintf(stderr, "Drawn %d frames FPS %.2f (simulation FPS %.2f) - duration %d ms\n", nb_frames_drawn, ((Float)nb_frames_drawn*1000)/tot_time,(Float) FPS, gf_term_get_time_in_ms(term) ); } } - if (print_codecs) { - if (video_odm) { - fprintf(stderr, "%s %dx%d sar=%d:%d duration %.2fs\n", v_odi.codec_name, v_odi.width, v_odi.height, v_odi.par ? (v_odi.par>>16)&0xFF : 1, v_odi.par ? (v_odi.par)&0xFF : 1, v_odi.duration); - if (final) { - u32 dec_run_time = v_odi.last_frame_time - v_odi.first_frame_time; - if (!dec_run_time) dec_run_time = 1; - if (v_odi.duration) fprintf(stderr, "%d%% ", (u32) (100*v_odi.current_time / v_odi.duration ) ); - fprintf(stderr, "%d frames FPS %.2f (max %d us/f) rate avg %d max %d", v_odi.nb_dec_frames, ((Float)v_odi.nb_dec_frames*1000) / dec_run_time, v_odi.max_dec_time, (u32) v_odi.avg_bitrate/1000, (u32) v_odi.max_bitrate/1000); - if (v_odi.nb_dropped) { - fprintf(stderr, " (Error during bench: %d frames drop)", v_odi.nb_dropped); - } - fprintf(stderr, "\n"); - } - } - if (audio_odm) { - fprintf(stderr, "%s SR %d num channels %d bpp %d duration %.2fs\n", a_odi.codec_name, a_odi.sample_rate, a_odi.num_channels, a_odi.bits_per_sample, a_odi.duration); - if (final) { - u32 dec_run_time = a_odi.last_frame_time - a_odi.first_frame_time; - if (!dec_run_time) dec_run_time = 1; - if (a_odi.duration) fprintf(stderr, "%d%% ", (u32) (100*a_odi.current_time / a_odi.duration ) ); - fprintf(stderr, "%d frames (ms/f %.2f avg %.2f max) rate avg %d max %d", a_odi.nb_dec_frames, ((Float)dec_run_time)/a_odi.nb_dec_frames, a_odi.max_dec_time/1000.0, (u32) a_odi.avg_bitrate/1000, (u32) a_odi.max_bitrate/1000); - if (a_odi.nb_dropped) { - fprintf(stderr, " (Error during bench: %d frames drop)", a_odi.nb_dropped); - } - fprintf(stderr, "\n"); + if (video_odm) { + fprintf(stderr, "%s %dx%d sar=%d:%d duration %.2fs\n", v_odi.codec_name, v_odi.width, v_odi.height, v_odi.par ? (v_odi.par>>16)&0xFF : 1, v_odi.par ? (v_odi.par)&0xFF : 1, v_odi.duration); + if (final) { + u32 dec_run_time = v_odi.last_frame_time - v_odi.first_frame_time; + if (!dec_run_time) dec_run_time = 1; + if (v_odi.duration) fprintf(stderr, "%d%% ", (u32) (100*v_odi.current_time / v_odi.duration ) ); + fprintf(stderr, "%d frames FPS %.2f (max %d us/f) rate avg %d max %d", v_odi.nb_dec_frames, ((Float)v_odi.nb_dec_frames*1000) / dec_run_time, v_odi.max_dec_time, (u32) v_odi.avg_bitrate/1000, (u32) v_odi.max_bitrate/1000); + if (v_odi.nb_dropped) { + fprintf(stderr, " (Error during bench: %d frames drop)", v_odi.nb_dropped); } + fprintf(stderr, "\n"); } - if (scene_odm) { - u32 w, h; - gf_term_get_visual_output_size(term, &w, &h); - fprintf(stderr, "%s scene size %dx%d rastered to %dx%d duration %.2fs\n", s_odi.codec_name ? s_odi.codec_name : "", s_odi.width, s_odi.height, w, h, s_odi.duration); - if (final) { - if (s_odi.nb_dec_frames>2 && s_odi.total_dec_time) { - u32 dec_run_time = s_odi.last_frame_time - s_odi.first_frame_time; - if (!dec_run_time) dec_run_time = 1; - fprintf(stderr, "%d frames FPS %.2f (max %d us/f) rate avg %d max %d", s_odi.nb_dec_frames, ((Float)s_odi.nb_dec_frames*1000) / dec_run_time, s_odi.max_dec_time, (u32) s_odi.avg_bitrate/1000, (u32) s_odi.max_bitrate/1000); - fprintf(stderr, "\n"); - } else { - u32 nb_frames_drawn; - Double FPS; - gf_term_get_simulation_frame_rate(term, &nb_frames_drawn); - tot_time = gf_sys_clock() - bench_mode_start; - FPS = gf_term_get_framerate(term, 0); - fprintf(stderr, "%d frames FPS %.2f (abs %.2f)\n", nb_frames_drawn, (1000.0*nb_frames_drawn / tot_time), FPS); - } + } + if (audio_odm) { + fprintf(stderr, "%s SR %d num channels %d %s duration %.2fs\n", a_odi.codec_name, a_odi.sample_rate, a_odi.num_channels, gf_audio_fmt_name(a_odi.afmt), a_odi.duration); + if (final) { + u32 dec_run_time = a_odi.last_frame_time - a_odi.first_frame_time; + if (!dec_run_time) dec_run_time = 1; + if (a_odi.duration) fprintf(stderr, "%d%% ", (u32) (100*a_odi.current_time / a_odi.duration ) ); + fprintf(stderr, "%d frames (ms/f %.2f avg %.2f max) rate avg %d max %d", a_odi.nb_dec_frames, ((Float)dec_run_time)/a_odi.nb_dec_frames, a_odi.max_dec_time/1000.0, (u32) a_odi.avg_bitrate/1000, (u32) a_odi.max_bitrate/1000); + if (a_odi.nb_dropped) { + fprintf(stderr, " (Error during bench: %d frames drop)", a_odi.nb_dropped); } + fprintf(stderr, "\n"); } + } + if (scene_odm) { + u32 w, h; + gf_term_get_visual_output_size(term, &w, &h); + fprintf(stderr, "%s scene size %dx%d rastered to %dx%d duration %.2fs\n", s_odi.codec_name ? s_odi.codec_name : "", s_odi.width, s_odi.height, w, h, s_odi.duration); if (final) { + if (s_odi.nb_dec_frames>2 && s_odi.total_dec_time) { + u32 dec_run_time = s_odi.last_frame_time - s_odi.first_frame_time; + if (!dec_run_time) dec_run_time = 1; + fprintf(stderr, "%d frames FPS %.2f (max %d us/f) rate avg %d max %d", s_odi.nb_dec_frames, ((Float)s_odi.nb_dec_frames*1000) / dec_run_time, s_odi.max_dec_time, (u32) s_odi.avg_bitrate/1000, (u32) s_odi.max_bitrate/1000); + fprintf(stderr, "\n"); + } else { + u32 nb_frames_drawn; + Double FPS; + gf_term_get_simulation_frame_rate(term, &nb_frames_drawn); + tot_time = gf_sys_clock() - bench_mode_start; + FPS = gf_term_get_framerate(term, 0); + fprintf(stderr, "%d frames FPS %.2f (abs %.2f)\n", nb_frames_drawn, (1000.0*nb_frames_drawn / tot_time), FPS); + } + fprintf(stderr, "**********************************************************\n\n"); return; } @@ -2517,7 +2400,7 @@ void PrintAVInfo(Bool final) tot_time = v_odi.last_frame_time - v_odi.first_frame_time; if (!tot_time) tot_time=1; if (v_odi.duration) fprintf(stderr, "%d%% ", (u32) (100*v_odi.current_time / v_odi.duration ) ); - fprintf(stderr, "%d f FPS %.2f (%.2f ms max) rate %d ", v_odi.nb_dec_frames, ((Float)v_odi.nb_dec_frames*1000) / tot_time, v_odi.max_dec_time/1000.0, (u32) v_odi.instant_bitrate/1000); + fprintf(stderr, "%d f FPS %.2f (%.2f ms max) rate %d ", v_odi.nb_dec_frames, ((Float)v_odi.nb_dec_frames*1000) / tot_time, v_odi.max_dec_time/1000.0, (u32) v_odi.avg_bitrate/1000); } else if (scene_odm) { @@ -2525,7 +2408,7 @@ void PrintAVInfo(Bool final) avg_dec_time = (Float) 1000000 * s_odi.nb_dec_frames; avg_dec_time /= s_odi.total_dec_time; if (s_odi.duration) fprintf(stderr, "%d%% ", (u32) (100*s_odi.current_time / s_odi.duration ) ); - fprintf(stderr, "%d f %.2f (%d us max) - rate %d ", s_odi.nb_dec_frames, avg_dec_time, s_odi.max_dec_time, (u32) s_odi.instant_bitrate/1000); + fprintf(stderr, "%d f %.2f (%d us max) - rate %d ", s_odi.nb_dec_frames, avg_dec_time, s_odi.max_dec_time, (u32) s_odi.avg_bitrate/1000); } else { u32 nb_frames_drawn; Double FPS; @@ -2536,9 +2419,8 @@ void PrintAVInfo(Bool final) } } else if (audio_odm) { - if (!print_codecs) { - gf_term_get_object_info(term, audio_odm, &a_odi); - } + gf_term_get_object_info(term, audio_odm, &a_odi); + tot_time = a_odi.last_frame_time - a_odi.first_frame_time; if (!tot_time) tot_time=1; if (a_odi.duration) fprintf(stderr, "%d%% ", (u32) (100*a_odi.current_time / a_odi.duration ) ); @@ -2546,7 +2428,7 @@ void PrintAVInfo(Bool final) } } -void PrintWorldInfo(GF_Terminal *term) +static void PrintWorldInfo(GF_Terminal *term) { u32 i; const char *title; @@ -2565,12 +2447,11 @@ void PrintWorldInfo(GF_Terminal *term) gf_list_del(descs); } -void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name) +static void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name) { GF_MediaInfo odi; u32 i, count; char szIndent[50]; - GF_ObjectManager *odm; if (!root_odm) { fprintf(stderr, "Currently loaded objects:\n"); @@ -2583,7 +2464,7 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind fprintf(stderr, "Current service ID %d\n", count); if (gf_term_get_object_info(term, root_odm, &odi) != GF_OK) return; - if (!odi.od) { + if (!odi.ODID) { fprintf(stderr, "Service not attached\n"); return; } @@ -2593,11 +2474,11 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind fprintf(stderr, "%s", szIndent); fprintf(stderr, "#%d %s - ", num, root_name); - if (odi.od->ServiceID) fprintf(stderr, "Service ID %d ", odi.od->ServiceID); + if (odi.ServiceID) fprintf(stderr, "Service ID %d ", odi.ServiceID); if (odi.media_url) { fprintf(stderr, "%s\n", odi.media_url); } else { - fprintf(stderr, "OD ID %d\n", odi.od->objectDescriptorID); + fprintf(stderr, "OD ID %d\n", odi.ODID); } szIndent[indent]=' '; @@ -2606,7 +2487,7 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind count = gf_term_get_object_count(term, root_odm); for (i=0; iobjectDescriptorID); + fprintf(stderr, "ID %d", odi.ODID); } fprintf(stderr, " - %s", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems"); - if (odi.od && odi.od->ServiceID) fprintf(stderr, " - Service ID %d", odi.od->ServiceID); + if (odi.ServiceID) fprintf(stderr, " - Service ID %d", odi.ServiceID); fprintf(stderr, "\n"); break; } @@ -2637,12 +2522,12 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind } } -void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *szURL) +static void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *szURL) { GF_MediaInfo odi; - u32 i, j, count, d_enum,id; + u32 i, count, d_enum, id; + GF_TermNetStats stats; GF_Err e; - NetStatCommand com; GF_ObjectManager *odm, *root_odm = gf_term_get_root_object(term); if (!root_odm) return; @@ -2657,7 +2542,7 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *szURL) if (!odm) break; if (gf_term_get_object_info(term, odm, &odi) == GF_OK) { if (szURL && strstr(odi.service_url, szURL)) break; - if ((number == (u32)(-1)) && (odi.od->objectDescriptorID == OD_ID)) break; + if ((number == (u32)(-1)) && (odi.ODID == OD_ID)) break; else if (i == (u32)(number-1)) break; } odm = NULL; @@ -2669,26 +2554,12 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *szURL) else fprintf(stderr, "cannot find OD with number %d\n", number); return; } - if (!odi.od) { + if (!odi.ODID) { if (number == (u32)-1) fprintf(stderr, "Object %d not attached yet\n", OD_ID); else fprintf(stderr, "Object #%d not attached yet\n", number); return; } - if (!odi.od) { - fprintf(stderr, "Service not attached\n"); - return; - } - - if (odi.od->tag==GF_ODF_IOD_TAG) { - fprintf(stderr, "InitialObjectDescriptor %d\n", odi.od->objectDescriptorID); - fprintf(stderr, "Profiles and Levels: Scene %x - Graphics %x - Visual %x - Audio %x - OD %x\n", - odi.scene_pl, odi.graphics_pl, odi.visual_pl, odi.audio_pl, odi.OD_pl); - fprintf(stderr, "Inline Profile Flag %d\n", odi.inline_pl); - } else { - fprintf(stderr, "ObjectDescriptor %d\n", odi.od->objectDescriptorID); - } - fprintf(stderr, "Object Duration: "); if (odi.duration) { PrintTime((u32) (odi.duration*1000)); @@ -2741,114 +2612,13 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *szURL) } if (odi.protection) fprintf(stderr, "Encrypted Media%s\n", (odi.protection==2) ? " NOT UNLOCKED" : ""); - count = gf_list_count(odi.od->ESDescriptors); - fprintf(stderr, "%d streams in OD\n", count); - for (i=0; iESDescriptors, i); - - fprintf(stderr, "\nStream ID %d - Clock ID %d\n", esd->ESID, esd->OCRESID); - if (esd->dependsOnESID) fprintf(stderr, "\tDepends on Stream ID %d for decoding\n", esd->dependsOnESID); - - switch (esd->decoderConfig->streamType) { - case GF_STREAM_OD: - fprintf(stderr, "\tOD Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_OCR: - fprintf(stderr, "\tOCR Stream\n"); - break; - case GF_STREAM_SCENE: - fprintf(stderr, "\tScene Description Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_VISUAL: - fprintf(stderr, "\tVisual Stream - media type: %s", gf_esd_get_textual_description(esd)); - break; - case GF_STREAM_AUDIO: - fprintf(stderr, "\tAudio Stream - media type: %s", gf_esd_get_textual_description(esd)); - break; - case GF_STREAM_MPEG7: - fprintf(stderr, "\tMPEG-7 Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_IPMP: - fprintf(stderr, "\tIPMP Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_OCI: - fprintf(stderr, "\tOCI Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_MPEGJ: - fprintf(stderr, "\tMPEGJ Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_INTERACT: - fprintf(stderr, "\tUser Interaction Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - case GF_STREAM_TEXT: - fprintf(stderr, "\tStreaming Text Stream - version %d\n", esd->decoderConfig->objectTypeIndication); - break; - default: - fprintf(stderr, "\tUnknown Stream\n"); - break; - } - - fprintf(stderr, "\tBuffer Size %d\n\tAverage Bitrate %d bps\n\tMaximum Bitrate %d bps\n", esd->decoderConfig->bufferSizeDB, esd->decoderConfig->avgBitrate, esd->decoderConfig->maxBitrate); - if (esd->slConfig->predefined==SLPredef_SkipSL) { - fprintf(stderr, "\tNot using MPEG-4 Synchronization Layer\n"); - } else { - fprintf(stderr, "\tStream Clock Resolution %d\n", esd->slConfig->timestampResolution); - } - if (esd->URLString) fprintf(stderr, "\tStream Location: %s\n", esd->URLString); + fprintf(stderr, "\nStream ID %d - %s - Clock ID %d\n", odi.pid_id, gf_stream_type_name(odi.od_type), odi.ocr_id); +// if (esd->dependsOnESID) fprintf(stderr, "\tDepends on Stream ID %d for decoding\n", esd->dependsOnESID); - /*check language*/ - if (esd->langDesc) { - s32 lang_idx; - char lan[4]; - lan[0] = esd->langDesc->langCode>>16; - lan[1] = (esd->langDesc->langCode>>8)&0xFF; - lan[2] = (esd->langDesc->langCode)&0xFF; - lan[3] = 0; + if (odi.lang_code) + fprintf(stderr, "\tStream Language: %s\n", odi.lang_code); - lang_idx = gf_lang_find(lan); - if (lang_idx>=0) { - fprintf(stderr, "\tStream Language: %s\n", gf_lang_get_name(lang_idx)); - } - } - } fprintf(stderr, "\n"); - /*check OCI (not everything interests us) - FIXME: support for unicode*/ - count = gf_list_count(odi.od->OCIDescriptors); - if (count) { - fprintf(stderr, "%d Object Content Information descriptors in OD\n", count); - for (i=0; iOCIDescriptors, i); - switch (desc->tag) { - case GF_ODF_SEGMENT_TAG: - { - GF_Segment *sd = (GF_Segment *) desc; - fprintf(stderr, "Segment Descriptor: Name: %s - start time %g sec - duration %g sec\n", sd->SegmentName, sd->startTime, sd->Duration); - } - break; - case GF_ODF_CC_NAME_TAG: - { - GF_CC_Name *ccn = (GF_CC_Name *)desc; - fprintf(stderr, "Content Creators:\n"); - for (j=0; jContentCreators); j++) { - GF_ContentCreatorInfo *ci = (GF_ContentCreatorInfo *) gf_list_get(ccn->ContentCreators, j); - if (!ci->isUTF8) continue; - fprintf(stderr, "\t%s\n", ci->contentCreatorName); - } - } - break; - - case GF_ODF_SHORT_TEXT_TAG: - { - GF_ShortTextual *std = (GF_ShortTextual *)desc; - fprintf(stderr, "Description:\n\tEvent: %s\n\t%s\n", std->eventName, std->eventText); - } - break; - default: - break; - } - } - fprintf(stderr, "\n"); - } switch (odi.status) { case 0: @@ -2878,7 +2648,7 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *szURL) const char *url; u32 done, total, bps; d_enum = 0; - while (gf_term_get_download_info(term, odm, &d_enum, &url, NULL, &done, &total, &bps)) { + while (gf_term_get_download_info(term, odm, &d_enum, &url, &done, &total, &bps)) { if (d_enum==1) fprintf(stderr, "Current Downloads in service:\n"); if (done && total) { fprintf(stderr, "%s: %d / %d bytes (%.2f %%) - %.2f kBps\n", url, done, total, (100.0f*done)/total, ((Float)bps)/1024.0f); @@ -2889,34 +2659,35 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number, const char *szURL) if (!d_enum) fprintf(stderr, "No Downloads in service\n"); fprintf(stderr, "\n"); } + d_enum = 0; - while (gf_term_get_channel_net_info(term, odm, &d_enum, &id, &com, &e)) { + while (gf_term_get_channel_net_info(term, odm, &d_enum, &id, &stats, &e)) { if (e) continue; - if (!com.bw_down && !com.bw_up) continue; + if (!stats.bw_down && !stats.bw_up) continue; fprintf(stderr, "Stream ID %d statistics:\n", id); - if (com.multiplex_port) { - fprintf(stderr, "\tMultiplex Port %d - multiplex ID %d\n", com.multiplex_port, com.port); + if (stats.multiplex_port) { + fprintf(stderr, "\tMultiplex Port %d - multiplex ID %d\n", stats.multiplex_port, stats.port); } else { - fprintf(stderr, "\tPort %d\n", com.port); - } - fprintf(stderr, "\tPacket Loss Percentage: %.4f\n", com.pck_loss_percentage); - fprintf(stderr, "\tDown Bandwidth: %d bps\n", com.bw_down); - if (com.bw_up) fprintf(stderr, "\tUp Bandwidth: %d bps\n", com.bw_up); - if (com.ctrl_port) { - if (com.multiplex_port) { - fprintf(stderr, "\tControl Multiplex Port: %d - Control Multiplex ID %d\n", com.multiplex_port, com.ctrl_port); + fprintf(stderr, "\tPort %d\n", stats.port); + } + fprintf(stderr, "\tPacket Loss Percentage: %.4f\n", stats.pck_loss_percentage); + fprintf(stderr, "\tDown Bandwidth: %d bps\n", stats.bw_down); + if (stats.bw_up) fprintf(stderr, "\tUp Bandwidth: %d bps\n", stats.bw_up); + if (stats.ctrl_port) { + if (stats.multiplex_port) { + fprintf(stderr, "\tControl Multiplex Port: %d - Control Multiplex ID %d\n", stats.multiplex_port, stats.ctrl_port); } else { - fprintf(stderr, "\tControl Port: %d\n", com.ctrl_port); + fprintf(stderr, "\tControl Port: %d\n", stats.ctrl_port); } - fprintf(stderr, "\tDown Bandwidth: %d bps\n", com.ctrl_bw_down); - fprintf(stderr, "\tUp Bandwidth: %d bps\n", com.ctrl_bw_up); + fprintf(stderr, "\tDown Bandwidth: %d bps\n", stats.ctrl_bw_down); + fprintf(stderr, "\tUp Bandwidth: %d bps\n", stats.ctrl_bw_up); } fprintf(stderr, "\n"); } } -void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) +static void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) { GF_MediaInfo odi; u32 ind = indent; @@ -2924,7 +2695,7 @@ void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) if (!odm) return; if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return; - if (!odi.od) { + if (!odi.ODID) { fprintf(stderr, "Service not attached\n"); return; } @@ -2935,7 +2706,7 @@ void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) if (! odi.generated_scene) { - fprintf(stderr, "- OD %d: ", odi.od->objectDescriptorID); + fprintf(stderr, "- OD %d: ", odi.ODID); switch (odi.status) { case 1: fprintf(stderr, "Playing - "); @@ -2967,7 +2738,7 @@ void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) } -void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) +static void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) { Float avg_dec_time; GF_MediaInfo odi; @@ -2975,7 +2746,7 @@ void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) if (!odm) return; if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return; - if (!odi.od) { + if (!odi.ODID) { fprintf(stderr, "Service not attached\n"); return; } @@ -2989,7 +2760,7 @@ void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) if (odi.generated_scene) { fprintf(stderr, "+ Service %s:\n", odi.service_url); } else { - fprintf(stderr, "- OD %d: ", odi.od->objectDescriptorID); + fprintf(stderr, "- OD %d: ", odi.ODID); switch (odi.status) { case 1: fprintf(stderr, "Playing"); @@ -3037,7 +2808,7 @@ void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm, u32 indent) } -void ViewODs(GF_Terminal *term, Bool show_timing) +static void ViewODs(GF_Terminal *term, Bool show_timing) { GF_ObjectManager *root_odm = gf_term_get_root_object(term); if (!root_odm) return; @@ -3049,41 +2820,3 @@ void ViewODs(GF_Terminal *term, Bool show_timing) } fprintf(stderr, "\n"); } - - -void PrintGPACConfig() -{ - u32 i, j, cfg_count, key_count; - char szName[200]; - char *secName = NULL; - - fprintf(stderr, "Enter section name (\"*\" for complete dump):\n"); - if (1 > scanf("%s", szName)) { - fprintf(stderr, "No section name, aborting.\n"); - return; - } - if (strcmp(szName, "*")) secName = szName; - - fprintf(stderr, "\n\n*** GPAC Configuration ***\n\n"); - - cfg_count = gf_cfg_get_section_count(cfg_file); - for (i=0; i.depend + +distclean: clean + rm -f Makefile.bak .depend + +-include .depend diff --git a/applications/testapps/atscdmx/main.c b/applications/testapps/atscdmx/main.c new file mode 100644 index 0000000..792a3bc --- /dev/null +++ b/applications/testapps/atscdmx/main.c @@ -0,0 +1,151 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean Le Feuvre + * Copyright (c) Telecom ParisTech 2018 + * All rights reserved + * + * This file is part of GPAC - ATSC/ROUTE implementation + * + */ + +#include +#include + +void PrintUsage() +{ + fprintf(stderr, "USAGE: [OPTS]\n" +#ifdef GPAC_MEMORY_TRACKING + "-mem-track: enables memory tracker\n" + "-mem-track-stack: enables memory tracker with stack dumping\n" +#endif + "-log-file file: sets output log file. Also works with -lf\n" + "-logs log_args: sets log tools and levels, formatted as a ':'-separated list of toolX[:toolZ]@levelX\n" + "-log-clock or -lc logs time in micro sec since start time of GPAC before each log line.\n" + "-log-utc or -lu logs UTC time in ms before each log line.\n" + "-ifce IP: IP adress of network interface to use\n" + "-dir PATH: local filesystem path to which the files are written. If not set, memory mode is used.\n" + " NOTE: memory mode is not yet implemented ...\n" + "-service ID: ID of the service to play. If not set, all services are dumped. If 0, no services are dumped\n" + "\n" + "\n on OSX with VM packet replay you will need to force mcast routing, eg:\n" + "route add -net 239.255.1.4/32 -interface vboxnet0\n" + ); +} + +static u64 log_time_start = 0; +static Bool log_utc_time = GF_FALSE; +static u64 last_log_time=0; +static void on_atscd_log(void *cbk, GF_LOG_Level ll, GF_LOG_Tool lm, const char *fmt, va_list list) +{ + FILE *logs = cbk ? cbk : stderr; + if (log_time_start) { + u64 now = gf_sys_clock_high_res(); + fprintf(logs, "At "LLD" (diff %d) - ", now - log_time_start, (u32) (now - last_log_time) ); + last_log_time = now; + } + if (log_utc_time) { + u64 utc_clock = gf_net_get_utc() ; + time_t secs = utc_clock/1000; + struct tm t; + t = *gmtime(&secs); + fprintf(logs, "UTC %d-%02d-%02dT%02d:%02d:%02dZ (TS "LLU") - ", 1900+t.tm_year, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, utc_clock); + } + vfprintf(logs, fmt, list); + fflush(logs); +} + +int main(int argc, char **argv) +{ + u32 i, serviceID=0xFFFFFFFF; + Bool run = GF_TRUE; + GF_MemTrackerType mem_track = GF_MemTrackerNone; + const char *ifce = NULL; + const char *dir = NULL; + FILE *logfile = NULL; + GF_ATSCDmx *atscd; + if (argc<1) { + PrintUsage(); + return 0; + } + for (i=0; i<(u32)argc; i++) { + char *arg = argv[i]; + if (!strcmp(arg, "-mem-track") || !strcmp(arg, "-mem-track-stack")) { +#ifdef GPAC_MEMORY_TRACKING + mem_track = !strcmp(arg, "-mem-track-stack") ? GF_MemTrackerBackTrace : GF_MemTrackerSimple; +#else + fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"%s\"\n", argv[i]); +#endif + } + } + + /*****************/ + /* gpac init */ + /*****************/ +#ifdef GPAC_MEMORY_TRACKING + gf_sys_init(mem_track); +#else + gf_sys_init(GF_MemTrackerNone); +#endif + gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING); + gf_log_set_tool_level(GF_LOG_CONTAINER, GF_LOG_INFO); + + //parse args + for (i=0; i<(u32)argc; i++) { + char *arg = argv[i]; + + if (!strcmp(arg, "-ifce")) ifce=argv[++i]; + else if (!strcmp(arg, "-dir")) dir=argv[++i]; + else if (!strcmp(arg, "-service")) serviceID=atoi(argv[++i]); + else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) { + logfile = gf_fopen(argv[i+1], "wt"); + i++; + } else if (!strcmp(arg, "-logs") ) { + if (gf_log_set_tools_levels(argv[i+1]) != GF_OK) { + return 1; + } + i++; + } else if (!strcmp(arg, "-log-clock") || !strcmp(arg, "-lc")) { + log_time_start = 1; + } else if (!strcmp(arg, "-log-utc") || !strcmp(arg, "-lu")) { + log_utc_time = 1; + } + } + + gf_log_set_callback(logfile, on_atscd_log); + if (log_time_start) log_time_start = gf_sys_clock_high_res(); + /*****************/ + /* atsc init */ + /*****************/ + atscd = gf_atsc3_dmx_new(ifce, dir, 0); + gf_atsc3_tune_in(atscd, serviceID, GF_FALSE); + + while (atscd && run) { + GF_Err e = gf_atsc3_dmx_process(atscd); + if (e == GF_IP_NETWORK_EMPTY) + gf_sleep(1); + + if (gf_prompt_has_input()) { + u8 c = gf_prompt_get_char(); + switch (c) { + case 'q': + run = GF_FALSE; + break; + } + } + } + gf_atsc3_dmx_del(atscd); + + if (logfile) gf_fclose(logfile); + gf_sys_close(); + +#ifdef GPAC_MEMORY_TRACKING + if (mem_track && (gf_memory_size() || gf_file_handles_count() )) { + gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO); + gf_memory_print(); + return 2; + } +#endif + return 0; +} + diff --git a/applications/testapps/bmp4demux/Makefile b/applications/testapps/bmp4demux/Makefile index 031c4bb..db23616 100644 --- a/applications/testapps/bmp4demux/Makefile +++ b/applications/testapps/bmp4demux/Makefile @@ -4,12 +4,12 @@ vpath %.c $(SRC_PATH)/applications/testapps/bmp4demux CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif diff --git a/applications/testapps/broadcaster/Makefile b/applications/testapps/broadcaster/Makefile index c3c3056..821a1f4 100644 --- a/applications/testapps/broadcaster/Makefile +++ b/applications/testapps/broadcaster/Makefile @@ -8,12 +8,12 @@ SOURCES= APPNAME=broadcaster -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif diff --git a/applications/testapps/broadcaster/RTP_serv_generator.c b/applications/testapps/broadcaster/RTP_serv_generator.c index 027aa3a..4e927b0 100644 --- a/applications/testapps/broadcaster/RTP_serv_generator.c +++ b/applications/testapps/broadcaster/RTP_serv_generator.c @@ -207,7 +207,7 @@ static char * eat_buffer_to_bs(char * data, int newStart, int upToPosition, int GF_Err PNC_processBIFSGenerator(PNC_CallbackData * data) { const int tmpBufferSize = 2048; - char *tmpBuffer = (char*)alloca(tmpBufferSize); + char *tmpBuffer = (char*)malloc(tmpBufferSize); int byteRead=0; char *bsBuffer; @@ -219,6 +219,7 @@ GF_Err PNC_processBIFSGenerator(PNC_CallbackData * data) data->socket = NULL; e = gf_sk_accept(data->server_socket, &(data->socket)); if (e) { + free(tmpBuffer); return GF_OK; } else { dprintf(DEBUG_RTP_serv_generator, "New TCP client connected !\n"); diff --git a/applications/testapps/broadcaster/broadcaster.c b/applications/testapps/broadcaster/broadcaster.c index 287667d..f685d4f 100644 --- a/applications/testapps/broadcaster/broadcaster.c +++ b/applications/testapps/broadcaster/broadcaster.c @@ -62,8 +62,10 @@ static int command_line_parsing(int argc, const char** argv, unsigned short * tc } else if (!strcmp("-m", a) || !strcmp("--mtu", a)) { - *mtu_size = atoi(argv[counter+1]); - if (!(mtu_size)) return -3; + if (mtu_size) { + *mtu_size = atoi(argv[counter+1]); + if (! (*mtu_size)) return -3; + } } else if (!strcmp("-d", a) || !strcmp("--debug", a)) { @@ -102,10 +104,10 @@ u32 RAP_send(void *par) { RAP_Input *input = par; PNC_CallbackData *data = input->data; - u32 *timer; input->status = 1; while (input->status==1) { + u32 *timer; gf_mx_p(input->carrousel_mutex); timer = input->RAPtimer; @@ -169,7 +171,6 @@ u32 tcp_server(void *par) unsigned char temp[MAX_BUF]; FILE *fp; u32 byte_read; - int ret; GF_Config *gf_config_file; GF_Socket *TCP_socket; GF_Socket *conn_socket; @@ -186,6 +187,7 @@ u32 tcp_server(void *par) while(input->status == 1) { + int ret; memset(buffer, 0, sizeof(buffer)); e = gf_sk_accept(TCP_socket, &conn_socket); if (e == GF_OK) { @@ -237,7 +239,7 @@ u32 tcp_server(void *par) while (1) { - GF_Err e = gf_sk_receive(conn_socket, temp, sizeof(temp), 0, &byte_read); + e = gf_sk_receive(conn_socket, temp, sizeof(temp), 0, &byte_read); if (e == GF_OK) { gf_fwrite(temp, 1, byte_read, fp); @@ -410,7 +412,7 @@ int main (const int argc, const char** argv) run = 1; while (run) { - GF_Err e = PNC_processBIFSGenerator(data); + e = PNC_processBIFSGenerator(data); if (e) { fprintf(stderr, "Cannot Process BIFS data (%s)\n", gf_error_to_string(e)); break; diff --git a/applications/testapps/broadcaster/sdp_generator.c b/applications/testapps/broadcaster/sdp_generator.c index 2547037..fd31578 100644 --- a/applications/testapps/broadcaster/sdp_generator.c +++ b/applications/testapps/broadcaster/sdp_generator.c @@ -7,7 +7,6 @@ int sdp_generator(PNC_CallbackData *data, char *ip_dest, char *sdp_fmt) GF_ESD *esd = NULL; u32 size,size64; char *buffer; - char buf64[5000]; FILE *fp; int ret; char temp[5000]; @@ -35,6 +34,7 @@ int sdp_generator(PNC_CallbackData *data, char *ip_dest, char *sdp_fmt) codec = (GF_SceneEngine *) data->codec; if (codec) { + char buf64[5000]; buffer = NULL; size = 0; gf_odf_desc_write((GF_Descriptor *) codec->ctx->root_od, &buffer, &size); diff --git a/applications/testapps/fmp4demux/Makefile b/applications/testapps/fmp4demux/Makefile index c36d72a..f0ee334 100644 --- a/applications/testapps/fmp4demux/Makefile +++ b/applications/testapps/fmp4demux/Makefile @@ -4,12 +4,12 @@ vpath %.c $(SRC_PATH)/applications/testapps/fmp4demux CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif diff --git a/applications/testapps/fmp4demux/main.c b/applications/testapps/fmp4demux/main.c index 5ff6b87..062b813 100644 --- a/applications/testapps/fmp4demux/main.c +++ b/applications/testapps/fmp4demux/main.c @@ -139,7 +139,6 @@ static u32 iso_progressive_read_thread(void *param) /* release internal structures associated with the samples read so far */ gf_isom_reset_tables(reader->movie, GF_TRUE); -#if 1 /* release the associated input data as well */ gf_isom_reset_data_offset(reader->movie, &new_buffer_start); if (new_buffer_start) { @@ -149,7 +148,6 @@ static u32 iso_progressive_read_thread(void *param) } sprintf(reader->data_url, "gmem://%d@%p", reader->valid_data_size, reader->data); gf_isom_refresh_fragmented(reader->movie, &missing_bytes, reader->data_url); -#endif /* update the sample count and sample index */ sample_count = new_sample_count - sample_count; diff --git a/applications/testapps/hevcbench/Makefile b/applications/testapps/hevcbench/Makefile index 9668111..768dcb0 100644 --- a/applications/testapps/hevcbench/Makefile +++ b/applications/testapps/hevcbench/Makefile @@ -4,12 +4,12 @@ vpath %.c $(SRC_PATH)/applications/testapps/hevcbench CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" $(SDL_CFLAGS) $(OGL_INCLS) $(OHEVC_CFLAGS) -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif diff --git a/applications/testapps/hevcbench/main.c b/applications/testapps/hevcbench/main.c index a6c92b1..74c12fe 100644 --- a/applications/testapps/hevcbench/main.c +++ b/applications/testapps/hevcbench/main.c @@ -563,27 +563,33 @@ void sdl_draw_frame(u8 *pY, u8 *pU, u8 *pV, u32 w, u32 h, u32 bit_depth, u32 str glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB); #if (COPY_TYPE!=5) - needs_stride=0; +// needs_stride=0; #endif #if (NO_TEX==0) glBindTexture(texture_type, txid[0] ); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_Y); +#if (COPY_TYPE!=5) if (needs_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, needs_stride); +#endif glTexImage2D(texture_type, 0, GL_LUMINANCE, w, h, 0, pixel_format, memory_format, NULL); //glTexSubImage2D crashes with PBO and 2-bytes luminance on my FirePro W5000 ... // glTexSubImage2D(texture_type, 0, 0, 0, w, h, pixel_format, memory_format, pY); glBindTexture(texture_type, txid[1] ); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_U); +#if (COPY_TYPE!=5) if (needs_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, needs_stride/2); +#endif glTexImage2D(texture_type, 0, GL_LUMINANCE, uv_w, uv_h, 0, pixel_format, memory_format, NULL); // glTexSubImage2D(texture_type, 0, 0, 0, uv_w, uv_h, pixel_format, memory_format, pU); glBindTexture(texture_type, txid[2] ); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo_V); +#if (COPY_TYPE!=5) if (needs_stride) glPixelStorei(GL_UNPACK_ROW_LENGTH, needs_stride/2); +#endif glTexImage2D(texture_type, 0, GL_LUMINANCE, uv_w, uv_h, 0, pixel_format, memory_format, NULL); // glTexSubImage2D(texture_type, 0, 0, 0, uv_w, uv_h, pixel_format, memory_format, pV); #endif @@ -868,7 +874,7 @@ int main(int argc, char **argv) if (!sdl_is_init && !no_display) { u64 sdl_init_time = gf_sys_clock_high_res(); u32 stride = HVCFrame.frameInfo.nYPitch; - u32 bpp = HVCFrame.frameInfo.nBitDepth; + bpp = HVCFrame.frameInfo.nBitDepth; if ((bpp==10) && output_8bit) { bpp = 8; stride = HVCFrame.frameInfo.nYPitch/2; diff --git a/applications/testapps/loadcompare/Makefile b/applications/testapps/loadcompare/Makefile index 46b6d98..9d3c500 100644 --- a/applications/testapps/loadcompare/Makefile +++ b/applications/testapps/loadcompare/Makefile @@ -4,12 +4,12 @@ vpath %.c $(SRC_PATH)/applications/testapps/loadcompare CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif diff --git a/applications/testapps/loadcompare/loadcompare.c b/applications/testapps/loadcompare/loadcompare.c index 5388ef1..62ef67d 100644 --- a/applications/testapps/loadcompare/loadcompare.c +++ b/applications/testapps/loadcompare/loadcompare.c @@ -59,7 +59,6 @@ GF_Err load_mp4(GF_LoadCompare *lc, GF_ISOFile *mp4, u32 *loadtime) { GF_Err e = GF_OK; GF_SceneLoader load; - GF_SceneGraph *sg; u32 i, starttime, endtime; u32 nb; if (lc->spread_repeat) nb = 1; @@ -67,6 +66,7 @@ GF_Err load_mp4(GF_LoadCompare *lc, GF_ISOFile *mp4, u32 *loadtime) *loadtime = 0; for (i = 0; i< nb; i++) { + GF_SceneGraph *sg; memset(&load, 0, sizeof(GF_SceneLoader)); sg = gf_sg_new(); load.ctx = gf_sm_new(sg); @@ -101,7 +101,6 @@ GF_Err gpacctx_load_file(GF_LoadCompare *lc, char *item_path, u32 *loadtime) { GF_Err e = GF_OK; GF_SceneLoader load; - GF_SceneGraph *sg; u32 i, starttime, endtime; u32 nb; @@ -111,6 +110,7 @@ GF_Err gpacctx_load_file(GF_LoadCompare *lc, char *item_path, u32 *loadtime) *loadtime = 0; for (i = 0; iverbose) fprintf(stdout, "Could not open file %s\n", mp4_path); e = GF_IO_ERR; } else { + GF_SceneGraph *sg; sg = gf_sg_new(); ctx = gf_sm_new(sg); memset(&load, 0, sizeof(GF_SceneLoader)); @@ -347,9 +347,7 @@ GF_Err decode_svg(GF_LoadCompare *lc, char *item_name, char *item_path, char *sv GF_Err libxml_load_svg(GF_LoadCompare *lc, char *item_path, u32 *loadtime) { GF_Err e = GF_OK; - GF_SceneGraph *sg; u32 i, starttime, endtime; - void *p; u32 nb; if (lc->spread_repeat) nb = 1; @@ -358,6 +356,8 @@ GF_Err libxml_load_svg(GF_LoadCompare *lc, char *item_path, u32 *loadtime) *loadtime = 0; for (i = 0; iverbose) fprintf(stdout, "Could not open file %s or %s\n", item_path, gz_path); e = GF_IO_ERR; } else { + char buffer[100]; while ((read = fread(buffer, 1, 100, file))) gzwrite(gz, buffer, read); gf_fclose(file); gzclose(gz); @@ -600,7 +600,6 @@ void usage() int main(int argc, char **argv) { u32 i; - char *arg; GF_LoadCompare lc; Bool single = 0; char *out = NULL; @@ -613,7 +612,7 @@ int main(int argc, char **argv) lc.out = stdout; for (i = 1; i < (u32) argc ; i++) { - arg = argv[i]; + char *arg = argv[i]; if (!stricmp(arg, "-out")) { out = argv[i+1]; i++; diff --git a/applications/testapps/mpedemux/Makefile b/applications/testapps/mpedemux/Makefile index 21b3b8e..e54df3e 100644 --- a/applications/testapps/mpedemux/Makefile +++ b/applications/testapps/mpedemux/Makefile @@ -4,22 +4,22 @@ vpath %.c $(SRC_PATH)/applications/test_apps/mpedemux CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -ifeq ($(DEBUGBUILD), yes) +ifeq ($(DEBUGBUILD),yes) CFLAGS+=-g LDFLAGS+=-g endif -ifeq ($(GPROFBUILD), yes) +ifeq ($(GPROFBUILD),yes) CFLAGS+=-pg LDFLAGS+=-pg endif #file format is read-only -ifeq ($(GPACREADONLY), yes) +ifeq ($(GPACREADONLY),yes) CFLAGS+= -DGPAC_READ_ONLY endif -ifeq ($(DISABLE_SVG), yes) +ifeq ($(DISABLE_SVG),yes) CFLAGS+=-DGPAC_DISABLE_SVG endif diff --git a/applications/testapps/player_api/main.c b/applications/testapps/player_api/main.c index fc622c3..318a6d2 100644 --- a/applications/testapps/player_api/main.c +++ b/applications/testapps/player_api/main.c @@ -68,7 +68,7 @@ static Bool player_foreach(int argc, char **argv) if (!term) return GF_FALSE; - for (i=0; imaterial = gf_node_new(sg, TAG_MPEG4_Material2D); @@ -181,7 +181,7 @@ static GF_Node *add_transform2d(SVG2BIFS_Converter *converter, GF_Node *node) return (GF_Node *)tr; } -static void svg_parse_animation(GF_SceneGraph *sg, SVG_DeferedAnimation *anim) +static void svg_parse_animation(GF_SceneGraph *sg, SVG_DeferredAnimation *anim) { GF_FieldInfo info; u32 tag; @@ -280,7 +280,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na char *id_string = NULL; u32 tag; SVG_Element *elt; - SVG_DeferedAnimation *anim = NULL; + SVG_DeferredAnimation *anim = NULL; tag = gf_xml_get_element_tag(name, 0); elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag); @@ -296,7 +296,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na // if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent)); if (gf_svg_is_animation_tag(tag)) { - GF_SAFEALLOC(anim, SVG_DeferedAnimation); + GF_SAFEALLOC(anim, SVG_DeferredAnimation); /*default anim target is parent node*/ anim->animation_elt = elt; if (converter->svg_parent) { @@ -532,7 +532,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na if (converter->all_atts.d) { M_Coordinate2D *c2d; M_XCurve2D *xc = (M_XCurve2D *)shape->geometry; - u32 i, j, c, k; + u32 j, c, k; xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)xc->point; @@ -630,7 +630,6 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na if (converter->all_atts.points) { M_Coordinate2D *c2d; M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry; - u32 i; ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D); c2d = (M_Coordinate2D *)ifs->coord; @@ -837,7 +836,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child; if (converter->all_atts.keyTimes) { SFFloat *g; - u32 count, i; + u32 count; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); @@ -847,7 +846,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na } if (converter->all_atts.values) { SFVec2f *g; - u32 count, i; + u32 count; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point_Angle *p; @@ -879,7 +878,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na M_ScalarInterpolator *si = (M_ScalarInterpolator *)child; if (converter->all_atts.keyTimes) { SFFloat *g; - u32 count, i; + u32 count; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); @@ -889,7 +888,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na } if (converter->all_atts.values) { SFFloat *g; - u32 count, i; + u32 count; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point_Angle *p; @@ -926,7 +925,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child; if (converter->all_atts.keyTimes) { SFFloat *g; - u32 count, i; + u32 count; count = gf_list_count(*converter->all_atts.keyTimes); for (i = 0; i < count; i++) { Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i); @@ -936,7 +935,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na } if (converter->all_atts.values) { SFVec2f *g; - u32 count, i; + u32 count; count = gf_list_count(converter->all_atts.values->values); for (i = 0; i < count; i++) { SVG_Point *p; diff --git a/applications/testapps/ts2hds/Makefile b/applications/testapps/ts2hds/Makefile new file mode 100644 index 0000000..965762d --- /dev/null +++ b/applications/testapps/ts2hds/Makefile @@ -0,0 +1,50 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/applications/ts2hds + +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 f4v.o f4m.o + +LINKFLAGS=-L../../bin/gcc +ifeq ($(CONFIG_WIN32),yes) +EXE=.exe +PROG=ts2hds$(EXE) +else +EXT= +PROG=ts2hds +endif +LINKFLAGS+=-lgpac + + +SRCS := $(OBJS:.o=.c) + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) $(LDFLAGS) + +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 .depend diff --git a/applications/ts2hds/f4m.c b/applications/testapps/ts2hds/f4m.c similarity index 100% rename from applications/ts2hds/f4m.c rename to applications/testapps/ts2hds/f4m.c diff --git a/applications/testapps/ts2hds/f4v.c b/applications/testapps/ts2hds/f4v.c new file mode 100644 index 0000000..2cb3a12 --- /dev/null +++ b/applications/testapps/ts2hds/f4v.c @@ -0,0 +1,194 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Author: Romain Bouqueau + * Copyright (c) Romain Bouqueau 2012- + * All rights reserved + * + * Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com) + * + * This file is part of GPAC / TS to HDS (ts2hds) 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 "ts2hds.h" + +//we need to write Adobe custom boxes +#include + +extern struct box_registry_entry box_registry[]; +extern u32 get_box_reg_idx(u32 boxCode, u32 parent_type); +extern size_t size_registry(); + +GF_Err adobize_segment(GF_ISOFile *isom_file, AdobeHDSCtx *ctx) +{ + GF_Err e; + GF_BitStream *bs; + + GF_AdobeFragRandomAccessBox *afra = (GF_AdobeFragRandomAccessBox*) afra_New(); + GF_AfraEntry *ae = (GF_AfraEntry*) gf_calloc(1, sizeof(GF_AfraEntry)); + GF_AdobeBootstrapInfoBox *abst = (GF_AdobeBootstrapInfoBox*) abst_New(); + GF_AdobeSegmentRunTableBox *asrt = (GF_AdobeSegmentRunTableBox*) asrt_New(); + GF_AdobeSegmentRunEntry *asre = (GF_AdobeSegmentRunEntry*) gf_calloc(1, sizeof(GF_AdobeSegmentRunEntry)); + GF_AdobeFragmentRunTableBox *afrt = (GF_AdobeFragmentRunTableBox*) afrt_New(); + GF_AdobeFragmentRunEntry *afre = (GF_AdobeFragmentRunEntry*) gf_calloc(1, sizeof(GF_AdobeFragmentRunEntry)); + + u64 init_seg_time = ctx->curr_time; + u32 seg_duration = (u32)gf_isom_get_duration(isom_file); + + //update context + ctx->curr_time += seg_duration; + + //Adobe specific boxes + //Random Access + afra->type = GF_4CC('a', 'f', 'r', 'a'); + afra->version = 0; + afra->flags = 0; + afra->registry = (const struct box_registry_entry*)((u8*)& box_registry + size_registry() * get_box_reg_idx(afra->type, 0)); + afra->long_ids = 1; + afra->long_offsets = 1; + afra->global_entries = 0; + afra->time_scale = gf_isom_get_timescale(isom_file); + + afra->entry_count = 1; + ae->time = init_seg_time; + ae->offset = 3999; + gf_list_add(afra->local_access_entries, ae); + + afra->global_entries = 0; + afra->global_entry_count = 0; + + e = gf_list_add(isom_file->TopBoxes, afra); + if (e) { + fprintf(stderr, "Impossible to write AFRA box: %s\n", gf_error_to_string(e)); + assert(0); + return e; + } + + //Bootstrap Info + abst->type = GF_4CC('a', 'b', 's', 't'); + abst->version = 0; + abst->flags = 0; + abst->registry = (const struct box_registry_entry*)((u8*)& box_registry + size_registry() * get_box_reg_idx(abst->type, 0)); + abst->bootstrapinfo_version = 1; + abst->profile = 0; + abst->live = 1; + abst->update = 0; + abst->time_scale = gf_isom_get_timescale(isom_file); + abst->current_media_time = init_seg_time+seg_duration; + abst->smpte_time_code_offset = 0; + + abst->movie_identifier = NULL; + abst->drm_data = NULL; + abst->meta_data = NULL; + + abst->server_entry_count = 0; + abst->quality_entry_count = 0; + + abst->segment_run_table_count = 1; + { + //Segment Run + asrt->type = GF_4CC('a', 's', 'r', 't'); + asrt->version = 0; + asrt->flags = 0; + asrt->registry = (const struct box_registry_entry*)((u8*)& box_registry + size_registry() * get_box_reg_idx(asrt->type, 0)); + asrt->segment_run_entry_count = 1; + { + asre->first_segment = ctx->segnum; + asre->fragment_per_segment = 1; + } + e = gf_list_add(asrt->segment_run_entry_table, asre); + if (e) { + fprintf(stderr, "Impossible to write ASR Entry: %s\n", gf_error_to_string(e)); + assert(0); + return e; + } + } + e = gf_list_add(abst->segment_run_table_entries, asrt); + if (e) { + fprintf(stderr, "Impossible to write ASRT box: %s\n", gf_error_to_string(e)); + assert(0); + return e; + } + + abst->fragment_run_table_count = 1; + { + //Fragment Run + afrt->type = GF_4CC('a', 'f', 'r', 't'); + afrt->version = 0; + afrt->flags = 0; + afrt->registry = (const struct box_registry_entry*)((u8*)& box_registry + size_registry() * get_box_reg_idx(afrt->type, 0)); + afrt->timescale = gf_isom_get_timescale(isom_file); + afrt->fragment_run_entry_count = 1; + { + afre->first_fragment = 1; + afre->first_fragment_timestamp = 0; + afre->fragment_duration = seg_duration; + } + e = gf_list_add(afrt->fragment_run_entry_table, afre); + if (e) { + fprintf(stderr, "Impossible to write AFR Entry: %s\n", gf_error_to_string(e)); + assert(0); + return e; + } + } + e = gf_list_add(abst->fragment_run_table_entries, afrt); + if (e) { + fprintf(stderr, "Impossible to write AFRT box: %s\n", gf_error_to_string(e)); + assert(0); + return e; + } + + e = gf_list_add(isom_file->TopBoxes, abst); + if (e) { + fprintf(stderr, "Impossible to write ABST box: %s\n", gf_error_to_string(e)); + assert(0); + return e; + } + + abst->size = 12; /*full box*/ + e = abst_Size((GF_Box*)abst); + if (e) { + fprintf(stderr, "Impossible to compute ABST box size: %s\n", gf_error_to_string(e)); + assert(0); + return e; + } + ctx->bootstrap_size = (size_t)abst->size; + ctx->bootstrap = gf_malloc(ctx->bootstrap_size); + bs = gf_bs_new(ctx->bootstrap, ctx->bootstrap_size, GF_BITSTREAM_WRITE); + e = abst_Write((GF_Box*)abst, bs); + if (e) { + fprintf(stderr, "Impossible to code the ABST box: %s\n", gf_error_to_string(e)); + assert(0); + gf_bs_del(bs); + return e; + } + gf_bs_del(bs); + + //set brands as reversed engineered from f4v files + /*e = gf_isom_reset_alt_brands(isom_file); + if (e) { + fprintf(stderr, "Warning: couldn't reset ISOM brands: %s\n", gf_error_to_string(e)); + assert(0); + }*/ + gf_isom_set_brand_info(isom_file, GF_4CC('f','4','v',' '), 1); + gf_isom_modify_alternate_brand(isom_file, GF_4CC('i','s','o','m'), 1); + gf_isom_modify_alternate_brand(isom_file, GF_4CC('m','p','4','2'), 1); + gf_isom_modify_alternate_brand(isom_file, GF_4CC('m','4','v',' '), 1); + + return GF_OK; +} diff --git a/applications/testapps/ts2hds/main.c b/applications/testapps/ts2hds/main.c new file mode 100644 index 0000000..125751c --- /dev/null +++ b/applications/testapps/ts2hds/main.c @@ -0,0 +1,303 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Author: Romain Bouqueau + * Copyright (c) Romain Bouqueau 2012- + * All rights reserved + * + * Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com) + * + * This file is part of GPAC / TS to HDS (ts2hds) 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 "ts2hds.h" + +//FIXME: test only +//#include +//#include + +#ifdef WIN32 +#define strnicmp _strnicmp +#endif + +#define CHECK_NEXT_ARG if (i+1==(u32)argc) { fprintf(stderr, "Missing arg - please check usage\n"); exit(1); } + +#ifdef GPAC_DISABLE_ISOM + +#error "Cannot compile TS2HDS if GPAC is not built with ISO File Format support" + +#endif + + +static GFINLINE void usage(const char * progname) +{ + fprintf(stderr, "USAGE: %s -i input -o output\n" + "\n" +#ifdef GPAC_MEMORY_TRACKING + "\t-mem-track: enables memory tracker\n" +#endif + , progname); +} + + +/*parse TS2HDS arguments*/ +static GFINLINE GF_Err parse_args(int argc, char **argv, char **input, char **output, u64 *curr_time, u32 *segnum) +{ + Bool input_found=0, output_found=0; + char *arg = NULL, *error_msg = "no argument found"; + s32 i; + + for (i=1; isize = bootstrap[2]*256+bootstrap[3]; + assert(abst->size.depend + +distclean: clean + rm -f Makefile.bak .depend + +-include .depend diff --git a/applications/testapps/udptsseg/main.c b/applications/testapps/udptsseg/main.c new file mode 100644 index 0000000..7c87714 --- /dev/null +++ b/applications/testapps/udptsseg/main.c @@ -0,0 +1,312 @@ +/* +* GPAC - Multimedia Framework C SDK +* + * Authors: Cyril COncolato, Romain Bouqueau + * Copyright (c) Telecom ParisTech 2008-2012 +* All rights reserved +* +* This file is part of GPAC / udp TS segmenter (udptsseg) application +* +* 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 +#include + +#define UDP_BUFFER_SIZE 64484 + +/* adapted from http://svn.assembla.com/svn/legend/segmenter/segmenter.c */ +static GF_Err write_manifest(char *manifest, char *segment_dir, u32 segment_duration, char *segment_prefix, char *http_prefix, + u32 first_segment, u32 last_segment, Bool end) { + FILE *manifest_fp; + u32 i; + char manifest_tmp_name[GF_MAX_PATH]; + char manifest_name[GF_MAX_PATH]; + char *tmp_manifest = manifest_tmp_name; + + if (segment_dir) { + sprintf(manifest_tmp_name, "%stmp.m3u8", segment_dir); + sprintf(manifest_name, "%s%s", segment_dir, manifest); + } else { + sprintf(manifest_tmp_name, "tmp.m3u8"); + sprintf(manifest_name, "%s", manifest); + } + + manifest_fp = gf_fopen(tmp_manifest, "w"); + if (!manifest_fp) { + fprintf(stderr, "Could not create m3u8 manifest file (%s)\n", tmp_manifest); + return GF_BAD_PARAM; + } + + fprintf(manifest_fp, "#EXTM3U\n#EXT-X-TARGETDURATION:%u\n#EXT-X-MEDIA-SEQUENCE:%u\n", segment_duration, first_segment); + + for (i = first_segment; i <= last_segment; i++) { + fprintf(manifest_fp, "#EXTINF:%u,\n%s%s_%u.ts\n", segment_duration, http_prefix, segment_prefix, i); + } + + if (end) { + fprintf(manifest_fp, "#EXT-X-ENDLIST\n"); + } + gf_fclose(manifest_fp); + + if (!rename(tmp_manifest, manifest_name)) { + return GF_OK; + } else { + if (remove(manifest_name)) { + fprintf(stdout, "Error removing file %s\n", manifest_name); + return GF_IO_ERR; + } else if (rename(tmp_manifest, manifest_name)) { + fprintf(stderr, "Could not rename temporary m3u8 manifest file (%s) into %s\n", tmp_manifest, manifest_name); + return GF_IO_ERR; + } else { + return GF_OK; + } + } +} + +void usage() +{ + fprintf(stderr, "usage: udptsseg -src=UDP -dst-file=FILE -segment-duration=DUR -segment-dir=DIR -segment-manifest=M3U8 -segment-http-prefix=P -segment-number=N\n" + "-src=UDP udp://address:port providing the input transport stream\n" + "-dst-file=FILE e.g. out.ts, radical name of all segments\n" + "-segment-dir=DIR server local directory to store segments (with the trailing path separator)\n" + "-segment-duration=DUR segment duration in seconds\n" + "-segment-manifest=M3U8 m3u8 file basename\n" + "-segment-http-prefix=P client address for accessing server segments\n" + "-segment-number=N only n segments are used using a cyclic pattern\n" + "\n"); +} + +int main(int argc, char **argv) +{ + u32 i; + char *arg = NULL; + char *ts_in = NULL; + char *segment_dir = NULL; + char *segment_manifest = NULL; + char *segment_http_prefix = NULL; + u32 run_time = 0; + char *input_ip = NULL; + u32 input_port = 0; + GF_Socket *input_udp_sk = NULL; + char *input_buffer = NULL; + u32 input_buffer_size = UDP_BUFFER_SIZE; + GF_Err e = GF_OK; + FILE *ts_output_file = NULL; + char *ts_out = NULL; + char segment_prefix[GF_MAX_PATH]; + char segment_name[GF_MAX_PATH]; + u32 segment_duration = 0; + u32 segment_index = 0; + u32 segment_number = 0; + char segment_manifest_default[GF_MAX_PATH]; + u32 last_segment_time = 0; + u32 last_segment_size = 0; + u32 read = 0; + u32 towrite = 0; + u32 leftinbuffer = 0; + + fprintf(stdout, "UDP Transport Stream Segmenter\n"); + + if (argc < 7) { + usage(); + return 0; + } + /*****************/ + /* gpac init */ + /*****************/ + gf_sys_init(GF_MemTrackerNone); + + /*****************/ + /* parsing of the arguments */ + /*****************/ + for (i = 1; i < (u32) argc ; i++) { + arg = argv[i]; + if (!strnicmp(arg, "-src=udp://",11)) { + char *sep; + arg+=11; + sep = strchr(arg+6, ':'); + if (sep) { + input_port = atoi(sep+1); + sep[0]=0; + input_ip = gf_strdup(arg); + sep[0]=':'; + } else { + input_ip = gf_strdup(arg); + } + + } else if (!strnicmp(arg, "-time=", 6)) { + run_time = atoi(arg+6); + } else if (!strnicmp(arg, "-dst-file=", 10)) { + ts_out = gf_strdup(arg+10); + } else if (!strnicmp(arg, "-segment-dir=", 13)) { + segment_dir = gf_strdup(arg+13); + } else if (!strnicmp(arg, "-segment-duration=", 18)) { + segment_duration = atoi(arg+18); + } else if (!strnicmp(arg, "-segment-manifest=", 18)) { + segment_manifest = gf_strdup(arg+18); + } else if (!strnicmp(arg, "-segment-http-prefix=", 21)) { + segment_http_prefix = gf_strdup(arg+21); + } else if (!strnicmp(arg, "-segment-number=", 16)) { + segment_number = atoi(arg+16); + } + } + fprintf(stdout, "Listening to TS input on %s:%d\n", input_ip, input_port); + fprintf(stdout, "Creating %d sec. segments in directory %s\n", segment_duration, segment_dir); + fprintf(stdout, "Creating %s manifest with %d segments\n", segment_manifest, segment_number); + + /*****************/ + /* creation of the input socket */ + /*****************/ + input_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); + if (gf_sk_is_multicast_address((char *)input_ip)) { + e = gf_sk_setup_multicast(input_udp_sk, (char *)input_ip, input_port, 32, 0, NULL); + } else { + e = gf_sk_bind(input_udp_sk, NULL, input_port, (char *)input_ip, input_port, GF_SOCK_REUSE_PORT); + } + if (e) { + fprintf(stdout, "Error initializing UDP socket for %s:%d : %s\n", input_ip, input_port, gf_error_to_string(e)); + goto exit; + } + gf_sk_set_buffer_size(input_udp_sk, 0, UDP_BUFFER_SIZE); + gf_sk_set_block_mode(input_udp_sk, 1); + + /*****************/ + /* Initialisation of the TS and Manifest files */ + /*****************/ + + if (segment_duration) { + char *dot; + strcpy(segment_prefix, ts_out); + dot = strrchr(segment_prefix, '.'); + dot[0] = 0; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); + } else { + sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); + } + } else { + sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); + } + fprintf(stderr, "Processing %s segment\r", segment_name); + ts_out = gf_strdup(segment_name); + if (!segment_manifest) { + sprintf(segment_manifest_default, "%s.m3u8", segment_prefix); + segment_manifest = segment_manifest_default; + } + //write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index, 0, 0); + } + ts_output_file = gf_fopen(ts_out, "wb"); + if (!ts_output_file) { + fprintf(stderr, "Error opening %s\n", ts_out); + goto exit; + } + + /*allocate data buffer*/ + input_buffer = (char*)gf_malloc(input_buffer_size); + assert(input_buffer); + + /*****************/ + /* main loop */ + /*****************/ + last_segment_time = gf_sys_clock(); + last_segment_size = 0; + while (1) { + /*check for some input from the network*/ + if (input_ip) { + gf_sk_receive(input_udp_sk, input_buffer+leftinbuffer, input_buffer_size-leftinbuffer, 0, &read); + leftinbuffer += read; + if (leftinbuffer) { + fprintf(stderr, "Processing %s segment ... received %d bytes (buffer: %d, segment: %d)\n", segment_name, read, leftinbuffer, last_segment_size); + if (input_buffer[0] != 0x47) { + while ((i < leftinbuffer) && (input_buffer[i] != 0x47)) i++; + fprintf(stderr, "Warning: data in buffer not starting with the MPEG-2 TS sync byte, skipping %d bytes of %d\n", i, leftinbuffer); + if (i < leftinbuffer) memmove(input_buffer, input_buffer+i, leftinbuffer-i); + leftinbuffer -=i; + } + if ((leftinbuffer % 188) != 0) { + fprintf(stderr, "Warning: data in buffer with a size (%d bytes) not multiple of 188 bytes\n", leftinbuffer); + towrite = leftinbuffer - (leftinbuffer % 188); + } else { + towrite = leftinbuffer; + } + } else { + towrite = 0; + } + /*write to current file */ + if (ts_output_file != NULL) { + u32 now = gf_sys_clock(); + if (towrite) { + gf_fwrite(input_buffer, 1, towrite, ts_output_file); + if (towrite < leftinbuffer) { + fprintf(stderr, "Warning: wrote %d bytes, keeping %d bytes\n", towrite, (leftinbuffer-towrite)); + memmove(input_buffer, input_buffer+towrite, leftinbuffer-towrite); + } + leftinbuffer -= towrite; + last_segment_size += towrite; + } + if ((now - last_segment_time) > segment_duration*1000) { + last_segment_time = now; + gf_fclose(ts_output_file); + fprintf(stderr, "Closing segment %s (%d bytes)\n", segment_name, last_segment_size); + last_segment_size = 0; + segment_index++; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); + } else { + sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); + } + } else { + sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); + } + ts_output_file = gf_fopen(segment_name, "wb"); + if (!ts_output_file) { + fprintf(stderr, "Error opening segment %s\n", segment_name); + goto exit; + } + /* delete the oldest segment */ + if (segment_number && ((s32) (segment_index - segment_number - 1) >= 0)) { + char old_segment_name[GF_MAX_PATH]; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(old_segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); + } else { + sprintf(old_segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); + } + } else { + sprintf(old_segment_name, "%s_%d.ts", segment_prefix, segment_index - segment_number - 1); + } + gf_delete_file(old_segment_name); + fprintf(stderr, "Deleting segment %s\n", old_segment_name); + } + write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, + // (segment_index >= segment_number/2 ? segment_index - segment_number/2 : 0), segment_index >1 ? segment_index-1 : 0, 0); + ( (segment_index > segment_number ) ? segment_index - segment_number : 0), segment_index >1 ? segment_index-1 : 0, 0); + } + } + + //} + } + /*cpu load regulation*/ + gf_sleep(1); + } +exit: + return 0; +} diff --git a/applications/udptsseg/udptsseg.dsp b/applications/testapps/udptsseg/udptsseg.dsp similarity index 100% rename from applications/udptsseg/udptsseg.dsp rename to applications/testapps/udptsseg/udptsseg.dsp diff --git a/applications/udptsseg/udptsseg.vcproj b/applications/testapps/udptsseg/udptsseg.vcproj similarity index 100% rename from applications/udptsseg/udptsseg.vcproj rename to applications/testapps/udptsseg/udptsseg.vcproj diff --git a/applications/ts2hds/Makefile b/applications/ts2hds/Makefile deleted file mode 100644 index c379871..0000000 --- a/applications/ts2hds/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/applications/ts2hds - -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 f4v.o f4m.o - -LINKFLAGS=-L../../bin/gcc -ifeq ($(CONFIG_WIN32),yes) -EXE=.exe -PROG=ts2hds$(EXE) -else -EXT= -PROG=ts2hds -endif -LINKFLAGS+=-lgpac - - -SRCS := $(OBJS:.o=.c) - -all: $(PROG) - -$(PROG): $(OBJS) - $(CC) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) $(LDFLAGS) - -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 .depend diff --git a/applications/ts2hds/f4v.c b/applications/ts2hds/f4v.c deleted file mode 100644 index c507f48..0000000 --- a/applications/ts2hds/f4v.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Author: Romain Bouqueau - * Copyright (c) Romain Bouqueau 2012- - * All rights reserved - * - * Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com) - * - * This file is part of GPAC / TS to HDS (ts2hds) 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 "ts2hds.h" - -//we need to write Adobe custom boxes -#include - -GF_Err adobize_segment(GF_ISOFile *isom_file, AdobeHDSCtx *ctx) -{ - GF_Err e; - GF_BitStream *bs; - - GF_AdobeFragRandomAccessBox *afra = (GF_AdobeFragRandomAccessBox*) afra_New(); - GF_AfraEntry *ae = (GF_AfraEntry*) gf_calloc(1, sizeof(GF_AfraEntry)); - GF_AdobeBootstrapInfoBox *abst = (GF_AdobeBootstrapInfoBox*) abst_New(); - GF_AdobeSegmentRunTableBox *asrt = (GF_AdobeSegmentRunTableBox*) asrt_New(); - GF_AdobeSegmentRunEntry *asre = (GF_AdobeSegmentRunEntry*) gf_calloc(1, sizeof(GF_AdobeSegmentRunEntry)); - GF_AdobeFragmentRunTableBox *afrt = (GF_AdobeFragmentRunTableBox*) afrt_New(); - GF_AdobeFragmentRunEntry *afre = (GF_AdobeFragmentRunEntry*) gf_calloc(1, sizeof(GF_AdobeFragmentRunEntry)); - - u64 init_seg_time = ctx->curr_time; - u32 seg_duration = (u32)gf_isom_get_duration(isom_file); - - //update context - ctx->curr_time += seg_duration; - - //Adobe specific boxes - //Random Access - afra->type = GF_4CC('a', 'f', 'r', 'a'); - afra->version = 0; - afra->flags = 0; - afra->long_ids = 1; - afra->long_offsets = 1; - afra->global_entries = 0; - afra->time_scale = gf_isom_get_timescale(isom_file); - - afra->entry_count = 1; - ae->time = init_seg_time; - ae->offset = 3999; - gf_list_add(afra->local_access_entries, ae); - - afra->global_entries = 0; - afra->global_entry_count = 0; - - e = gf_list_add(isom_file->TopBoxes, afra); - if (e) { - fprintf(stderr, "Impossible to write AFRA box: %s\n", gf_error_to_string(e)); - assert(0); - return e; - } - - //Bootstrap Info - abst->type = GF_4CC('a', 'b', 's', 't'); - abst->version = 0; - abst->flags = 0; - abst->bootstrapinfo_version = 1; - abst->profile = 0; - abst->live = 1; - abst->update = 0; - abst->time_scale = gf_isom_get_timescale(isom_file); - abst->current_media_time = init_seg_time+seg_duration; - abst->smpte_time_code_offset = 0; - - abst->movie_identifier = NULL; - abst->drm_data = NULL; - abst->meta_data = NULL; - - abst->server_entry_count = 0; - abst->quality_entry_count = 0; - - abst->segment_run_table_count = 1; - { - //Segment Run - asrt->type = GF_4CC('a', 's', 'r', 't'); - asrt->version = 0; - asrt->flags = 0; - asrt->segment_run_entry_count = 1; - { - asre->first_segment = ctx->segnum; - asre->fragment_per_segment = 1; - } - e = gf_list_add(asrt->segment_run_entry_table, asre); - if (e) { - fprintf(stderr, "Impossible to write ASR Entry: %s\n", gf_error_to_string(e)); - assert(0); - return e; - } - } - e = gf_list_add(abst->segment_run_table_entries, asrt); - if (e) { - fprintf(stderr, "Impossible to write ASRT box: %s\n", gf_error_to_string(e)); - assert(0); - return e; - } - - abst->fragment_run_table_count = 1; - { - //Fragment Run - afrt->type = GF_4CC('a', 'f', 'r', 't'); - afrt->version = 0; - afrt->flags = 0; - afrt->timescale = gf_isom_get_timescale(isom_file); - afrt->fragment_run_entry_count = 1; - { - afre->first_fragment = 1; - afre->first_fragment_timestamp = 0; - afre->fragment_duration = seg_duration; - } - e = gf_list_add(afrt->fragment_run_entry_table, afre); - if (e) { - fprintf(stderr, "Impossible to write AFR Entry: %s\n", gf_error_to_string(e)); - assert(0); - return e; - } - } - e = gf_list_add(abst->fragment_run_table_entries, afrt); - if (e) { - fprintf(stderr, "Impossible to write AFRT box: %s\n", gf_error_to_string(e)); - assert(0); - return e; - } - - e = gf_list_add(isom_file->TopBoxes, abst); - if (e) { - fprintf(stderr, "Impossible to write ABST box: %s\n", gf_error_to_string(e)); - assert(0); - return e; - } - - e = abst_Size((GF_Box*)abst); - if (e) { - fprintf(stderr, "Impossible to compute ABST box size: %s\n", gf_error_to_string(e)); - assert(0); - return e; - } - ctx->bootstrap_size = (size_t)abst->size; - ctx->bootstrap = gf_malloc(ctx->bootstrap_size); - bs = gf_bs_new(ctx->bootstrap, ctx->bootstrap_size, GF_BITSTREAM_WRITE); - e = abst_Write((GF_Box*)abst, bs); - if (e) { - fprintf(stderr, "Impossible to code the ABST box: %s\n", gf_error_to_string(e)); - assert(0); - gf_bs_del(bs); - return e; - } - gf_bs_del(bs); - - //set brands as reversed engineered from f4v files - /*e = gf_isom_reset_alt_brands(isom_file); - if (e) { - fprintf(stderr, "Warning: couldn't reset ISOM brands: %s\n", gf_error_to_string(e)); - assert(0); - }*/ - gf_isom_set_brand_info(isom_file, GF_4CC('f','4','v',' '), 1); - gf_isom_modify_alternate_brand(isom_file, GF_4CC('i','s','o','m'), 1); - gf_isom_modify_alternate_brand(isom_file, GF_4CC('m','p','4','2'), 1); - gf_isom_modify_alternate_brand(isom_file, GF_4CC('m','4','v',' '), 1); - - return GF_OK; -} \ No newline at end of file diff --git a/applications/ts2hds/main.c b/applications/ts2hds/main.c deleted file mode 100644 index 2298fe6..0000000 --- a/applications/ts2hds/main.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Author: Romain Bouqueau - * Copyright (c) Romain Bouqueau 2012- - * All rights reserved - * - * Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com) - * - * This file is part of GPAC / TS to HDS (ts2hds) 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 "ts2hds.h" - -//FIXME: test only -//#include -//#include - -#ifdef WIN32 -#define strnicmp _strnicmp -#endif - -#define CHECK_NEXT_ARG if (i+1==(u32)argc) { fprintf(stderr, "Missing arg - please check usage\n"); exit(1); } - -#ifdef GPAC_DISABLE_ISOM - -#error "Cannot compile TS2HDS if GPAC is not built with ISO File Format support" - -#endif - - -static GFINLINE void usage(const char * progname) -{ - fprintf(stderr, "USAGE: %s -i input -o output\n" - "\n" -#ifdef GPAC_MEMORY_TRACKING - "\t-mem-track: enables memory tracker\n" -#endif - , progname); -} - - -/*parse TS2HDS arguments*/ -static GFINLINE GF_Err parse_args(int argc, char **argv, char **input, char **output, u64 *curr_time, u32 *segnum) -{ - Bool input_found=0, output_found=0; - char *arg = NULL, *error_msg = "no argument found"; - s32 i; - - for (i=1; isize = bootstrap[2]*256+bootstrap[3]; - assert(abst->size.depend - -distclean: clean - rm -f Makefile.bak .depend - --include .depend diff --git a/applications/udptsseg/main.c b/applications/udptsseg/main.c deleted file mode 100644 index 5074095..0000000 --- a/applications/udptsseg/main.c +++ /dev/null @@ -1,314 +0,0 @@ -/* -* GPAC - Multimedia Framework C SDK -* - * Authors: Cyril COncolato, Romain Bouqueau - * Copyright (c) Telecom ParisTech 2008-2012 -* All rights reserved -* -* This file is part of GPAC / udp TS segmenter (udptsseg) application -* -* 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 -#include - -#define UDP_BUFFER_SIZE 64484 - -/* adapted from http://svn.assembla.com/svn/legend/segmenter/segmenter.c */ -static GF_Err write_manifest(char *manifest, char *segment_dir, u32 segment_duration, char *segment_prefix, char *http_prefix, - u32 first_segment, u32 last_segment, Bool end) { - FILE *manifest_fp; - u32 i; - char manifest_tmp_name[GF_MAX_PATH]; - char manifest_name[GF_MAX_PATH]; - char *tmp_manifest = manifest_tmp_name; - - if (segment_dir) { - sprintf(manifest_tmp_name, "%stmp.m3u8", segment_dir); - sprintf(manifest_name, "%s%s", segment_dir, manifest); - } else { - sprintf(manifest_tmp_name, "tmp.m3u8"); - sprintf(manifest_name, "%s", manifest); - } - - manifest_fp = gf_fopen(tmp_manifest, "w"); - if (!manifest_fp) { - fprintf(stderr, "Could not create m3u8 manifest file (%s)\n", tmp_manifest); - return GF_BAD_PARAM; - } - - fprintf(manifest_fp, "#EXTM3U\n#EXT-X-TARGETDURATION:%u\n#EXT-X-MEDIA-SEQUENCE:%u\n", segment_duration, first_segment); - - for (i = first_segment; i <= last_segment; i++) { - fprintf(manifest_fp, "#EXTINF:%u,\n%s%s_%u.ts\n", segment_duration, http_prefix, segment_prefix, i); - } - - if (end) { - fprintf(manifest_fp, "#EXT-X-ENDLIST\n"); - } - gf_fclose(manifest_fp); - - if (!rename(tmp_manifest, manifest_name)) { - return GF_OK; - } else { - if (remove(manifest_name)) { - fprintf(stdout, "Error removing file %s\n", manifest_name); - return GF_IO_ERR; - } else if (rename(tmp_manifest, manifest_name)) { - fprintf(stderr, "Could not rename temporary m3u8 manifest file (%s) into %s\n", tmp_manifest, manifest_name); - return GF_IO_ERR; - } else { - return GF_OK; - } - } -} - -void usage() -{ - fprintf(stderr, "usage: udptsseg -src=UDP -dst-file=FILE -segment-duration=DUR -segment-dir=DIR -segment-manifest=M3U8 -segment-http-prefix=P -segment-number=N\n" - "-src=UDP udp://address:port providing the input transport stream\n" - "-dst-file=FILE e.g. out.ts, radical name of all segments\n" - "-segment-dir=DIR server local directory to store segments (with the trailing path separator)\n" - "-segment-duration=DUR segment duration in seconds\n" - "-segment-manifest=M3U8 m3u8 file basename\n" - "-segment-http-prefix=P client address for accessing server segments\n" - "-segment-number=N only n segments are used using a cyclic pattern\n" - "\n"); -} - -int main(int argc, char **argv) -{ - u32 i; - char *arg = NULL; - char *ts_in = NULL; - char *segment_dir = NULL; - char *segment_manifest = NULL; - char *segment_http_prefix = NULL; - u32 run_time = 0; - char *input_ip = NULL; - u32 input_port = 0; - GF_Socket *input_udp_sk = NULL; - char *input_buffer = NULL; - u32 input_buffer_size = UDP_BUFFER_SIZE; - GF_Err e = GF_OK; - FILE *ts_output_file = NULL; - char *ts_out = NULL; - char segment_prefix[GF_MAX_PATH]; - char segment_name[GF_MAX_PATH]; - u32 segment_duration = 0; - u32 segment_index = 0; - u32 segment_number = 0; - char segment_manifest_default[GF_MAX_PATH]; - u32 run = 1; - u32 last_segment_time = 0; - u32 last_segment_size = 0; - u32 read = 0; - u32 towrite = 0; - u32 leftinbuffer = 0; - - fprintf(stdout, "UDP Transport Stream Segmenter\n"); - - if (argc < 7) { - usage(); - return 0; - } - /*****************/ - /* gpac init */ - /*****************/ - gf_sys_init(GF_MemTrackerNone); - - /*****************/ - /* parsing of the arguments */ - /*****************/ - for (i = 1; i < (u32) argc ; i++) { - arg = argv[i]; - if (!strnicmp(arg, "-src=udp://",11)) { - char *sep; - arg+=11; - sep = strchr(arg+6, ':'); - if (sep) { - input_port = atoi(sep+1); - sep[0]=0; - input_ip = gf_strdup(arg); - sep[0]=':'; - } else { - input_ip = gf_strdup(arg); - } - - } else if (!strnicmp(arg, "-time=", 6)) { - run_time = atoi(arg+6); - } else if (!strnicmp(arg, "-dst-file=", 10)) { - ts_out = gf_strdup(arg+10); - } else if (!strnicmp(arg, "-segment-dir=", 13)) { - segment_dir = gf_strdup(arg+13); - } else if (!strnicmp(arg, "-segment-duration=", 18)) { - segment_duration = atoi(arg+18); - } else if (!strnicmp(arg, "-segment-manifest=", 18)) { - segment_manifest = gf_strdup(arg+18); - } else if (!strnicmp(arg, "-segment-http-prefix=", 21)) { - segment_http_prefix = gf_strdup(arg+21); - } else if (!strnicmp(arg, "-segment-number=", 16)) { - segment_number = atoi(arg+16); - } - } - fprintf(stdout, "Listening to TS input on %s:%d\n", input_ip, input_port); - fprintf(stdout, "Creating %d sec. segments in directory %s\n", segment_duration, segment_dir); - fprintf(stdout, "Creating %s manifest with %d segments\n", segment_manifest, segment_number); - - /*****************/ - /* creation of the input socket */ - /*****************/ - input_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); - if (gf_sk_is_multicast_address((char *)input_ip)) { - e = gf_sk_setup_multicast(input_udp_sk, (char *)input_ip, input_port, 32, 0, NULL); - } else { - e = gf_sk_bind(input_udp_sk, NULL, input_port, (char *)input_ip, input_port, GF_SOCK_REUSE_PORT); - } - if (e) { - fprintf(stdout, "Error initializing UDP socket for %s:%d : %s\n", input_ip, input_port, gf_error_to_string(e)); - goto exit; - } - gf_sk_set_buffer_size(input_udp_sk, 0, UDP_BUFFER_SIZE); - gf_sk_set_block_mode(input_udp_sk, 1); - - /*****************/ - /* Initialisation of the TS and Manifest files */ - /*****************/ - - if (segment_duration) { - char *dot; - strcpy(segment_prefix, ts_out); - dot = strrchr(segment_prefix, '.'); - dot[0] = 0; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); - } else { - sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); - } - } else { - sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); - } - fprintf(stderr, "Processing %s segment\r", segment_name); - ts_out = gf_strdup(segment_name); - if (!segment_manifest) { - sprintf(segment_manifest_default, "%s.m3u8", segment_prefix); - segment_manifest = segment_manifest_default; - } - //write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index, 0, 0); - } - ts_output_file = gf_fopen(ts_out, "wb"); - if (!ts_output_file) { - fprintf(stderr, "Error opening %s\n", ts_out); - goto exit; - } - - /*allocate data buffer*/ - input_buffer = (char*)gf_malloc(input_buffer_size); - assert(input_buffer); - - /*****************/ - /* main loop */ - /*****************/ - last_segment_time = gf_sys_clock(); - last_segment_size = 0; - while (run) { - /*check for some input from the network*/ - if (input_ip) { - gf_sk_receive(input_udp_sk, input_buffer+leftinbuffer, input_buffer_size-leftinbuffer, 0, &read); - leftinbuffer += read; - if (leftinbuffer) { - fprintf(stderr, "Processing %s segment ... received %d bytes (buffer: %d, segment: %d)\n", segment_name, read, leftinbuffer, last_segment_size); - if (input_buffer[0] != 0x47) { - u32 i = 0; - while (input_buffer[i] != 0x47 && i < leftinbuffer) i++; - fprintf(stderr, "Warning: data in buffer not starting with the MPEG-2 TS sync byte, skipping %d bytes of %d\n", i, leftinbuffer); - if (i < leftinbuffer) memmove(input_buffer, input_buffer+i, leftinbuffer-i); - leftinbuffer -=i; - } - if ((leftinbuffer % 188) != 0) { - fprintf(stderr, "Warning: data in buffer with a size (%d bytes) not multiple of 188 bytes\n", leftinbuffer); - towrite = leftinbuffer - (leftinbuffer % 188); - } else { - towrite = leftinbuffer; - } - } else { - towrite = 0; - } - /*write to current file */ - if (ts_output_file != NULL) { - u32 now = gf_sys_clock(); - if (towrite) { - gf_fwrite(input_buffer, 1, towrite, ts_output_file); - if (towrite < leftinbuffer) { - fprintf(stderr, "Warning: wrote %d bytes, keeping %d bytes\n", towrite, (leftinbuffer-towrite)); - memmove(input_buffer, input_buffer+towrite, leftinbuffer-towrite); - } - leftinbuffer -= towrite; - last_segment_size += towrite; - } - if ((now - last_segment_time) > segment_duration*1000) { - last_segment_time = now; - gf_fclose(ts_output_file); - fprintf(stderr, "Closing segment %s (%d bytes)\n", segment_name, last_segment_size); - last_segment_size = 0; - segment_index++; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); - } else { - sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); - } - } else { - sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); - } - ts_output_file = gf_fopen(segment_name, "wb"); - if (!ts_output_file) { - fprintf(stderr, "Error opening segment %s\n", segment_name); - goto exit; - } - /* delete the oldest segment */ - if (segment_number && ((s32) (segment_index - segment_number - 1) >= 0)) { - char old_segment_name[GF_MAX_PATH]; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(old_segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); - } else { - sprintf(old_segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); - } - } else { - sprintf(old_segment_name, "%s_%d.ts", segment_prefix, segment_index - segment_number - 1); - } - gf_delete_file(old_segment_name); - fprintf(stderr, "Deleting segment %s\n", old_segment_name); - } - write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, - // (segment_index >= segment_number/2 ? segment_index - segment_number/2 : 0), segment_index >1 ? segment_index-1 : 0, 0); - ( (segment_index > segment_number ) ? segment_index - segment_number : 0), segment_index >1 ? segment_index-1 : 0, 0); - } - } - - //} - } - /*cpu load regulation*/ - gf_sleep(1); - } -exit: - return 0; -} diff --git a/bin/smartphone 2003 (armv4)/release/install/archive.bat b/bin/smartphone 2003 (armv4)/release/install/archive.bat deleted file mode 100644 index d0af58f..0000000 --- a/bin/smartphone 2003 (armv4)/release/install/archive.bat +++ /dev/null @@ -1,16 +0,0 @@ -set OLDDIR=%CD% -cd /d %~dp0 - -for /f "delims=" %%a in ('git describe --tags --long') do @set VERSION=%%a -for /f "delims=" %%a in ('git describe --tags --abbrev=0') do @set TAG=%%a- -for /f "delims=" %%a in ('git rev-parse --abbrev-ref HEAD') do @set BRANCH=%%a -REM remove anotated tag from VERSION -setlocal enabledelayedexpansion -call set VERSION=%%VERSION:!TAG!=%% -setlocal disabledelayedexpansion -set revision="%VERSION%-%BRANCH%" -set gpac_version="0.7.1-r%gpac_revision% - -zip "GPAC_%gpac_version%_WindowsMobile.zip" ../*.dll ../*.exe ../*.plg - -cd /d %OLDDIR% diff --git a/bin/smartphone 2003 (armv4)/release/install/build_installer.bat b/bin/smartphone 2003 (armv4)/release/install/build_installer.bat deleted file mode 100644 index 9850f4e..0000000 --- a/bin/smartphone 2003 (armv4)/release/install/build_installer.bat +++ /dev/null @@ -1,42 +0,0 @@ -set OLDDIR=%CD% -cd /d %~dp0 - -for /f "delims=" %%a in ('git describe --tags --long') do @set VERSION=%%a -for /f "delims=" %%a in ('git describe --tags --abbrev=0') do @set TAG=%%a- -for /f "delims=" %%a in ('git rev-parse --abbrev-ref HEAD') do @set BRANCH=%%a -REM remove anotated tag from VERSION -setlocal enabledelayedexpansion -call set VERSION=%%VERSION:!TAG!=%% -setlocal disabledelayedexpansion -set revision="%VERSION%-%BRANCH%" - -set gpac_version="0.7.1-r%gpac_revision% - -ECHO [Version] > gpaccab.inf -ECHO Provider = "GPAC %gpac_version%" >> gpaccab.inf -type gpac.inf >> gpaccab.inf - -CabWiz gpaccab.inf - -ECHO off - -ECHO [CEAppManager]> gpac.ini -ECHO Version = %gpac_version%>> gpac.ini -ECHO Component = GPAC for Windows Mobile>> gpac.ini -ECHO [GPAC for Windows Mobile]>> gpac.ini -ECHO Description = GPAC MPEG-4 Player>> gpac.ini -ECHO Uninstall = GPAC Osmophone>> gpac.ini -ECHO IconFile = ..\..\..\..\doc\osmo4.ico>> gpac.ini -ECHO IconIndex = 0 >> gpac.ini -ECHO CabFiles = gpaccab.cab >> gpac.ini - -ECHO on - -ezsetup -l english -i gpac.ini -r readme.txt -e ../../../../COPYING -o gpac.exe -rename gpac.exe "GPAC_%gpac_version%_WindowsMobile.exe" -DEL gpaccab.cab -DEL gpaccab.inf -DEL gpac.ini -DEL *.tmp - -cd /d %OLDDIR% diff --git a/bin/smartphone 2003 (armv4)/release/install/readme.txt b/bin/smartphone 2003 (armv4)/release/install/readme.txt deleted file mode 100644 index 43ce565..0000000 --- a/bin/smartphone 2003 (armv4)/release/install/readme.txt +++ /dev/null @@ -1,6 +0,0 @@ -This will install GPAC for ARM PocketPC/SmartPhones 2003 Platforms - -GPAC is an open source MPEG-4 framework developped by ENST and available at: - http://gpac.sourceforge.net - -WARNING: THIS RELEASE COMES WITH NO WARRANTY, AND MAY EVEN DAMAGE YOUR HANDHELD DEVICE. PLEASE READ CAREFULLY THE LICENSE HEREJOIN diff --git a/change_version.sh b/change_version.sh index 0301f7c..821c387 100755 --- a/change_version.sh +++ b/change_version.sh @@ -14,18 +14,6 @@ sed -e "s/README for GPAC version.*/README for GPAC version $version/;" $source rm $source mv ftmp $source -#patch doc/configuration.html -source="doc/configuration.html" -sed -e "s/GPAC Version.*/GPAC Version $version/;" $source > ftmp -rm $source -mv ftmp $source - -#patch doc/man/gpac.1 -source="doc/man/gpac.1" -sed -e "s/GPAC framework version.*/GPAC framework version $version./;" $source > ftmp -rm $source -mv ftmp $source - #patch applications/osmo4_ios/osmo4ios-Info.plist @@ -34,26 +22,6 @@ sed -e "/CFBundleShortVersionString/{n;s/.*/ $version<\/string>/;}" $sou rm $source mv ftmp $source -# patch applications/osmo4_w32/Osmo4.rc - -source="applications/osmo4_w32/Osmo4.rc" -sed -e "/\"FileDescription\", \"Osmo4-GPAC\"/{n;s/.*/ VALUE \"FileVersion\", \"$version\"/;}" $source | sed -e "/\"ProductName\", \"Osmo4-GPAC\"/{n;s/.*/ VALUE \"ProductVersion\", \"$version\"/;}" > ftmp -rm $source -mv ftmp $source - -# patch bin/smartphone 2003 (armv4)/release/install/archive.bat -source="bin/smartphone 2003 (armv4)/release/install/archive.bat" -sed -e "s/set gpac_version=.*/set gpac_version=\"$version-r%gpac_revision%/;" "$source" > ftmp -rm "$source" -mv ftmp "$source" - - -# patch bin/smartphone 2003 (armv4)/release/install/build_installer.bat -source="bin/smartphone 2003 (armv4)/release/install/build_installer.bat" -sed -e "s/set gpac_version=.*/set gpac_version=\"$version-r%gpac_revision%/;" "$source" > ftmp -rm "$source" -mv ftmp "$source" - # patch file gpac.pc source="gpac.pc" sed -e "s/Version:.*/Version:$version/;" $source > ftmp @@ -77,3 +45,9 @@ source="packagers/win32_64/nsis/gpac_installer.nsi" sed -e "s/\!define GPAC_VERSION.*/\!define GPAC_VERSION $version/;" $source > ftmp rm $source mv ftmp $source + +# patch file share/doc/configuration.html +source="share/doc/configuration.html" +sed -e "s/GPAC Version.* ftmp +rm $source +mv ftmp $source diff --git a/configure b/configure index 485bfe2..de8ea99 100755 --- a/configure +++ b/configure @@ -1,12 +1,11 @@ #!/bin/sh # -# GPAC configure script -# (c) 2003-2012 Telecom ParisTech +# GPAC configure script +# (c) 2003-2018 Telecom ParisTech # Authors: Jean Le Feuvre, Romain Bouqueau # #set -v - #set temporary file name if test ! -z "$TMPDIR" ; then TMPDIR1="${TMPDIR}" @@ -68,8 +67,6 @@ libdir="lib" #GPAC module config static_modules="no" -js_flags="XP_UNIX" -js_lib="-ljs" lm_lib="" has_mingw_directx="no" has_js="no" @@ -105,14 +102,15 @@ enable_tinygl="no" has_ssl="no" has_ipv6="no" has_dvb4linux="no" -has_xmlrpc="no" has_openjpeg="no" gprof_build="no" static_build="no" want_pic="no" want_gcov="no" has_joystick="no" -has_xul="no" +has_hid="no" +has_sock_un="no" +has_lzma="no" enable_joystick="no" static_mp4box="no" disable_core_tools="no" @@ -146,7 +144,7 @@ disable_loader_xmt="no" disable_od_dump="no" disable_od_parse="no" disable_isom_dump="no" -disable_mcrypt="no" +disable_crypto="no" disable_mpd="no" disable_dash="no" disable_isoff="no" @@ -163,13 +161,18 @@ disable_vobsub="no" disable_ttxt="no" disable_ttml="no" disable_hevc="no" +disable_atsc="no" +disable_crypto="no" +enable_qjs="yes" enable_depth_compositor="no" enable_renoir="no" +enable_sanitizer="no" has_avcap="no" avcap_cflags="" avcap_ldflags="-lavcap" has_opensvc="no" has_openhevc="no" +has_vtb="no" win32="no" mingw32="no" @@ -209,7 +212,7 @@ Options: [defaults in brackets after descriptions] GPAC configuration options: --help print this message --prefix=PREFIX install in PREFIX [$prefix] - --mandir=DIR man documentation in DIR [PREFIX/man] + --mandir=DIR man documentation in DIR [PREFIX/share/man] --verbose enable verbose building [$verbose] --source-path=PATH path of source code [$source_path] @@ -238,9 +241,10 @@ GPAC configuration options: --std-allocator uses standard lib memory allocator --static-modules includes static modules in libgpac whenever possible --enable-mem-track enable tracking of all memory allocated by gpac + --enable-sanitizer enable adress sanitizer + --enable-afl enable instrumentation for American Fuzzy Lop --disable-opt disable GCC optimizations --disable-ipv6 disable IPV6 support - --disable-wx disable wxWidgets support --disable-platinum disable Platinum UPnP support --disable-alsa disable Alsa audio --disable-oss-audio disable OSS audio @@ -294,7 +298,7 @@ Configuration options for libgpac - all options can be enabled with --enable-opt --disable-loader-xmt disable scene loading from ISO File Format --disable-od-dump disable OD dump --disable-isom-dump disable ISOM dump - --disable-mcrypt disable mcrypt + --disable-crypt disable crypto tools --disable-isoff disable ISO File Format --disable-isoff-write disable ISO File Format edit/write --disable-isoff-hint disable ISO File Format hinting @@ -308,9 +312,10 @@ Configuration options for libgpac - all options can be enabled with --enable-opt --disable-player disable player (terminal and compositor) --disable-scenegraph disable scenegraph, scene parsers and player (terminal and compositor) --disable-hevc disable HEVC support + --disable-atsc disable ATSC3 support + --disable-crypto disable crypto support -Extra libraries configuration. You can turn a libray off or force using the local version in gpac/extra_lib/ - --use-js=OPT force SpiderMonkey ECMAScript OPT=[no,local] +Extra libraries configuration. You can turn a library off or force using the local version in gpac/extra_lib/ --use-ft=OPT force FreeType OPT=[no,local] --use-zlib=OPT force ZLIB OPT=[no,system,local] --use-jpeg=OPT force JPEG OPT=[no,local] @@ -325,7 +330,7 @@ Extra libraries configuration. You can turn a libray off or force using the loca --use-openjpeg=OPT force openjpeg OPT=[no,system,local] --use-a52=OPT force a52 (ac3) OPT=[no,system,local] -NOTE: The object files are build at the place where configure is launched +NOTE: The object files are built at the place where configure is launched EOF exit 1 fi @@ -368,6 +373,8 @@ for opt do ;; --enable-gcov) want_gcov="yes"; ;; + --enable-afl) cc_orig="afl-gcc"; cxx_orig="afl-g++" + ;; --verbose) verbose="yes"; ;; esac @@ -414,7 +421,7 @@ case "$cpu" in ;; ppc64) cpu="powerpc" - ;; + ;; "Power Macintosh"|ppc) cpu="powerpc" ;; @@ -481,8 +488,6 @@ if test "$targetos" = "" ; then fi case $targetos in BeOS) - js_flags=-DXP_BEOS - xul_flags=-DXP_BEOS prefix="/boot/home/config" CFLAGS="$CFLAGS -DPIC -fomit-frame-pointer" # 3 gcc releases known for BeOS, each with ugly bugs @@ -539,7 +544,6 @@ EOF CFLAGS="$CFLAGS -pthread" GPAC_SH_FLAGS=-pthread freebsd="yes" - js_flags="-DXP_UNIX -I/usr/include/js" ;; BSD/OS) @@ -548,10 +552,8 @@ EOF ;; Darwin) - js_flags=-DXP_MAC - xul_flags=-DXP_MAC CFLAGS_DIR="-I$prefix/include" - LDFLAGS="-L$prefix/lib" + LDFLAGS="-L$prefix/$libdir" if test -d /sw/bin ; then alt_macosx_dir="/sw" CFLAGS_DIR="-I/sw/include $CFLAGS_DIR" @@ -573,20 +575,19 @@ EOF darwin="yes" gcc_version=`$cc -v 2>>$logs | grep version | cut -d ' ' -f3` case "$gcc_version" in - *2.95*) + *2.95*) CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer" ;; 3.*) CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer -mdynamic-no-pic -fno-common" ;; - 4.*) + 4.*) CFLAGS="$CFLAGS -pipe -fomit-frame-pointer -fno-common" ;; esac ;; MINGW32*|mingw32|MINGW64*|mingw64|msys*|MSYS*) - js_flags="-DXP_PC -D_declspec=__declspec" mingw32="yes" win32="yes" want_pic="no" @@ -610,14 +611,12 @@ EOF ;; CYGWIN*|cygwin*) - js_flags=-DXP_PC extralibs="$extralibs -lws2_32 -lwinmm" cygwin="yes" win32="yes" ;; Linux|linux|android) - js_flags="-DXP_UNIX -I/usr/include/js" LDFLAGS="$LDFLAGS -Wl,--warn-common -Wl,-z,defs" linux="yes" case "$cpu" in @@ -643,7 +642,7 @@ esac #defines directory for binaries and libs (ex. for TinyGL) -target_bin_dir="" +target_bin_dir="" if test "$cross_prefix" = "" ; then target_bin_dir=`${cc} -v 2>>$logs | sed -n '2p' | awk ' {print $2}'`-${cc_orig} else @@ -660,7 +659,8 @@ mkdir -p extra_lib/lib/gcc #OK check for all local & systems lib local_inc=$source_path/extra_lib/include -local_lib=extra_lib/lib/gcc +local_lib=$source_path/extra_lib/lib/gcc +execdir=$source_path/bin/gcc dolog() { @@ -687,7 +687,7 @@ docc() { docxx() { - $cc -o $TMPO $TMPC $@ 0>/dev/null 2>$TMPL + $cc -o $TMPO $TMPCXX $@ 0>/dev/null 2>$TMPL dolog $@ } @@ -777,247 +777,15 @@ fi -#look for spidermonkey JS support -mozjs_pkgcfg="no" - -#spidermonkey test for new API -if test "$has_js" = "no" ; then - -cat > $TMPC << EOF -#include -int main( void ) { JSContext *cx=NULL; jsval rp; return JS_AddValueRoot(cx, &rp); } -EOF - - #try local - js_inc="$local_inc/js" - js_flags="-DXP_UNIX -I$local_inc/js" - if test "$pkg_config" != "no"; then - #try pkg-config - if $pkg_config --exists mozilla-js ; then - mozjs_pkgcfg="mozilla-js" - elif $pkg_config --exists mozjs ; then - mozjs_pkgcfg="mozjs" - elif $pkg_config --exists mozjs185 ; then - mozjs_pkgcfg="mozjs185" - elif docc $js_flags -L$local_lib -ljs -lpthread ; then - has_js="local" - #dc added - fi - - if test $mozjs_pkgcfg != "no" ; then - js_flags=`$pkg_config --cflags $mozjs_pkgcfg` - js_lib_pkg=`$pkg_config --libs $mozjs_pkgcfg` - if docc $js_flags $js_lib_pkg $LDFLAGS -lpthread ; then - has_js="system" - js_lib=`$pkg_config --libs $mozjs_pkgcfg` - fi - #try firefox folders (starting at ubuntu 11.10, no pkg-config) - elif ls -d /usr/lib/firefox* > /dev/null 2>>$logs ; then - firefox_version=`cd /usr/lib ; ls -d firefox* | grep -v addons | grep -v devel ; cd - > /dev/null` - for i in $firefox_version ; do - if test "$has_js" = "no" ; then - js_inc="/usr/include/$i" - js_flags="-DXP_UNIX -I$js_inc" - js_lib="-L/usr/lib/$i/ -lxul -lmozsqlite3 -lmozalloc -lnssutil3 -lnss3 -lnspr4 -lsmime3" - if docc $js_flags $js_lib ; then - has_js="$i" - elif docc $js_flags -lnssutil3 $js_lib -lssl3 ; then - #firefox 11 compatibility - has_js="$i" - js_lib="-lnssutil3 $js_lib -lssl3" - fi - fi - done - fi - - if test "$has_js" = "no" ; then - #try prefix (DC) - js_inc="$prefix/include/js" - js_flags="-DXP_UNIX -I$prefix/include/js" - if docc $js_flags -L$prefix/lib -ljs -lpthread ; then - has_js="prefix" - #dc added end - else - if docc $js_flags $LDFLAGS -ljs -lpthread ; then - js_inc="/usr/include" - has_js="system" - elif docc -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib $LDFLAGS -ljs -lpthread 2>>$logs ; 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 docc $js_flags $LDFLAGS -lsmjs -lpthread ; 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 docc $js_flags $LDFLAGS -lmozjs -lpthread ; then - has_js="system" - js_lib="-lmozjs" - fi - fi - fi - fi - fi - fi -fi - -new_js_api="no" -if test "$has_js" != "no" ; then - js_flags="-DSPIDERMONKEY_NEW_API $js_flags" - new_js_api="yes" -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 test "$cpu" = "sh4" ; then - lm_lib="-lm" - fi - if docc $js_flags $lm_lib -L$local_lib -ljs ; then - has_js="local" - #dc added - else - #try prefix (DC) - js_inc="$prefix/include/js" - js_flags="-DXP_UNIX -I$prefix/include/js" - if docc $js_flags -L$prefix/lib -ljs ; then - has_js="prefix" - #dc added end - elif test "$pkg_config" != "no"; then - if $pkg_config --exists mozilla-js ; then - mozjs_pkgcfg="mozilla-js" - elif $pkg_config --exists mozjs ; then - mozjs_pkgcfg="mozjs" - elif $pkg_config --exists mozjs185 ; then - mozjs_pkgcfg="mozjs185" - fi - - if test $mozjs_pkgcfg != "no" ; then - js_flags=`$pkg_config --cflags $mozjs_pkgcfg` - js_lib_pkg=`$pkg_config --libs $mozjs_pkgcfg` - if docc $js_flags $js_lib_pkg $LDFLAGS -lpthread ; then - has_js="system" - js_lib=`$pkg_config --libs $mozjs_pkgcfg` - fi - fi - fi - if test "$has_js" = "no" ; then - if docc $js_flags $LDFLAGS -ljs ; then - js_inc="/usr/include" - has_js="system" - elif docc -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib $LDFLAGS -ljs 2>>$logs ; 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 docc $js_flags $LDFLAGS -lsmjs ; 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 docc $js_flags $LDFLAGS -lmozjs ; then - has_js="system" - js_lib="-lmozjs" - 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 - #in the header, it was enabled in the build - if test "$new_js_api" = "no" ; then - if grep MOZILLA_1_8_BRANCH $js_inc/jsapi.h > /dev/null 2>>$logs ; then - js_flags="-DMOZILLA_1_8_BRANCH $js_flags" - echo "WARNING: Turning on MOZILLA_1_8_BRANCH SpiderMonkey macro" - echo "If you have troubles with scripts in GPAC, disable this macro and recompile" - fi - else - -cat > $TMPC << EOF -#include -int main( void ) { JSObject *obj; JS_GetPrivate(obj); return 0; } -EOF - if docc $js_flags $LDFLAGS $js_lib ; then - -cat > $TMPC << EOF -#include -int main( void ) { jsval vp; JSContext *cx=NULL; JSObject *obj = JS_NewObjectForConstructor(cx, &vp); return 0; } -EOF - if docc $js_flags $LDFLAGS $js_lib ; then - js_flags="-DUSE_FFDEV_12 $js_flags" - elif grep JSMutableHandleValue $js_inc/jsapi.h | grep JSHasInstanceOp > /dev/null 2>>$logs ; then - js_flags="-DUSE_FFDEV_18 $js_flags" - elif grep JSMutableHandleValue $js_inc/jsapi.h > /dev/null 2>>$logs ; then - js_flags="-DUSE_FFDEV_18 $js_flags" - elif ! grep JS_ConstructObject $js_inc/jsapi.h > /dev/null 2>>$logs ; then - js_flags="-DUSE_FFDEV_16 $js_flags" - elif grep JSHandleObject $js_inc/jsapi.h > /dev/null 2>>$logs ; then - js_flags="-DUSE_FFDEV_15 $js_flags" - else - js_flags="-DUSE_FFDEV_14 $js_flags" - fi - fi - fi - fi - fi -fi - - - -if test "$has_js" != "no" ; then -cat > $TMPC << EOF -#include -int main( void ) { JSContext *cx=NULL; JS_SetRuntimeThread(cx); return 0;} -EOF - if docc $js_flags $LDFLAGS $js_lib ; then - js_flags="$js_flags" - else - js_flags="-DNO_JS_RUNTIMETHREAD $js_flags" - fi -fi - - -#end JS test - - - #look for platinum support -cat > $TMPC << EOF +cat > $TMPCXX << EOF #include int main( void ) { return 0; } EOF -if docxx -o $TMPO $TMPC -I$local_inc/platinum $LDFLAGS -L$local_lib -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRenderer -lNeptune -lZlib -lpthread ; then +if docxx -I$local_inc/platinum $LDFLAGS -L$local_lib -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRenderer -lNeptune -lZlib -lpthread ; then has_platinum="yes" fi - #look for avcap support avcap_cflags="" avcap_ldflags="-lavcap" @@ -1025,14 +793,14 @@ avcap_ldflags="-lavcap" cat > $TMPC << EOF #include using namespace avcap; -int main( void ) { +int main( void ) { const DeviceCollector::DeviceList& dl = DEVICE_COLLECTOR::instance().getDeviceList(); DeviceDescriptor* dd = 0; for (DeviceCollector::DeviceList::const_iterator i = dl.begin(); i != dl.end(); i++) { dd = *i; std::cout << dd->getName().c_str() << "\n"; } - return 0; + return 0; } EOF if docxx -o $TMPO $TMPC $LDFLAGS $avcap_cflags $avcap_ldflags ; then @@ -1047,7 +815,7 @@ else fi if docxx -o $TMPO $TMPC $avcap_cflags $LDFLAGS -L$local_lib $avcap_ldflags ; then has_avcap="yes" - avcap_ldflags="-L../../$local_lib $avcap_ldflags" + avcap_ldflags="-L$local_lib $avcap_ldflags" fi fi @@ -1069,12 +837,12 @@ EOF if docc $osvc_cflags $LDFLAGS $osvc_ldflags ; then has_opensvc="yes" else -osvc_cflags="-I$local_inc" +osvc_cflags="-idirafter $local_inc" osvc_ldflags="-lOpenSVCDec" if docc $osvc_cflags $LDFLAGS -L$local_lib $osvc_ldflags ; then has_opensvc="yes" - osvc_ldflags="-L../../$local_lib $osvc_ldflags" + osvc_ldflags="-L$local_lib $osvc_ldflags" fi fi @@ -1083,32 +851,34 @@ fi if test "$darwin" = "yes" ; then ohevc_cflags="-I/usr/include -I/usr/local/include" - ohevc_ldflags="-L/usr/lib -L/usr/local/lib -lLibOpenHevcWrapper -lm -lpthread " + ohevc_ldflags="-L/usr/lib -L/usr/local/lib -lopenhevc -lm -lpthread " elif test "$cross_prefix" = "" ; then ohevc_cflags="-I/usr/include -I/usr/local/include" - ohevc_ldflags="-L/usr/lib -L/usr/local/lib -lLibOpenHevcWrapper -lm -lpthread" + ohevc_ldflags="-L/usr/lib -L/usr/local/lib -lopenhevc -lm -lpthread" else ohevc_cflags="-I${prefix}include" - ohevc_ldflags="-lLibOpenHevcWrapper -lm -lpthread" + ohevc_ldflags="-lopenhevc -lm -lpthread" fi cat > $TMPC << EOF #include -#include -int main( void ) { libOpenHevcInit(1, 1); return 0; } +#include +int main( void ) { oh_init(1, 1); return 0; } EOF if docc $ohevc_cflags $ohevc_ldflags $LDFLAGS ; then has_openhevc="yes" else ohevc_cflags="-I$local_inc" - ohevc_ldflags="-lLibOpenHevcWrapper -lm -lpthread" + ohevc_ldflags="-lopenhevc -lm -lpthread" if docc $ohevc_cflags $ohevc_ldflags $LDFLAGS -L$local_lib ; then has_openhevc="yes" - ohevc_ldflags="-L../../$local_lib $ohevc_ldflags" + ohevc_ldflags="-L$local_lib $ohevc_ldflags" + elif docc $ohevc_cflags $ohevc_ldflags $LDFLAGS -L$execdir ; then + has_openhevc="yes" + ohevc_ldflags="-L$execdir $ohevc_ldflags" fi fi - #look for freetype support cat > $TMPC << EOF #include @@ -1118,32 +888,29 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF ft_cflags="-I$prefix/include " -ft_lflags="-L$prefix/lib -lfreetype" +ft_lflags="-L$prefix/$libdir -lfreetype" if docc $CFLAGS_DIR $ft_cflags $ft_lflags $LDFLAGS ; then has_ft="system" fi -if test "$cross_prefix" = "" ; then - if test "$has_ft" = "no" ; then - ft_cflags="`freetype-config --cflags 2>>$logs`" - ft_lflags="`freetype-config --libs 2>>$logs`" - if docc $ft_cflags $ft_lflags $LDFLAGS ; then - has_ft="system" - fi + +if test "$has_ft" = "no" ; then + ft_cflags="`pkg-config --cflags freetype2 2>>$logs`" + ft_lflags="`pkg-config --libs freetype2 2>>$logs`" + if docc $ft_cflags $ft_lflags $LDFLAGS ; then + has_ft="system" fi fi + if test "$has_ft" = "no" ; then - if test "`which freetype-config 2>>$logs`" != ""; then - ft_cflags="-I$local_inc/freetype" - ft_lflags="-L$local_lib -lfreetype" - if docc $ft_cflags $ft_lflags ; then - has_ft="local" - fi + ft_cflags="-I$local_inc/freetype" + ft_lflags="-L$local_lib -lfreetype" + if docc $ft_cflags $ft_lflags ; then + has_ft="local" fi fi #end freetype test - #look for OpenSSL support cat > $TMPC << EOF #include @@ -1166,6 +933,48 @@ if docc $CFLAGS_DIR $LINK_SSL $LDFLAGS ; then fi +#look for atomic.h +cat > $TMPC << EOF +#include +#include +int main( void ) { return 0; } +EOF + +has_atomic="no" +if docc $CFLAGS_DIR $LDFLAGS ; then + has_atomic="yes" +else + CFLAGS="$CFLAGS -DGPAC_NO_STDATOMIC" +fi + + +cat > $TMPC << EOF +#include +int main(void) { + int i4 = 4; + __int64_t i8 = 8; + __sync_add_and_fetch(&i4, 12); + __sync_add_and_fetch(&i8, 12); +} +EOF +has_builtinatomic="no" +if docc ; then + has_builtinatomic="yes" +else +cat > $TMPC << EOF +#include +int main(void) { + int i4 = 4; + __int64_t i8 = 8; + __atomic_add_fetch(&i4, 12, __ATOMIC_SEQ_CST); + __atomic_add_fetch(&i8, 12, __ATOMIC_SEQ_CST); +} +EOF + if docc -latomic ; then + CFLAGS="$CFLAGS -DGPAC_NEED_LIBATOMIC" + LDFLAGS="$LDFLAGS -latomic" + fi +fi #look for JPEG support cat > $TMPC << EOF @@ -1191,7 +1000,7 @@ if test "$cross_prefix" = "" ; then fi else jpeg_cflags="-I$prefix/include" - jpeg_lflags="-L$prefix/lib -ljpeg" + jpeg_lflags="-L$prefix/$libdir -ljpeg" if docc $jpeg_cflags $jpeg_lflags $LDFLAGS ; then has_jpeg="system" fi @@ -1209,6 +1018,20 @@ fi #look for OpenJPEG support + +if test "$cross_prefix" = "" -a "$pkg_config" != "no"; then + if $pkg_config --exists libopenjp2 ; then + has_openjpeg="system" + openjpeg_cflags=`$pkg_config --cflags libopenjp2` + openjpeg_ldflags=`$pkg_config --libs libopenjp2` + elif $pkg_config --exists libopenjpeg ; then + has_openjpeg="system" + openjpeg_cflags=`$pkg_config --cflags libopenjpeg` + openjpeg_ldflags=`$pkg_config --libs libopenjpeg` + fi +fi + +if test "$has_openjpeg" = "no" ; then cat > $TMPC << EOF #include #include @@ -1217,12 +1040,14 @@ EOF if docc $LDFLAGS -lopenjpeg ; then has_openjpeg="system" + openjpeg_ldflags="-lopenjpeg" fi if test "$cross_prefix" = "" ; then if test "$has_openjpeg" = "no" ; then if test "$alt_macosx_dir" != "" ; then - if cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib $LDFLAGS -ljpeg 2>>$logs ; then + if cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib $LDFLAGS -lopenjpeg 2>>$logs ; then has_openjpeg="system" + openjpeg_ldflags="-lopenjpeg" fi fi fi @@ -1231,9 +1056,11 @@ fi if test "$has_openjpeg" = "no" ; then if docc -I$local_inc/openjpeg -L$local_lib -lopenjpeg ; then has_openjpeg="local" + openjpeg_ldflags="-lopenjpeg" fi fi +fi #look for PNG support @@ -1243,7 +1070,7 @@ int main( void ) { return 0; } EOF png_cflags="-I$prefix/include" -png_lflags="-L$prefix/lib -lpng -lz" +png_lflags="-L$prefix/$libdir -lpng -lz" if docc $png_cflags $png_lflags $LDFLAGS ; then has_png="system" elif docc $LDFLAGS -lpng -lz ; then @@ -1285,7 +1112,7 @@ if test "$cross_prefix" = "" ; then fi fi if test "$has_mad" = "no" ; then - if docc -I$local_inc/mad -L$local_lib -lmad ; then + if docc -I$local_inc -L$local_lib -lmad ; then has_mad="local" fi fi @@ -1328,7 +1155,7 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF -if docc -I$prefix/include -L$prefix/lib $LDFLAGS -lxvidcore -lpthread ; then +if docc -I$prefix/include -L$prefix/$libdir $LDFLAGS -lxvidcore -lpthread ; then has_xvid="system" elif docc $LDFLAGS -lxvidcore -lpthread ; then has_xvid="system" @@ -1343,7 +1170,7 @@ if test "$cross_prefix" = "" ; then fi fi if test "$has_xvid" = "no" ; then - if docc -I$local_inc/xvid -L$local_lib -lxvidcore -lpthread ; then + if docc -I$local_inc -L$local_lib -lxvidcore -lpthread ; then has_xvid="local" fi fi @@ -1369,7 +1196,7 @@ if test "$cross_prefix" = "" ; then fi fi if test "$has_faad" = "no" ; then - if docc -I$local_inc/faad -L$local_lib -lfaad -lm ; then + if docc -I$local_inc -L$local_lib -lfaad -lm ; then has_faad="local" fi fi @@ -1379,14 +1206,12 @@ fi #look for FFMPEG support ffmpeg_cflags="" -ffmpeg_lflags="-lz -lavcodec -lavformat -lavutil -lswscale $ffmpeg_extra_ldflags" -ffmpeg_lflags_dashcast="$ffmpeg_lflags -lavdevice" +ffmpeg_lflags="-lz -lavcodec -lavformat -lavutil -lavdevice -lswscale -lswresample -lavfilter $ffmpeg_extra_ldflags" if test "$cross_prefix" = "" -a "$pkg_config" != "no"; then - if $pkg_config --exists libavcodec libavformat libswscale libavdevice libavutil libavresample ; then - ffmpeg_cflags=`$pkg_config --cflags libavcodec libavformat libswscale libavutil libavdevice libavresample` - ffmpeg_lflags=`$pkg_config --libs libavcodec libavformat libswscale libavutil` - ffmpeg_lflags_dashcast=`$pkg_config --libs libavcodec libavformat libswscale libavutil libavdevice` + if $pkg_config --exists libavcodec libavformat libswscale libavdevice libavutil libswresample libavfilter ; then + ffmpeg_cflags=`$pkg_config --cflags libavcodec libavformat libavutil libavdevice libswscale libswresample libavfilter` + ffmpeg_lflags=`$pkg_config --libs libavcodec libavformat libavutil libavdevice libswscale libswresample libavfilter` has_ffmpeg="system" fi fi @@ -1403,6 +1228,7 @@ if docc $ffmpeg_cflags $ffmpeg_lflags $LDFLAGS ; then else old_ffmpeg_inc="yes" +# this is immediatly overwritten below?? cat > $TMPC << EOF #include #include @@ -1429,11 +1255,10 @@ int main(void) { } EOF -if docc -I$prefix/include -L$prefix/lib $ffmpeg_lflags $LDFLAGS ; then +if docc -I$prefix/include -L$prefix/$libdir $ffmpeg_lflags $LDFLAGS ; then has_ffmpeg="system" ffmpeg_cflags="-I$prefix/include" - ffmpeg_lflags="-L$prefix/lib $ffmpeg_lflags" - ffmpeg_lflags_dashcast="-L$prefix/lib $ffmpeg_lflags_dashcast" + ffmpeg_lflags="-L$prefix/$libdir $ffmpeg_lflags" elif docc $ffmpeg_lflags $LDFLAGS ; then has_ffmpeg="system" fi @@ -1444,7 +1269,6 @@ if test "$cross_prefix" = "" ; then has_ffmpeg="system" ffmpeg_cflags="-I$alt_macosx_dir/include" ffmpeg_lflags="-L$alt_macosx_dir/lib $ffmpeg_lflags" - ffmpeg_lflags_dashcast="-L$alt_macosx_dir/lib $ffmpeg_lflags_dashcast" fi fi fi @@ -1454,10 +1278,25 @@ if test "$has_ffmpeg" = "no" ; then has_ffmpeg="local" ffmpeg_cflags="-I$local_inc" ffmpeg_lflags="-L$local_lib $ffmpeg_lflags" - ffmpeg_lflags_dashcast="-L$local_lib $ffmpeg_lflags_dashcast" fi fi + +#now that cflags has been correctly set, retest +cat > $TMPC << EOF +#include +int main(void) { + return 0; +} +EOF + +if docc $ffmpeg_cflags $ffmpeg_lflags $LDFLAGS ; then + old_ffmpeg_inc="no" +else + old_ffmpeg_inc="yes" +fi + + cat > $TMPC << EOF #include #include @@ -1490,21 +1329,21 @@ EOF fi fi -#detect libavresample (libav only, but ffmpeg backported with '--enable-avresample') for dashcast only +#detect libswresample for dashcast only cat > $TMPC << EOF -#include "libavresample/avresample.h" +#include "libswresample/swresample.h" int main(void) { - AVAudioResampleContext *aresampler = avresample_alloc_context(); + SwrContext *aresampler = swr_alloc(); free(aresampler); return 0; } EOF -if docc $ffmpeg_cflags $ffmpeg_lflags_dashcast -lavresample ; then - has_libavresample="yes" - ffmpeg_lflags_dashcast="$ffmpeg_lflags_dashcast -lavresample" +if docc $ffmpeg_cflags $ffmpeg_lflags_dashcast -lswresample ; then + has_libswresample="yes" + ffmpeg_lflags_dashcast="$ffmpeg_lflags_dashcast -lswresample" else - has_libavresample="no" + has_libswresample="no" fi @@ -1517,8 +1356,8 @@ if test "$pkg_config" != "no"; then freenect_flags=`$pkg_config --cflags libfreenect` freenect_libs=`$pkg_config --libs libfreenect` has_freenect="system" - freenect_flags="-DFREENECT_FLAT_HEADERS $freenect_flags" - fi + freenect_flags="-DFREENECT_FLAT_HEADERS $freenect_flags" + fi fi if test "$has_freenect" = "no"; then @@ -1609,6 +1448,21 @@ else fi +#look for VideoToolBox support + +if test "$darwin" = "yes" ; then +vtb_ldflags="-framework CoreFoundation -framework CoreVideo -framework CoreMedia -framework VideoToolBox" + cat > $TMPC << EOF +#include +int main( void ) { return 0; } +EOF + +if docc $LDFLAGS $vtb_ldflags ; then + has_vtb="yes" +fi +fi + + #look for OSS support if test "$darwin" = "yes" ; then @@ -1652,53 +1506,6 @@ EOF fi - - -#look for wxWidgets support -has_wx="no" -wx_too_old="no" - -if test "$cross_prefix" = "" ; then - if type wx-config >/dev/null 2>>$logs; then - - wx_version=`wx-config --version | sed 's/[^0-9]//g'` - - if test "$wx_version" -lt 250 ; then - wx_too_old="yes" - has_wx="yes" - else - if test "$wx_version" -lt 260 ; then - has_wx="yes" - wx_cflags=`wx-config --cppflags` - wx_lflags=`wx-config --libs` - else - has_wx="yes" - wx_cflags=`wx-config --cppflags core, base` - wx_lflags=`wx-config --libs core, base` - fi - - if test "$darwin" = "yes" ; then - wx_lflags="-Wl,-bind_at_load $wx_lflags -lstdc++" #10.4 needs it, not sure about 10.3 - fi - fi - - cat > $TMPCXX << EOF -#include -int main( void ) { return 0; } -EOF - - if $cc $wx_cflags -o $TMPO $TMPCXX $wx_lflags > /dev/null 2>>$logs ; then - wx_version=`wx-config --version | sed 's/[^0-9]//g'` - if test "$wx_version" -lt 254 ; then - wx_too_old="yes" - else - has_wx="yes" - fi - fi - fi -fi -#end wx test - #look for IPv6 cat > $TMPC << EOF #include @@ -1737,23 +1544,6 @@ if docc $LDFLAGS ; then fi - -#look for XMLRPC -cat > $TMPC << EOF -#include -#include -#include -int main( void ) { -return 0; -} -EOF - -if docc $LDFLAGS ; then - has_xmlrpc="yes" -fi - - - #look for alsa cat > $TMPC << EOF #include @@ -1845,6 +1635,41 @@ EOF fi +#look for hid support +cat > $TMPC << EOF +#include +int main( void ) { hid_init(); hid_exit(); return 0; } +EOF + +if docc -lhidapi-hidraw $LDFLAGS ; then + hid_lib="-lhidapi-hidraw" + has_hid="yes" +fi + +#look for sys/un.h support +cat > $TMPC << EOF +#include +int main( void ) { struct sockaddr_un serv_add; return 0; } +EOF + +if docc $LDFLAGS ; then + has_sock_un="yes" +fi + + +#look for lzma support +cat > $TMPC << EOF +#include +int main( void ) { lzma_options_lzma opt_lzma2; lzma_lzma_preset(&opt_lzma2, 9); return 0; } +EOF + +if docc $CFLAGS_DIR -llzma $LDFLAGS ; then + has_lzma="yes" + GPAC_SH_FLAGS="$GPAC_SH_FLAGS -llzma" + if test "$win32" = "yes"; then + extralibs="$extralibs -llzma" + fi +fi #overwrite detection with manual settings for opt do @@ -1887,8 +1712,6 @@ for opt do ;; --disable-ipv6) has_ipv6="no" ;; - --disable-wx) has_wx="no" - ;; --disable-platinum) has_platinum="no" ;; --disable-oss-audio) has_oss_audio="no" @@ -1905,10 +1728,14 @@ for opt do ;; --enable-mem-track) use_memory_tracking="yes" ;; + --enable-sanitizer) enable_sanitizer="yes" + ;; --enable-tinygl) enable_tinygl="yes" ;; --disable-ssl) has_ssl="no" ;; + --disable-lzma) has_lzma="no" + ;; --enable-depth) enable_depth_compositor="yes" ;; --static-mp4box) static_mp4box="yes" @@ -1935,13 +1762,13 @@ for opt do if test "$tmp_has_png" = "system" ; then if test "$has_png" != "system" ; then if test "$cross_prefix" != "" ; then - echo + echo echo "WARNING: PNG has been forced to system, but we are cross-compiling, it will have to be on target" - echo + echo else - echo + echo echo "WARNING!! : PNG has been forced to system even though it hasn't been found in this host" - echo + echo fi fi fi @@ -1951,21 +1778,26 @@ for opt do if test "$tmp_has_zlib" = "system" ; then if test "$has_zlib" != "system" ; then if test "$cross_prefix" != "" ; then - echo + echo echo "WARNING: ZLIB has been forced to system, but we are cross-compiling, it will have to be on target" - echo + echo else - echo + echo echo "WARNING!! : ZLIB has been forced to system even though it hasn't been found in this host" - echo + echo fi fi has_zlib=$tmp_has_zlib elif test "$tmp_has_zlib" = "no" ; then - echo + echo echo "WARNING!! : you have forced not to use ZLIB. This will disable some core functionalities of GPAC." - echo + echo has_zlib="force-no" + elif test "$tmp_has_zlib" = "local" ; then + echo + echo "WARNING!! : zlib is forced to be local without check - make sure it is avaliable in $local_lib" + echo + has_zlib="local" fi ;; --use-ogg=*) has_ogg=${opt#--use-ogg=} @@ -1980,9 +1812,9 @@ for opt do ;; --enable-pulseaudio) has_pulseaudio="yes" ;; - --disable-all) has_pulseaudio="no"; has_alsa="no"; disable_core_tools="yes"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_seng="yes"; disable_qtvr="yes"; disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_od_parse="yes"; disable_isom_dump="yes"; disable_mcrypt="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"; disable_player="yes"; disable_vobsub="yes"; disable_scenegraph="yes"; disable_dvbx="yes"; disable_ttxt="yes"; disable_ttml="yes"; disable_saf="yes"; disable_smgr="yes"; disable_mpd="yes"; disable_dash="yes"; disable_isoff_hds="yes"; disable_hevc="yes" + --disable-all) has_pulseaudio="no"; has_alsa="no"; disable_core_tools="yes"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_seng="yes"; disable_qtvr="yes"; disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_od_parse="yes"; disable_isom_dump="yes"; disable_crypto="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"; disable_player="yes"; disable_vobsub="yes"; disable_scenegraph="yes"; disable_dvbx="yes"; disable_ttxt="yes"; disable_vtt="yes"; disable_ttml="yes"; disable_saf="yes"; disable_smgr="yes"; disable_mpd="yes"; disable_dash="yes"; disable_isoff_hds="yes"; disable_hevc="yes" ; disable_atsc="yes" ; enable_qjs="no" ;; - --isomedia-only) has_pulseaudio="no"; has_alsa="no"; disable_core_tools="yes"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_seng="yes"; disable_qtvr="yes"; disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_od_parse="yes"; disable_isom_dump="yes"; disable_mcrypt="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"; disable_player="yes"; disable_vobsub="yes"; disable_scenegraph="yes"; disable_dvbx="yes"; disable_ttxt="yes"; disable_saf="yes"; disable_smgr="yes"; disable_mpd="yes"; disable_dash="yes"; disable_hevc="no"; disable_isoff="no"; disable_isoff_hds="no"; disable_isoff_write="no"; disable_isoff_hint="no"; disable_isoff_frag="no" + --isomedia-only) has_pulseaudio="no"; has_alsa="no"; disable_core_tools="yes"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_seng="yes"; disable_qtvr="yes"; disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_od_parse="yes"; disable_isom_dump="yes"; disable_crypto="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no"; disable_player="yes"; disable_vobsub="yes"; disable_scenegraph="yes"; disable_dvbx="yes"; disable_ttxt="yes"; disable_saf="yes"; disable_smgr="yes"; disable_mpd="yes"; disable_dash="yes"; disable_hevc="no"; disable_isoff="no"; disable_isoff_hds="no"; disable_isoff_write="no"; disable_isoff_hint="no"; disable_isoff_frag="no" ; disable_atsc="yes" ; enable_qjs="no" ;; --disable-3d) disable_3d="yes" ;; @@ -2098,9 +1930,9 @@ for opt do ;; --enable-isom-dump) disable_isom_dump="no" ;; - --disable-mcrypt) disable_mcrypt="yes" + --disable-crypto) disable_crypto="yes" ;; - --enable-mcrypt) disable_mcrypt="no" + --enable-crypto) disable_crypto="no" ;; --disable-isoff) disable_isoff="yes" ;; @@ -2125,55 +1957,67 @@ for opt do --disable-streaming) disable_streaming="yes" ;; --enable-streaming) disable_streaming="no" - ;; + ;; --disable-player) disable_player="yes" ;; --enable-player) disable_player="no" - ;; + ;; --disable-scenegraph) disable_scenegraph="yes" ;; --enable-scenegraph) disable_scenegraph="no" - ;; + ;; --disable-dvbx) disable_dvbx="yes" ;; --enable-dvbx) disable_dvbx="no" - ;; + ;; --disable-vobsub) disable_vobsub="yes" ;; --enable-vobsub) disable_vobsub="no" - ;; + ;; --disable-ttxt) disable_ttxt="yes" ;; --enable-ttxt) disable_ttxt="no" - ;; + ;; --disable-ttml) disable_ttml="yes" ;; + --enable-vtt) disable_vtt="no" + ;; + --disable-vtt) disable_vtt="yes" + ;; --enable-ttml) disable_ttml="no" - ;; + ;; --disable-saf) disable_saf="yes" ;; --enable-saf) disable_saf="no" - ;; + ;; --disable-smgr) disable_smgr="yes" ;; --enable-smgr) disable_smgr="no" - ;; + ;; --disable-mpd) disable_mpd="yes" ;; --enable-mpd) disable_mpd="no" - ;; + ;; --disable-dash) disable_dash="yes" ;; --enable-dash) disable_dash="no" - ;; + ;; --disable-core) disable_core_tools="yes" ;; --enable-core) disable_core_tools="no" - ;; + ;; --disable-hevc) disable_hevc="yes" ;; --enable-hevc) disable_hevc="no" - ;; + ;; + --disable-atsc) disable_atsc="yes" + ;; + --enable-atsc) disable_atsc="no" + ;; + --disable-qjs) enable_qjs="no" + ;; + --enable-qjs) enable_qjs="yes" + ;; esac done @@ -2259,48 +2103,6 @@ if test "$enable_tinygl" = "yes" ;then fi - -#look for GECKO support -cat > $TMPCXX << EOF -#include -int main( void ) { return 0; } -EOF - -if docxx -I$xulsdk_path $LDFLAGS ; then - has_xul="system" - xul_flags="-I$xulsdk_path $xul_flags" -fi - -if test "$pkg_config" != "no"; then - if test "$has_xul" = "no" ; then - if $pkg_config --exists libxul 2>>$logs ; then - if docxx -o $TMPO $TMPCXX `$pkg_config --cflags libxul` `$pkg_config --libs libxul` ; then - has_xul="system" - xul_flags="`$pkg_config --cflags libxul` `$pkg_config --libs libxul`" - fi - fi - fi -fi - -if test "$has_xul" = "no" ; then - if docxx $xul_flags -I$local_inc/gecko-sdk/include $LDFLAGS ; then - has_xul="local" - xul_flags="-I$local_inc/gecko-sdk/include $xul_flags" - else - #xulrunner directories are sometimes included through js/xul/ff packages - if test ! "$has_js" = "no" -a ! "$has_js" = "local" ; then - if docxx $js_flags $js_lib_pkg $LDFLAGS ; then - if test "$mozjs_pkgcfg" != "no" ; then - xul_flags=`$pkg_config --cflags $mozjs_pkgcfg` - has_xul="$has_js" - fi - fi - fi - fi -fi - - - #look for joystick support cat > $TMPC << EOF #include @@ -2335,8 +2137,6 @@ EOF fi - - #look for SDL support sdl_too_old=no has_sdl=no @@ -2412,8 +2212,6 @@ EOF fi #end SDL check - - #look at endianess if test -z "$cross_prefix" ; then @@ -2447,7 +2245,7 @@ fi #man dir if test x"$mandir" = x""; then - mandir="${prefix}/man" + mandir="share/man" fi if test "$static_mp4box" = "yes"; then @@ -2560,9 +2358,11 @@ echo "debug version: $debuginfo" echo "GProf enabled: $gprof_build" echo "Static build enabled: $static_build" echo "Memory tracking enabled: $use_memory_tracking" +echo "Sanitizer enabled: $enable_sanitizer" echo "Fixed-Point Version: $use_fixed_point" echo "IPV6 Support: $has_ipv6" echo "Static Modules: $static_modules" +echo "QuickJS Support: $enable_qjs" if test "$disable_player" = "yes" ; then echo "Player disabled" @@ -2704,9 +2504,9 @@ if test "$disable_isom_dump" = "yes" ; then echo "ISOM dump disabled" echo "#define GPAC_DISABLE_ISOM_DUMP" >> $TMPH fi -if test "$disable_mcrypt" = "yes" ; then - echo "MCrypt disabled" - echo "#define GPAC_DISABLE_MCRYPT" >> $TMPH +if test "$disable_crypto" = "yes" ; then + echo "Crypto tools disabled" + echo "#define GPAC_DISABLE_CRYPTO" >> $TMPH fi if test "$disable_isoff" = "yes" ; then echo "ISO File Format disabled" @@ -2752,6 +2552,11 @@ if test "$disable_ttml" = "yes" ; then echo "#define GPAC_DISABLE_TTML" >> $TMPH fi +if test "$disable_vtt" = "yes" ; then + echo "WebVTT disabled" + echo "#define GPAC_DISABLE_VTT" >> $TMPH +fi + if test "$enable_depth_compositor" = "yes" ; then echo "Depth Compositor enabled" echo "#define GF_SR_USE_DEPTH" >> $TMPH @@ -2772,6 +2577,16 @@ if test "$disable_hevc" = "yes" ; then echo "#define GPAC_DISABLE_HEVC" >> $TMPH fi +if test "$disable_atsc" = "yes" ; then + echo "ATSC3 Support disabled" + echo "#define GPAC_DISABLE_ATSC" >> $TMPH +fi + +if test "$disable_crypto" = "yes" ; then + echo "CRYPTO Support disabled" + echo "#define GPAC_DISABLE_CRYPTO" >> $TMPH +fi + echo "" echo "** Detected libraries **" @@ -2797,8 +2612,6 @@ echo "OpenGL support: $has_opengl" echo "TinyGL support: $has_tinygl" echo "OpenSSL support: $has_ssl" -echo "Mozilla XUL/GECKO support: $has_xul" - if test "$win32" = "yes" ; then echo "DirectX Support: $has_mingw_directx" fi @@ -2806,22 +2619,8 @@ if test "$linux" = "yes" ; then echo "DVB Support: $has_dvb4linux" fi -echo "XMLRPC Support: $has_xmlrpc" - -if test "$wx_too_old" = "yes" ; then - has_wx="no" - echo "wxWidgets Version too old - please upgrade to 2.6.0 for wxWidgets support" -fi -if test "$has_wx" = "yes" ; then - echo "wxWidgets support: Version $wx_version" -else - echo "wxWidgets support: no" -fi - - echo "" echo "** Extra Libraries used **" -echo "SpiderMonkey: $has_js" echo "FreeType: $has_ft" echo "JPEG: $has_jpeg" echo "OpenJPEG: $has_openjpeg" @@ -2830,6 +2629,7 @@ echo "MAD: $has_mad" echo "FAAD: $has_faad" echo "XVID: $has_xvid" echo "FFMPEG: $has_ffmpeg" +echo "LZMA: $has_lzma" echo "Xiph OGG: $has_ogg" echo "Platinum UPnP: $has_platinum" echo "AVCap: $has_avcap" @@ -2888,10 +2688,20 @@ if test "$gprof_build" = "yes"; then fi fi +#we add no deprecate by default on osx (due to opengl ...) if test "$darwin" = "yes" ; then - CFLAGS="$CFLAGS_DIR $CFLAGS" + CFLAGS="$CFLAGS_DIR $CFLAGS -Wno-deprecated -Wno-deprecated-declarations" +else + CFLAGS="$CFLAGS -Wno-deprecated -Wno-deprecated-declarations -Wno-int-in-bool-context" fi + +if test "$enable_sanitizer" = "yes" ; then + CFLAGS="$CFLAGS -fsanitize=address,undefined -fno-sanitize-recover -g" + LDFLAGS="$LDFLAGS -fsanitize=address,undefined -ldl" +fi + + ldir=`pwd` CFLAGS="$CFLAGS -DGPAC_HAVE_CONFIG_H -I\"$ldir\"" if test "$win32" = "no" ; then @@ -2907,9 +2717,7 @@ echo "GPAC_CONFIGURATION=$GPAC_CONFIGURATION" >> config.mak echo "prefix=$prefix" >> config.mak echo "DESTDIR=$DESTDIR" >> config.mak -echo "moddir=$prefix/$libdir/gpac" >> config.mak -echo "moddir_path=$prefix/$libdir/gpac" >> config.mak -echo "mandir=$mandir" >> config.mak +echo "moddir=gpac" >> config.mak echo "tinygl_target_bin_dir=$target_bin_dir" >> config.mak echo "MAKE=$make" >> config.mak @@ -2934,7 +2742,15 @@ echo "OPTFLAGS=$CFLAGS" >> config.mak echo "CXXFLAGS=$CXXFLAGS" >> config.mak echo "LDFLAGS=$LDFLAGS" >> config.mak echo "SHFLAGS=$SHFLAGS" >> config.mak -echo "libdir=$libdir" >> config.mak + +pf="$prefix/" +lib_dir=${libdir#"$pf"} +echo "lib_dir=$lib_dir" >> config.mak + +pf="$prefix/" +man_dir=${mandir#"$pf"} +echo "man_dir=$man_dir" >> config.mak + echo "STATIC_MODULES=$static_modules" >> config.mak @@ -2988,7 +2804,7 @@ if test "$win32" = "yes" ; then echo "#define fseeko64 fseek" >> $TMPH fi if test "$mingw32" = "yes" ; then - + # -municode test cat > $TMPC << EOF #include @@ -3046,18 +2862,11 @@ fi echo "INSTFLAGS=$INSTFLAGS" >> config.mak -echo "CONFIG_JS=$has_js" >> config.mak -if test "$has_js" = "no" ; then - has_js="no" -else - if test "$has_js" = "local" ; then - js_flags="-DXP_UNIX -I$local_inc/js" - js_lib="-ljs" - fi - echo "JS_FLAGS=$js_flags" >> config.mak - echo "JS_LIBS=$js_lib" >> config.mak - echo "#define GPAC_HAS_SPIDERMONKEY" >> $TMPH +echo "CONFIG_JS=$enable_qjs" >> config.mak +if test "$enable_qjs" = "yes" ; then +echo "#define GPAC_HAS_QJS" >> $TMPH fi + if test "$has_zlib" = "no" -o "$has_zlib" = "force-no" ; then echo "#define GPAC_DISABLE_ZLIB" >> $TMPH echo "CONFIG_ZLIB=no" >> config.mak @@ -3069,6 +2878,8 @@ echo "CONFIG_FT=$has_ft" >> config.mak echo "CONFIG_JPEG=$has_jpeg" >> config.mak if test "$has_jpeg" != "no" ; then echo "#define GPAC_HAS_JPEG" >> $TMPH + echo "jpeg_cflags=$jpeg_cflags" >> config.mak + echo "jpeg_lflags=$jpeg_lflags" >> config.mak fi echo "CONFIG_PNG=$has_png" >> config.mak @@ -3076,22 +2887,57 @@ if test "$has_png" != "no" ; then echo "#define GPAC_HAS_PNG" >> $TMPH fi +echo "CONFIG_VTB=$has_vtb" >> config.mak +if test "$has_vtb" != "no" ; then + echo "#define GPAC_HAS_VTB" >> $TMPH + echo "vtb_ldflags=$vtb_ldflags" >> config.mak +fi + +if test "$has_sock_un" != "no" ; then + echo "#define GPAC_HAS_SOCK_UN" >> $TMPH +fi + +echo "CONFIG_LZMA=$has_lzma" >> config.mak +if test "$has_lzma" = "yes"; then +echo "#define GPAC_HAS_LZMA" >> $TMPH +fi + echo "CONFIG_JP2=$has_openjpeg" >> config.mak +if test "$has_openjpeg" != "no" ; then + echo "JP2_CFLAGS=$openjpeg_cflags" >> config.mak + echo "JP2_LDFLAGS=$openjpeg_ldflags" >> config.mak + echo "#define GPAC_HAS_JP2" >> $TMPH +fi echo "CONFIG_FAAD=$has_faad" >> config.mak +if test "$has_faad" != "no" ; then + echo "#define GPAC_HAS_FAAD" >> $TMPH +fi echo "CONFIG_MAD=$has_mad" >> config.mak +if test "$has_mad" != "no" ; then + echo "#define GPAC_HAS_MAD" >> $TMPH +fi echo "CONFIG_XVID=$has_xvid" >> config.mak +if test "$has_xvid" != "no" ; then + echo "#define GPAC_HAS_XVID" >> $TMPH +fi echo "CONFIG_OGG=$has_ogg" >> config.mak echo "CONFIG_VORBIS=$has_vorbis" >> config.mak +if test "$has_vorbis" != "no" ; then + echo "#define GPAC_HAS_VORBIS" >> $TMPH +fi echo "CONFIG_THEORA=$has_theora" >> config.mak +if test "$has_theora" != "no" ; then + echo "#define GPAC_HAS_THEORA" >> $TMPH +fi echo "CONFIG_FFMPEG=$has_ffmpeg" >> config.mak if test "$has_ffmpeg" = "no"; then echo "DISABLE_DASHCAST=yes" >> config.mak else echo "ffmpeg_cflags=$ffmpeg_cflags" >> config.mak echo "ffmpeg_lflags=$ffmpeg_lflags" >> config.mak - echo "ffmpeg_lflags_dashcast=$ffmpeg_lflags_dashcast" >> config.mak echo "CONFIG_LIBAV=$is_libav" >> config.mak - echo "CONFIG_LIBAVRESAMPLE=$has_libavresample" >> config.mak + echo "CONFIG_LIBSWRESAMPLE=$has_libswresample" >> config.mak + echo "#define GPAC_HAS_FFMPEG" >> $TMPH fi echo "CONFIG_FFMPEG_OLD=$old_ffmpeg_inc" >> config.mak @@ -3099,6 +2945,9 @@ 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 +if test "$has_a52" != "no" ; then + echo "#define GPAC_HAS_LIBA52" >> $TMPH +fi echo "CONFIG_PULSEAUDIO=$has_pulseaudio" >> config.mak echo "CONFIG_FREENECT=$has_freenect" >> config.mak if test "$has_freenect" != "no" @@ -3107,6 +2956,10 @@ then echo "FREENECT_LDLAGS=$freenect_ld" >> config.mak fi +if test "$want_gcov" = "yes" ; then + echo "#define GPAC_ENABLE_COVERAGE" >> $TMPH +fi + echo "DISABLE_PLAYER=$disable_player" >> config.mak echo "DISABLE_STREAMING=$disable_streaming" >> config.mak echo "DISABLE_SVG=$disable_svg" >> config.mak @@ -3123,7 +2976,7 @@ echo "DISABLE_SCENE_STATS=$disable_scene_stats" >> config.mak echo "DISABLE_SCENE_DUMP=$disable_scene_dump" >> config.mak echo "DISABLE_SCENE_ENCODE=$disable_scene_encode" >> config.mak echo "DISABLE_SCENEGRAPH=$disable_scenegraph" >> config.mak -echo "DISABLE_MCRYPT=$disable_mcrypt" >> config.mak +echo "DISABLE_CRYPTO=$disable_crypto" >> config.mak echo "DISABLE_DVBX=$disable_dvbx" >> config.mak echo "DISABLE_AVILIB=$disable_avi" >> config.mak echo "DISABLE_M2PS=$disable_m2ps" >> config.mak @@ -3145,6 +2998,8 @@ echo "DISABLE_OD_PARSE=$disable_od_parse" >> config.mak echo "MINIMAL_OD=$disable_od" >> config.mak echo "DISABLE_ISOM_ADOBE=$disable_isoff_hds" >> config.mak echo "DISABLE_VRML=$disable_vrml" >> config.mak +echo "DISABLE_ATSC=$disable_atsc" >> config.mak +echo "DISABLE_CRYPTO=$disable_crypto" >> config.mak if test "$disable_parsers" = "yes" ; then disable_m2ts_mux="yes" @@ -3211,12 +3066,6 @@ if test "$win32" = "yes" ; then fi fi -echo "USE_WXWIDGETS=$has_wx" >> config.mak -if test "$has_wx" = "yes"; then - echo "WX_CFLAGS=$wx_cflags" >> config.mak - echo "WX_LFLAGS=$wx_lflags" >> config.mak -fi - echo "CONFIG_PLATINUM=$has_platinum" >> config.mak echo "CONFIG_AVCAP=$has_avcap" >> config.mak @@ -3229,28 +3078,23 @@ echo "CONFIG_OPENSVC=$has_opensvc" >> config.mak if test "$has_opensvc" = "yes" ; then echo "OSVC_CFLAGS=$osvc_cflags" >> config.mak echo "OSVC_LDFLAGS=$osvc_ldflags" >> config.mak + echo "#define GPAC_HAS_OPENSVC" >> $TMPH fi echo "CONFIG_OPENHEVC=$has_openhevc" >> config.mak if test "$has_openhevc" = "yes" ; then echo "OHEVC_CFLAGS=$ohevc_cflags" >> config.mak echo "OHEVC_LDFLAGS=$ohevc_ldflags" >> config.mak + echo "#define GPAC_HAS_OPENHEVC" >> $TMPH fi echo "MOZILLA_DIR=$moz_path" >> config.mak -echo "CONFIG_XUL=$has_xul" >> config.mak -if test "$has_xul" != "no"; then - echo "XUL_CFLAGS=$xul_flags" >> config.mak -fi - echo "LINUX_DVB=$has_dvb4linux" >> config.mak if test "$has_dvb4linux" = "yes"; then echo "#define GPAC_HAS_LINUX_DVB" >> $TMPH fi -echo "XMLRPC_INC=$has_xmlrpc" >> config.mak - if test "$has_oss_audio" != "no"; then echo "OSS_INC_TYPE=$has_oss_audio" >> config.mak echo "OSS_CFLAGS=$OSS_CFLAGS" >> config.mak @@ -3270,6 +3114,11 @@ if test "$has_x11_xv" = "yes"; then echo "USE_X11_XV=$has_x11_xv" >> config.mak fi +echo "CONFIG_HID=$has_hid" >> config.mak +echo "HID_LDFLAGS=$hid_lib" >> config.mak + + + if test "$is_64" = "yes"; then #not on OSX ... if test "$darwin" = "yes"; then @@ -3315,9 +3164,9 @@ echo "GPAC_ENST_INC=$GPAC_ENST" >> config.mak 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" + SRC_DIRS="src src/utils src/isomedia src/ietf src/odf src/bifs src/scenegraph src/filter_core src/filters src/terminal src/crypto src/media_tools src/scene_manager src/compositor src/laser src/evg src/quickjs src/jsmods" - APP_DIRS="applications/mp4box applications/mp4client applications/osmozilla applications/osmo4_wx applications/mp42ts applications/dashcast" + APP_DIRS="applications/gpac applications/mp4box applications/mp4client" for dir in $SRC_DIRS ; do mkdir -p "$dir" @@ -3413,16 +3262,46 @@ fi echo ' $(CXX) $(CFLAGS) -c -o $@ $<' >> config.mak #pkg-config -echo "prefix=$prefix" > gpac.pc -echo "exec_prefix=\${prefix}" >> gpac.pc -echo "libdir=\${exec_prefix}/$libdir" >> gpac.pc -echo "includedir=\${exec_prefix}/include" >> gpac.pc -echo "" >> gpac.pc -echo "Name: gpac" >> gpac.pc -echo "Description: GPAC Multimedia Framework" >> gpac.pc -echo "URL: http://gpac.sourceforge.net" >> gpac.pc -echo "Version:$version" >> gpac.pc -echo "Cflags: -I\${prefix}/include/gpac" >> gpac.pc -echo "Libs: -L\${libdir} -lgpac" >> gpac.pc +generate_pkgconfig () { + echo "prefix=$prefix" + echo "exec_prefix=\${prefix}" + echo "libdir=\${exec_prefix}/$libdir" + echo "includedir=\${exec_prefix}/include" + echo "" + echo "Name: gpac" + echo "Description: GPAC Multimedia Framework" + echo "URL: http://gpac.io" + echo "Version:$version" + echo "Cflags: -I\${prefix}/include" + echo "Libs: -L\${libdir} -lgpac" +} + +generate_pkgconfig > gpac.pc + + +generate_gpacdesktop () { + echo "[Desktop Entry]" + echo "Version=1.0" + echo "Name=MP4Client" + echo "Comment=GPAC Media Player" + echo "GenericName=Media Player" + echo "Keywords=Media Player" + echo "Exec=MP4Client -gui %u" + echo "Terminal=false" + echo "X-MultipleArgs=false" + echo "Type=Application" + echo "Icon=$prefix/share/pixmaps/gpac.png" + echo "Categories=AudioVideo" + echo "MimeType=text/text;text/xml;application/xhtml+xml;application/xml;image/jpeg;image/png;video/webm;video/mp4;video/mpeg;audio/mp4;audio/mpeg;x-scheme-handler/rtsp;x-scheme-handler/rtp;x-scheme-handler/atsc" + echo "StartupNotify=true" + echo "Actions=new-window" + echo "" + echo "[Desktop Action new-window]" + echo "Name=Open a New Window" + echo "Exec=MP4Client" + echo "" +} + +generate_gpacdesktop > "$source_path/share/gpac.desktop" echo "Done - type 'make help' for make info, 'make' to build" diff --git a/doc/CODING_STYLE b/doc/CODING_STYLE deleted file mode 100644 index 9440327..0000000 --- a/doc/CODING_STYLE +++ /dev/null @@ -1,133 +0,0 @@ -GPAC coding style - -Introduction - coding styles only concern the GPAC library (M4Systems in GPAC<=0.3.0, libgpac now), and, although recommended, are not mandatory for plugins - or applications development. - - AStyle is a code beautifier tool. Code should be compliant with the following pattern provided by AStyle : - AStyle -r --indent=tab '*.c' '*.h' '*.cpp' '*.hpp' - -1 Exported symbols - - 1.0 Informative note - The GF_ or gf_ stands for "gpac framework" - - 1.1 typedef of structures - typedef of base types - typedef of functions - -All symbols defined within libgpac library and exported for application development purposes shall begin be named GF_* -with the first character of "*" being in capital, regardless of their functionality. -For example, GF_Thread (structure), GF_Err (redefined type), GF_LineCap (enum typedef) - -All structure typedefs, whether defined (declaration exported through ehaders) or not (declaration intern to the GPAC core lib), must follow -this principle. -Furthermore, typedef of non exported structure shall only apply to the structure itself, not a pointer to it. - typedef struct _my_gpac_thingy *GF_LPMYGPACSTUFF; /*this is FORBIDDEN*/ - typedef struct _my_gpac_thingy GF_MyGPACStuff; /*this is OK*/ -This will allow easy exporting of structure declaration if needed at some point in the development. - - - 1.2 constants - -All constants (whether #defines or enums) shall be in capital letters and begin with "GF_" and use "_" for word separation -For example, error code GF_BAD_PARAM. - -Enums names shall refer to the main module they are used in through a keyword right after the GF_ . -For example, - * enums refering to file format (isomedia) will be prefixed by GF_ISOM_ - * enums refering to MPEG-4 OD tools (odf) will be prefixed by GF_ODF_ - - 1.3 functions - -All exported functions and pointer to functions shall begin with "gf_". The name shall refer to the main module they are sued in -through a keyword right after the gf_ when reasonable (gf_isom_, gf_odf_, gf_term_), or to the tool they refer to (gf_bs_, gf_url, ...) - -2 Miscalleanous - -All exported functions' names shall be in lower case exclusively. -All exported functions' parameters should be in lower case exclusively. -Exported structures may use case in any fashion as long as they respect the rules expressed in section 1 above. -Exported structures member should preferably all be lower case - this may not be feasible for scene graph nodes & like... - -All exported header files shall be in lower case -All source files within the gpac core shall be in lower case - -All comments should be C-like ones (/**/) not C++ ones (//) -All exported headers documentation should be written with dowygen syntax -All constructor-like functions should be of style gf_zzz_new -All destructor like functions should be of style gf_zzz_del - -3 Rearchitecture of the GPAC repository - - This recaps the changes between gpac 0.3.0 and gpac 0.4.0 as far as the core architecture is concerned. - - - The former M4Systems library is now simply libGPAC (eg libgpac.lib, libgpac.dll, libgpac.so, libgpac.a) - Currently no decision has been taken regarding splitting of this library in smaller packages, this still needs discussion. - - directory architecture: - /gpac - /gpac/applications/ - former Applications/, misc renames - /gpac/applications/generators: former SceneGenerators - /gpac/applications/testapps: added for apps testing some features of gpac (currently only BIFSEngine tester) - /gpac/bin - rename of directories: - arm_debug -> arm_ppc02_deb - arm_release -> arm_ppc02_rel - Debug -> w32_deb - Release -> w32_rel - /gpac/build: former IDEs directory, with project files for MS eVC*/VC* - /gpac/doc - /gpac/doc/libgpac: future place for doc of all exported functions from libgpac - /gpac/extra_lib - /gpac/extra_lib/include - unchanged - /gpac/extra_lib/lib - rename of directories: - arm_debug -> arm_ppc02_deb - arm_release -> arm_ppc02_rel - w32_debug -> w32_deb - w32_release -> w32_rel - - - /gpac/src: former M4Systems directory, source for the gpac core lib - /gpac/src/utils: - former Tools - function names: gf_* - /gpac/src/isomedia: - former MP4 - code for isomedia - function names: gf_isom_* - /gpac/src/odf: - former OD - code for MPEG-4 OD Framework - function names: gf_odf_* - /gpac/src/ietf: - former IETF - code for IETF SDP/RTP/RTCP/RTSP protocols - function names: (or gf_sdp_*, gf_rtp_*, gf_rtsp_*) - moved packetizers in this place since payloads are quite related to IETF... - /gpac/src/bifs: - former BIFS - code for BIFS encoding and decoding - exported function names: gf_bifs_* - /gpac/src/terminal: - former ESM - code for terminal module - exported function names: gf_term_* - /gpac/src/mcrypt: - unchaged - function names: gf_crypt_* - /gpac/src/renderer: - former renderer - function names: gf_sr_* - /gpac/src/scenegraph: - former SceneGraph - function names: gf_sg_* for all common code (base nodes and graph handling), - gf_sg_vrml_*: MPEG4, VRML, X3D related - gf_sg_svg_*: SVG related (maybe laser-related) - - /gpac/src/media_tools: - former authoring on media import/export and IsoMedia file stuff. function names: gf_media_*, gf_hinter_ - - /gpac/src/scene_manager: - former authoring on scene manager. function names: gf_sm_* - - - /gpac/include - /gpac/include/gpac: - splitting of former m4_tools.h into dedicated headers, and for some other modules too (media parsers, ...) - - /gpac/include/gpac/internal: - former intern , no big changes - - /gpac/modules: - former Plugins directory. - - \ No newline at end of file diff --git a/doc/INSTALL.gcc b/doc/INSTALL.gcc deleted file mode 100644 index a3517cc..0000000 --- a/doc/INSTALL.gcc +++ /dev/null @@ -1,116 +0,0 @@ -Installation instructions for GPAC on GCC-powered platforms -last modified: December 2008 - -0 Foreword - The output directory for all plugins and applications is gpac/bin/gcc - - As of 0.2.2, GPAC cannot be compiled without ZLIB. You'd better make sure it is installed on your system (zlib is provided in gpac_extra_libs package) - -I Extra lib installation - It is recommended to install (source or package) all extra libs needed by gpac not installed on your system. - Libraries found on the system are indicated as an output of the configure script - - -II GPAC compilation - - II.1 SDL Support - GPAC can use SDL for audio/video output. If SDL is not installed on your system, you may indicate configure to build with a local copy: - --sdl-cfg=path/to/local/sdlcfg/ - (make sure to update the local sdl-cfg according to your needs) - - If you can't get SDL and don't have OSS or WAV audio nor DirectX or X11 video support on your system, you won't be able to play any presentation with GPAC, - but you can still use MP4Box. - - II.2 wxWidgets Support - GPAC comes with a GUI player called Osmo4. To compile this player you will need wxWidgets 2.6.0 (2.5.2 should work) installed on your system. - Both unicode and ANSI versions of wxWidgets should be supported. - If you don't use wxWidgets, you can always use GPAC command-line player MP4Client. - - II.3 MinGW DirectX support - When building GPAC under MinGW, it is also possible to compile the DirectX plugin. You will need the MinGW versions of DX libs - (available at http://alleg.sourceforge.net/files/). Get dx70_mgw or dx80_mgw (dx8 is provided in gpac_extra_libs package) - copy the archive content in your MSys tree (for ex, /usr/local/DirectX) and configure gpac with the option --dxsdk-path=/usr/local/DirectX - ** you must keep include and lib folders under the same directory for the configure script to detect DirectX ** - - II.4 Building GPAC - go to root of gpac distribution - ./configure (--help for options) - you may need to "chmod +x" this file... - make - - any fixes to configure are welcome :) - - II.5 Installing GPAC - get root - type "make install" in gpac/ - - This will install MP4Client, Osmo4 if configured, MP4Box and all plugins as well as GPAC documentation man: MP4Box(1), MP4Client(1) and GPAC(1). - type "make uninstall" to remove gpac from your system - - II.6 Installing GPAC SDK - get root - type "make install-lib" in gpac/ - - This will install gpac base headers (), gpac development headers ( and libgpac_static - the static version of libgpac shared library. - type "make uninstall-lib" to remove gpac from your system - There is no documentation regarding headers/SDK for now, you will have to rely on function descriptions in each header. - -III Running GPAC - - III.1 MP4Client - MP4Client is a command-line interface to GPAC. Note that the player cannot work without video support - - You need a GPAC configuration file to run MP4Client, and you will need it each time. - - First launch of MP4Client - go to gpac/bin/gcc if not using the install. - type MP4Client - the prompt will ask for - 1- GPAC plugin dir: enter the path from / to gpac/bin/gcc. This is skipped when using the install version of MP4Client (the plugin path is hardcoded to - the plugins install location on the system) - 2- Font directory: enter the path to a truetype font directory on your system (note that if you don't have compiled with freetype any directory will do) - 3- cache directory: any directory with write access - You now have a valid config file for GPAC, more info on this try "man GPAC" or check gpac/doc/configuration.html. - - The config file is called ".gpacrc" and is located in the user home directory. You may run the client with a different config file by using the "-c" option. - - *If you don't see any output window, check the config file doesn't use gm_raw_out.so as a video renderer (or simply remove gm_raw_out.so). - - MINGW USERS: there are known and terrible bugs with MSys rxvt stdio buffering, do NOT use it to run MP4Client unless you want to understand - these bugs. Use w32 CMD.exe instead. Other GPAC apps are no pb for MSys rxvt. - - III.2 Osmo4 - Osmo4 is the GUI frontend to GPAC. If you have installed Osmo4 on your system, the first launch of the player should ask you to locate a - directory with TrueType fonts and a cache directory for internet downloads if no configuration file is found. - - III.3 MP4Box - MP4Box is a tool to encode, decode and manipulate MPEG-4 systems data. It does not need a configuration file. - Help for MP4Box is available on GPAC web site, with man MP4Box (except on MinGW) and with 'MP4Box -h' - - III.4 Osmozilla - Osmozilla is GPAC plugin for Mozilla-based browsers. It is by default installed to the user mozilla directory ~/.mozilla - To install the plugin on the system - * get root - * ./configure --mozdir=/path/to/mozilla - for example --mozdir=/usr/lib/mozilla-firefox - * make -C applications/osmozilla install - - * OR you may copy by hand bin/gcc/nposmozilla.so to /usr/lib/moz**/plugins and bin/gcc/nposmozilla.xpt to /usr/lib/moz**/components - -IV Configuration - - IV.0 Foreword - All configuration information is described in gpac/doc/configuration.html, or man gpac. - - IV.1 OpenGL - OpenGL is badly known for performing quite poorly as far as high data rate texturing is involved. This is a big issue when displaying a typical movie and you will likely find the GPAC 3D Rendering very slow on your system. If your GPU supports non power of 2 texturing or rectangular texturing (most Win32 drivers do) - you shouldn't have any problem with video. Otherwise here are some tips to configure GPAC on your system: - 1- set the "BitmapCopyPixels" option on: some cards perform rather well at direct pixel transfer. If no improvement, set it off. - 2- set the "BitmapCopyPixels" option off and the "EmulatePOW2" option on. This will trick the GL texturing by using only Power Of 2 textures when converting from YUV to RGB. - 3- If this does not improve video playback, you're only chance is through discussion forums & co to gather info about your system, your GL implementation and how to fine-tune it. - -V Misc - - There is a demo 2D authoring tool called V4Studio. No makefiles available yet but should compile without pbs (only needs libgpac - and wxWidgets ). It is not usable to design content but is a funny toy. - - diff --git a/doc/INSTALL.gpe b/doc/INSTALL.gpe deleted file mode 100644 index 84169cb..0000000 --- a/doc/INSTALL.gpe +++ /dev/null @@ -1,100 +0,0 @@ -Installation instructions for GPAC on Familiar+GPE platforms -last modified: December 2008 - -0 Foreword - This file is about installing the GPAC framework on an arm device running Linux familiar (cf http://www.handhelds.org) - - Compilation has only been tested for familiar+GPE platforms ( http://gpe.handhelds.org). - The GPE version enables GPAC to use X11 video output directly, including shared memory extensions. - - The output directory for all plugins and applications is gpac/bin/gcc - - As of 0.2.2, GPAC cannot be compiled without ZLIB. You'd better make sure it is installed on your system (zlib is provided in gpac_extra_libs package) - - To install the arm cross-compilation environement on your linux system, refer to: - * http://www.handhelds.org - * we're currently using the following tool-chain for Familiar+GPE compil http://www.roebling.de/embedded.html, with X11 and GTK+ support, - already compiled. - - Do not forget to update your environment variables according to your toolchain. - -I Extra lib installation - It is recommended to install all extra libs needed by gpac not installed on your system. - -II GPAC compilation - - II.1 SDL Support - GPAC can use SDL for audio/video output. If SDL is not installed on your system, you may indicate configure to build with a local copy: - --sdl-cfg=path/to/local/sdlcfg/ - (make sure to update the local sdl-cfg according to your needs) - - If you can't get SDL and don't have OSS audio nor X11 video support on your system, you won't be able to play any presentation with GPAC, - but you can still use MP4Box. - - II.2 wxWidgets Support - GPAC comes with a GUI player called Osmo4. To compile this player you will need wxWidgets 2.6.0 (2.5.2 should work) installed on your system. - NOTE: Osmo4+wxWidgets is quite slow on familiar+GPE, and is therefore not recommended at the time being. - You can always use GPAC command-line player MP4Client. - - II.3 OpenGL ES support - OpenGL ES is not yet supported on Familiar-GPE. However, GPAC renderer supports OpenGL ES API. Porting the 3D module only requires modifying the X11 output (modules/x11_out) for - OpenGL ES. - - II.4 Building GPAC - go to root of gpac distribution. Note: you may need to "chmod +x" the configure file. - (./configure --help for options) - ./configure --prefix=/usr/local/arm/3.3.2 --cpu=armv4l --enable-fixed-point - Note: this assume the cross-compilation tool-chain is located in /usr/local/arm/3.3.2 - Note: you may also specify any other option supported by configure. It is not recommended to use the floating-point version of GPAC for ARM-based architectures. - make - - II.5 Installing GPAC - copy all files to your device, possibly creating a dedicated directory for modules - edit or create ~/.gpacrc to have at least the following lines: - [General] - ModulesDirectory=AbsolutePathToTheModules - - For more information on GPAC configuration file, cf man GPAC of gpac/doc/configuration.html - -III Running GPAC - - III.1 MP4Client - MP4Client is a command-line interface to GPAC. Note that the player cannot work without video support (so you'd better get SDL) - - You need a GPAC configuration file to run MP4Client, and you will need it each time. - - First launch of MP4Client - go to gpac/bin/gcc if not using the install. - type MP4Client - the prompt will ask for - 1- GPAC plugin dir: enter the path from / to gpac/bin/gcc. This is skipped when using the install version of MP4Client (the plugin path is hardcoded to - the plugins install location on the system) - 2- Font directory: enter the path to a truetype font directory on your system (note that if you don't have compiled with freetype any directory will do) - 3- cache directory: any directory with write access - You now have a valid config file for GPAC, more info on this try "man GPAC" or check gpac/doc/configuration.html. - - The config file is called ".gpacrc" and is located in the user home directory. You may run the client with a different config file by using the "-c" option. - - *If you don't see any output window, check the config file doesn't use raw_out.so as a video renderer (or simply remove raw_out.so). - - III.2 Osmo4 - Osmo4 is the GUI frontend to GPAC. If you have installed Osmo4 on your system, the first launch of the player should ask you to locate a - directory with TrueType fonts and a cache directory for internet downloads if no configuration file is found. - - III.3 MP4Box - MP4Box is a tool to encode, decode and manipulate MPEG-4 systems data. It does not need a configuration file. - Help for MP4Box is available on GPAC web site, with man MP4Box and with 'MP4Box -h' - -IV Configuration - - IV.0 Foreword - All configuration information is described in gpac/doc/configuration.html, or man gpac. - - IV.1 OpenGL - OpenGL is badly known for performing quite poorly as far as high data rate texturing is involved. This is a big issue when displaying a typical movie and you will likely find the GPAC 3D Renderer very slow on your system. If your GPU supports non power of 2 texturing or rectangular texturing (most Win32 drivers do) - you shouldn't have any problem with video. Otherwise here are some tips to configure GPAC on your system: - 1- set the "BitmapCopyPixels" option on: some cards perform rather well at direct pixel transfer. If no improvement, set it off. - 2- set the "BitmapCopyPixels" option off and the "EmulatePOW2" option on. This will trick the GL texturing by using only Power Of 2 textures when converting from YUV to RGB. - 3- If this does not improve video playback, you're only chance is through discussion forums & co to gather info about your system, your GL implementation and how to fine-tune it. - - diff --git a/doc/INSTALL.symbian b/doc/INSTALL.symbian deleted file mode 100644 index 3918cd5..0000000 --- a/doc/INSTALL.symbian +++ /dev/null @@ -1,84 +0,0 @@ -Installation instructions for GPAC 0.4.5 on Symbian 9.1 (S60 3rd Edition) platform -last modified: December 2008 - -0 Foreword - ! GPAC versions later than 0.4.5 are no longer supported on Symbian ! - - Compilation has only been tested with GCCE & Nokia S60 SDK - In order to fully compile, you must get: - - the complete S60 3rd edition SDK (maintainance release) - - the MMF SDK update - - IMPORTANT NOTE: - You must install the SDK and the code you will compile with it (be it GPAC or anything else) - !! ON THE SAME LOGICAL DRIVE !! - If you do not do so, compilation will simply fail due to some misbehavior of the SDK's environment variables. - - - What is currently supported on symbian: - * all GPAC core, with audio and video output - * MP4 demux, AAC demux, MP3 demux, AMR demux - * native audio media codec from the phone through MMF: AAC and AMR - * MPEG-4 ASP video decoding through xvid - * JPEG and PNG decoding through libjpeg and libpng - * MP3 decoding through MAD - * TrueType fonts through FreeType - * Scripting with JS32 (not fully tested yet) - * FFMPEG (not really stable, random crashes) - - What is currently NOT supported on symbian: - * networking - - TIP: - Global compiler options are located in SDKRoot\Epoc32\tools\compilation_config\ - you may edit the default C++ rules to remove some - warnings during C compil. - - Side notes: - several SDKs may coexist on the drive. - * To see the list of SDKs, at DOS prompt, c:\devices - * To change the default SDK, at DOS prompt, c:\devices -setdefault @sdk_name - you may need to exit prompt and start a new one in order to refresh environment variables. - GPAC should compile on EKA2 (Symbian OS v8.0b, v8.1b). - GPAC CANNOT COMPILE ON EKA1 (Symbian OS v6.1, v7.0, v7.0s, v8.0a v8.1a) because EKA1 does not support writable static data in DLLs - -I Extra lib installation - Please follow the instructions in gpac_extra_lib/00_README_FIRST - -II GPAC compilation - - Go to gpac/build/symbian - - II.1 Configuring extra libs - * If you don't have libjs, libpng or libjpeg for symbian, comment indicated lines in libgpac.mmp (change #if 1 into #if 0) - * If you don't have OpenGL ES for symbian, comment indicated lines in libgpac.mmp (change #if 1 into #if 0) - * If you don't have freetype for symbian, comment ft_font.mmp in file bld.inf - * If you don't have ffmpeg for symbian, comment ffmpeg_in.mmp in file bld.inf - * If you don't have libmad for symbian, comment indicated lines in mp3_in.mmp - * If you don't have libopenjpeg (JPEG 2000) for symbian, comment indicated lines in img_in.mmp (change #if 1 into #if 0) - - II.2 Compiling GPAC - cd gpac/build/symbian - bldmake bldfiles - * for GCCE - abld build gcce urel - * for thumb - abld build thumb urel - cd sis - set EPOCROOT=\path\to\epoc\root\ - * for GCCE - makesis -d%EPOCROOT% osmo4_gcce.pkg - signsis osmo4_gcce.SIS osmo4_gcce.SIS gpac.cer gpac.key password - * for THUMB - makesis -d%EPOCROOT% osmo4_thumb.pkg - - Note: If you need to sign the SIS with your own certificate, you may generate one with openssl: - openssl req -new -x509 -nodes -sha1 -days 3650 -key gpac.key > gpac.cer - -You will get a .SIS package that installs properly on a symbian device. -NOTES: -* The app and plugins are all installed in \sys\bin on the device. DO NOT change this path, since it won't work otherwise (due to symbian 9.1 caged data stuff) -* If you create/succeed to compile a new plugin for GPAC, you must: - - edit build/symbian/sis/osmo4_gcce.pkg to add your plugin in the installer - - edit build/symbian/sis/GPAC.cfg to instruct the player of this new plugin (enumeration of DLLs on Symbian 9.1 is just not possible without a good amount of $$) - - diff --git a/doc/INSTALL.w32 b/doc/INSTALL.w32 deleted file mode 100644 index a338b23..0000000 --- a/doc/INSTALL.w32 +++ /dev/null @@ -1,217 +0,0 @@ -Installation instructions for GPAC on windows platform -last modified: May 2012 - -0 Foreword - For any question on the installation procedure, please refer to http://gpac.sourceforge.net/home_download.php - - The output directory for all plugins and applications is - gpac/bin/win32/debug in debug mode - gpac/bin/win32/release in release mode - - As of 0.2.2, GPAC cannot be compiled without ZLIB. You'd better make sure it is installed locally or on your system (zlib is provided in gpac_extra_libs package) - -I Extra lib installation - - It is recommended to download and compile all extra libs needed by gpac on windows. Please read carefull the ReadMe file included in the gpac_extra_libs package - - -II GPAC compilation - - open the GPAC workspace: - gpac/build/msvc6/GPAC.dsw with MSVC6 - gpac/build/msvc8/gpac.sln with VS2005 - gpac/build/msvc9/gpac.sln with VS2008 - - NEVER ATTEMPT TO LOAD A PROJECT OUTSIDE THIS WORKSPACE, AS DEPENDENCY RULES WILL BE BROKEN - - II.1 Recompiling GPAC - libgpac is the core library of the GPAC framework used by all GPAC applications. It is available as a static library and as a dynamic one - Set the "libgpac_dll" project as the active one - If you have not installed the SpiderMonkey (JavaScript, libjs), JPEG or PNG libraries, remove the indicated macros in the file gpac/include/gpac/internal/config_static.h - recompile (libgpac_dll compilation will fail if zlib is not found) - - Note: If you wish to build the fixed-point version of GPAC (not recommended), you will have to modify by hand the file gpac/include/gpac/maths.h - and replace the line - #define GPAC_NO_FIXED_POINT - by the line - #define GPAC_FIXED_POINT - - !!Do not attempts to enable fixed-point compilation in any other way!! - - II.2 Recompiling MP4Box - MP4Box is GPAC command-line tool for content authoring. - Set the "MP4Box" project as the active one - Recompile - - II.3 Plugins check - Before compiling other applications in GPAC you must make sure the projects are configured with the right libraries - - * aac_in - If you have not installed faad2 library, remove the GPAC_HAS_FAAD preprocessor variable from the aac_in project settings. - Note that if no aac decoder is installed for gpac you may as well remove the "aac_in" project from the workspace (DEL). - - * ac3_in - If you have not installed liba52 library, remove the GPAC_HAS_LIBA52 preprocessor variable from the ac3_in project settings. - Note that if no ac3 decoder is installed for gpac you may as well remove the "ac3_in" project from the workspace (DEL). - - * mp3_in - If you have not installed mad library, remove the GPAC_HAS_MAD preprocessor variable from the mp3_in project settings. - Note that if no mp3 decoder is installed for gpac you may as well remove the "mp3_in" project from the workspace (DEL). - - * xvid_dec - if you have not installed xvid library, remove the "xvid_dec" project from the workspace (DEL). - - * img_in: - If you have not installed libopenjpeg, remove the GPAC_HAS_JP2 preprocessor variable from the img_in project settings - and the relevant library from the link settings - If you have not installed any of the above libraries, you may remove the "img_in" project from the workspace (DEL). - - * amr_float_dec - This plugin handles speech coded data using AMR Narrow Band and Wide Band formats. It uses two decoders from the 3GPP consortium available at: - AMR Narrowband decoder: http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-700.zip - AMR Wideband decoder: http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-710.zip - - (The same versions are included in gpac_extra_libs/AMR_NB_FT and gpac_extra_libs/AMR_WB_FT ) - - To compile this plugin, copy the source code to modules/amr_float_dec/amr_nb_ft and modules/amr_float_dec/amr_wb_ft respectively, WITHOUT OVERWRITING typedefs.h files. - You may as well compile with only one of these libraries installed: - If you have not installed AMR NB, remove the GPAC_HAS_AMR_FT preprocessor variable from the amr_float_dec project settings - If you have not installed AMR WB, remove the GPAC_HAS_AMR_FT_WB preprocessor variable from the amr_float_dec project settings - Otherwise, remove the "amr_float_dec" project from the workspace (DEL). - - * amr_dec - This plugin handles speech coded data using AMR Narrow Band format with a fixed-point decoder (suited for embedded platforms). - It uses the decoder of the 3GPP consortium (TS26.073) available from http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-700.zip. - It is the same version included in gpac_extra_libs/AMR_NB with a slight header modifcation. - To compile this plugin, copy the source code to modules/amr_dec/amr_nb WITHOUT OVERWRITING typedefs.h file. - Otherwise, remove the "amr_dec" project from the workspace (DEL). Note you usually won't need this plugin, the float version of the decoders being much faster. - - * ffmpeg_in - To install ffmpeg libraries, cf gpac_extra_libs/ReadMe - if you have not installed ffmpeg libraries (avcodec.lib/dll, avformat.lib/dll, avutil.lib/dll), remove the "ffmpeg_in" project from the workspace (DEL). - - * ft_font - if you have not installed freetype, simply remove the "ft_font" project from the workspace (DEL). - - * gdip_rend - To install GDIPLus, either get Microsft PlatformSDK (http://www.microsoft.com/msdownload/platformsdk/sdkupdate/) or read gpac_extra_libs/GDIPlus/install.txt - if you have not installed GDIPlus or WindowsSDK, remove the "gdip_rend" project from the workspace (DEL). - - * ogg - if you have not installed libogg library, remove the "ogg" project from the workspace (DEL). - if you have not installed libvorbis library, remove the GPAC_HAS_VORBIS preprocessor variable from the ogg project settings - if you have not installed libtheora library, remove the GPAC_HAS_THEORA preprocessor variable from the ogg project settings - 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 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. - If you don't want to install libSDL or don't plan to use MP4Client or wxOsmo4, simply remove the "sdl_out" project from the workspace (DEL). - NOTE: SDL is not needed at all on windows, you will still have audio and video support without SDL. The SDL plugin is much slower than the directX plugin - when dealing with video since it uses software YUV to RGB conversion. - - NOTE: if you have not installed GDIPlus nor freetype, you won't have text support at all in GPAC. - - - II.4 Recompiling Osmo4 - Osmo4 is the GUI MPEG-4 player of GPAC for the windows platform. - Set Osmo4 as the active project - recompile (enabled plugins will be recompiled in the process) - - II.5 Recompiling MP4Client - MP4Client is the command MPEG-4 player of GPAC. - Set MP4Client as the active project - recompile (enabled plugins will be recompiled in the process) - - II.6 Recompiling Osmo4/wxWidgets - Osmo4 / wxWidgets is the cross-platform GUI MPEG-4 player of GPAC. You must have wxWidgets 2.6.0 installed and configured on your system (this may be tricky. Please - make sure you can recompile some sample wxWidgets applications from wxWidgets distribution first). - Set wxOsmo4 as the active project - recompile (some plugins may be recompiled in the process). You may need to change the linker settings, depending on your wxWidgets version and config - - II.7 Recompiling Osmozilla - Osmozilla is GPAC plugin for Mozilla-based browsers, enabling embedding all GPAC supported contents in a web page. Recompile it only if you think it may - be helpful. - * Get the gecko sdk (http://ftp.mozilla.org/pub/mozilla.org/mozilla/releases/mozilla1.7.13/gecko-sdk-i586-pc-msvc-1.7.13.zip or in the gpac_extra_libs package) - * Extract it to gpac/extra_lib/include/gecko-sdk - * Set Osmozilla as the active project and recompile - - II.7 Recompiling GPAX - GPAX is GPAC ActiveX control, only usable as an Internet Explorer plugin for now, enabling to embed all GPAC supported contents in a web page. Recompile it only if you think it may - be helpful (Set as the active project and recompile) - -III Launching the applications - - If you have compiled libgpac with SpiderMonkey (JavaScript) enabled, copy the JS32.dll file in the output directory. - - Some applications need to locate the GPAC configuration file called GPAC.cfg. This file is automatically generated by Osmo4 in its directory. It is recommended -to first launch Osmo4 to get a working config file. - For more information regarding the config file, cf gpac/doc/configuration.html - - You can launch Osmo4 as is, the application should start and be operational right away. - - You can use MP4Box as is. - - MP4Client needs GPAC configuration file to run. It will by default search for the file in the current directory, and some hardcoded directories that will likely not work. - If the config file is not found, a new one is created in the current directory. You can pass a given config file as a parameter (MP4Client -c config_path). - You can also modify the hardcoded path in MP4Client (gpac/Applications/MP4Client/main.c) to point to gpac output directory and recompile. - - - Osmozilla cannot be launched without a mozilla-based web browser. You should not try to install it in any other way than with the GPAC installer - (cf below). Once installed, you may try any test in an html page viewed with your browser, for example: - - - - To make sure your browser has loaded the osmozilla plugin and to check the mime types supported, try typing "about:plugins" in your browser address bar. - - GPAX cannot be launched without Internet Explorer. You should not try to install it in any other way than with the GPAC installer - (cf below). Once installed, you may try any test in an html page viewed with your browser, for instance: - - - - - -IV Configuration - - IV.0 Foreword - All configuration information is described in gpac/doc/configuration.html, or man gpac. - - IV.1 OpenGL - OpenGL is badly known for performing quite poorly as far as high data rate texturing is involved. This is a big issue when displaying a typical movie and you - will likely find the GPAC 3D Renderer very slow on your system. If your GPU supports non power of 2 texturing or rectangular texturing (most Win32 drivers do) - you shouldn't have any problem with video. Otherwise here are some tips to configure GPAC on your system: - 1- set the "BitmapCopyPixels" option on: some cards perform rather well at direct pixel transfer. If no improvement, set it off. - 2- set the "BitmapCopyPixels" option off and the "EmulatePOW2" option on. This will trick the GL texturing by using only Power Of 2 textures when converting - from YUV to RGB. - 3- If this does not improve video playback, you're only chance is through discussion forums & co to gather info about your system, your GL implementation - and how to fine-tune it. - -V Misc - - V.1 Scene Generators - In gpac/applications/generators you will find the code generators for MPEG-4, X3D and SVG scene graphs used in gpac. - If you want to modify the set of nodes understood by GPAC in encoding/decoding/rendering, you will need those. - The Scene generators can be recompiled without dependencies to extra libraries nor libgpac library. - To recompile them, open the related project files (.dsp) and recompile. - To use them, cf gpac/doc/SceneGenerators - - VI.2 V4Studio - V4Studio is a very simple authoring tool for 2D content. It is not usable but may interest developers. - For Installation instructions cf gpac/Applications/V4Studio/install - - VI.3 GPAC Installer - The GPAC installer uses the NSIS installing system. The installation script is gpac/bin/w32_rel/install/GPAC_Install.nsi - - Before building the installer - * get NullSoft installer (nsis.sourceforge.net), at least version 2.0 - * make sure the js32.dll is copied in the gpac/bin/w32_rel dir if you have compiled GPAC with SpiderMonkey support, otherwise comment - out "..\js32.dll" line from the install script - * copy gdiplus.dll to gpac/bin/w32_rel/install - * make sure avcodec.dll and avformat.dll are copied in gpac/bin/w32_rel if you have built ffmpeg plugin - * make sure iconv.dll, libxml2.dll, zlib1.dll in gpac/bin/w32_rel if you have compiled libxml2 - - - Building GPAC installer - The installer includes Osmo4, MP4Box, Osmozilla and all modules except SDL_out and raw_out. To install, right click on "GPAC_Install.nsi" and compile - For other configurations, modify the script "GPAC_Install.nsi" to comment out unwanted features - diff --git a/doc/INSTALL.wCE b/doc/INSTALL.wCE deleted file mode 100644 index e308319..0000000 --- a/doc/INSTALL.wCE +++ /dev/null @@ -1,134 +0,0 @@ -Installation instructions for GPAC on windows CE platform -last modified: Mai 2012 - -0 Foreword - - ** GPAC IS NO LONGER MAINTAINED ON PocketPC 2002/eVC3 PLATFORMS ** - - Compilation has only been tested with evc4 and ARM platforms - - GPAC should be stable on most devices running PocketPC/SmartPhone 2003. It has know bugs with higher versions - of the Windows Mobile OS, but should still be stable. - - The output directory for all plugins and applications for Windows PocketPC 2003 is - gpac/bin/Smartphone 2003/Debug in debug mode - gpac/bin/Smartphone 2003/Release in release mode - - As of 0.2.2, GPAC cannot be compiled without ZLIB. You'd better make sure it is installed locally or on your system (zlib is provided in gpac_extra_libs package) - -I Extra lib installation - It is recommended to download and compile all extra libs needed by gpac on winCE. - In case you don't do so, you will need to to modify project settings. - - -II GPAC compilation - open /build/msvc8/gpac.sln (GPAC workspace) with MSVC 2005 - open /build/msvc9/gpac.sln (GPAC workspace) with MSVC 2008 - - NEVER ATTEMPT TO LOAD A PROJECT OUTSIDE THIS WORKSPACE - - II.1 Setting up libgpac - libgpac is the core library of the GPAC framework used by all GPAC applications - - If you have not installed the SpiderMonkey (JavaScript, libjs), JPEG or PNG libraries, remove the indicated macros in the file gpac/include/gpac/internal/config_static.h - - If you are compiling for PocketPC 2003 OS, and wish to use the Intel GPP library, uncomment the desired macro in - the file gpac/include/gpac/internal/config_static.h - - 3D Rendering - GPAC can use OpenGL ES for 3D rendering on embedded devices, but you will need development files of OpenGL ES. - GPAC has been tested with 2 implementations of OpenGL ES: - * HybridGraphics one (cf http://www.hybrid.fi/), by far the most efficient one tested, available for evc4/PockePC 2003 only - * Vincent3D (aka ogl-es, cf http://ogl-es.sourceforge.net/), slower but with good visual results - - To setup OpenGL ES, get one of these libraries, configure the IDE to locate the include and lib files (or copy them in gpac/extra_lib/ which is setup by default) - The GL ES lib shall be named "libGLES_CM.lib" or "libGLES_CL.lib" for the OpenGL-ES Light profile, and the GL ES include files shall be located in a "GLES" directory, the include path pointing to its parent directory. - - NOTE 1: The Klimt library (cf http://studierstube.org/klimt/), which is not 100% OpenGL_ES compliant, may be used but needs some code rewrite here and there, - mainly in gapi video output. - - NOTE 2: If you do not plan to support 3D rendering, uncomment the related macro in the file gpac/include/gpac/internal/config_static.h - - - II.2 Checking Plugins - - Before compiling GPAC plugins, you must make sure the projects are configured with the right libraries - * aac_in - If you have not installed faad2 library, remove the GPAC_HAS_FAAD preprocessor variable from the aac_in project settings. - Note that if no aac decoder is installed for gpac you may as well remove the "aac_in" project from the workspace (DEL). - - * ac3_in - If you have not installed liba52 library, remove the GPAC_HAS_LIBA52 preprocessor variable from the ac3_in project settings. - Note that if no ac3 decoder is installed for gpac you may as well remove the "ac3_in" project from the workspace (DEL). - - * mp3_in - If you have not installed mad library, remove the GPAC_HAS_MAD preprocessor variable from the mp3_in project settings. - Note that if no mp3 decoder is installed for gpac you may as well remove the "mp3_in" project from the workspace (DEL). - - * amr_nb - This plugin handles speech coded data using AMR Narrow Band format. It uses the decoder of the 3GPP consortium (TS26.073) available - from http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-700.zip. - It is the same version included in gpac_extra_libs/AMR_NB with a slight header modifcation. - To compile this plugin, copy the source code to modules/amr_dec/amr_nb WITHOUT OVERWRITING typedefs.h file. - Otherwise, remove the "amr_dec" project from the workspace (DEL). - - * img_in: - If you have not installed libopenjpeg, remove the GPAC_HAS_JP2 preprocessor variable from the img_in project settings - and the relevant library from the link settings - If none of the above lib is installed, you can simply remove the img_in project from the workspace (DEL). - - * ft_font - if you have not installed freetype, remove the project dependecies to freetype in project Osmo4 and MP4Client - NOTE: if you have not installed freetype, you won't have text support at all in GPAC. - - * ogg - if you have not installed libogg library, remove the "ogg" project from the workspace (DEL). - if you have not installed libvorbis library, remove the GPAC_HAS_VORBIS preprocessor variable from the ogg project settings - if you have not installed libtheora library, remove the GPAC_HAS_THEORA preprocessor variable from the ogg project settings - Note that if you have only installed libogg you can also remove the "ogg" project from the workspace, it won't be any usefull. - - * gapi: - you must make sure you have installed the GAPI SDK for windows (also known as GX) before compiling - cf gpac_extra_libs/ReadMe - - II.3 Recompiling - select the target platform (PocketPC or Smartphone) - Rebuild all (Build->Batch Build->Rebuild All) - - Note: - Osmo4 build will fail for smartphone devices, the GPAC GUI available on this platform is Osmophone - - II.4 Launching Osmo4 or Osmophone - Osmo4/Osmophone will automatically create a config file in the Osmo4/Osmophone executable directory if needed. You must copy all plugins to this - directory (recommended), or edit by hand the config file "ModulesDirectory" key to point to the modules directory, otherwise Osmo4/Osmophone will not - launch. You can then launch Osmo4/Osmophone (cf Misc section below) - -III GPAC Installer for WinCE - - The GPAC installer uses MS installer and EZSetup to get an Osmo4/Osmophone installer on PocketPC 2003 Systems - Install scripts are located in gpac/bin/arm_ppc02_rel/install and gpac/bin/arm_ppc03_rel/install - THIS INSTALLER IS ONLY INTENDED FOR STRONGARM BASED DEVICES - - * compile GPAC for PocketPC 2003 - * make sure the js.dll is copied in the release build directory if you have compiled GPAC with SpiderMonkey support, otherwise comment lines "js.dll" in gpac.inf - * make sure the libGLES_CM.dll (or libGLES_CL.dll ) is copied in the release build directory if you have compiled with OpenGL ES support, otherwise comment lines "libGLES_CM.dll" and "gm_render3d.dll" in gpac.inf - * make sure the libxml2.dll is copied in the release build directory if you have compiled the svg loader, otherwise comment lines "libxml2.dll" in gpac.inf - * remove any lines in gpac.inf that refer to plugins you have not built. - * if you have built the smartphone version, change AppName and ExeName accordingly in gpac.inf - * get MS PocketPC Cabwizard (search for Cabwiz.exe in your ActiveSync distribution) - * copy cabwiz.exe, cabwiz.ddf and MAKECAB.exe in the install directory - * if needed copy gx.dll in the install directory (download from microsoft, or use gpac extra libs version) - * get Ezsetup from http://www.eskimo.com/~scottlu/win/, and copy it in this directory - * run do.bat file - -IV Misc - - IV.1 Note on Video - As of 0.2.3, the OpenDivx plugin is no longer included in GPAC. A new, modified version of XviD 1.0 for ARM is included (cf gpac/modules/xvid_dec/xvid_wce/ReadMe.txt) - - IV.2 Note on Network - Ipaq devices under WindowsCE below Windows CE .NET 4.1 (and maybe other devices) have a small default UDP buffer size, and this buffer size cannot - be changed through WinSock (software) calls. To increase it, you must manually edit the registry and set (add a DWORD key if not present): - HKEY_LOCAL_MACHINE\Comm\Afd\DgramBuffer 16 - 16 is the maximum value possible, DON'T TRY TO SPECIFY MORE. - The device MUST be reseted (soft reset, cf your manual) for the parameter to be taken into account. - diff --git a/doc/configuration.html b/doc/configuration.html deleted file mode 100644 index 91fb4a1..0000000 --- a/doc/configuration.html +++ /dev/null @@ -1,999 +0,0 @@ - - - - - - GPAC Configuration documentation - - -

-
-GPAC Configuration file documentation -
-GPAC Version 0.7.1 -
-
-

- -

- -Overview -

-Some applications in the GPAC framework use a configuration file shared among modules and reloadable at run time. Modules may use the configuration file as well (to avoid multiple config files). This doc attempts to provide explanations for the different options. -

-The config file is ordered by sections and keys. -
A section is declared as SectionName. Defined sections are: -
-General -RecentFiles -Systems -Compositor -Audio -Video -Network -FontEngine -Downloader -HTTPProxy -Streaming -MimeTypes -StreamingCache -SAXLoader -XviD -FFMPEG -ISOReader -DVB -DASH -ALSA -Shortcuts -DSMCC -OpenHEVC -DirectFB -DektecVideo -M2TS -RAWVideo - -

-

-A key is declared as keyName=value. The key value is not interpreted and always handled as ASCII text. -

-
    -
  • -On Windows plateforms, this config file is called "GPAC.cfg" and is usually located in C:\\Program Files\\GPAC. Note that Osmo4 will always create a config file in its own directory when none is found. -

    -
  • -
  • -On Windows CE plateform, this config file is called "GPAC.cfg" and is usually located in \\Program Files\\GPAC. Note that Osmo4 / CE will always create a config file in its own directory when none is found. -

    -
  • -
  • -On GNU/Linux plateforms, this config file is called ".gpacrc" and is always located at the root of the user home directory (for ex, /home/jean/.gpacrc). -

    -
  • -
-
- -

Note on module names: -
Module names as given in the config file are names exported by each interface and not name of the physical library file (.dll, .so, ...). The physical file name can however be used to identify a module - it will then be replaced by the module name. - -

-

- - -Section "General" Back to top -

-The General section of the config file holds player specific options. -

-ModulesDirectory [value: path to directory] -

-Specifies the path to modules directory. The MPEG-4 Systems engine cannot be loaded without modules. This option is used by GPAC clients on all platforms. -

-CacheDirectory [value: path to storage directory] -

-Specifies location of temp files. The user must have write access to this location. Although not used by applications, this is used by several modules. -

-StartupFile [value: filename] -

-Specifies file to load upon startup of most clients (Osmo4/MP4Client). If not specified, no file is loaded. -

- -LogFile [value: filename] -

-Specifies where to output GPAC's log. By default, the logs are written to stdout. Note that GPAC may be compiled without log support. This is not used by MP4Client. -

-Logs [value: tool[:tool]@level:tool[:tool]@level] -

-Specifies log level for each tool. By default, only errors are logged. Available levels are: -

    -
  • quiet : no logging is performed on the tool
  • -
  • error : only errors are logged
  • -
  • warning : warnings are also logged.
  • -
  • info : information messages are also logged
  • -
  • debug : debug messages are also logged
  • -
-
-Available tools are: -
    -
  • core : libgpac core
  • -
  • coding : bitstream formats (audio, video, scene)
  • -
  • container : container formats (ISO File, MPEG-2 TS, AVI, ...)
  • -
  • network : network data exept RTP trafic
  • -
  • rtp : rtp, rtcp and rtsp trafic
  • -
  • author : authoring tools (hint, import, export)
  • -
  • sync : terminal sync layer
  • -
  • codec : terminal codec messages
  • -
  • parser : scene parsers (svg, xmt, bt) and other
  • -
  • media : terminal media object management
  • -
  • scene : scene graph and scene manager
  • -
  • script : scripting engine messages
  • -
  • interact : user interaction messages
  • -
  • compose : composition engine (events, etc)
  • -
  • cache : HTTP cache
  • -
  • mmio : Audio/Video HW I/O management
  • -
  • rti : Run-time info (CPU, mem, ...)
  • -
  • smil : SMIL timing and animation
  • -
  • memory : GPAC memory tracker
  • -
  • audio : Audio renderer and mixers
  • -
  • module : used by some modules
  • -
  • mutex : mutex information
  • -
  • console : console messages, such as script alert() and error notifications
  • -
-

- -

-

-

- -Options defined for Osmo4 (Windows version and wxWidgets version):

-Loop [value: "yes" "no"] -

-Specifies whether the presentation has to be restarted when done playing. -

-ConsoleOff [value: "yes" "no"] -

-Specifies whether application messages (script, buffering, download progress) are displayed in the console or not. -

-SingleInstance [value: "yes", "no"] -

-Specifies if the player should be a single instance application or not (Osmo4-Win32 only). -

-LookForSubtitles [value: "yes" "no"] -

-Specifies if Osmo4 shall look for subtitle files when opening a presentation. -

-ViewXMT [value: "yes" "no"] -

-Specifies if scene dumping shall be done in XML (XMT, X3D) or in VRML-like syntax (BT, WRL). -

-ConfigPanel [value: positive integer] -

-Specifies the latest config panel selected by user. -

-NoMIMETypeFetch [value: "yes", "no"] -

-Specifies if the player has to check for mime type when following hyperlinks, or only follow links of known extensions. -

-Loop [value: "yes", "no"] -

-Specifies if the playlist shall be restarted when playback is over. -

-PLEntry [value: positive integer] -

-Indicates active playlist entry when player was last closed. Playlist backup is: -

-
    -
  • "gpac_pl.m3u" on win32 platforms, stored in same directory as application
  • -
  • ".gpac_pl.m3u" on other platforms, stored in user home directory
  • -
-FillScreen [value: "yes", "no"] -

-Specifies if the display area shall fill all available space on screen. WindowsMobile/Symbian only -

-DisableBackLight [value: "yes", "no"] -

-Specifies if the screen backlighting shall be disabled while playing. WindowsMobile/Symbian only -

-LastWorkingDir [value: "yes", "no"] -

-Specifies the directory of the last local file opened. Smartphone Windows only -

-Browser [value: string] -

-Specifies prefered browser for WWW anchors and scene graph viewing - Only used by Osmo4/wxWidgets. -

- - -Section "RecentFiles" Back to top -

-The "RecentFiles" section of the config file holds last accessed files (hardcoded to no more than 20) in the last access order. The keys are -the file names and no value is used. This section is only used by GUI clients (osmo4/wxOsmo4) -

- - -Section "Systems" Back to top -

-The "Systems" section of the config file holds all configuration options for the MPEG-4 Systems engine. -

-LanguageName [value: string] -

-Specifies the user prefered language in readable english. This is used to select streams in case of alternate content in an audio object. -

-Language3CC [value: 3-char code from ISO 639-2] -

-Specifies the user prefered language as expressed in ISO 639-2. This is used to select streams in case of alternate content in an audio object. -

-Language2CC [value: 2-char code from ISO 639-1] -

-Specifies the user prefered language as expressed in ISO 639-1. This is used to select streams in case of alternate content in an audio object. -

-DrawLateFrames [value: "yes" "no"] -

-If set, late frames will still be drawn. If not set, the late frames are droped (or executed for systems decoders) untill the decoder output is back in sync. This is by default on to keep better testing heavy content or slow renderers, but should be set to off when needing a better sync or monitoring skipped frames. -

-ForceSingleClock [value: "yes" "no"] -

-One big problem with MP4 files is that the notion of "duration" has been unclear for a long time, and most content available (audio-video files) specifiy a -wrong BIFS duration. In such a case the movie cannot be controled/seeked into. Another problem with ISMA streaming is that BIFS/OD don't use the same clock as -audio/video, thus seeking the main timeline does not seek AV media. Setting the ForceSingleClock will handle both cases by using a single timeline for all media -streams and setting the duration to the one of the longest stream. -

-ThreadingPolicy [value: "Free" "Single" "Multi"] -

-Specifies how media decoders are to be threaded. "Free" lets decoders decide of their threading, "Single" means that all decoders are managed in a single thread performing scheduling and priority -handling and "Multi" means that each decoder runs in its own thread. -

-Priority [value: "low" "normal" "high" "real-time"] -

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

-TimeSlice [value: unsigned integer] -

-Specifies the target maximum time (in ms) of one cycle of the media manager (the media manager will attempts to call all the active decoders within this time. Depending on the threading mode this option can be ignored; -

-ModuleUnload [value: "yes" "no"] -

-Specifies whether modules should be unloaded if not used or not. Default: "yes". -

-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. -

-DefAudioDec , DefVideoDec and DefImageDec [value: string] -

-Specifies which module to use by default for audio/video/image decoding. The string is the name of the module to be used (same considerations as other modules, cf introduction). -

-codec_XX_XX [value: string] -

-Allows to specify default media module (audio/video) per stream type and object type. This is usefull if you have more than one decoder for a given type (ex, XviD and FFMPEG for MPEG-4 visual SP). The syntax is: -
codec_AA_BB=modulename
-where AA is the hexadecimal MPEG-4 streamType value for the codec (04=visual, 05=audio) and BB is the hexadecimal MPEG-4 objectTypeIndication of the media (0x20 = MPEG-4 video, 0x40=MPEG-4 Audio, ...). -The string is the name of the module to be used (same considerations as other modules, cf introduction). -

- - -Section "Compositor" Back to top -

-The "Compositor" section of the config file holds all configuration options for the compositor (logical rendering engine). -

-Raster2D [value: string] -

-Specifies the 2D rasterizer to use for vectorial drawing. Same as above, this module cannot be reloaded during a presentation.

-FrameRate [value: float] -

-Specifies the simulation frame-rate of the presentation - this value is also used by the MPEG-4 Systems engine to determine when a BIFS frame is mature for decoding.

-AntiAlias [value: "None" "All" "Text"] -

-Specifies antialiasing settings - whether the setting is applied or not depends on the graphics module / graphic card. -

-
    -
  • "None": no anti-aliasing
  • -
  • "Text": anti-aliasing for text only
  • -
  • "All": complete anti-aliasing
  • -
-HighSpeed [value: "yes" "no"] -

-Specifies whether rendering should target speed or quality - whether the setting is applied or not depends on the renderer, graphics module / graphic card.

-ForceSceneSize [value: "yes" "no"] -

-Forces the scene to resize to the biggest bitmap available if no size info is given in the BIFS configuration.

-StressMode [value: "yes" "no"] -

-Specifies that the renderer runs in worst case scenario, recomputing display lists and reloading textures (sending them to graphics card) at each frame even when no change has occured.

-BoundingVolume [value: "None" "Box" "AABB"] -

-Specifies whether the bounding volume of an object shall be drawn or not. Note that the 2D renderer only uses rectangles as bounding volumes. The "AABB" value is used by the -3D renderer only, and specifies the object bounding-box tree shall be drawn.

-ColorKey [value: unsigned hexadecimal integer, formated as AARRGGBB] -

-Specifies the color key to use for windowless rendering. GPAC currently doesn't support true alpha blitting to desktop due to limitations in most windowing toolkit, it therefore uses color keying mechanism. The alpha part of the key is used for global transparency of GPAC's output, if supported. -

-BackColor [value: unsigned hexadecimal integer, formated as AARRGGBB] -

-Specifies the background color to use when displaying transparent images or video with no scene compoistion instructions. -

-DrawMode [value: "immediate" "defer" "defer-debug"] -

-Specifies whether immediate drawing should be used or not. In immediate mode, the screen is completely redrawn at each frame. In defer mode -object positioning is tracked from frame to frame and dirty rectangles info is collected in order to redraw the minimal amount of the screen buffer. Whether -the setting is applied or not depends on the graphics module (currently all modules handle both mode). Defer Debug mode only renders changed areas.

-ScalableZoom [value: "yes" "no"] -

-Specifies whether scalable zoom should be used or not. When scalable zoom is enabled, resizing the output window will also recompute all vectorial objects. Otherwise only the final buffer is stretched.

-DisableYUV [value: "yes" "no"] -

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

-TextureFromDecoderMemory [value: "yes" "no"] -

-Allows video textures to be build directly from video decoder internal buffers. This may increase performances on some systems. Default is no.

-ForceOpenGL [value: "always", "disable", "hybrid", "raster"] -

-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, and 2D graphics will not loo as nice as 2D mode. The hybrid mode performs software drawing of 2D graphics with no textures (better quality) and uses OpenGL for all textures. The raster mode only uses OpenGL for pixel IO but does not perform polygin fill (no tesselation) (slow, mainly for test purposes).

-EnablePBO [value: "yes", "no"] -

-Uses PixelBufferObjects to push YUV textures to GPU in OpenGL Mode.. This may slightly increase the performances of the playback.

-DefaultNavigationMode [value: "Walk", "Fly", "Examine"] -

-Overrides the default navigation mode of MPEG-4/VRML (Walk) and X3D (Examine).

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

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

-PolygonAA [value: "yes" "no"] -

-Specifies whether polygon antialiasing should be used in full antialiasing mode. If not set, only lines and points antialiasing are used.

-DisableBackFaceCulling [value: "yes" "no"] -

-Specifies whether backface culling shall be disable or not. If not set, backface culling is performed.

-Wireframe [value: "WireNone" "WireOnly" "WireOnSolid"] -

-Specifies wireframe drawing options:

-
    -
  • "WireNone": objects are drawn as solid
  • -
  • "WireOnly": objects are drawn as wireframe only
  • -
  • "WireOnSolid": objects are drawn as solid and wireframe is then drawn
  • -
-DisableRectExt [value: "yes" "no"] -

-Specifies whether OpenGL rectangular texture extension (GL_EXT_texture_rectangle or GL_NV_texture_rectangle) shall be used or not.

-
    -
  • "yes": textures whose dimensions are not power of two are rescaled except if hardware support non-power-of-two textures (GL_ARB_texture_non_power_of_two) natively.
  • -
  • "no": if extension is available, textures are used without rescaling. Note that in this case texture transformations are disabled.
  • -
-EmulatePOW2 [value: "yes" "no"] -

-Enables power of 2 emulation. Ignored if openGL rectangular texture extension is enabled.

-
    -
  • "yes": video texture is not resized but emulated with padding. This usually speeds up video mapping on shapes but disables texture transformations.
  • -
  • "no": video is resized to a power of 2 texture when mapping to a shape.
  • -
-DisableGLUScale [value: "yes" "no"] -

-Disables usage of gluScaleImage, which may be slower but nicer than GPAC's software stretch routines.

-TextureTextMode (value: "Default", "Never", "Always"] -

-Specifies whether text shall be drawn to a texture and then rendered or directly rendered. Using textured text can improve text rendering in 3D and also improve text-on-video like content. Default value will use texturing for OpenGL rendering.

-OpenGLExtensions [value: string] -

-Read-only option listing the OpenGL extensions supported by the GL driver. Only valid after the 3D renderer has been used. -

-StereoType [value: "None", "SideBySide", "StereoHeadset", "TopToBottom", "Anaglyph", "Columns", "Rows", "SPV19", "Custom"] -

-Specifies the stereo output type (default "None"). If your graphic card does not support OpenGL shaders, only SideBySide and TopToBottom modes will be available.

-
    -
  • "SideBySide": images are displayed side by side from left to right.
  • -
  • "TopToBottom": images are displayed from top (laft view) to bottom (right view).
  • -
  • "StereoHeadset": same as SideBySide except that view aspect ratio is not changed.
  • -
  • "Anaglyph": Standard color anaglyph (red for left view, green and blue for right view) is used.
  • -
  • "Columns": images are interleaved by columns, left view on even columns and left view on odd columns.
  • -
  • "Rows": images are interleaved by columns, left view on even rows and left view on odd rows.
  • -
  • "SPV19": images are interleaved by for SpatialView 19'' 5 views display, fullscreen mode.
  • -
  • "Custom": images are interleaved according to the shader specified by InterleaverShader -
- -NumViews [value: unsigned integer] -

-Specifies the number of views to use in stereo mode. If mode is "Anaglyph", "Columns" or "Rows", the number of views is forced to 2.

- -InterleaverShader [value: path to fragment shader file] -

-Specifies the fragment shader file to use for view interleaving. Each view is rendered in its own texture. The shader is exposed each view as uniform sampler2D gfViewX, where X is the view number starting from the left (gfView1).

- -ReverseViews [value: "yes", "no"] -

-Specifies if the view order should be reversed (from right to left) or not.

-EyeSeparation [value: float] -

-Specifies the eye separation in cm (distance between the cameras). Default: 6.3 cm.

-CameraLayout [value: "OffAxis", Linear", "Circular"] -

-Specifies the camera layout. The default value is OffAxis in (auto-)stereo modes, ignored in mono mode.

-ViewDistance [value: integer] -

-Specifies the distance in cm between the camera and the zero-disparity plane. There is currently no automatic calibration of depth in GPAC.

- -Output8bit [value: "yes" "no"] -

-Specifies whether 10 bit textures should be converted to 8 bit before GPU upload or use as is. Default is no if screen supports 10 bpp, yes otherwise.

- -VRDefaultFOV [value: float] -

-Default field of view for VR 360. Default is PI/2.

- - -

- - -Section "Audio" Back to top -

The "Audio" section of the config file holds all configuration options for the audio rendering engine and hardware.

-DriverName [value: string] -

-Specifies the driver to use for audio rendering. This driver cannot be reloaded at run-time, the complete system must be restarted.

-ForceConfig [value: "yes" "no"] -

-Forces a given sound card configuration to be used. If not set the sound card will be setup to use 2 audio buffers of 1024 samples each. -This may not work properly on some audio cards due to hardware latency, therefore forcing the config may be very usefull.

-NumBuffers [value: positive integer, 0 forbidden] -

-When config is forced, specifies the number of audio buffers to allocate (audio buffers are played in ring).

-TotalDuration [value: positive integer, 0 forbidden] -

-When config is forced, specifies the total audio buffer size in milliseconds. Be aware that the longer the audio buffer is, the longer the audio latency will be when pausing an -audio object. The quality of fast forward audio playback will also be degradated when using large audio buffers.

-NoResync [value: "yes" "no"] -

-Disables audio resynchronization: audio data is never dropped but may get out of sync.

-DisableMultiChannel [value: "yes" "no"] -

-Disables audio multichannel output and always downmix to stereo. This may be usefull if the multichannel output behaves weirdly.

-DisableNotification [value: "yes" "no"] -

-Disables usage of audio buffer notifications when supported (currently only DirectSound supports it). If DirectSound audio sounds weird try without notifications.

-Volume [value: integer (0-100)] -

-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.

- -

- - -Section "Video" Back to top -

The "Video" section of the config file holds all configuration options for the video renderer and hardware.

-DriverName [value: string] -

-Specifies the driver to use for video memory access. This driver cannot be reloaded at run-time, the complete system must be restarted.

-SwitchResolution [value: "yes" "no"] -

-Specifies fullscreen resolution mode. If enabled, selects smallest video resolution larger than scene size, otherwise use current video resolution.

-HardwareMemory [value: "Auto" "Always" "Never"] -

-Only valid for 2D renderer. Specifies if main video backbuffer is always on hardware, always on system memory or selected by GPAC (default mode). Depending on the scene type, this may drastically change the playback speed.

-DisableColorKeying [value: "yes" "no"] -

-Only valid for 2D renderer. Specifies if partial overlays should be disabled. If not disabled, hardware color keying for overlays is tested and used if present. Otherwise, only the top-most video with no overlapping objects will be drawn using overlays. Default value is "no".

-UseGLDoubleBuffering [value: "yes" "no"] -

-Specifies if OpenGL double buffering shall be used. Default is "no".

-GLNbBitsPerComponent [value: positive integer] -

-Specifies the number of bits per color component. Default is 5.

-GLNbBitsDepth [value: positive integer] -

-Specifies the number of bits for the depth buffer. Default is 16.

-X113DOffscreenMode [value: "Window" "VisibleWindow" "Pixmap"] -

-Specifies the type of OpenGL offscreen rendering in X11. Default mode is "Pixmap".

-
    -
  • "Window": A hidden window is used to perform offscreen rendering. Depending on your video driver and X11 configuration, this may not work.
  • -
  • "VisibleWindow": A visible window is used to perform offscreen rendering. This can be usefull while debugging.
  • -
  • "Pixmap": An X11 Pixmap is used to perform offscreen rendering. Depending on your video driver and X11 configuration, this may not work and can even crash the player.
  • -
- - -

- -Section "Network" Back to top -

The "Network" section of the config file holds all configuration options for the network used by modules and systems engine.

-AutoReconfigUDP [value: "yes" "no"] -

-Specifies if network manager shall reconnect a scene if UDP is not present.

-DataTimeout [value: positive integer] -

-Specifies timeout in ms befor initial media buffering aborts. Default terminal value is 20000 (20 seconds).

-UDPNotAvailable [value: "yes" "no"] -

-Specifies if UDP traffic is not available. This is automatically set by GPAC if AutoReconfigUDP is set.

-UDPTimeout [value: positive integer] -

-Specifies timeout in ms for initial UDP detection. Once a UDP packet is recieved the timeout is ignored.

-BufferLength [value: positive integer] -

-Specifies the length of the decoding buffer in milliseconds. The client will wait for the buffer to be filled before starting decoding. A module may decide to use a different value based on protocol and network jitters.

-RebufferLength [value: positive integer] -

-Specifies rebuffering length of the decoding buffer in milliseconds. Whenever the decoding buffer fullness is less than this value, the object clock is paused and -the stream rebuffered till BufferLength. Therefore a value of 0 means no rebuffering. A module may decide to use a different value based on protocol and network jitters. -

-BufferMaxOccupancy [value: positive integer] -

-Specifies maximum buffer occupancy for buffer regulation. Corresponds to the max amount of data to be prefetch. Any value less than BufferLength will be forced to BufferLength. -

- -LowLatencyBufferMax [value: positive integer] -

-Specifies the maximum buffer level for low latency mode, in ms. If media buffer max is above this value, full buffering will be done (clock resume at first frame displayed). Default value is 500 ms.

-

-MobileIP [value: IP Address] -

-Specifies a Mobile IP interface overriding the default IP. If set, all sockets will be locally bound to this IP address.

-

-DefaultMCastInterface [value: IP Address] -

-Specifies a default IP interface for Multicast overriding the default IP.If not set, the multicast will be setup using the default IP.

-

-HTTPRebuffer [value: positive integer] -

-Specifies the default HTTP rebuffer time in ms. When playback position reaches download position, playback will be paused if this integer is not zero. Playback will resume once the HTTPRebuffer ms of playback are available. Default value is 5000 ms.

-

-HTTPAutoRebuffer [value: "yes", "no"] -

-Specifies whether auto rebuffering is used. When auto-rebuffering is used, playback only resumes when estimated time to download the rest of the movie is less than remaining time of the playback. Default value is no.

-

- - - -

- -Section "FontEngine" Back to top -

The "FontEngine" section of the config file holds all configuration options for the font handling. The GPAC rendering module handles text through vectorial outline, allowing graphics module development without having to -integrate text rendering which is always heavy work.

-FontReader [value: string] -

-Specifies the module to use for font handling. This module cannot be reloaded at run-time, GPAC must be restarted.

-WaitForFontLoad [value: "yes" "no"] -

-Forces to wait for SVG fonts to be loaded before displaying frames - default is "no".

-FontDirectory (value: path to TrueType (*.ttf, *.ttc) font directory] -

-Specifies the directory where fonts are located - currently only one directory can be specified (however nothing stops a font module from using a private directory). -
Note: -The freetype module will scan the entire sub-directories for fonts. -

-FontSerif [value: string]}: specifies default SERIF font.
-FontSans [value: string]}: specifies default SANS font.
-FontFixed [value: string]}: specifies default fixed font.
-
-Note:
-The FreeType module uses this section to cache familly names to font file name associations. - - -

- -Section "Downloader" Back to top -

The "Downloader" section of the config file holds all configuration options for file downloading and caching.

-CleanCache [value: "yes" "no"] -

-Specifies whether downloaded files shall be removed once used.

-DisableCache [value: "yes" "no"] -

-Specifies whether HTTP caching instructions are disabled or not.

-AllowOfflineCache [value: "yes" "no"] -

-When enabled, allows HTTP request to use cached file if any when network is not available.

-MaxRate [value: positive integer] -

-Specifies a maximum data rate in kilo bits per seconds for file downloading. This is used for simulation purposes. A value of 0 means no rate restriction.

-UserAgent [value: string] -

-Specifies an alternate user agent (default one is "GPAC $VERSION").

-HTTPHeadTimeout [value: positive integer] -

-Specifies timeout in milliseconds before considering HEAD request failed. 0 means no HEAD request is issued, only GET.

-AllowBrokenCertificate [value: yes no] -

-If set to yes, ignores invalid certificates and process anyway. Default is no.

- -

- -Section "HTTPProxy" Back to top -

The "HTTPProxy" section of the config file holds configuration option for HTTP proxy adressing. Currently only one proxy can be enabled, and no URI selection is done.

-Enabled [value: "yes" "no"] -

-Specifies whether the proxy should be used or not when downloading files.

-Name [value: string] -

-Specifies the proxy name (IP address or resolved name) without protocol identifier (eg, no "http://"). If not present, the proxy is disabled.

-Port [value: positive integer] -

-Specifies the port to use with the proxy. If no port is specified, the default HTTP port (80) is used.

- -

- -Section "Streaming" Back to top -

The "Streaming" section of the config file holds all configuration options for real-time streaming using IETF SDP/RTSP/RTP/RTCP protocols.

-DefaultPort [value: unsigned short] -

-Specifies the default port to use when connecting to a server (ignored if a port is specified in the url) if the port is 80 or 8080 (HTTP), the client will connect to the -RTSP server through an HTTP tunnel, and transport will take place on the RTSP connection.

-ReorderSize [value: positive integer] -

-Size of the RTP reordering buffer - 0 means no reordering. Ignored when transport takes place on the RTSP connection. The bigger this value, the longer the reordering delay will be.

-RTPoverRTSP [value: "yes" "no" "OnlyCritical"] -

-Specifies whether RTP packets should be carried on the RTSP connection (TCP or UDP), or carried on UDP. If the connection port is an HTTP port, this value is assumed to be true. If set to OnlyCritical, transport will take place on TCP only if a critical media (eg, neither audio nor video) is found in the session.

-RTSPTimeout [value: positive integer] -

-Specifies connection timeout with the server: an RTSP request is considered as failed when the timeout expires.

-ForceFirstPort [value: positive integer] -

-Specifies first port for RTP channels. If not set, the default first port used by GPAC is 7040.

-NATKeepAlive [value: positive integer] -

-Specifies the maximum inactivity period in milliseconds for RTP sockets. If no data is received after this period, an empty RTP packet will be sent in order to keep any NAT alive. If 0 (default), disables NAT keep-alive packets.

-ForceMulticastIP [value: IP4 or IP6 address] -

-Forces the specified multicast address to be used instead of the regular unicast. Note that some servers may not support multicast initiation by the client.

-ForceMulticastTTL [value: Positive integer] -

-Indicates the TTL to use when the client initiates the multicast. Default value is 127.

-FirstPacketDrop [value: positive integer] -

-Specifies the sequence number of the first RTP packet to be droped - 0 means no packet drop. Used for packet drop simulation tests.

-PacketDropFrequency [value: positive integer] -

-Specifies the frequency at which SL packets are droped. If value is 20, one packet every 20 recieved packets will be droped. Used for packet drop simulation tests.

- -

- - -Section "MimeTypes" Back to top -

This section is used to keep MIME types and file associations for GPAC modules. -
The format of the key is: -
mimeType="fileExt1 filexExt2 .. filexExtN" "MimeType description" ModuleName -
-The description is used for GUI purposes (open file dialogs). You may modify the file extension list to support your own extensions. -MIME Type is always checked when processing a remote ressource (eg http file) in order to load the appropriated modules. -If MIME type is not available, provided extensions are first checked, then all input modules are queried. -

- -

- - -Section "StreamingCache" Back to top -

The "StreamingCache" section of the config file holds all configuration options for the streaming cache. Streaming cache allows for recording of -live sources such as RTP/RTSP sessions and internet radios. This is currently just an experimental feature in GPAC.

-RecordDirectory [value: path] -

-Specifies path for recorded files. Cached data is written directly to disk (no re-interleaving or similar processes). -If not specified, the default cache directory (cf General) is used.

-BaseFileName [value: string] -

-Specifies the base name for recorded files. If not present in configuration file, the service name (URL) is used.

-KeepExistingFiles [value: "yes" "no"] -

-Specifies if cached files with same name should be kept or not. If not, an integer number is added to the cached file name, the higest number for the latest file.

- -

- - -Section "SAXLoader" Back to top -

The "SAXLoader" section of the config file holds all configuration options for XML SAX parsing of SVG, XMT and X3D files.

-Progressive [value: "yes" "no" "DOM"] -

Specifies XML parsing mode used by different file loaders using the SAX parser.

-
    -
  • "yes": SAX parsing is used with progressive loading of the document.
  • -
  • "no": SAX parsing is used, document will first be completely downloaded.
  • -
  • "DOM": DOM parsing is used, document will first be completely downloaded. Only supported by libXML2 plugin, otherwise handled as "no".
  • -
-MaxDuration [value positive integer] -

-Specifies the maximum amount of time the SAX parser should spent loading a portion of the document. Only used with SAX Progressive mode

- -

- - -Section "XviD" Back to top -

The "XviD" section of the config file holds all configuration options for the XviD codec.

-PostProc [value: "FilmEffect" "Deblock_Y" "Deblock_UV"] -

-Specifies filters to apply when decoding video. The string is a list of filters separated with a space character.

-
    -
  • "FilmEffect": xvid 1.0.0 filmEffect.
  • -
  • "Deblock_Y": Y plane deblocking filter.
  • -
  • "Deblock_UV": UV plane deblocking filter.
  • -
-Threaded [value "yes" "no"] -

Specifies whether the decoder should run in its own thread or not.

- -

- - -Section "FFMPEG" Back to top -

The "FFMPEG" section of the config file holds all configuration options for the FFMPEG demuxer and decoder.

-DataBufferMS [value: positive integer] -

-Specifies the amount of video/audio data (in milliseconds) to be bufferer before starting decoding. For developpers only.

-IOBufferSize [value: positive integer] -

-Specifies the size (in bytes) of the buffer used to fecth data from network (http playback only). Default size is 8192 bytes.

- -

- - -Section "ISOReader" Back to top -

The "ISOReader" section of the config file holds all configuration options for the ISO Media File demuxer.

-IgnoreMPEG-4ForBrands [value: Full 4CC or 4CC pattern (abc* ab*)] -

-Ignores all MPEG-4 systems tracks and IOD for files showing the listed brands in their compatible brand list.

- -

- - -Section "DVB" Back to top -

The "DVB" section of the config file holds all configuration options for DVB playback on GNU/Linux systems.

-ChannelsFile [value: Absolute file path] -

-Specifies the DVB channels configuration file as produced by dvbtools' scan util.

- -

- - -Section "DASH" Back to top -

The "DASH" section of the config file holds all configuration options for DASH or HLS/M3U8 playback.

-KeepFiles [value: yes, no] -

-Specifies whether downloaded files should not be deleted.

-AutoSwitchCount [value: positive integer] -

-For debug purposes, instructs the player to switch representation every N segments. If 0 (default), switching is disabled.

-BufferingMode [value: segments, minBuffer, none] -

-Selects buffer mode: -

    -
  • segments: buffers complete segments as indicated in MPD before handing them to the player.
  • -
  • minBuffer: asks the player to buffer media for the time indicated in the MPD, but segments are not pre-buffered. Default mode.
  • -
  • none: uses the player settings for buffering.
  • -
-

-NetworkAdaptation [value: disabled, bandwidth, buffer] -

-Sets automatic adaptation logic mode: -

    -
  • disabled: no adaptation to network condition is used.
  • -
  • bandwidth: network adaptation is based only on available download rate.
  • -
  • buffer: network adaptation is based on available download rate for quality increase and buffer levels for quality drops. Default mode.
  • -
- -

-MemoryStorage [value: yes, no] -

-Files are only stored in memory and destroyed after playback, no disk IO is used. Default is yes

-UseMaxResolution [value: yes, no] -

-Forces the player to set the output video resolution to the max resolution available instead of resizing the window. Default is yes

-UseScreenResolution [value: yes, no] -

-Disables all resolutions that are higher than the screen resolution. Default is yes

-StartRepresentation [value: minBandwidth, maxBandwidth, maxBandwidthTiles, minQuality, maxQuality] -

-Instructs the DASH client to start playing the indicated representation before doing any switching. Default is minBandwidth. -maxBandwidthTiles selects the highest bandwidth for tiles with high priority and lowest for other tiles, whereas maxBandwidth selects the highest bandwidth for tiles with high priority and closest lower bandwidth for other tiles. -

-InitialTimeshift [value: positive integer ] -

-If between 0 and 100, indicates the percentage of the timeshift buffer when starting playback.
-If more than 100, indicates the number of milliseconds to rewind in the timeshift buffer when starting playback.
-Default is 0 to tune to the live point.

-LowLatency [value: always, chunk, no] -

-Sets low-latency mode enabled. In low-latency mode, media data is parsed as soon as possible while segment is being downloaded. Default is no. -If chunk is selected, media data is re-parsed at each HTTP 1.1 chunk end. If always is selected, media data is re-parsed as soon as HTTP data is received.

-AllowAbort [value: yes, no] -

-Enables aborts of HTTP transfer when rate gets too low. This imply data loss and may also result in a connection loss. Default is no.

-UseServerUTC [value: yes, no] -

-Enables using Server-UTC HTTP header to compensate any drift between client and server. Default is yes.

-DebugAdaptationSet [value: integer] -

-Plays only the adaptation set indicated by its index in the MPD. If index is negative, all sets are used (default mode). -

-TimeBetween404 [value: unsigned integer] -

-Sets how many millisconds to wait between two 404 on the same segment. Default is 500. -

-SegmentExpirationThreshold [value: unsigned integer] -

-Sets how many millisconds to wait after the segment AvailabilityEndDate before considering the segment lost. Default is 100. -

-ThreadedDownload [value: yes no] -

-Enables threade download of media segments. When low latency mode is used, this option is forced to yes. Default is no. -

-SpeedAdaptation [value: yes no] -

-Enables adaptation based on playback speed. Default is no. -

-SwitchProbeCount [value: unsigned integer] -

-Sets how many segments the client shall wait before switching up bandwidth. If 0, switch will happen as soon as the bandwidth is enough, but this is more prone to network variations. -Default value is 1. -

-AgressiveSwitching [value: yes no] -

-If yes, switching targets to the closest bandwidth fitting the available download rate. If no, switching targets the lowest bitrate representation that is above the currently played (eg does not try to switch to max bandwidth). Default value is no. -

-TileAdaptation [value: none, rows, reverseRows, middleRows, columns, reverseColumns, middleColumns, center] -

-Selects how bitrate is shared across tiles of a video: -

    -
  • none: bitrate is shared equaly accross all tiles (default).
  • -
  • rows: bitrate decreases for each row of tiles starting from the top, same rate for each tile on the row.
  • -
  • reverseRows: bitrate decreases for each row of tiles starting from the bottom, same rate for each tile on the row.
  • -
  • middleRows: bitrate decreased for top and bottom rows only, same rate for each tile on the row.
  • -
  • columns: bitrate decreases for each columns of tiles starting from the left, same rate for each tile on the columns.
  • -
  • reverseColumns: bitrate decreases for each columns of tiles starting from the right, same rate for each tile on the columns.
  • -
  • middleColumns: bitrate decreased for left and right columns only, same rate for each tile on the columns.
  • -
  • center: bitrate decreased for all tiles on the edge of the picture.
  • -
  • edges: bitrate decreased for all tiles on the center of the picture.
  • -
-

-TileRateDecrease [value: percentage] -

-Indicates the amount of bandwidth to use at each quality level. The rate is recursively applied at each level, e.g. if 50%, Level1 gets 50%, level2 gets 25%, ... If 100, automatic rate allocation will be done by maximizing the quality in order of priority. -If 0, bitstream will not be smoothed across tiles/qualities, and concurrency may happen between different media. -Default is 100.

- - -

- - -Section "ALSA" Back to top -

The "ALSA" section of the config file holds all configuration options of the ALSA audio output module on GNU/Linux systems.

-DeviceName [value: string] -

-Specifies the ALSA device to use. Default device is "hw:0,0".

- -

- - -Section "StreamingText" Back to top -

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.<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
- -

- - -Section "DSMCC" Back to top -

-The "DSMCC" section of the config file holds the configuration option for the processing of DSMCC data. -

-Activated [value: "true" "false"] -

-Specifies if the DSMCC data will be processed (true). It implies creations of directories and files in the temp directory.

- - -

- - -Section "OpenHEVC" Back to top -

-The openHEVC section of the config file holds the configuration option for the OpenHEVC decoder. -

-NumThreads [value: unsigned integer] -

-Specifies the number of threads to allocate to the OpenHEVC decoder. Default is the number of detected cores minus one, or one if core detection fails.

-ThreadingType [value: frame , wpp , frame+wpp ] -

-Specifies the threading type for the openHEVC decoder. Default is frame (wpp disabled).

-CBUnits [value: unsigned integer ] -

-Specifies the number of decoded frames in memory before display. Default value is 4.

-PackHFR [value: yes, no ] -

-Packs 4 consecutive frames in a single 4x frame.

- - -

- - -Section "DirectFB" Back to top -

-The "DirectFB" section of the config file holds the configuration options for the DirectFB output module. You may also want to check the official documentation. -

-DisableAcceleration [value: "yes" "no"] -

-Forces to disable hardware acceleration.

-DisableDisplay [value: "yes" "no"] -

-Specifies the DisableDisplay parameter value.

-FlipSyncMode [value: "waitsync" "wait" "sync" "swap"] -

-Specifies the flip sync mode.

-DisableBlit [value: "yes" "no"] -

-Forces to disable hardware blitting.

-WindowMode [value: "X11" "SDL"] -

-Specifies the underlying windowing library.

- - -

- - -Section "DektecVideo" Back to top -

-The "DektecVideo" section of the config file holds the configuration options for the Dektec SDI video output module. -

-SDIOutput [value: unsigned integer] -

-Specifies the output port of the card. Default value is 1.

- -

- - -Section "M2TS" Back to top -

-The "M2TS" section of the config file holds configuration options for MPEG-2 TS demultiplexer module. -

-ForceTEMILocation [value: URL string] -

-Overrides the URL in TEMI location descriptor with the specified value.

-RecordTo [value: file path] -

-Records the TS content to the specified file.

- - -Section "RAWVideo" Back to top -

-The "RAWVideo" section of the config file holds configuration options for Raw video and audio output module. -

-RawOutput [value: "null" or any string] -

-If set to null string, the raw output does nothing (no bliting calls, no backbuffer) - used for bench mode only.

-PixelFormat [value: 555, 565, rgb, bgr, rgb32, bgr32, rgba, argb] -

-Sets the output video format of the raw module, mostly used for testing. The default format is rgb.

- - - diff --git a/doc/doxyfile b/doc/doxyfile deleted file mode 100644 index d0aeef1..0000000 --- a/doc/doxyfile +++ /dev/null @@ -1,2433 +0,0 @@ -# Doxyfile 1.8.10 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = libgpac - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "Documentation of the core library of GPAC. For more information, check out http://gpac.wp.mines-telecom.fr" - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = ../tests/media/auxiliary_files/logo.png - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = . - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = NO - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = NO - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = NO - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = YES - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = YES - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = NO - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = NO - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. -# The default value is: NO. - -WARN_NO_PARAMDOC = YES - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = doxygen_warnings.txt - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = ../include/gpac/ - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, -# *.vhdl, *.ucf, *.qsf, *.as and *.js. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = ../include/gpac/nodes_mpeg4.h \ - ../include/gpac/nodes_svg.h \ - ../include/gpac/nodes_x3d.h \ - ../include/gpac/nodes_xbl.h \ - ../include/gpac/configuration.h \ - ../include/gpac/revision.h \ - ../include/gpac/ringbuffer.h \ - ../include/gpac/ait.h \ - ../include/gpac/dsmcc.h \ - ../include/gpac/dvb_mpe.h - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = */doc/* \ - */tests/* \ - */build/* \ - */bin/* \ - */applications/* \ - */modules/* - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = NO - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html-libgpac - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = YES - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /