From 71c83b6dfdd48bc7d7c0157f2ab3790cdd935926 Mon Sep 17 00:00:00 2001 From: Prateek Sunal Date: Sat, 6 May 2023 16:42:49 +0530 Subject: [PATCH 001/177] feat: unpack gpac --- .gitignore | 2 - docs/708_STATUS.TXT | 2 +- linux/Makefile.am | 119 +- linux/build | 8 +- linux/build-static.sh | 6 +- linux/configure.ac | 17 +- linux/module_generator | 9 +- mac/Makefile.am | 92 +- mac/build.command | 9 +- src/BUILD | 1 - src/CMakeLists.txt | 14 +- src/lib_ccx/BUILD | 8 +- src/lib_ccx/CMakeLists.txt | 14 - src/lib_ccx/params.c | 1 + .../freetype/tools/ftrandom/Makefile | 1 + src/thirdparty/gpacmp4/BUILD | 9 - src/thirdparty/gpacmp4/ReadMe.txt | 40 - src/thirdparty/gpacmp4/av_parsers.c | 9009 ------------ src/thirdparty/gpacmp4/avc_ext.c | 3397 ----- src/thirdparty/gpacmp4/avilib.c | 3143 ---- src/thirdparty/gpacmp4/base_encoding.c | 451 - src/thirdparty/gpacmp4/bitstream.c | 1654 --- src/thirdparty/gpacmp4/box_code_3gpp.c | 1208 -- src/thirdparty/gpacmp4/box_code_adobe.c | 735 - src/thirdparty/gpacmp4/box_code_apple.c | 978 -- src/thirdparty/gpacmp4/box_code_base.c | 11956 ---------------- src/thirdparty/gpacmp4/box_code_drm.c | 1812 --- src/thirdparty/gpacmp4/box_code_meta.c | 846 -- src/thirdparty/gpacmp4/box_dump.c | 5790 -------- src/thirdparty/gpacmp4/box_funcs.c | 2016 --- src/thirdparty/gpacmp4/color.c | 4366 ------ src/thirdparty/gpacmp4/configfile.c | 597 - src/thirdparty/gpacmp4/constants.c | 1439 -- src/thirdparty/gpacmp4/data_map.c | 688 - src/thirdparty/gpacmp4/desc_private.c | 711 - src/thirdparty/gpacmp4/descriptors.c | 1397 -- src/thirdparty/gpacmp4/drm_sample.c | 1892 --- src/thirdparty/gpacmp4/error.c | 1776 --- src/thirdparty/gpacmp4/gpac/avparse.h | 833 -- src/thirdparty/gpacmp4/gpac/base_coding.h | 108 - src/thirdparty/gpacmp4/gpac/bitstream.h | 634 - src/thirdparty/gpacmp4/gpac/cache.h | 282 - src/thirdparty/gpacmp4/gpac/color.h | 296 - src/thirdparty/gpacmp4/gpac/config.h | 5 - src/thirdparty/gpacmp4/gpac/config_file.h | 202 - src/thirdparty/gpacmp4/gpac/constants.h | 1303 -- src/thirdparty/gpacmp4/gpac/download.h | 561 - src/thirdparty/gpacmp4/gpac/events.h | 425 - .../gpacmp4/gpac/events_constants.h | 528 - src/thirdparty/gpacmp4/gpac/filters.h | 3811 ----- src/thirdparty/gpacmp4/gpac/ietf.h | 1603 --- src/thirdparty/gpacmp4/gpac/internal/avilib.h | 423 - .../gpacmp4/gpac/internal/isomedia_dev.h | 4373 ------ .../gpacmp4/gpac/internal/media_dev.h | 833 -- .../gpacmp4/gpac/internal/odf_dev.h | 364 - .../gpacmp4/gpac/internal/odf_parse_common.h | 51 - src/thirdparty/gpacmp4/gpac/internal/ogg.h | 213 - src/thirdparty/gpacmp4/gpac/iso639.h | 89 - src/thirdparty/gpacmp4/gpac/isomedia.h | 6048 -------- src/thirdparty/gpacmp4/gpac/list.h | 235 - src/thirdparty/gpacmp4/gpac/main.h | 253 - src/thirdparty/gpacmp4/gpac/maths.h | 1166 -- src/thirdparty/gpacmp4/gpac/media_tools.h | 1383 -- src/thirdparty/gpacmp4/gpac/module.h | 300 - .../gpacmp4/gpac/modules/audio_out.h | 135 - src/thirdparty/gpacmp4/gpac/modules/font.h | 127 - .../gpacmp4/gpac/modules/video_out.h | 237 - src/thirdparty/gpacmp4/gpac/mpeg4_odf.h | 2345 --- src/thirdparty/gpacmp4/gpac/network.h | 666 - src/thirdparty/gpacmp4/gpac/path2d.h | 622 - src/thirdparty/gpacmp4/gpac/revision.h | 1 - src/thirdparty/gpacmp4/gpac/setup.h | 729 - src/thirdparty/gpacmp4/gpac/sync_layer.h | 180 - src/thirdparty/gpacmp4/gpac/thread.h | 378 - src/thirdparty/gpacmp4/gpac/tools.h | 1973 --- src/thirdparty/gpacmp4/gpac/user.h | 122 - src/thirdparty/gpacmp4/gpac/utf.h | 136 - src/thirdparty/gpacmp4/gpac/version.h | 70 - src/thirdparty/gpacmp4/gpac/webvtt.h | 125 - src/thirdparty/gpacmp4/gpac/xml.h | 415 - src/thirdparty/gpacmp4/gpac_ogg.c | 1393 -- src/thirdparty/gpacmp4/hint_track.c | 1022 -- src/thirdparty/gpacmp4/hinting.c | 1137 -- src/thirdparty/gpacmp4/ipmpx_code.c | 2170 --- src/thirdparty/gpacmp4/ipmpx_parse.c | 712 - src/thirdparty/gpacmp4/isom_intern.c | 1311 -- src/thirdparty/gpacmp4/isom_read.c | 5068 ------- src/thirdparty/gpacmp4/isom_store.c | 1818 --- src/thirdparty/gpacmp4/isom_write.c | 7441 ---------- src/thirdparty/gpacmp4/list.c | 845 -- src/thirdparty/gpacmp4/math.c | 2703 ---- src/thirdparty/gpacmp4/media.c | 1161 -- src/thirdparty/gpacmp4/media_odf.c | 529 - src/thirdparty/gpacmp4/meta.c | 1217 -- src/thirdparty/gpacmp4/module.c | 606 - src/thirdparty/gpacmp4/module_wrap.h | 100 - src/thirdparty/gpacmp4/movie_fragments.c | 3235 ----- src/thirdparty/gpacmp4/odf_code.c | 3404 ----- src/thirdparty/gpacmp4/odf_codec.c | 736 - src/thirdparty/gpacmp4/odf_command.c | 657 - src/thirdparty/gpacmp4/os_config_init.c | 2095 --- src/thirdparty/gpacmp4/os_divers.c | 2700 ---- src/thirdparty/gpacmp4/os_file.c | 1657 --- src/thirdparty/gpacmp4/os_module.c | 338 - src/thirdparty/gpacmp4/os_thread.c | 873 -- src/thirdparty/gpacmp4/qos.c | 447 - src/thirdparty/gpacmp4/sample_descs.c | 1631 --- src/thirdparty/gpacmp4/slc.c | 425 - src/thirdparty/gpacmp4/stbl_read.c | 617 - src/thirdparty/gpacmp4/stbl_write.c | 2148 --- src/thirdparty/gpacmp4/track.c | 1611 --- src/thirdparty/gpacmp4/tx3g.c | 907 -- src/thirdparty/gpacmp4/url.c | 497 - src/thirdparty/gpacmp4/utf.c | 695 - src/thirdparty/gpacmp4/xml_parser.c | 2310 --- tests/Makefile | 2 +- windows/ccextractor.vcxproj | 87 +- windows/ccextractor.vcxproj.filters | 252 - 118 files changed, 68 insertions(+), 147285 deletions(-) delete mode 100644 src/thirdparty/gpacmp4/BUILD delete mode 100644 src/thirdparty/gpacmp4/ReadMe.txt delete mode 100644 src/thirdparty/gpacmp4/av_parsers.c delete mode 100644 src/thirdparty/gpacmp4/avc_ext.c delete mode 100644 src/thirdparty/gpacmp4/avilib.c delete mode 100644 src/thirdparty/gpacmp4/base_encoding.c delete mode 100644 src/thirdparty/gpacmp4/bitstream.c delete mode 100644 src/thirdparty/gpacmp4/box_code_3gpp.c delete mode 100644 src/thirdparty/gpacmp4/box_code_adobe.c delete mode 100644 src/thirdparty/gpacmp4/box_code_apple.c delete mode 100644 src/thirdparty/gpacmp4/box_code_base.c delete mode 100644 src/thirdparty/gpacmp4/box_code_drm.c delete mode 100644 src/thirdparty/gpacmp4/box_code_meta.c delete mode 100644 src/thirdparty/gpacmp4/box_dump.c delete mode 100644 src/thirdparty/gpacmp4/box_funcs.c delete mode 100644 src/thirdparty/gpacmp4/color.c delete mode 100644 src/thirdparty/gpacmp4/configfile.c delete mode 100644 src/thirdparty/gpacmp4/constants.c delete mode 100644 src/thirdparty/gpacmp4/data_map.c delete mode 100644 src/thirdparty/gpacmp4/desc_private.c delete mode 100644 src/thirdparty/gpacmp4/descriptors.c delete mode 100644 src/thirdparty/gpacmp4/drm_sample.c delete mode 100644 src/thirdparty/gpacmp4/error.c delete mode 100644 src/thirdparty/gpacmp4/gpac/avparse.h delete mode 100644 src/thirdparty/gpacmp4/gpac/base_coding.h delete mode 100644 src/thirdparty/gpacmp4/gpac/bitstream.h delete mode 100644 src/thirdparty/gpacmp4/gpac/cache.h delete mode 100644 src/thirdparty/gpacmp4/gpac/color.h delete mode 100644 src/thirdparty/gpacmp4/gpac/config.h delete mode 100644 src/thirdparty/gpacmp4/gpac/config_file.h delete mode 100644 src/thirdparty/gpacmp4/gpac/constants.h delete mode 100644 src/thirdparty/gpacmp4/gpac/download.h delete mode 100644 src/thirdparty/gpacmp4/gpac/events.h delete mode 100644 src/thirdparty/gpacmp4/gpac/events_constants.h delete mode 100644 src/thirdparty/gpacmp4/gpac/filters.h delete mode 100644 src/thirdparty/gpacmp4/gpac/ietf.h delete mode 100644 src/thirdparty/gpacmp4/gpac/internal/avilib.h delete mode 100644 src/thirdparty/gpacmp4/gpac/internal/isomedia_dev.h delete mode 100644 src/thirdparty/gpacmp4/gpac/internal/media_dev.h delete mode 100644 src/thirdparty/gpacmp4/gpac/internal/odf_dev.h delete mode 100644 src/thirdparty/gpacmp4/gpac/internal/odf_parse_common.h delete mode 100644 src/thirdparty/gpacmp4/gpac/internal/ogg.h delete mode 100644 src/thirdparty/gpacmp4/gpac/iso639.h delete mode 100644 src/thirdparty/gpacmp4/gpac/isomedia.h delete mode 100644 src/thirdparty/gpacmp4/gpac/list.h delete mode 100644 src/thirdparty/gpacmp4/gpac/main.h delete mode 100644 src/thirdparty/gpacmp4/gpac/maths.h delete mode 100644 src/thirdparty/gpacmp4/gpac/media_tools.h delete mode 100644 src/thirdparty/gpacmp4/gpac/module.h delete mode 100644 src/thirdparty/gpacmp4/gpac/modules/audio_out.h delete mode 100644 src/thirdparty/gpacmp4/gpac/modules/font.h delete mode 100644 src/thirdparty/gpacmp4/gpac/modules/video_out.h delete mode 100644 src/thirdparty/gpacmp4/gpac/mpeg4_odf.h delete mode 100644 src/thirdparty/gpacmp4/gpac/network.h delete mode 100644 src/thirdparty/gpacmp4/gpac/path2d.h delete mode 100644 src/thirdparty/gpacmp4/gpac/revision.h delete mode 100644 src/thirdparty/gpacmp4/gpac/setup.h delete mode 100644 src/thirdparty/gpacmp4/gpac/sync_layer.h delete mode 100644 src/thirdparty/gpacmp4/gpac/thread.h delete mode 100644 src/thirdparty/gpacmp4/gpac/tools.h delete mode 100644 src/thirdparty/gpacmp4/gpac/user.h delete mode 100644 src/thirdparty/gpacmp4/gpac/utf.h delete mode 100644 src/thirdparty/gpacmp4/gpac/version.h delete mode 100644 src/thirdparty/gpacmp4/gpac/webvtt.h delete mode 100644 src/thirdparty/gpacmp4/gpac/xml.h delete mode 100644 src/thirdparty/gpacmp4/gpac_ogg.c delete mode 100644 src/thirdparty/gpacmp4/hint_track.c delete mode 100644 src/thirdparty/gpacmp4/hinting.c delete mode 100644 src/thirdparty/gpacmp4/ipmpx_code.c delete mode 100644 src/thirdparty/gpacmp4/ipmpx_parse.c delete mode 100644 src/thirdparty/gpacmp4/isom_intern.c delete mode 100644 src/thirdparty/gpacmp4/isom_read.c delete mode 100644 src/thirdparty/gpacmp4/isom_store.c delete mode 100644 src/thirdparty/gpacmp4/isom_write.c delete mode 100644 src/thirdparty/gpacmp4/list.c delete mode 100644 src/thirdparty/gpacmp4/math.c delete mode 100644 src/thirdparty/gpacmp4/media.c delete mode 100644 src/thirdparty/gpacmp4/media_odf.c delete mode 100644 src/thirdparty/gpacmp4/meta.c delete mode 100644 src/thirdparty/gpacmp4/module.c delete mode 100644 src/thirdparty/gpacmp4/module_wrap.h delete mode 100644 src/thirdparty/gpacmp4/movie_fragments.c delete mode 100644 src/thirdparty/gpacmp4/odf_code.c delete mode 100644 src/thirdparty/gpacmp4/odf_codec.c delete mode 100644 src/thirdparty/gpacmp4/odf_command.c delete mode 100644 src/thirdparty/gpacmp4/os_config_init.c delete mode 100644 src/thirdparty/gpacmp4/os_divers.c delete mode 100644 src/thirdparty/gpacmp4/os_file.c delete mode 100644 src/thirdparty/gpacmp4/os_module.c delete mode 100644 src/thirdparty/gpacmp4/os_thread.c delete mode 100644 src/thirdparty/gpacmp4/qos.c delete mode 100644 src/thirdparty/gpacmp4/sample_descs.c delete mode 100644 src/thirdparty/gpacmp4/slc.c delete mode 100644 src/thirdparty/gpacmp4/stbl_read.c delete mode 100644 src/thirdparty/gpacmp4/stbl_write.c delete mode 100644 src/thirdparty/gpacmp4/track.c delete mode 100644 src/thirdparty/gpacmp4/tx3g.c delete mode 100644 src/thirdparty/gpacmp4/url.c delete mode 100644 src/thirdparty/gpacmp4/utf.c delete mode 100644 src/thirdparty/gpacmp4/xml_parser.c diff --git a/.gitignore b/.gitignore index 50e187721..0c621c0cc 100644 --- a/.gitignore +++ b/.gitignore @@ -97,8 +97,6 @@ package_creators/*tar.gz package_creators/build/*.deb src/.deps/ src/.dirstamp -src/gpacmp4/.deps/ -src/gpacmp4/.dirstamp src/lib_ccx/.deps/ src/lib_ccx/.dirstamp src/lib_hash/.deps/ diff --git a/docs/708_STATUS.TXT b/docs/708_STATUS.TXT index 5fa36ef72..501d569ca 100644 --- a/docs/708_STATUS.TXT +++ b/docs/708_STATUS.TXT @@ -29,7 +29,7 @@ To do: though. No samples, no support. - A few commands are not yet supported, specifically those related to delay. -- Detect and extract captions from MP4 (MOV) files, handled by gpacmp4 +- Detect and extract captions from MP4 (MOV) files, handled by gpac Done (18.08.2015): diff --git a/linux/Makefile.am b/linux/Makefile.am index 6f9bea014..0b8c167fc 100644 --- a/linux/Makefile.am +++ b/linux/Makefile.am @@ -5,88 +5,33 @@ bin_PROGRAMS = ccextractor ccextractor_SOURCES = \ ../src/ccextractor.c \ ../src/ccextractor.h \ - ../src/thirdparty/gpacmp4/avc_ext.c \ - ../src/thirdparty/gpacmp4/avilib.c \ - ../src/thirdparty/gpacmp4/av_parsers.c \ - ../src/thirdparty/gpacmp4/base_encoding.c \ - ../src/thirdparty/gpacmp4/bitstream.c \ - ../src/thirdparty/gpacmp4/box_code_3gpp.c \ - ../src/thirdparty/gpacmp4/box_code_adobe.c \ - ../src/thirdparty/gpacmp4/box_code_apple.c \ - ../src/thirdparty/gpacmp4/box_code_base.c \ - ../src/thirdparty/gpacmp4/box_code_drm.c \ - ../src/thirdparty/gpacmp4/box_dump.c \ - ../src/thirdparty/gpacmp4/box_code_meta.c \ - ../src/thirdparty/gpacmp4/box_funcs.c \ - ../src/thirdparty/gpacmp4/color.c \ - ../src/thirdparty/gpacmp4/configfile.c \ - ../src/thirdparty/gpacmp4/data_map.c \ - ../src/thirdparty/gpacmp4/desc_private.c \ - ../src/thirdparty/gpacmp4/descriptors.c \ - ../src/thirdparty/gpacmp4/drm_sample.c \ - ../src/thirdparty/gpacmp4/error.c \ - ../src/thirdparty/gpacmp4/gpac_ogg.c \ - ../src/thirdparty/gpacmp4/hint_track.c \ - ../src/thirdparty/gpacmp4/hinting.c \ - ../src/thirdparty/gpacmp4/ipmpx_code.c \ - ../src/thirdparty/gpacmp4/ipmpx_parse.c \ - ../src/thirdparty/gpacmp4/isom_intern.c \ - ../src/thirdparty/gpacmp4/isom_read.c \ - ../src/thirdparty/gpacmp4/isom_store.c \ - ../src/thirdparty/gpacmp4/isom_write.c \ - ../src/thirdparty/gpacmp4/list.c \ - ../src/thirdparty/gpacmp4/math.c \ - ../src/thirdparty/gpacmp4/media.c \ - ../src/thirdparty/gpacmp4/media_odf.c \ - ../src/thirdparty/gpacmp4/meta.c \ - ../src/thirdparty/gpacmp4/movie_fragments.c \ - ../src/thirdparty/gpacmp4/odf_code.c \ - ../src/thirdparty/gpacmp4/odf_codec.c \ - ../src/thirdparty/gpacmp4/odf_command.c \ - ../src/thirdparty/gpacmp4/os_config_init.c \ - ../src/thirdparty/gpacmp4/os_divers.c \ - ../src/thirdparty/gpacmp4/os_file.c \ - ../src/thirdparty/gpacmp4/qos.c \ - ../src/thirdparty/gpacmp4/sample_descs.c \ - ../src/thirdparty/gpacmp4/slc.c \ - ../src/thirdparty/gpacmp4/stbl_read.c \ - ../src/thirdparty/gpacmp4/stbl_write.c \ - ../src/thirdparty/gpacmp4/track.c \ - ../src/thirdparty/gpacmp4/tx3g.c \ - ../src/thirdparty/gpacmp4/url.c \ - ../src/thirdparty/gpacmp4/utf.c \ - ../src/thirdparty/gpacmp4/os_thread.c \ - ../src/thirdparty/gpacmp4/module.c \ - ../src/thirdparty/gpacmp4/os_module.c \ - ../src/thirdparty/gpacmp4/xml_parser.c \ - ../src/thirdparty/gpacmp4/constants.c \ - ../src/thirdparty/gpacmp4/gpac/avparse.h \ - ../src/thirdparty/gpacmp4/gpac/base_coding.h \ - ../src/thirdparty/gpacmp4/gpac/bitstream.h \ - ../src/thirdparty/gpacmp4/gpac/color.h \ - ../src/thirdparty/gpacmp4/gpac/config_file.h \ - ../src/thirdparty/gpacmp4/gpac/configuration.h \ - ../src/thirdparty/gpacmp4/gpac/constants.h \ - ../src/thirdparty/gpacmp4/gpac/events_constants.h \ - ../src/thirdparty/gpacmp4/gpac/ietf.h \ - ../src/thirdparty/gpacmp4/gpac/isomedia.h \ - ../src/thirdparty/gpacmp4/gpac/list.h \ - ../src/thirdparty/gpacmp4/gpac/maths.h \ - ../src/thirdparty/gpacmp4/gpac/media_tools.h \ - ../src/thirdparty/gpacmp4/gpac/mpeg4_odf.h \ - ../src/thirdparty/gpacmp4/gpac/network.h \ - ../src/thirdparty/gpacmp4/gpac/revision.h \ - ../src/thirdparty/gpacmp4/gpac/setup.h \ - ../src/thirdparty/gpacmp4/gpac/tools.h \ - ../src/thirdparty/gpacmp4/gpac/utf.h \ - ../src/thirdparty/gpacmp4/gpac/version.h \ - ../src/thirdparty/gpacmp4/gpac/iso639.h \ - ../src/thirdparty/gpacmp4/gpac/internal/avilib.h \ - ../src/thirdparty/gpacmp4/gpac/internal/isomedia_dev.h \ - ../src/thirdparty/gpacmp4/gpac/internal/media_dev.h \ - ../src/thirdparty/gpacmp4/gpac/internal/odf_dev.h \ - ../src/thirdparty/gpacmp4/gpac/internal/odf_parse_common.h \ - ../src/thirdparty/gpacmp4/gpac/internal/ogg.h \ + /usr/include/gpac/avparse.h \ + /usr/include/gpac/base_coding.h \ + /usr/include/gpac/bitstream.h \ + /usr/include/gpac/color.h \ + /usr/include/gpac/config_file.h \ + /usr/include/gpac/configuration.h \ + /usr/include/gpac/constants.h \ + /usr/include/gpac/events_constants.h \ + /usr/include/gpac/ietf.h \ + /usr/include/gpac/isomedia.h \ + /usr/include/gpac/list.h \ + /usr/include/gpac/maths.h \ + /usr/include/gpac/media_tools.h \ + /usr/include/gpac/mpeg4_odf.h \ + /usr/include/gpac/network.h \ + /usr/include/gpac/revision.h \ + /usr/include/gpac/setup.h \ + /usr/include/gpac/tools.h \ + /usr/include/gpac/utf.h \ + /usr/include/gpac/version.h \ + /usr/include/gpac/iso639.h \ + /usr/include/gpac/internal/avilib.h \ + /usr/include/gpac/internal/isomedia_dev.h \ + /usr/include/gpac/internal/media_dev.h \ + /usr/include/gpac/internal/odf_dev.h \ + /usr/include/gpac/internal/odf_parse_common.h \ + /usr/include/gpac/internal/ogg.h \ ../src/thirdparty/libpng/pngstruct.h \ ../src/thirdparty/libpng/pngpriv.h \ ../src/thirdparty/libpng/pnginfo.h \ @@ -325,16 +270,16 @@ ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \ ../src/thirdparty/libpng/arm/palette_neon_intrinsics.c endif -ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H +ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/ +ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I/usr/include/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/ -ccextractor_LDADD=-lm -lpthread -ldl +ccextractor_LDADD=-lm -lpthread -ldl -lgpac if SYS_IS_LINUX -ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX +ccextractor_CFLAGS += -O3 -s endif if SYS_IS_MAC @@ -405,5 +350,5 @@ endif cd ../src/rust && \ CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(HARDSUBX_FEATURE_RUST) $(CARGO_RELEASE_ARGS); -EXTRA_DIST = ../src/thirdparty/gpacmp4/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/ +EXTRA_DIST = /usr/include/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/ diff --git a/linux/build b/linux/build index e0483a50d..2d5f5652f 100755 --- a/linux/build +++ b/linux/build @@ -29,17 +29,17 @@ while [[ $# -gt 0 ]]; do esac done -BLD_FLAGS="$BLD_FLAGS -std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_LINUX -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DENABLE_OCR -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H" +BLD_FLAGS="$BLD_FLAGS -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DENABLE_OCR -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP" bit_os=$(getconf LONG_BIT) if [ "$bit_os"=="64" ] then BLD_FLAGS="$BLD_FLAGS -DGPAC_64_BITS" fi -BLD_INCLUDE="-I../src -I /usr/include/leptonica/ -I /usr/include/tesseract/ -I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng -I../src/thirdparty/zlib -I../src/lib_ccx/zvbi -I../src/thirdparty/lib_hash -I../src/thirdparty/protobuf-c -I../src/thirdparty -I../src/thirdparty/freetype/include" +BLD_INCLUDE="-I../src -I /usr/include/leptonica/ -I /usr/include/tesseract/ -I../src/lib_ccx/ -I /usr/include/gpac/ -I../src/thirdparty/libpng -I../src/thirdparty/zlib -I../src/lib_ccx/zvbi -I../src/thirdparty/lib_hash -I../src/thirdparty/protobuf-c -I../src/thirdparty -I../src/thirdparty/freetype/include" SRC_LIBPNG="$(find ../src/thirdparty/libpng/ -name '*.c')" SRC_ZLIB="$(find ../src/thirdparty/zlib/ -name '*.c')" SRC_CCX="$(find ../src/lib_ccx/ -name '*.c')" -SRC_GPAC="$(find ../src/thirdparty/gpacmp4/ -name '*.c')" +SRC_GPAC="$(find /usr/include/gpac/ -name '*.c')" SRC_HASH="$(find ../src/thirdparty/lib_hash/ -name '*.c')" SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c/ -name '*.c')" SRC_UTF8PROC="../src/thirdparty/utf8proc/utf8proc.c" @@ -85,7 +85,7 @@ SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c ../src/thirdparty/freetype/type42/type42.c ../src/thirdparty/freetype/winfonts/winfnt.c" BLD_SOURCES="../src/ccextractor.c $SRC_CCX $SRC_GPAC $SRC_ZLIB $SRC_LIBPNG $SRC_HASH $SRC_PROTOBUF $SRC_UTF8PROC $SRC_FREETYPE" -BLD_LINKER="$BLD_LINKER -lm -zmuldefs -l tesseract -l lept -lpthread -ldl" +BLD_LINKER="$BLD_LINKER -lm -zmuldefs -l tesseract -l lept -lpthread -ldl -lgpac" echo "Running pre-build script..." ./pre-build.sh diff --git a/linux/build-static.sh b/linux/build-static.sh index 0648ca7b2..c7920a0ad 100755 --- a/linux/build-static.sh +++ b/linux/build-static.sh @@ -84,15 +84,13 @@ cd -; git clone https://github.com/CCExtractor/ccextractor; cd ccextractor/linux/; perl -i -pe 's/O3 /O3 -static /' Makefile; -# quick patch: -perl -i -pe 's/(strchr|strstr)\(/$1((char *)/' ../src/thirdparty/gpacmp4/url.c ../src/thirdparty/gpacmp4/error.c; set +e; # this _will_ FAIL at the end.. make ENABLE_OCR=yes; set -e; # I confess hand-compiling (cherrypicking which .a to use when there are 2, etc.) is fragile... # But it was the _only_ way I could get a fully static build after hours of thrashing... -gcc -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -O3 -std=gnu99 -s -DGPAC_CONFIG_LINUX -DENABLE_OCR -DPNG_NO_CONFIG_H -I/usr/local/include/tesseract -I/usr/local/include/leptonica objs/*.o -o ccextractor \ - --static -lm \ +gcc -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -O3 -std=gnu99 -s -DENABLE_OCR -DPNG_NO_CONFIG_H -I/usr/local/include/tesseract -I/usr/local/include/leptonica objs/*.o -o ccextractor \ + --static -lm -lgpac \ /usr/local/lib/libtesseract.a \ /usr/local/lib/liblept.a \ /usr/local/lib/libgif.a \ diff --git a/linux/configure.ac b/linux/configure.ac index 120efa70d..d6080cd13 100644 --- a/linux/configure.ac +++ b/linux/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_PREREQ([2.69]) +AC_PREREQ([2.71]) AC_INIT([CCExtractor], [0.94], [carlos@ccextractor.org]) AC_CONFIG_AUX_DIR([build-conf]) AC_CONFIG_SRCDIR([../src/ccextractor.c]) @@ -29,7 +29,6 @@ AC_CHECK_LIB([lept], [getLeptonicaVersion], [HAS_LEPT=1 && PKG_CHECK_MODULES([le AC_CHECK_LIB([tesseract], [TessVersion], [HAS_TESSERACT=1 && PKG_CHECK_MODULES([tesseract], [tesseract])], [HAS_TESSERACT=0]) AC_CHECK_LIB([avcodec], [avcodec_version], [HAS_AVCODEC=1 && PKG_CHECK_MODULES([libavcodec], [libavcodec])], [HAS_AVCODEC=0]) AC_CHECK_LIB([avformat], [avformat_version], [HAS_AVFORMAT=1 && PKG_CHECK_MODULES([libavformat], [libavformat])], [HAS_AVFORMAT=0]) -AC_CHECK_LIB([avfilter], [avfilter_version], [HAS_AVFILTER=1 && PKG_CHECK_MODULES([libavfilter], [libavfilter])], [HAS_AVFILTER=0]) AC_CHECK_LIB([avutil], [avutil_version], [HAS_AVUTIL=1 && PKG_CHECK_MODULES([libavutil], [libavutil])], [HAS_AVUTIL=0]) AC_CHECK_LIB([swscale], [swscale_version], [HAS_SWSCALE=1 && PKG_CHECK_MODULES([libswscale], [libswscale])], [HAS_SWSCALE=0]) @@ -64,7 +63,7 @@ AC_CHECK_FUNCS([floor ftruncate gethostbyname gettimeofday inet_ntoa mblen memch # Checks for arguments with configure AC_ARG_ENABLE([hardsubx], -AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard subtitles)]), +AS_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard subtitles)]), [case "${enableval}" in yes) hardsubx=true ;; no) hardsubx=false ;; @@ -72,7 +71,7 @@ AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard esac],[hardsubx=false]) AC_ARG_ENABLE([ocr], -AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]), +AS_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]), [case "${enableval}" in yes) ocr=true ;; no) ocr=false ;; @@ -80,7 +79,7 @@ AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]), esac],[ocr=false]) AC_ARG_ENABLE([ffmpeg], -AC_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]), +AS_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]), [case "${enableval}" in yes) ffmpeg=true ;; no) ffmpeg=false ;; @@ -89,7 +88,7 @@ esac],[ffmpeg=false]) #Add argument for rust AC_ARG_WITH([rust], -AC_HELP_STRING([--with-rust], [Builds CCExtractor with rust library]), +AS_HELP_STRING([--with-rust], [Builds CCExtractor with rust library]), [with_rust=$withval], [with_rust=yes]) @@ -115,7 +114,7 @@ fi AM_CONDITIONAL([WITH_RUST], [test "x$with_rust" = "xyes"]) AC_ARG_ENABLE(debug, - AC_HELP_STRING([--enable-debug], + AS_HELP_STRING([--enable-debug], [Build Rust code with debugging information [default=no]]), [debug_release=$enableval], [debug_release=no]) @@ -137,8 +136,6 @@ AS_IF([ test x$hardsubx = xtrue && test $HAS_AVCODEC -gt 0 ], [AC_MSG_NOTICE(avc AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVCODEC -gt 0 ], [AC_MSG_ERROR(avcodec library not found. Please install the avcodec library before proceeding)]) AS_IF([ test x$hardsubx = xtrue && test $HAS_AVFORMAT -gt 0 ], [AC_MSG_NOTICE(avformat library found)]) AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVFORMAT -gt 0 ], [AC_MSG_ERROR(avformat library not found. Please install the avformat library before proceeding)]) -AS_IF([ test x$hardsubx = xtrue && test $HAS_AVFILTER -gt 0 ], [AC_MSG_NOTICE(avfilter library found)]) -AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVFILTER -gt 0 ], [AC_MSG_ERROR(avfilter library not found. Please install the avfilter library before proceeding)]) AS_IF([ test x$hardsubx = xtrue && test $HAS_AVUTIL -gt 0 ], [AC_MSG_NOTICE(avutil library found)]) AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVUTIL -gt 0 ], [AC_MSG_ERROR(avutil library not found. Please install the avutil library before proceeding)]) AS_IF([ test x$hardsubx = xtrue && test $HAS_SWSCALE -gt 0 ], [AC_MSG_NOTICE(swscale library found)]) @@ -152,7 +149,7 @@ AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_LEPT -gt AM_CONDITIONAL(HARDSUBX_IS_ENABLED, [ test x$hardsubx = xtrue ]) AM_CONDITIONAL(OCR_IS_ENABLED, [ test x$ocr = xtrue || test x$hardsubx = xtrue ]) AM_CONDITIONAL(FFMPEG_IS_ENABLED, [ test x$ffmpeg = xtrue ]) -AM_CONDITIONAL(TESSERACT_PRESENT, [ test -n "$(pkg-config --libs-only-l --silence-errors tesseract)" ]) +AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silence-errors tesseract` ]) AM_CONDITIONAL(TESSERACT_PRESENT_RPI, [ test -d "/usr/include/tesseract" && test `ls -A /usr/include/tesseract | wc -l` -gt 0 ]) AM_CONDITIONAL(SYS_IS_LINUX, [ test `uname -s` = "Linux"]) AM_CONDITIONAL(SYS_IS_MAC, [ test `uname -s` = "Darwin"]) diff --git a/linux/module_generator b/linux/module_generator index e4db84ab2..1da6d7537 100755 --- a/linux/module_generator +++ b/linux/module_generator @@ -1,12 +1,11 @@ #!/usr/bin/env bash SRC_LIBPNG="$(find ../src/thirdparty/libpng/ -name '*.c')" -SRC_ZLIB="$(find ../sr/thirdpartyc/zlib/ -name '*.c')" -SRC_ZVBI="$(find ../sr/thirdpartyc/zvbi/ -name '*.c')" +SRC_ZLIB="$(find ../src/thirdparty/zlib/ -name '*.c')" +SRC_ZVBI="$(find ../src/thirdparty/zvbi/ -name '*.c')" SRC_CCX="$(find ../src/lib_ccx/ -name '*.c')" -SRC_GPAC="$(find ../sr/thirdpartyc/gpacmp4/ -name '*.c')" -SRC_HASH="$(find ../sr/thirdpartyc/lib_hash/ -name '*.c')" +SRC_HASH="$(find ../src/thirdparty/lib_hash/ -name '*.c')" SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c/ -name '*.c')" SRC_UTF8PROC="../src/utf8proc/utf8proc.c" -BLD_SOURCES="../src/ccextractor.c ../src/ccextractorapi_wrap.c $SRC_CCX $SRC_GPAC $SRC_ZLIB $SRC_ZVBI $SRC_LIBPNG $SRC_HASH $SRC_PROTOBUF $SRC_UTF8PROC" +BLD_SOURCES="../src/ccextractor.c ../src/ccextractorapi_wrap.c $SRC_CCX $SRC_ZLIB $SRC_ZVBI $SRC_LIBPNG $SRC_HASH $SRC_PROTOBUF $SRC_UTF8PROC" python setup.py $BLD_SOURCES diff --git a/mac/Makefile.am b/mac/Makefile.am index be725403b..862f54528 100644 --- a/mac/Makefile.am +++ b/mac/Makefile.am @@ -5,88 +5,6 @@ bin_PROGRAMS = ccextractor ccextractor_SOURCES = \ ../src/ccextractor.c \ ../src/ccextractor.h \ - ../src/thirdparty/gpacmp4/avc_ext.c \ - ../src/thirdparty/gpacmp4/avilib.c \ - ../src/thirdparty/gpacmp4/av_parsers.c \ - ../src/thirdparty/gpacmp4/base_encoding.c \ - ../src/thirdparty/gpacmp4/bitstream.c \ - ../src/thirdparty/gpacmp4/box_code_3gpp.c \ - ../src/thirdparty/gpacmp4/box_code_adobe.c \ - ../src/thirdparty/gpacmp4/box_code_apple.c \ - ../src/thirdparty/gpacmp4/box_code_base.c \ - ../src/thirdparty/gpacmp4/box_code_drm.c \ - ../src/thirdparty/gpacmp4/box_dump.c \ - ../src/thirdparty/gpacmp4/box_code_meta.c \ - ../src/thirdparty/gpacmp4/box_funcs.c \ - ../src/thirdparty/gpacmp4/color.c \ - ../src/thirdparty/gpacmp4/configfile.c \ - ../src/thirdparty/gpacmp4/data_map.c \ - ../src/thirdparty/gpacmp4/desc_private.c \ - ../src/thirdparty/gpacmp4/descriptors.c \ - ../src/thirdparty/gpacmp4/drm_sample.c \ - ../src/thirdparty/gpacmp4/error.c \ - ../src/thirdparty/gpacmp4/gpac_ogg.c \ - ../src/thirdparty/gpacmp4/hint_track.c \ - ../src/thirdparty/gpacmp4/hinting.c \ - ../src/thirdparty/gpacmp4/ipmpx_code.c \ - ../src/thirdparty/gpacmp4/ipmpx_parse.c \ - ../src/thirdparty/gpacmp4/isom_intern.c \ - ../src/thirdparty/gpacmp4/isom_read.c \ - ../src/thirdparty/gpacmp4/isom_store.c \ - ../src/thirdparty/gpacmp4/isom_write.c \ - ../src/thirdparty/gpacmp4/list.c \ - ../src/thirdparty/gpacmp4/math.c \ - ../src/thirdparty/gpacmp4/media.c \ - ../src/thirdparty/gpacmp4/media_odf.c \ - ../src/thirdparty/gpacmp4/meta.c \ - ../src/thirdparty/gpacmp4/movie_fragments.c \ - ../src/thirdparty/gpacmp4/odf_code.c \ - ../src/thirdparty/gpacmp4/odf_codec.c \ - ../src/thirdparty/gpacmp4/odf_command.c \ - ../src/thirdparty/gpacmp4/os_config_init.c \ - ../src/thirdparty/gpacmp4/os_divers.c \ - ../src/thirdparty/gpacmp4/os_file.c \ - ../src/thirdparty/gpacmp4/qos.c \ - ../src/thirdparty/gpacmp4/sample_descs.c \ - ../src/thirdparty/gpacmp4/slc.c \ - ../src/thirdparty/gpacmp4/stbl_read.c \ - ../src/thirdparty/gpacmp4/stbl_write.c \ - ../src/thirdparty/gpacmp4/track.c \ - ../src/thirdparty/gpacmp4/tx3g.c \ - ../src/thirdparty/gpacmp4/url.c \ - ../src/thirdparty/gpacmp4/utf.c \ - ../src/thirdparty/gpacmp4/os_thread.c \ - ../src/thirdparty/gpacmp4/module.c \ - ../src/thirdparty/gpacmp4/os_module.c \ - ../src/thirdparty/gpacmp4/xml_parser.c \ - ../src/thirdparty/gpacmp4/constants.c \ - ../src/thirdparty/gpacmp4/gpac/avparse.h \ - ../src/thirdparty/gpacmp4/gpac/base_coding.h \ - ../src/thirdparty/gpacmp4/gpac/bitstream.h \ - ../src/thirdparty/gpacmp4/gpac/color.h \ - ../src/thirdparty/gpacmp4/gpac/config_file.h \ - ../src/thirdparty/gpacmp4/gpac/configuration.h \ - ../src/thirdparty/gpacmp4/gpac/constants.h \ - ../src/thirdparty/gpacmp4/gpac/events_constants.h \ - ../src/thirdparty/gpacmp4/gpac/ietf.h \ - ../src/thirdparty/gpacmp4/gpac/isomedia.h \ - ../src/thirdparty/gpacmp4/gpac/list.h \ - ../src/thirdparty/gpacmp4/gpac/maths.h \ - ../src/thirdparty/gpacmp4/gpac/media_tools.h \ - ../src/thirdparty/gpacmp4/gpac/mpeg4_odf.h \ - ../src/thirdparty/gpacmp4/gpac/network.h \ - ../src/thirdparty/gpacmp4/gpac/revision.h \ - ../src/thirdparty/gpacmp4/gpac/setup.h \ - ../src/thirdparty/gpacmp4/gpac/tools.h \ - ../src/thirdparty/gpacmp4/gpac/utf.h \ - ../src/thirdparty/gpacmp4/gpac/version.h \ - ../src/thirdparty/gpacmp4/gpac/iso639.h \ - ../src/thirdparty/gpacmp4/gpac/internal/avilib.h \ - ../src/thirdparty/gpacmp4/gpac/internal/isomedia_dev.h \ - ../src/thirdparty/gpacmp4/gpac/internal/media_dev.h \ - ../src/thirdparty/gpacmp4/gpac/internal/odf_dev.h \ - ../src/thirdparty/gpacmp4/gpac/internal/odf_parse_common.h \ - ../src/thirdparty/gpacmp4/gpac/internal/ogg.h \ ../src/thirdparty/libpng/pngstruct.h \ ../src/thirdparty/libpng/pngpriv.h \ ../src/thirdparty/libpng/pnginfo.h \ @@ -324,16 +242,16 @@ ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \ ../src/thirdparty/libpng/arm/palette_neon_intrinsics.c endif -ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H +ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/ +ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/ -ccextractor_LDADD=-lm -lpthread -ldl +ccextractor_LDADD=-lm -lpthread -ldl -lgpac if SYS_IS_LINUX -ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX +ccextractor_CFLAGS += -O3 -s endif if SYS_IS_MAC @@ -402,5 +320,5 @@ endif cd ../src/rust && \ CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(HARDSUBX_FEATURE_RUST) $(CARGO_RELEASE_ARGS); -EXTRA_DIST = ../src/thirdparty/gpacmp4/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/ +EXTRA_DIST = ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/ diff --git a/mac/build.command b/mac/build.command index 4f86630d7..7a547e8ae 100755 --- a/mac/build.command +++ b/mac/build.command @@ -1,11 +1,10 @@ #!/bin/bash cd `dirname $0` -BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_DARWIN -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H -DDISABLE_RUST" +BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DDISABLE_RUST" [[ $1 = "OCR" ]] && BLD_FLAGS="$BLD_FLAGS -DENABLE_OCR" -BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/gpacmp4 -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/freetype/include" +BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/freetype/include gpac" [[ $1 = "OCR" ]] && BLD_INCLUDE="$BLD_INCLUDE `pkg-config --cflags --silence-errors tesseract`" SRC_CCX="$(find ../src/lib_ccx -name '*.c')" -SRC_GPAC="$(find ../src/thirdparty/gpacmp4 -name '*.c')" SRC_LIB_HASH="$(find ../src/thirdparty/lib_hash -name '*.c')" SRC_LIBPNG="$(find ../src/thirdparty/libpng -name '*.c')" SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c -name '*.c')" @@ -52,8 +51,8 @@ SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c \ ../src/thirdparty/freetype/type1/type1.c \ ../src/thirdparty/freetype/type42/type42.c \ ../src/thirdparty/freetype/winfonts/winfnt.c" -BLD_SOURCES="../src/ccextractor.c $SRC_API $SRC_CCX $SRC_GPAC $SRC_LIB_HASH $SRC_LIBPNG $SRC_PROTOBUF $SRC_UTF8 $SRC_ZLIB $SRC_ZVBI $SRC_FREETYPE" -BLD_LINKER="-lm -liconv -lpthread -ldl" +BLD_SOURCES="../src/ccextractor.c $SRC_API $SRC_CCX $SRC_LIB_HASH $SRC_LIBPNG $SRC_PROTOBUF $SRC_UTF8 $SRC_ZLIB $SRC_ZVBI $SRC_FREETYPE" +BLD_LINKER="-lm -liconv -lpthread -ldl -lgpac" [[ $1 = "OCR" ]] && BLD_LINKER="$BLD_LINKER `pkg-config --libs --silence-errors tesseract` `pkg-config --libs --silence-errors lept`" ./pre-build.sh diff --git a/src/BUILD b/src/BUILD index 772dd3763..b2add66c6 100644 --- a/src/BUILD +++ b/src/BUILD @@ -5,7 +5,6 @@ cc_binary( deps = [ "//src/lib_ccx:lib_ccx", "//src/thirdparty/protobuf-c:protobuf-c", - "//src/thirdparty/gpacmp4:gpacmp4", "//src/thirdparty/zlib:zlib", "//src/thirdparty/freetype:freetype" ], diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 405c5e6d0..048e86023 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,15 +41,7 @@ configure_file ( "${PROJECT_SOURCE_DIR}/lib_ccx/compile_info_real.h" ) -add_definitions(-DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H) - -if(UNIX) - if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - add_definitions(-DGPAC_CONFIG_DARWIN) - else () - add_definitions(-DGPAC_CONFIG_LINUX) - endif() -endif(UNIX) +add_definitions(-DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP) if(CMAKE_SIZEOF_VOID_P EQUAL 8) add_definitions(-DGPAC_64_BITS) @@ -59,7 +51,6 @@ include_directories(${PROJECT_SOURCE_DIR}) include_directories(${PROJECT_SOURCE_DIR}/lib_ccx) include_directories(${PROJECT_SOURCE_DIR}/lib_ccx/zvbi) include_directories(${PROJECT_SOURCE_DIR}/thirdparty) -include_directories(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/lib_hash) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng) @@ -71,7 +62,6 @@ endif () include_directories(${PROJECT_SOURCE_DIR}/thirdparty/zlib) include_directories(${PROJECT_SOURCE_DIR}/thirdparty/freetype/include) -aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4/ SOURCEFILE) aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/lib_hash/ SOURCEFILE) aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/libpng/ SOURCEFILE) aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c/ SOURCEFILE) @@ -153,7 +143,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") -set (EXTRA_LIBS ${EXTRA_LIBS} -lm -lpthread -ldl) +set (EXTRA_LIBS ${EXTRA_LIBS} -lm -lpthread -ldl -lgpac) find_package (PkgConfig) diff --git a/src/lib_ccx/BUILD b/src/lib_ccx/BUILD index f31306287..9b4404acb 100644 --- a/src/lib_ccx/BUILD +++ b/src/lib_ccx/BUILD @@ -9,22 +9,18 @@ cc_library( "//src/thirdparty/protobuf-c:protobuf-c", "//src/thirdparty/libpng:libpng", "//src/thirdparty/freetype:freetype", - "//src/thirdparty/gpacmp4:gpacmp4", "//src/thirdparty/lib_hash:lib_hash", "//src/thirdparty/utf8proc:utf8proc", ], - includes = [ "thirdparty/protobuf-c", "thirdparty/libpng", "thirdparty/gpacmp4" , "." , + includes = [ "thirdparty/protobuf-c", "thirdparty/libpng", "." , "thirdparty/freetype/include" ], copts = [ "-Isrc/thirdparty/protobuf-c", "-Isrc/thirdparty/libpng", "-Isrc/", - "-Isrc/thirdparty/gpacmp4", "-Isrc/thirdparty/freetype", "-Isrc/thirdparty/lib_hash", "-Isrc/thirdparty/freetype/include", - "-Isrc/thirdparty/", - "-DGPAC_HAVE_CONFIG_H" - + "-Isrc/thirdparty/" ] ) diff --git a/src/lib_ccx/CMakeLists.txt b/src/lib_ccx/CMakeLists.txt index e62216581..f0b4ae595 100644 --- a/src/lib_ccx/CMakeLists.txt +++ b/src/lib_ccx/CMakeLists.txt @@ -55,7 +55,6 @@ if (WITH_SHARING) endif (WITH_SHARING) aux_source_directory ("${PROJECT_SOURCE_DIR}/lib_ccx/" SOURCEFILE) -aux_source_directory ("${PROJECT_SOURCE_DIR}/gpacmp4/" SOURCEFILE) add_library (ccx ${SOURCEFILE} ccx_dtvcc.h ccx_dtvcc.c ccx_encoders_mcc.c ccx_encoders_mcc.h) target_link_libraries (ccx ${EXTRA_LIBS}) @@ -85,23 +84,10 @@ if (WITH_HARDSUBX) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_HARDSUBX") endif (WITH_HARDSUBX) -if (MINGW OR CYGWIN) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_WIN32") -endif (MINGW OR CYGWIN) - if (WITHOUT_RUST) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_RUST") endif (WITHOUT_RUST) -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_LINUX") -endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_DARWIN") -endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - - file (GLOB HeaderFiles *.h) file (WRITE ccx.pc "prefix=${CMAKE_INSTALL_PREFIX}\n" "includedir=\${prefix}/include\n" diff --git a/src/lib_ccx/params.c b/src/lib_ccx/params.c index 173468721..1c06588d8 100644 --- a/src/lib_ccx/params.c +++ b/src/lib_ccx/params.c @@ -1,6 +1,7 @@ #include #include "protobuf-c.h" #include "zlib.h" +#include "gpac/setup.h" #include "gpac/version.h" #include "lib_ccx.h" #include "ccx_common_option.h" diff --git a/src/thirdparty/freetype/tools/ftrandom/Makefile b/src/thirdparty/freetype/tools/ftrandom/Makefile index 24dc49c56..cc4f055b6 100644 --- a/src/thirdparty/freetype/tools/ftrandom/Makefile +++ b/src/thirdparty/freetype/tools/ftrandom/Makefile @@ -29,6 +29,7 @@ CFLAGS = $(WFLAGS) \ INCLUDES = -I $(TOP_DIR)/include LDFLAGS = LIBS = -lm \ + -lgpac \ -lz \ -lpng \ -lbz2 \ diff --git a/src/thirdparty/gpacmp4/BUILD b/src/thirdparty/gpacmp4/BUILD deleted file mode 100644 index 5efef5cee..000000000 --- a/src/thirdparty/gpacmp4/BUILD +++ /dev/null @@ -1,9 +0,0 @@ -cc_library( - name = "gpacmp4", - srcs = glob(["*.c"]), - hdrs = glob(["*.h", "gpac/*.h", "gpac/internal/*.h", "gpac/modules/*.h" ]), - copts = [ "-I src/thirdparty/gpacmp4/" , "-DGPAC_CONFIG_LINUX -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DENABLE_OCR -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H" ], - visibility = ["//visibility:public"], - linkopts = ["-ldl", "-lpthread"], -) - diff --git a/src/thirdparty/gpacmp4/ReadMe.txt b/src/thirdparty/gpacmp4/ReadMe.txt deleted file mode 100644 index 7b9c5669f..000000000 --- a/src/thirdparty/gpacmp4/ReadMe.txt +++ /dev/null @@ -1,40 +0,0 @@ -======================================================================== - CONSOLE APPLICATION : gpacmp4 Project Overview -======================================================================== - -AppWizard has created this gpacmp4 application for you. - -This file contains a summary of what you will find in each of the files that -make up your gpacmp4 application. - - -gpacmp4.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -gpacmp4.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -gpacmp4.cpp - This is the main application source file. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named gpacmp4.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/src/thirdparty/gpacmp4/av_parsers.c b/src/thirdparty/gpacmp4/av_parsers.c deleted file mode 100644 index 3d7520f0c..000000000 --- a/src/thirdparty/gpacmp4/av_parsers.c +++ /dev/null @@ -1,9009 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre, Romain Bouqueau, Cyril Concolato - * Copyright (c) Telecom ParisTech 2000-2020 - * All rights reserved - * - * This file is part of GPAC / Media Tools sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include - -#ifndef GPAC_DISABLE_OGG -#include -#endif - -static const struct { - u32 w, h; -} std_par[] = -{ - { 4, 3}, {3, 2}, {16, 9}, {5, 3}, {5, 4}, {8, 5}, {2, 1}, {1, 1}, - {0, 0}, -}; - -GF_EXPORT -void gf_media_reduce_aspect_ratio(u32 *width, u32 *height) -{ - u32 i = 0; - u32 w = *width; - u32 h = *height; - while (std_par[i].w) { - if (std_par[i].w * h == std_par[i].h * w) { - *width = std_par[i].w; - *height = std_par[i].h; - return; - } - i++; - } -} - -GF_EXPORT -void gf_media_get_reduced_frame_rate(u32 *timescale, u32 *sample_dur) -{ - u32 res; - if (!*sample_dur) return; - res = *timescale / *sample_dur; - if (res * (*sample_dur) == *timescale) { - *timescale = res; - *sample_dur = 1; - } - else if ((double)(*timescale * 1001 - (res + 1) * *sample_dur * 1000) / ((res + 1) * *sample_dur * 1000) < 0.001) { - *timescale = (res + 1) * 1000; - *sample_dur = 1001; - } -} - -struct __m4v_profile -{ - u32 value; - const char *name; -} M4VProfiles[] = { - {0x00, "Reserved (0x00) Profile"}, - {0x01, "Simple Profile @ Level 1"}, - {0x02, "Simple Profile @ Level 2"}, - {0x03, "Simple Profile @ Level 3"}, - {0x08, "Simple Profile @ Level 0"}, - {0x10, "Simple Scalable Profile @ Level 0"}, - {0x11, "Simple Scalable Profile @ Level 1"}, - {0x12, "Simple Scalable Profile @ Level 2"}, - {0x21, "Core Profile @ Level 1"}, - {0x22, "Core Profile @ Level 2"}, - {0x32, "Main Profile @ Level 2"}, - {0x33, "Main Profile @ Level 3"}, - {0x34, "Main Profile @ Level 4"}, - {0x42, "N-bit Profile @ Level 2"}, - {0x51, "Scalable Texture Profile @ Level 1"}, - {0x61, "Simple Face Animation Profile @ Level 1"}, - {0x62, "Simple Face Animation Profile @ Level 2"}, - {0x63, "Simple FBA Profile @ Level 1"}, - {0x64, "Simple FBA Profile @ Level 2"}, - {0x71, "Basic Animated Texture Profile @ Level 1"}, - {0x72, "Basic Animated Texture Profile @ Level 2"}, - {0x7F, "AVC/H264 Profile"}, - {0x81, "Hybrid Profile @ Level 1"}, - {0x82, "Hybrid Profile @ Level 2"}, - {0x91, "Advanced Real Time Simple Profile @ Level 1"}, - {0x92, "Advanced Real Time Simple Profile @ Level 2"}, - {0x93, "Advanced Real Time Simple Profile @ Level 3"}, - {0x94, "Advanced Real Time Simple Profile @ Level 4"}, - {0xA1, "Core Scalable Profile @ Level1"}, - {0xA2, "Core Scalable Profile @ Level2"}, - {0xA3, "Core Scalable Profile @ Level3"}, - {0xB1, "Advanced Coding Efficiency Profile @ Level 1"}, - {0xB2, "Advanced Coding Efficiency Profile @ Level 2"}, - {0xB3, "Advanced Coding Efficiency Profile @ Level 3"}, - {0xB4, "Advanced Coding Efficiency Profile @ Level 4"}, - {0xC1, "Advanced Core Profile @ Level 1"}, - {0xC2, "Advanced Core Profile @ Level 2"}, - {0xD1, "Advanced Scalable Texture @ Level1"}, - {0xD2, "Advanced Scalable Texture @ Level2"}, - {0xE1, "Simple Studio Profile @ Level 1"}, - {0xE2, "Simple Studio Profile @ Level 2"}, - {0xE3, "Simple Studio Profile @ Level 3"}, - {0xE4, "Simple Studio Profile @ Level 4"}, - {0xE5, "Core Studio Profile @ Level 1"}, - {0xE6, "Core Studio Profile @ Level 2"}, - {0xE7, "Core Studio Profile @ Level 3"}, - {0xE8, "Core Studio Profile @ Level 4"}, - {0xF0, "Advanced Simple Profile @ Level 0"}, - {0xF1, "Advanced Simple Profile @ Level 1"}, - {0xF2, "Advanced Simple Profile @ Level 2"}, - {0xF3, "Advanced Simple Profile @ Level 3"}, - {0xF4, "Advanced Simple Profile @ Level 4"}, - {0xF5, "Advanced Simple Profile @ Level 5"}, - {0xF7, "Advanced Simple Profile @ Level 3b"}, - {0xF8, "Fine Granularity Scalable Profile @ Level 0"}, - {0xF9, "Fine Granularity Scalable Profile @ Level 1"}, - {0xFA, "Fine Granularity Scalable Profile @ Level 2"}, - {0xFB, "Fine Granularity Scalable Profile @ Level 3"}, - {0xFC, "Fine Granularity Scalable Profile @ Level 4"}, - {0xFD, "Fine Granularity Scalable Profile @ Level 5"}, - {0xFE, "Not part of MPEG-4 Visual profiles"}, - {0xFF, "No visual capability required"} -}; - -GF_EXPORT -const char *gf_m4v_get_profile_name(u8 video_pl) -{ - u32 i, count = GF_ARRAY_LENGTH(M4VProfiles); - for (i=0; i> 8; -#else - value = (pbuffer[0] << 16) | (pbuffer[1] << 8) | (pbuffer[2] << 0); -#endif - - if (value == MPEG12_START_CODE_PREFIX) { - *optr = offset; - *scode = (value << 8) | pbuffer[3]; - return 0; - } - } - return -1; -} - -s32 gf_mv12_next_slice_start(unsigned char *pbuffer, u32 startoffset, u32 buflen, u32 *slice_offset) -{ - u32 slicestart, code; - while (gf_mv12_next_start_code(pbuffer + startoffset, buflen - startoffset, &slicestart, &code) >= 0) { - if ((code >= MPEG12_SLICE_MIN_START) && (code <= MPEG12_SLICE_MAX_START)) { - *slice_offset = slicestart + startoffset; - return 0; - } - startoffset += slicestart + 4; - } - return -1; -} - - -/* - MPEG-4 video (14496-2) -*/ - -struct __tag_m4v_parser -{ - GF_BitStream *bs; - Bool mpeg12, step_mode; - u32 current_object_type; - u32 force_next_obj_type; - u64 current_object_start; - u32 tc_dec, prev_tc_dec, tc_disp, prev_tc_disp; -}; - -GF_EXPORT -GF_M4VParser *gf_m4v_parser_new(u8 *data, u64 data_size, Bool mpeg12video) -{ - GF_M4VParser *tmp; - if (!data || !data_size) return NULL; - GF_SAFEALLOC(tmp, GF_M4VParser); - if (!tmp) return NULL; - tmp->bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ); - tmp->mpeg12 = mpeg12video; - return tmp; -} - -GF_M4VParser *gf_m4v_parser_bs_new(GF_BitStream *bs, Bool mpeg12video) -{ - GF_M4VParser *tmp; - GF_SAFEALLOC(tmp, GF_M4VParser); - if (!tmp) return NULL; - tmp->bs = bs; - tmp->mpeg12 = mpeg12video; - return tmp; -} - -GF_EXPORT -void gf_m4v_parser_del(GF_M4VParser *m4v) -{ - gf_bs_del(m4v->bs); - gf_free(m4v); -} - -GF_EXPORT -void gf_m4v_parser_del_no_bs(GF_M4VParser *m4v) -{ - gf_free(m4v); -} - -GF_EXPORT -void gf_m4v_parser_set_inspect(GF_M4VParser *m4v) -{ - if (m4v) m4v->step_mode = 1; -} -GF_EXPORT -u32 gf_m4v_parser_get_obj_type(GF_M4VParser *m4v) -{ - if (m4v) return m4v->current_object_type; - return 0; -} - -#define M4V_CACHE_SIZE 4096 -s32 M4V_LoadObject(GF_M4VParser *m4v) -{ - u32 v, bpos, found; - char m4v_cache[M4V_CACHE_SIZE]; - u64 end, cache_start, load_size; - if (!m4v) return 0; - if (m4v->force_next_obj_type) { - m4v->current_object_type = m4v->force_next_obj_type - 1; - m4v->force_next_obj_type = 0; - return (s32)m4v->current_object_type; - } - - bpos = 0; - found = 0; - load_size = 0; - end = 0; - cache_start = 0; - v = 0xffffffff; - while (!end) { - /*refill cache*/ - if (bpos == (u32)load_size) { - if (!gf_bs_available(m4v->bs)) break; - load_size = gf_bs_available(m4v->bs); - if (load_size > M4V_CACHE_SIZE) load_size = M4V_CACHE_SIZE; - bpos = 0; - cache_start = gf_bs_get_position(m4v->bs); - gf_bs_read_data(m4v->bs, m4v_cache, (u32)load_size); - } - v = ((v << 8) & 0xFFFFFF00) | ((u8)m4v_cache[bpos]); - bpos++; - if ((v & 0xFFFFFF00) == 0x00000100) { - end = cache_start + bpos - 4; - found = 1; - break; - } - } - if (!found) return -1; - m4v->current_object_start = end; - gf_bs_seek(m4v->bs, end + 3); - m4v->current_object_type = gf_bs_read_u8(m4v->bs); - return (s32)m4v->current_object_type; -} - - -GF_EXPORT -void gf_m4v_rewrite_pl(u8 **o_data, u32 *o_dataLen, u8 PL) -{ - u32 pos = 0; - unsigned char *data = (unsigned char *)*o_data; - u32 dataLen = *o_dataLen; - - while (pos + 4 < dataLen) { - if (!data[pos] && !data[pos + 1] && (data[pos + 2] == 0x01) && (data[pos + 3] == M4V_VOS_START_CODE)) { - data[pos + 4] = PL; - return; - } - pos++; - } - /*emulate VOS at beggining*/ - (*o_data) = (char *)gf_malloc(sizeof(char)*(dataLen + 5)); - (*o_data)[0] = 0; - (*o_data)[1] = 0; - (*o_data)[2] = 1; - (*o_data)[3] = (char)M4V_VOS_START_CODE; - (*o_data)[4] = PL; - memcpy((*o_data + 5), data, sizeof(char)*dataLen); - gf_free(data); - (*o_dataLen) = dataLen + 5; -} - -static GF_Err M4V_Reset(GF_M4VParser *m4v, u64 start) -{ - gf_bs_seek(m4v->bs, start); - - assert(start < (u64)1<<31); - m4v->current_object_start = (u32)start; - m4v->current_object_type = 0; - return GF_OK; -} - -void gf_m4v_parser_reset(GF_M4VParser *m4v, u8 sc_type) -{ - m4v->current_object_start = 0; - m4v->current_object_type = 0; - m4v->force_next_obj_type = sc_type; -} -static GF_Err gf_m4v_parse_config_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi) -{ - unsigned char p[4]; - u32 ext_type; - s32 o_type; - u8 go, par; - - if (!m4v || !dsi) return GF_BAD_PARAM; - - memset(dsi, 0, sizeof(GF_M4VDecSpecInfo)); - dsi->VideoPL = 0; - - go = 1; - while (go) { - o_type = M4V_LoadObject(m4v); - switch (o_type) { - case M2V_SEQ_START_CODE: - dsi->RAP_stream = 1; - gf_bs_read_data(m4v->bs, (char *)p, 4); - dsi->width = (p[0] << 4) | ((p[1] >> 4) & 0xf); - dsi->height = ((p[1] & 0xf) << 8) | p[2]; - - dsi->VideoPL = GF_CODECID_MPEG1; - par = (p[3] >> 4) & 0xf; - switch (par) { - case 2: - dsi->par_num = dsi->height / 3; - dsi->par_den = dsi->width / 4; - break; - case 3: - dsi->par_num = dsi->height / 9; - dsi->par_den = dsi->width / 16; - break; - case 4: - dsi->par_num = dsi->height / 2; - dsi->par_den = dsi->width / 21; - break; - default: - dsi->par_den = dsi->par_num = 0; - break; - } - switch (p[3] & 0xf) { - case 0: - break; - case 1: - dsi->fps = 24000.0 / 1001.0; - break; - case 2: - dsi->fps = 24.0; - break; - case 3: - dsi->fps = 25.0; - break; - case 4: - dsi->fps = 30000.0 / 1001.0; - break; - case 5: - dsi->fps = 30.0; - break; - case 6: - dsi->fps = 50.0; - break; - case 7: - dsi->fps = ((60.0*1000.0) / 1001.0); - break; - case 8: - dsi->fps = 60.0; - break; - case 9: - dsi->fps = 1; - break; - case 10: - dsi->fps = 5; - break; - case 11: - dsi->fps = 10; - break; - case 12: - dsi->fps = 12; - break; - case 13: - dsi->fps = 15; - break; - } - break; - case M2V_EXT_START_CODE: - gf_bs_read_data(m4v->bs, (char *)p, 4); - ext_type = ((p[0] >> 4) & 0xf); - if (ext_type == 1) { - dsi->VideoPL = 0x65; - dsi->height = ((p[1] & 0x1) << 13) | ((p[2] & 0x80) << 5) | (dsi->height & 0x0fff); - dsi->width = (((p[2] >> 5) & 0x3) << 12) | (dsi->width & 0x0fff); - } - break; - case M2V_PIC_START_CODE: - if (dsi->width) go = 0; - break; - default: - break; - /*EOS*/ - case -1: - go = 0; - m4v->current_object_start = gf_bs_get_position(m4v->bs); - break; - } - } - M4V_Reset(m4v, 0); - return GF_OK; -} - - -static const struct { - u32 w, h; -} m4v_sar[6] = { { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, { 40, 33 } }; - -static u8 m4v_get_sar_idx(u32 w, u32 h) -{ - u32 i; - for (i = 0; i < 6; i++) { - if ((m4v_sar[i].w == w) && (m4v_sar[i].h == h)) return i; - } - return 0xF; -} - -static void gf_m4v_parse_vol(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi) -{ - u8 verid, par; - s32 clock_rate; - u8 vpl = dsi->VideoPL; - - memset(dsi, 0, sizeof(GF_M4VDecSpecInfo)); - dsi->VideoPL = vpl; - - verid = 0; - dsi->RAP_stream = gf_bs_read_int(m4v->bs, 1); - dsi->objectType = gf_bs_read_int(m4v->bs, 8); - if (gf_bs_read_int(m4v->bs, 1)) { - verid = gf_bs_read_int(m4v->bs, 4); - gf_bs_read_int(m4v->bs, 3); - } - par = gf_bs_read_int(m4v->bs, 4); - if (par == 0xF) { - dsi->par_num = gf_bs_read_int(m4v->bs, 8); - dsi->par_den = gf_bs_read_int(m4v->bs, 8); - } else if (par<6) { - dsi->par_num = m4v_sar[par].w; - dsi->par_den = m4v_sar[par].h; - } - if (gf_bs_read_int(m4v->bs, 1)) { - gf_bs_read_int(m4v->bs, 3); - if (gf_bs_read_int(m4v->bs, 1)) gf_bs_read_int(m4v->bs, 79); - } - dsi->has_shape = gf_bs_read_int(m4v->bs, 2); - if (dsi->has_shape && (verid!=1) ) gf_bs_read_int(m4v->bs, 4); - gf_bs_read_int(m4v->bs, 1); - /*clock rate*/ - dsi->clock_rate = gf_bs_read_int(m4v->bs, 16); - /*marker*/ - gf_bs_read_int(m4v->bs, 1); - - clock_rate = dsi->clock_rate-1; - if (clock_rate >= 65536) clock_rate = 65535; - if (clock_rate > 0) { - for (dsi->NumBitsTimeIncrement = 1; dsi->NumBitsTimeIncrement < 16; dsi->NumBitsTimeIncrement++) { - if (clock_rate == 1) break; - clock_rate = (clock_rate >> 1); - } - } else { - /*fix from vivien for divX*/ - dsi->NumBitsTimeIncrement = 1; - } - /*fixed FPS stream*/ - dsi->time_increment = 0; - if (gf_bs_read_int(m4v->bs, 1)) { - dsi->time_increment = gf_bs_read_int(m4v->bs, dsi->NumBitsTimeIncrement); - } - if (!dsi->has_shape) { - gf_bs_read_int(m4v->bs, 1); - dsi->width = gf_bs_read_int(m4v->bs, 13); - gf_bs_read_int(m4v->bs, 1); - dsi->height = gf_bs_read_int(m4v->bs, 13); - } else { - dsi->width = dsi->height = 0; - } - -} - -static GF_Err gf_m4v_parse_config_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi) -{ - s32 o_type; - u8 go; - - if (!m4v || !dsi) return GF_BAD_PARAM; - - memset(dsi, 0, sizeof(GF_M4VDecSpecInfo)); - - go = 1; - while (go) { - o_type = M4V_LoadObject(m4v); - switch (o_type) { - /*vosh*/ - case M4V_VOS_START_CODE: - dsi->VideoPL = (u8)gf_bs_read_u8(m4v->bs); - break; - - case M4V_VOL_START_CODE: - gf_m4v_parse_vol(m4v, dsi); - /*shape will be done later*/ - gf_bs_align(m4v->bs); - break; - - case M4V_VOP_START_CODE: - case M4V_GOV_START_CODE: - go = 0; - break; - /*EOS*/ - case -1: - m4v->current_object_start = gf_bs_get_position(m4v->bs); - return GF_EOS; - /*don't interest us*/ - case M4V_UDTA_START_CODE: - default: - break; - } - } - return GF_OK; -} - -GF_EXPORT -GF_Err gf_m4v_parse_config(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi) -{ - if (m4v->mpeg12) { - return gf_m4v_parse_config_mpeg12(m4v, dsi); - } - else { - return gf_m4v_parse_config_mpeg4(m4v, dsi); - } -} - -static GF_Err gf_m4v_parse_frame_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded) -{ - u8 go, hasVOP, firstObj, val; - s32 o_type; - - if (!m4v || !size || !start || !frame_type) return GF_BAD_PARAM; - - *size = 0; - firstObj = 1; - hasVOP = 0; - *is_coded = GF_FALSE; - m4v->current_object_type = (u32)-1; - *frame_type = 0; - - if (!m4v->step_mode) - M4V_Reset(m4v, m4v->current_object_start); - - go = 1; - while (go) { - o_type = M4V_LoadObject(m4v); - switch (o_type) { - case M2V_PIC_START_CODE: - /*done*/ - if (hasVOP) { - go = 0; - break; - } - if (firstObj) { - *start = m4v->current_object_start; - firstObj = 0; - } - hasVOP = 1; - *is_coded = 1; - - /*val = */gf_bs_read_u8(m4v->bs); - val = gf_bs_read_u8(m4v->bs); - *frame_type = ((val >> 3) & 0x7) - 1; - break; - case M2V_GOP_START_CODE: - if (firstObj) { - *start = m4v->current_object_start; - firstObj = 0; - } - if (hasVOP) go = 0; - break; - - case M2V_SEQ_START_CODE: - if (firstObj) { - *start = m4v->current_object_start; - firstObj = 0; - } - if (hasVOP) { - go = 0; - break; - } - - /**/ - break; - - default: - break; - - case -1: - *size = gf_bs_get_position(m4v->bs) - *start; - return GF_EOS; - } - if (m4v->step_mode) - return GF_OK; - } - *size = m4v->current_object_start - *start; - return GF_OK; -} - -static GF_Err gf_m4v_parse_frame_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded) -{ - u8 go, hasVOP, firstObj, secs; - s32 o_type; - u32 vop_inc = 0; - - if (!m4v || !size || !start || !frame_type) return GF_BAD_PARAM; - - *size = 0; - firstObj = 1; - hasVOP = 0; - *is_coded = 0; - m4v->current_object_type = (u32)-1; - *frame_type = 0; - *start = 0; - - if (!m4v->step_mode) - M4V_Reset(m4v, m4v->current_object_start); - - go = 1; - while (go) { - o_type = M4V_LoadObject(m4v); - switch (o_type) { - case M4V_VOP_START_CODE: - /*done*/ - if (hasVOP) { - go = 0; - break; - } - if (firstObj) { - *start = m4v->current_object_start; - firstObj = 0; - } - hasVOP = 1; - - /*coding type*/ - *frame_type = gf_bs_read_int(m4v->bs, 2); - /*modulo time base*/ - secs = 0; - while (gf_bs_read_int(m4v->bs, 1) != 0) - secs++; - /*no support for B frames in parsing*/ - secs += (dsi->enh_layer || *frame_type!=2) ? m4v->tc_dec : m4v->tc_disp; - /*marker*/ - gf_bs_read_int(m4v->bs, 1); - /*vop_time_inc*/ - if (dsi->NumBitsTimeIncrement) - vop_inc = gf_bs_read_int(m4v->bs, dsi->NumBitsTimeIncrement); - - m4v->prev_tc_dec = m4v->tc_dec; - m4v->prev_tc_disp = m4v->tc_disp; - if (dsi->enh_layer || *frame_type!=2) { - m4v->tc_disp = m4v->tc_dec; - m4v->tc_dec = secs; - } - *time_inc = secs * dsi->clock_rate + vop_inc; - /*marker*/ - gf_bs_read_int(m4v->bs, 1); - /*coded*/ - *is_coded = gf_bs_read_int(m4v->bs, 1); - gf_bs_align(m4v->bs); - break; - case M4V_GOV_START_CODE: - if (firstObj) { - *start = m4v->current_object_start; - firstObj = 0; - } - if (hasVOP) go = 0; - break; - - case M4V_VOL_START_CODE: - if (m4v->step_mode) - gf_m4v_parse_vol(m4v, dsi); - case M4V_VOS_START_CODE: - if (hasVOP) { - go = 0; - } - else if (firstObj) { - *start = m4v->current_object_start; - firstObj = 0; - } - break; - - case M4V_VO_START_CODE: - default: - break; - - case -1: - *size = gf_bs_get_position(m4v->bs) - *start; - return GF_EOS; - } - if (m4v->step_mode) - return GF_OK; - } - assert(m4v->current_object_start >= *start); - *size = m4v->current_object_start - *start; - return GF_OK; -} - -GF_EXPORT -GF_Err gf_m4v_parse_frame(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded) -{ - if (m4v->mpeg12) { - return gf_m4v_parse_frame_mpeg12(m4v, dsi, frame_type, time_inc, size, start, is_coded); - } - else { - return gf_m4v_parse_frame_mpeg4(m4v, dsi, frame_type, time_inc, size, start, is_coded); - } -} - -GF_Err gf_m4v_rewrite_par(u8 **o_data, u32 *o_dataLen, s32 par_n, s32 par_d) -{ - u64 start, end, size; - GF_BitStream *mod; - GF_M4VParser *m4v; - Bool go = 1; - - m4v = gf_m4v_parser_new(*o_data, *o_dataLen, 0); - mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - - start = 0; - while (go) { - u32 type = M4V_LoadObject(m4v); - - end = gf_bs_get_position(m4v->bs) - 4; - size = end - start; - /*store previous object*/ - if (size) { - assert (size < (u64)1<<31); - gf_bs_write_data(mod, *o_data + start, (u32)size); - start = end; - } - - switch (type) { - case M4V_VOL_START_CODE: - gf_bs_write_int(mod, 0, 8); - gf_bs_write_int(mod, 0, 8); - gf_bs_write_int(mod, 1, 8); - gf_bs_write_int(mod, M4V_VOL_START_CODE, 8); - gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 1), 1); - gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 8), 8); - start = gf_bs_read_int(m4v->bs, 1); - gf_bs_write_int(mod, (u32)start, 1); - if (start) { - gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 7), 7); - } - start = gf_bs_read_int(m4v->bs, 4); - if (start == 0xF) { - gf_bs_read_int(m4v->bs, 8); - gf_bs_read_int(m4v->bs, 8); - } - if ((par_n >= 0) && (par_d >= 0)) { - u8 par = m4v_get_sar_idx(par_n, par_d); - gf_bs_write_int(mod, par, 4); - if (par == 0xF) { - gf_bs_write_int(mod, par_n, 8); - gf_bs_write_int(mod, par_d, 8); - } - } - else { - gf_bs_write_int(mod, 0x0, 4); - } - case -1: - go = 0; - break; - default: - break; - } - } - while (gf_bs_bits_available(m4v->bs)) { - u32 b = gf_bs_read_int(m4v->bs, 1); - gf_bs_write_int(mod, b, 1); - } - - gf_m4v_parser_del(m4v); - gf_free(*o_data); - gf_bs_get_content(mod, o_data, o_dataLen); - gf_bs_del(mod); - return GF_OK; -} - -GF_EXPORT -u64 gf_m4v_get_object_start(GF_M4VParser *m4v) -{ - return m4v->current_object_start; -} - -#if 0 //unused -Bool gf_m4v_is_valid_object_type(GF_M4VParser *m4v) -{ - return ((s32)m4v->current_object_type == -1) ? 0 : 1; -} -#endif - - -GF_EXPORT -GF_Err gf_m4v_get_config(u8 *rawdsi, u32 rawdsi_size, GF_M4VDecSpecInfo *dsi) -{ - GF_Err e; - GF_M4VParser *vparse; - if (!rawdsi || !rawdsi_size) return GF_NON_COMPLIANT_BITSTREAM; - vparse = gf_m4v_parser_new(rawdsi, rawdsi_size, 0); - e = gf_m4v_parse_config(vparse, dsi); - dsi->next_object_start = (u32)vparse->current_object_start; - gf_m4v_parser_del(vparse); - return e < 0 ? e : GF_OK; -} - -GF_EXPORT -GF_Err gf_mpegv12_get_config(u8 *rawdsi, u32 rawdsi_size, GF_M4VDecSpecInfo *dsi) -{ - GF_Err e; - GF_M4VParser *vparse; - if (!rawdsi || !rawdsi_size) return GF_NON_COMPLIANT_BITSTREAM; - vparse = gf_m4v_parser_new(rawdsi, rawdsi_size, GF_TRUE); - e = gf_m4v_parse_config(vparse, dsi); - dsi->next_object_start = (u32)vparse->current_object_start; - gf_m4v_parser_del(vparse); - return e; -} - -#endif - - -/* - AAC parser -*/ - -struct __m4a_oti -{ - u32 type; - const char *name; -} M4AObjectTypes[] = { - {0, "MPEG-4 Audio Reserved"}, - {1, "MPEG-4 Audio AAC Main"}, - {2, "MPEG-4 Audio AAC LC"}, - {3, "MPEG-4 Audio AAC SSR"}, - {4, "MPEG-4 Audio AAC LTP"}, - {5, "MPEG-4 Audio SBR"}, - {6, "MPEG-4 Audio AAC Scalable"}, - {7, "MPEG-4 Audio TwinVQ"}, - {8, "MPEG-4 Audio CELP"}, - {9, "MPEG-4 Audio HVXC"}, - {10, "MPEG-4 Audio Reserved"}, - {11, "MPEG-4 Audio Reserved"}, - {12, "MPEG-4 Audio TTSI"}, - {13, "MPEG-4 Audio Main synthetic"}, - {14, "MPEG-4 Audio Wavetable synthesis"}, - {15, "MPEG-4 Audio General MIDI"}, - {16, "MPEG-4 Audio Algorithmic Synthesis and Audio FX"}, - {17, "MPEG-4 Audio ER AAC LC"}, - {18, "MPEG-4 Audio Reserved"}, - {19, "MPEG-4 Audio ER AAC LTP"}, - {20, "MPEG-4 Audio ER AAC scalable"}, - {21, "MPEG-4 Audio ER TwinVQ"}, - {22, "MPEG-4 Audio ER BSAC"}, - {23, "MPEG-4 Audio ER AAC LD"}, - {24, "MPEG-4 Audio ER CELP"}, - {25, "MPEG-4 Audio ER HVXC"}, - {26, "MPEG-4 Audio ER HILN"}, - {27, "MPEG-4 Audio ER Parametric"}, - {28, "MPEG-4 Audio SSC"}, - {29, "MPEG-4 Audio ParametricStereo"}, - {30, "MPEG-4 Audio Reserved"}, - {31, "MPEG-4 Audio Reserved"}, - {32, "MPEG-1 Audio Layer-1"}, - {33, "MPEG-1 Audio Layer-2"}, - {34, "MPEG-1 Audio Layer-3"}, - {35, "MPEG-4 Audio DST"}, - {36, "MPEG-4 Audio ALS"} -}; - -GF_EXPORT -const char *gf_m4a_object_type_name(u32 objectType) -{ - u32 i, count = GF_ARRAY_LENGTH(M4AObjectTypes); - for (i=0; ibase_object_type) { - case 2: /*AAC LC*/ - if (cfg->nb_chan <= 2) - return (cfg->base_sr <= 24000) ? 0x28 : 0x29; /*LC@L1 or LC@L2*/ - if (cfg->nb_chan <= 5) - return (cfg->base_sr <= 48000) ? 0x2A : 0x2B; /*LC@L4 or LC@L5*/ - return (cfg->base_sr <= 48000) ? 0x50 : 0x51; /*LC@L4 or LC@L5*/ - case 5: /*HE-AAC - SBR*/ - if (cfg->nb_chan <= 2) - return (cfg->base_sr <= 24000) ? 0x2C : 0x2D; /*HE@L2 or HE@L3*/ - if (cfg->nb_chan <= 5) - return (cfg->base_sr <= 48000) ? 0x2E : 0x2F; /*HE@L4 or HE@L5*/ - return (cfg->base_sr <= 48000) ? 0x52 : 0x53; /*HE@L6 or HE@L7*/ - case 29: /*HE-AACv2 - SBR+PS*/ - if (cfg->nb_chan <= 2) - return (cfg->base_sr <= 24000) ? 0x30 : 0x31; /*HE-AACv2@L2 or HE-AACv2@L3*/ - if (cfg->nb_chan <= 5) - return (cfg->base_sr <= 48000) ? 0x32 : 0x33; /*HE-AACv2@L4 or HE-AACv2@L5*/ - return (cfg->base_sr <= 48000) ? 0x54 : 0x55; /*HE-AACv2@L6 or HE-AACv2@L7*/ - /*default to HQ*/ - default: - if (cfg->nb_chan <= 2) return (cfg->base_sr < 24000) ? 0x0E : 0x0F; /*HQ@L1 or HQ@L2*/ - return 0x10; /*HQ@L3*/ - } -} - - - -GF_EXPORT -GF_Err gf_m4a_parse_config(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg, Bool size_known) -{ - u32 channel_configuration = 0; - memset(cfg, 0, sizeof(GF_M4ADecSpecInfo)); - cfg->base_object_type = gf_bs_read_int(bs, 5); - /*extended object type*/ - if (cfg->base_object_type == 31) { - cfg->base_object_type = 32 + gf_bs_read_int(bs, 6); - } - cfg->base_sr_index = gf_bs_read_int(bs, 4); - if (cfg->base_sr_index == 0x0F) { - cfg->base_sr = gf_bs_read_int(bs, 24); - } - else { - cfg->base_sr = GF_M4ASampleRates[cfg->base_sr_index]; - } - - channel_configuration = gf_bs_read_int(bs, 4); - - if (channel_configuration) { - cfg->nb_chan = GF_M4ANumChannels[channel_configuration - 1]; - } - - if (cfg->base_object_type == 5 || cfg->base_object_type == 29) { - if (cfg->base_object_type == 29) { - cfg->has_ps = 1; - cfg->nb_chan = 1; - } - cfg->has_sbr = GF_TRUE; - cfg->sbr_sr_index = gf_bs_read_int(bs, 4); - if (cfg->sbr_sr_index == 0x0F) { - cfg->sbr_sr = gf_bs_read_int(bs, 24); - } - else { - cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index]; - } - cfg->sbr_object_type = gf_bs_read_int(bs, 5); - } - - /*object cfg*/ - switch (cfg->base_object_type) { - case 1: - case 2: - case 3: - case 4: - case 6: - case 7: - case 17: - case 19: - case 20: - case 21: - case 22: - case 23: - { - Bool ext_flag; - /*frame length flag*/ - /*fl_flag = */gf_bs_read_int(bs, 1); - /*depends on core coder*/ - if (gf_bs_read_int(bs, 1)) - /*delay = */gf_bs_read_int(bs, 14); - ext_flag = gf_bs_read_int(bs, 1); - - if (!channel_configuration) { - u32 i, cpe_channels=0; - cfg->program_config_element_present = 1; - cfg->element_instance_tag = gf_bs_read_int(bs, 4); - cfg->object_type = gf_bs_read_int(bs, 2); - cfg->sampling_frequency_index = gf_bs_read_int(bs, 4); - cfg->num_front_channel_elements = gf_bs_read_int(bs, 4); - cfg->num_side_channel_elements = gf_bs_read_int(bs, 4); - cfg->num_back_channel_elements = gf_bs_read_int(bs, 4); - cfg->num_lfe_channel_elements = gf_bs_read_int(bs, 2); - cfg->num_assoc_data_elements = gf_bs_read_int(bs, 3); - cfg->num_valid_cc_elements = gf_bs_read_int(bs, 4); - cfg->mono_mixdown_present = (Bool)gf_bs_read_int(bs, 1); - if (cfg->mono_mixdown_present) { - cfg->mono_mixdown_element_number = gf_bs_read_int(bs, 4); - } - cfg->stereo_mixdown_present = gf_bs_read_int(bs, 1); - if (cfg->stereo_mixdown_present) { - cfg->stereo_mixdown_element_number = gf_bs_read_int(bs, 4); - } - cfg->matrix_mixdown_idx_present = gf_bs_read_int(bs, 1); - if (cfg->matrix_mixdown_idx_present) { - cfg->matrix_mixdown_idx = gf_bs_read_int(bs, 2); - cfg->pseudo_surround_enable = gf_bs_read_int(bs, 1); - } - for (i = 0; i < cfg->num_front_channel_elements; i++) { - cfg->front_element_is_cpe[i] = gf_bs_read_int(bs, 1); - cfg->front_element_tag_select[i] = gf_bs_read_int(bs, 4); - if (cfg->front_element_is_cpe[i]) cpe_channels++; - } - for (i = 0; i < cfg->num_side_channel_elements; i++) { - cfg->side_element_is_cpe[i] = gf_bs_read_int(bs, 1); - cfg->side_element_tag_select[i] = gf_bs_read_int(bs, 4); - if (cfg->side_element_is_cpe[i]) cpe_channels++; - } - for (i = 0; i < cfg->num_back_channel_elements; i++) { - cfg->back_element_is_cpe[i] = gf_bs_read_int(bs, 1); - cfg->back_element_tag_select[i] = gf_bs_read_int(bs, 4); - if (cfg->back_element_is_cpe[i]) cpe_channels++; - } - for (i = 0; i < cfg->num_lfe_channel_elements; i++) { - cfg->lfe_element_tag_select[i] = gf_bs_read_int(bs, 4); - } - for (i = 0; i < cfg->num_assoc_data_elements; i++) { - cfg->assoc_data_element_tag_select[i] = gf_bs_read_int(bs, 4); - } - - for (i = 0; i < cfg->num_valid_cc_elements; i++) { - cfg->cc_element_is_ind_sw[i] = gf_bs_read_int(bs, 1); - cfg->valid_cc_element_tag_select[i] = gf_bs_read_int(bs, 4); - } - gf_bs_align(bs); - cfg->comment_field_bytes = gf_bs_read_int(bs, 8); - gf_bs_read_data(bs, (char *)cfg->comments, cfg->comment_field_bytes); - - cfg->nb_chan = cfg->num_front_channel_elements + cfg->num_back_channel_elements + cfg->num_side_channel_elements + cfg->num_lfe_channel_elements; - cfg->nb_chan += cpe_channels; - } - - if ((cfg->base_object_type == 6) || (cfg->base_object_type == 20)) { - gf_bs_read_int(bs, 3); - } - if (ext_flag) { - if (cfg->base_object_type == 22) { - gf_bs_read_int(bs, 5); - gf_bs_read_int(bs, 11); - } - if ((cfg->base_object_type == 17) - || (cfg->base_object_type == 19) - || (cfg->base_object_type == 20) - || (cfg->base_object_type == 23) - ) { - gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 1); - } - /*ext_flag = */gf_bs_read_int(bs, 1); - } - } - break; - } - /*ER cfg*/ - switch (cfg->base_object_type) { - case 17: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - { - u32 epConfig = gf_bs_read_int(bs, 2); - if ((epConfig == 2) || (epConfig == 3)) { - } - if (epConfig == 3) { - gf_bs_read_int(bs, 1); - } - } - break; - } - - if (size_known && (cfg->base_object_type != 5) && (cfg->base_object_type != 29)) { - while (gf_bs_available(bs) >= 2) { - u32 sync = gf_bs_peek_bits(bs, 11, 0); - if (sync == 0x2b7) { - gf_bs_read_int(bs, 11); - cfg->sbr_object_type = gf_bs_read_int(bs, 5); - cfg->has_sbr = gf_bs_read_int(bs, 1); - if (cfg->has_sbr) { - cfg->sbr_sr_index = gf_bs_read_int(bs, 4); - if (cfg->sbr_sr_index == 0x0F) { - cfg->sbr_sr = gf_bs_read_int(bs, 24); - } - else { - cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index]; - } - } - } - else if (sync == 0x548) { - gf_bs_read_int(bs, 11); - cfg->has_ps = gf_bs_read_int(bs, 1); - if (cfg->has_ps) - cfg->nb_chan = 1; - } - else { - break; - } - } - } - cfg->audioPL = gf_m4a_get_profile(cfg); - return GF_OK; -} - -GF_EXPORT -GF_Err gf_m4a_get_config(u8 *dsi, u32 dsi_size, GF_M4ADecSpecInfo *cfg) -{ - GF_BitStream *bs; - if (!dsi || !dsi_size || (dsi_size < 2)) return GF_NON_COMPLIANT_BITSTREAM; - bs = gf_bs_new(dsi, dsi_size, GF_BITSTREAM_READ); - gf_m4a_parse_config(bs, cfg, GF_TRUE); - gf_bs_del(bs); - return GF_OK; -} - -u32 gf_latm_get_value(GF_BitStream *bs) -{ - u32 i, tmp, value = 0; - u32 bytesForValue = gf_bs_read_int(bs, 2); - for (i = 0; i <= bytesForValue; i++) { - value <<= 8; - tmp = gf_bs_read_int(bs, 8); - value += tmp; - } - return value; -} - -GF_EXPORT -u32 gf_m4a_get_channel_cfg(u32 nb_chan) -{ - u32 i, count = sizeof(GF_M4ANumChannels) / sizeof(u32); - for (i = 0; i < count; i++) { - if (GF_M4ANumChannels[i] == nb_chan) return i + 1; - } - return 0; -} - -GF_EXPORT -GF_Err gf_m4a_write_config_bs(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg) -{ - if (!cfg->base_sr_index) { - if (!cfg->base_sr) return GF_BAD_PARAM; - while (GF_M4ASampleRates[cfg->base_sr_index]) { - if (GF_M4ASampleRates[cfg->base_sr_index] == cfg->base_sr) - break; - cfg->base_sr_index++; - } - } - if (cfg->sbr_sr && !cfg->sbr_sr_index) { - while (GF_M4ASampleRates[cfg->sbr_sr_index]) { - if (GF_M4ASampleRates[cfg->sbr_sr_index] == cfg->sbr_sr) - break; - cfg->sbr_sr_index++; - } - } - /*extended object type*/ - if (cfg->base_object_type >= 32) { - gf_bs_write_int(bs, 31, 5); - gf_bs_write_int(bs, cfg->base_object_type - 32, 6); - } - else { - gf_bs_write_int(bs, cfg->base_object_type, 5); - } - gf_bs_write_int(bs, cfg->base_sr_index, 4); - if (cfg->base_sr_index == 0x0F) { - gf_bs_write_int(bs, cfg->base_sr, 24); - } - - if (cfg->program_config_element_present) { - gf_bs_write_int(bs, 0, 4); - } - else { - gf_bs_write_int(bs, gf_m4a_get_channel_cfg(cfg->nb_chan), 4); - } - - if (cfg->base_object_type == 5 || cfg->base_object_type == 29) { - if (cfg->base_object_type == 29) { - cfg->has_ps = 1; - cfg->nb_chan = 1; - } - cfg->has_sbr = 1; - gf_bs_write_int(bs, cfg->sbr_sr_index, 4); - if (cfg->sbr_sr_index == 0x0F) { - gf_bs_write_int(bs, cfg->sbr_sr, 24); - } - gf_bs_write_int(bs, cfg->sbr_object_type, 5); - } - - /*object cfg*/ - switch (cfg->base_object_type) { - case 1: - case 2: - case 3: - case 4: - case 6: - case 7: - case 17: - case 19: - case 20: - case 21: - case 22: - case 23: - { - /*frame length flag*/ - gf_bs_write_int(bs, 0, 1); - /*depends on core coder*/ - gf_bs_write_int(bs, 0, 1); - /*ext flag*/ - gf_bs_write_int(bs, 0, 1); - - if (cfg->program_config_element_present) { - u32 i; - gf_bs_write_int(bs, cfg->element_instance_tag, 4); - gf_bs_write_int(bs, cfg->object_type, 2); - gf_bs_write_int(bs, cfg->sampling_frequency_index, 4); - gf_bs_write_int(bs, cfg->num_front_channel_elements, 4); - gf_bs_write_int(bs, cfg->num_side_channel_elements, 4); - gf_bs_write_int(bs, cfg->num_back_channel_elements, 4); - gf_bs_write_int(bs, cfg->num_lfe_channel_elements, 2); - gf_bs_write_int(bs, cfg->num_assoc_data_elements, 3); - gf_bs_write_int(bs, cfg->num_valid_cc_elements, 4); - gf_bs_write_int(bs, cfg->mono_mixdown_present, 1); - if (cfg->mono_mixdown_present) { - gf_bs_write_int(bs, cfg->mono_mixdown_element_number, 4); - } - gf_bs_write_int(bs, cfg->stereo_mixdown_present, 1); - if (cfg->stereo_mixdown_present) { - gf_bs_write_int(bs, cfg->stereo_mixdown_element_number, 4); - } - gf_bs_write_int(bs, cfg->matrix_mixdown_idx_present, 1); - if (cfg->matrix_mixdown_idx_present) { - gf_bs_write_int(bs, cfg->matrix_mixdown_idx, 2); - gf_bs_write_int(bs, cfg->pseudo_surround_enable, 1); - } - for (i = 0; i < cfg->num_front_channel_elements; i++) { - gf_bs_write_int(bs, cfg->front_element_is_cpe[i], 1); - gf_bs_write_int(bs, cfg->front_element_tag_select[i], 4); - } - for (i = 0; i < cfg->num_side_channel_elements; i++) { - gf_bs_write_int(bs, cfg->side_element_is_cpe[i], 1); - gf_bs_write_int(bs, cfg->side_element_tag_select[i], 4); - } - for (i = 0; i < cfg->num_back_channel_elements; i++) { - gf_bs_write_int(bs, cfg->back_element_is_cpe[i], 1); - gf_bs_write_int(bs, cfg->back_element_tag_select[i], 4); - } - for (i = 0; i < cfg->num_lfe_channel_elements; i++) { - gf_bs_write_int(bs, cfg->lfe_element_tag_select[i], 4); - } - for (i = 0; i < cfg->num_assoc_data_elements; i++) { - gf_bs_write_int(bs, cfg->assoc_data_element_tag_select[i], 4); - } - - for (i = 0; i < cfg->num_valid_cc_elements; i++) { - gf_bs_write_int(bs, cfg->cc_element_is_ind_sw[i], 1); - gf_bs_write_int(bs, cfg->valid_cc_element_tag_select[i], 4); - } - gf_bs_align(bs); - gf_bs_write_int(bs, cfg->comment_field_bytes, 8); - gf_bs_write_data(bs, (char *)cfg->comments, cfg->comment_field_bytes); - } - - if ((cfg->base_object_type == 6) || (cfg->base_object_type == 20)) { - gf_bs_write_int(bs, 0, 3); - } - } - break; - } - /*ER cfg - not supported*/ - - /*implicit sbr - not used yet*/ -#if 0 - if ((cfg->base_object_type != 5) && (cfg->base_object_type != 29)) { - gf_bs_write_int(bs, 0x2b7, 11); - cfg->sbr_object_type = gf_bs_read_int(bs, 5); - cfg->has_sbr = gf_bs_read_int(bs, 1); - if (cfg->has_sbr) { - cfg->sbr_sr_index = gf_bs_read_int(bs, 4); - if (cfg->sbr_sr_index == 0x0F) { - cfg->sbr_sr = gf_bs_read_int(bs, 24); - } - else { - cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index]; - } - } - } -#endif - - return GF_OK; -} - -GF_EXPORT -GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, u8 **dsi, u32 *dsi_size) -{ - GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - gf_m4a_write_config_bs(bs, cfg); - gf_bs_get_content(bs, dsi, dsi_size); - gf_bs_del(bs); - return GF_OK; -} - - -/*AV1 parsing*/ - -static u32 av1_read_ns(GF_BitStream *bs, u32 n) -{ - u32 v; - Bool extra_bit; - int w = (u32)(log(n) / log(2)) + 1; - u32 m = (1 << w) - n; - assert(w < 32); - v = gf_bs_read_int(bs, w - 1); - if (v < m) - return v; - extra_bit = gf_bs_read_int(bs, 1); - return (v << 1) - m + extra_bit; -} - -static void av1_color_config(GF_BitStream *bs, AV1State *state) -{ - state->config->high_bitdepth = gf_bs_read_int(bs, 1); - state->bit_depth = 8; - if (state->config->seq_profile == 2 && state->config->high_bitdepth) { - state->config->twelve_bit = gf_bs_read_int(bs, 1); - state->bit_depth = state->config->twelve_bit ? 12 : 10; - } - else if (state->config->seq_profile <= 2) { - state->bit_depth = state->config->high_bitdepth ? 10 : 8; - } - - state->config->monochrome = GF_FALSE; - if (state->config->seq_profile == 1) { - state->config->monochrome = GF_FALSE; - } - else { - state->config->monochrome = gf_bs_read_int(bs, 1); - } - /*NumPlanes = mono_chrome ? 1 : 3;*/ - state->color_description_present_flag = gf_bs_read_int(bs, 1); - if (state->color_description_present_flag) { - state->color_primaries = gf_bs_read_int(bs, 8); - state->transfer_characteristics = gf_bs_read_int(bs, 8); - state->matrix_coefficients = gf_bs_read_int(bs, 8); - } - else { - state->color_primaries = 2/*CP_UNSPECIFIED*/; - state->transfer_characteristics = 2/*TC_UNSPECIFIED*/; - state->matrix_coefficients = 2/*MC_UNSPECIFIED*/; - } - if (state->config->monochrome) { - state->color_range = gf_bs_read_int(bs, 1); - state->config->chroma_subsampling_x = GF_TRUE; - state->config->chroma_subsampling_y = GF_TRUE; - state->config->chroma_sample_position = 0/*CSP_UNKNOWN*/; - state->separate_uv_delta_q = 0; - return; - } - else if (state->color_primaries == 0/*CP_BT_709*/ && - state->transfer_characteristics == 13/*TC_SRGB*/ && - state->matrix_coefficients == 0/*MC_IDENTITY*/) { - state->color_range = GF_TRUE; - state->config->chroma_subsampling_x = GF_FALSE; - state->config->chroma_subsampling_y = GF_FALSE; - } - else { - state->config->chroma_subsampling_x = GF_FALSE; - state->config->chroma_subsampling_y = GF_FALSE; - - state->color_range = gf_bs_read_int(bs, 1); - if (state->config->seq_profile == 0) { - state->config->chroma_subsampling_x = GF_TRUE; - state->config->chroma_subsampling_y = GF_TRUE; - } - else if (state->config->seq_profile == 1) { - state->config->chroma_subsampling_x = GF_FALSE; - state->config->chroma_subsampling_y = GF_FALSE; - } - else { - if (state->bit_depth == 12) { - state->config->chroma_subsampling_x = gf_bs_read_int(bs, 1); - if (state->config->chroma_subsampling_x) - state->config->chroma_subsampling_y = gf_bs_read_int(bs, 1); - else - state->config->chroma_subsampling_y = GF_FALSE; - } - else { - state->config->chroma_subsampling_x = GF_TRUE; - state->config->chroma_subsampling_y = GF_FALSE; - } - } - if (state->config->chroma_subsampling_x && state->config->chroma_subsampling_y) { - state->config->chroma_sample_position = gf_bs_read_int(bs, 2); - } - } - state->separate_uv_delta_q = gf_bs_read_int(bs, 1); -} - - -static u32 uvlc(GF_BitStream *bs) { - u8 leadingZeros = 0; - while (1) { - Bool done = gf_bs_read_int(bs, 1); - if (done) - break; - leadingZeros++; - } - if (leadingZeros >= 32) { - return 0xFFFFFFFF; - } - return gf_bs_read_int(bs, leadingZeros) + (1 << leadingZeros) - 1; -} - -static void timing_info(GF_BitStream *bs, AV1State *state) { - u32 time_scale = 0; - /*num_units_in_display_tick*/ gf_bs_read_int(bs, 32); - time_scale = gf_bs_read_int(bs, 32); - state->equal_picture_interval = gf_bs_read_int(bs, 1); - if (state->equal_picture_interval) { - u32 num_ticks_per_picture_minus_1 = uvlc(bs); - state->tb_num = (num_ticks_per_picture_minus_1 + 1); - state->tb_den = time_scale; - } - else { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] VFR not supported.\n")); - //TODO: upload num_units_in_display_tick (eq. to the POC in H264), compute delta between frames, set it as dts_inc in gf_import_aom_av1() - } -} - -static void decoder_model_info(AV1State *state, GF_BitStream *bs) { - state->buffer_delay_length = 1 + gf_bs_read_int(bs, 5); - /*num_units_in_decoding_tick =*/ gf_bs_read_int(bs, 32); - state->buffer_removal_time_length = gf_bs_read_int(bs, 5); - state->frame_presentation_time_length = 1 + gf_bs_read_int(bs, 5); -} - -static void operating_parameters_info(GF_BitStream *bs, const u8 idx, const u8 buffer_delay_length_minus_1) { - const u8 n = buffer_delay_length_minus_1 + 1; - /*decoder_buffer_delay[op] =*/ gf_bs_read_int(bs, n); - /*encoder_buffer_delay[op] =*/ gf_bs_read_int(bs, n); - /*low_delay_mode_flag[op] =*/ gf_bs_read_int(bs, 1); -} - -static void av1_parse_sequence_header_obu(GF_BitStream *bs, AV1State *state) -{ - u8 buffer_delay_length_minus_1 = 0; - state->frame_state.seen_seq_header = GF_TRUE; - state->config->seq_profile = gf_bs_read_int(bs, 3); - state->still_picture = gf_bs_read_int(bs, 1); - state->reduced_still_picture_header = gf_bs_read_int(bs, 1); - if (state->reduced_still_picture_header) { - //timing_info_present_flag = GF_FALSE; - //initial_display_delay_present_flag = GF_FALSE; - state->operating_points_count = 1; - state->config->seq_level_idx_0 = gf_bs_read_int(bs, 5); - } - else { - u8 i = 0; - Bool initial_display_delay_present_flag; - Bool timing_info_present_flag = gf_bs_read_int(bs, 1); - if (timing_info_present_flag) { - timing_info(bs, state); - state->decoder_model_info_present_flag = gf_bs_read_int(bs, 1); - if (state->decoder_model_info_present_flag) { - decoder_model_info(state, bs); - } - } - else { - state->decoder_model_info_present_flag = GF_FALSE; - } - initial_display_delay_present_flag = gf_bs_read_int(bs, 1); - state->operating_points_count = 1 + gf_bs_read_int(bs, 5); - for (i = 0; i < state->operating_points_count; i++) { - u8 seq_level_idx_i, seq_tier = 0; - - state->operating_point_idc[i] = gf_bs_read_int(bs, 12); - - seq_level_idx_i = gf_bs_read_int(bs, 5); - if (i == 0) state->config->seq_level_idx_0 = seq_level_idx_i; - - if (seq_level_idx_i > 7) { - seq_tier = gf_bs_read_int(bs, 1); - } - if (i == 0) state->config->seq_tier_0 = seq_tier; - - if (state->decoder_model_info_present_flag) { - state->decoder_model_present_for_this_op[i] = gf_bs_read_int(bs, 1); - if (state->decoder_model_present_for_this_op[i]) { - operating_parameters_info(bs, i, buffer_delay_length_minus_1); - } - } - else { - state->decoder_model_present_for_this_op[i] = 0; - } - if (initial_display_delay_present_flag) { - if (gf_bs_read_int(bs, 1) /*initial_display_delay_present_for_this_op[i]*/) { - /*initial_display_delay_minus_1[i] =*/ gf_bs_read_int(bs, 4); - } - } - } - } - - //operatingPoint = av1_choose_operating_point(bs); - state->OperatingPointIdc = 0;//TODO: operating_point_idc[operatingPoint]; - - state->frame_width_bits_minus_1 = gf_bs_read_int(bs, 4); - state->frame_height_bits_minus_1 = gf_bs_read_int(bs, 4); - state->width = gf_bs_read_int(bs, state->frame_width_bits_minus_1 + 1) + 1; - state->height = gf_bs_read_int(bs, state->frame_height_bits_minus_1 + 1) + 1; - state->frame_id_numbers_present_flag = GF_FALSE; - if (!state->reduced_still_picture_header) { - state->frame_id_numbers_present_flag = gf_bs_read_int(bs, 1); - } - if (state->frame_id_numbers_present_flag) { - state->delta_frame_id_length_minus_2 = gf_bs_read_int(bs, 4); - state->additional_frame_id_length_minus_1 = gf_bs_read_int(bs, 3); - } - state->use_128x128_superblock = gf_bs_read_int(bs, 1); - /*enable_filter_intra =*/ gf_bs_read_int(bs, 1); - /*enable_intra_edge_filter =*/ gf_bs_read_int(bs, 1); - if (state->reduced_still_picture_header) { - /*enable_interintra_compound = 0; - enable_masked_compound = 0; - enable_dual_filter = 0; - enable_jnt_comp = 0; - enable_ref_frame_mvs = 0;*/ - state->enable_warped_motion = 0; - state->enable_order_hint = GF_FALSE; - state->OrderHintBits = 0; - state->seq_force_integer_mv = 2/*SELECT_INTEGER_MV*/; - state->seq_force_screen_content_tools = 2/*SELECT_SCREEN_CONTENT_TOOLS*/; - } - else { - Bool seq_choose_screen_content_tools; - /*enable_interintra_compound =*/ gf_bs_read_int(bs, 1); - /*enable_masked_compound =*/ gf_bs_read_int(bs, 1); - state->enable_warped_motion = gf_bs_read_int(bs, 1); - /*enable_dual_filter =*/ gf_bs_read_int(bs, 1); - state->enable_order_hint = gf_bs_read_int(bs, 1); - if (state->enable_order_hint) { - /*enable_jnt_comp =*/ gf_bs_read_int(bs, 1); - state->enable_ref_frame_mvs = gf_bs_read_int(bs, 1); - } - else { - /*enable_jnt_comp = 0*/; - /*enable_ref_frame_mvs = 0*/; - } - seq_choose_screen_content_tools = gf_bs_read_int(bs, 1); - state->seq_force_screen_content_tools = 0; - if (seq_choose_screen_content_tools) { - state->seq_force_screen_content_tools = 2/*SELECT_SCREEN_CONTENT_TOOLS*/; - } - else { - state->seq_force_screen_content_tools = gf_bs_read_int(bs, 1); - } - - state->seq_force_integer_mv = 0; - if (state->seq_force_screen_content_tools > 0) { - const Bool seq_choose_integer_mv = gf_bs_read_int(bs, 1); - if (seq_choose_integer_mv) { - state->seq_force_integer_mv = 2/*SELECT_INTEGER_MV*/; - } - else { - state->seq_force_integer_mv = gf_bs_read_int(bs, 1); - } - } - else { - state->seq_force_integer_mv = 2/*SELECT_INTEGER_MV*/; - } - if (state->enable_order_hint) { - u8 order_hint_bits_minus_1 = gf_bs_read_int(bs, 3); - state->OrderHintBits = order_hint_bits_minus_1 + 1; - } - else { - state->OrderHintBits = 0; - } - } - - state->enable_superres = gf_bs_read_int(bs, 1); - state->enable_cdef = gf_bs_read_int(bs, 1); - state->enable_restoration = gf_bs_read_int(bs, 1); - av1_color_config(bs, state); - state->film_grain_params_present = gf_bs_read_int(bs, 1); -} - - - -#define IVF_FILE_HEADER_SIZE 32 - -Bool gf_media_probe_ivf(GF_BitStream *bs) -{ - u32 dw = 0; - if (gf_bs_available(bs) < IVF_FILE_HEADER_SIZE) return GF_FALSE; - - dw = gf_bs_peek_bits(bs, 32, 0); - if (dw != GF_4CC('D', 'K', 'I', 'F')) { - return GF_FALSE; - } - return GF_TRUE; -} - -GF_Err gf_media_parse_ivf_file_header(GF_BitStream *bs, u32 *width, u32 *height, u32 *codec_fourcc, u32 *frame_rate, u32 *time_scale, u32 *num_frames) -{ - u32 dw = 0; - - if (!width || !height || !codec_fourcc || !frame_rate || !time_scale || !num_frames) { - assert(0); - return GF_BAD_PARAM; - } - - if (gf_bs_available(bs) < IVF_FILE_HEADER_SIZE) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IVF] Not enough bytes available ("LLU").\n", gf_bs_available(bs))); - return GF_NON_COMPLIANT_BITSTREAM; - } - - dw = gf_bs_read_u32(bs); - if (dw != GF_4CC('D', 'K', 'I', 'F')) { - GF_LOG(GF_LOG_INFO, GF_LOG_CODING, ("[IVF] Invalid signature\n")); - return GF_NON_COMPLIANT_BITSTREAM; - } - - dw = gf_bs_read_u16_le(bs); - if (dw != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IVF] Wrong IVF version. 0 expected, got %u\n", dw)); - return GF_NON_COMPLIANT_BITSTREAM; - } - - dw = gf_bs_read_u16_le(bs); //length of header in bytes - if (dw != IVF_FILE_HEADER_SIZE) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IVF] Wrong IVF header length. Expected 32 bytes, got %u\n", dw)); - return GF_NON_COMPLIANT_BITSTREAM; - } - - *codec_fourcc = gf_bs_read_u32(bs); - - *width = gf_bs_read_u16_le(bs); - *height = gf_bs_read_u16_le(bs); - - *frame_rate = gf_bs_read_u32_le(bs); - *time_scale = gf_bs_read_u32_le(bs); - - *num_frames = gf_bs_read_u32_le(bs); - gf_bs_read_u32_le(bs); //skip unused - - return GF_OK; -} - -GF_Err gf_media_parse_ivf_frame_header(GF_BitStream *bs, u64 *frame_size, u64 *pts) -{ - if (!frame_size) return GF_BAD_PARAM; - - *frame_size = gf_bs_read_u32_le(bs); - if (*frame_size > 256 * 1024 * 1024) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[IVF] Wrong frame size %u\n", *frame_size)); - *frame_size = 0; - return GF_NON_COMPLIANT_BITSTREAM; - } - - *pts = gf_bs_read_u64_le(bs); - - return GF_OK; -} - -GF_Err gf_media_vp9_parse_superframe(GF_BitStream *bs, u64 ivf_frame_size, u32 *num_frames_in_superframe, u32 frame_sizes[VP9_MAX_FRAMES_IN_SUPERFRAME], u32 *superframe_index_size) -{ - u32 byte, bytes_per_framesize; - u64 pos = gf_bs_get_position(bs), i = 0; - GF_Err e; - - assert(bs && num_frames_in_superframe); - - /*initialize like there is no superframe*/ - memset(frame_sizes, 0, VP9_MAX_FRAMES_IN_SUPERFRAME * sizeof(frame_sizes[0])); - *num_frames_in_superframe = 1; - frame_sizes[0] = (u32)ivf_frame_size; - *superframe_index_size = 0; - - e = gf_bs_seek(bs, pos + ivf_frame_size - 1); - if (e) return e; - - byte = gf_bs_read_u8(bs); - if ((byte & 0xe0) != 0xc0) - goto exit; /*no superframe*/ - - bytes_per_framesize = 1 + ((byte & 0x18) >> 3); - *num_frames_in_superframe = (u32)(1 + (byte & 0x7)); - - /*superframe_index()*/ - *superframe_index_size = 2 + bytes_per_framesize * *num_frames_in_superframe; - gf_bs_seek(bs, pos + ivf_frame_size - *superframe_index_size); - byte = gf_bs_read_u8(bs); - if ((byte & 0xe0) != 0xc0) - goto exit; /*no superframe*/ - - frame_sizes[0] = 0; - for (i = 0; i < *num_frames_in_superframe; ++i) { - gf_bs_read_data(bs, (char*)(frame_sizes + i), bytes_per_framesize); - } - -exit: - gf_bs_seek(bs, pos); - return e; -} - -static Bool vp9_frame_sync_code(GF_BitStream *bs) -{ - u8 val = gf_bs_read_int(bs, 8); - if (val != 0x49) - return GF_FALSE; - - val = gf_bs_read_int(bs, 8); - if (val != 0x83) - return GF_FALSE; - - val = gf_bs_read_int(bs, 8); - if (val != 0x42) - return GF_FALSE; - - return GF_TRUE; -} - -typedef enum { - CS_UNKNOWN = 0, - CS_BT_601 = 1, - CS_BT_709 = 2, - CS_SMPTE_170 = 3, - CS_SMPTE_240 = 4, - CS_BT_2020 = 5, - CS_RESERVED = 6, - CS_RGB = 7, -} VP9_color_space; - -static const int VP9_CS_to_23001_8_colour_primaries[] = { -1/*undefined*/, 5, 1, 6, 7, 9, -1/*reserved*/, 1 }; -static const int VP9_CS_to_23001_8_transfer_characteristics[] = { -1/*undefined*/, 5, 1, 6, 7, 9, -1/*reserved*/, 13 }; - -static GF_Err vp9_color_config(GF_BitStream *bs, GF_VPConfig *vp9_cfg) -{ - VP9_color_space color_space; - - if (vp9_cfg->profile >= 2) { - Bool ten_or_twelve_bit = gf_bs_read_int(bs, 1); - vp9_cfg->bit_depth = ten_or_twelve_bit ? 12 : 10; - } - else { - vp9_cfg->bit_depth = 8; - } - - color_space = gf_bs_read_int(bs, 3); - vp9_cfg->colour_primaries = VP9_CS_to_23001_8_colour_primaries[color_space]; - vp9_cfg->transfer_characteristics = VP9_CS_to_23001_8_transfer_characteristics[color_space]; - if (color_space != CS_RGB) { - vp9_cfg->video_fullRange_flag = gf_bs_read_int(bs, 1); - if (vp9_cfg->profile == 1 || vp9_cfg->profile == 3) { - u8 subsampling_x, subsampling_y, subsampling_xy_to_chroma_subsampling[2][2] = { {3, 0}, {2, 0} }; - subsampling_x = gf_bs_read_int(bs, 1); - subsampling_y = gf_bs_read_int(bs, 1); - vp9_cfg->chroma_subsampling = subsampling_xy_to_chroma_subsampling[subsampling_x][subsampling_y]; - Bool reserved_zero = gf_bs_read_int(bs, 1); - if (reserved_zero) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VP9] color config reserved zero (1) is not zero.\n")); - return GF_NON_COMPLIANT_BITSTREAM; - } - } - else { - vp9_cfg->chroma_subsampling = 0; - } - } - else { - vp9_cfg->video_fullRange_flag = GF_TRUE; - if (vp9_cfg->profile == 1 || vp9_cfg->profile == 3) { - vp9_cfg->chroma_subsampling = 3; - Bool reserved_zero = gf_bs_read_int(bs, 1); - if (reserved_zero) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VP9] color config reserved zero (2) is not zero.\n")); - return GF_NON_COMPLIANT_BITSTREAM; - } - } - } - - return GF_OK; -} - -static void vp9_compute_image_size(int FrameWidth, int FrameHeight, int *Sb64Cols, int *Sb64Rows) -{ - int MiCols = (FrameWidth + 7) >> 3; - int MiRows = (FrameHeight + 7) >> 3; - *Sb64Cols = (MiCols + 7) >> 3; - *Sb64Rows = (MiRows + 7) >> 3; -} - -static void vp9_frame_size(GF_BitStream *bs, int *FrameWidth, int *FrameHeight, int *Sb64Cols, int *Sb64Rows) -{ - int frame_width_minus_1 = gf_bs_read_int(bs, 16); - int frame_height_minus_1 = gf_bs_read_int(bs, 16); - if (frame_width_minus_1 + 1 != *FrameWidth || frame_height_minus_1 + 1 != *FrameHeight) { - if (*FrameWidth || *FrameHeight) - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[VP9] inconsistent frame dimensions: previous was %dx%d, new one is %dx%d.\n", *FrameWidth, *FrameHeight, frame_width_minus_1 + 1, frame_height_minus_1 + 1)); - } - *FrameWidth = frame_width_minus_1 + 1; - *FrameHeight = frame_height_minus_1 + 1; - vp9_compute_image_size(*FrameWidth, *FrameHeight, Sb64Cols, Sb64Rows); -} - -static void vp9_render_size(GF_BitStream *bs, int FrameWidth, int FrameHeight, int *renderWidth, int *renderHeight) -{ - Bool render_and_frame_size_different = gf_bs_read_int(bs, 1); - if (render_and_frame_size_different == 1) { - int render_width_minus_1 = gf_bs_read_int(bs, 16); - int render_height_minus_1 = gf_bs_read_int(bs, 16); - *renderWidth = render_width_minus_1 + 1; - *renderHeight = render_height_minus_1 + 1; - } - else { - *renderWidth = FrameWidth; - *renderHeight = FrameHeight; - } -} - -static s64 vp9_s(GF_BitStream *bs, int n) { - s64 value = gf_bs_read_int(bs, n); - Bool sign = gf_bs_read_int(bs, 1); - return sign ? -value : value; -} - -static void vp9_loop_filter_params(GF_BitStream *bs) -{ - /*loop_filter_level = */gf_bs_read_int(bs, 6); - /*loop_filter_sharpness = */gf_bs_read_int(bs, 3); - Bool loop_filter_delta_enabled = gf_bs_read_int(bs, 1); - if (loop_filter_delta_enabled == 1) { - Bool loop_filter_delta_update = gf_bs_read_int(bs, 1); - if (loop_filter_delta_update == GF_TRUE) { - int i; - for (i = 0; i < 4; i++) { - Bool update_ref_delta = gf_bs_read_int(bs, 1); - if (update_ref_delta == GF_TRUE) - /*loop_filter_ref_deltas[i] =*/ vp9_s(bs, 6); - } - for (i = 0; i < 2; i++) { - Bool update_mode_delta = gf_bs_read_int(bs, 1); - if (update_mode_delta == GF_TRUE) - /*loop_filter_mode_deltas[i] =*/ vp9_s(bs, 6); - } - } - } -} - -static void vp9_quantization_params(GF_BitStream *bs) -{ - /*base_q_idx = */gf_bs_read_int(bs, 8); -} - -#define VP9_MAX_SEGMENTS 8 -#define VP9_SEG_LVL_MAX 4 -static const int segmentation_feature_bits[VP9_SEG_LVL_MAX] = { 8, 6, 2, 0 }; -static const int segmentation_feature_signed[VP9_SEG_LVL_MAX] = { 1, 1, 0, 0 }; - -#define VP9_MIN_TILE_WIDTH_B64 4 -#define VP9_MAX_TILE_WIDTH_B64 64 - -static void vp9_segmentation_params(GF_BitStream *bs) -{ - Bool segmentation_enabled = gf_bs_read_int(bs, 1); - if (segmentation_enabled == 1) { - int i; - Bool segmentation_update_map = gf_bs_read_int(bs, 1); - if (segmentation_update_map) { - for (i = 0; i < 7; i++) - /*segmentation_tree_probs[i] = read_prob()*/ - /*segmentation_temporal_update = */gf_bs_read_int(bs, 1); - /*for (i = 0; i < 3; i++) - segmentation_pred_prob[i] = segmentation_temporal_update ? read_prob() : 255*/ - } - Bool segmentation_update_data = gf_bs_read_int(bs, 1); - if (segmentation_update_data == 1) { - /*segmentation_abs_or_delta_update =*/ gf_bs_read_int(bs, 1); - for (i = 0; i < VP9_MAX_SEGMENTS; i++) { - int j; - for (j = 0; j < VP9_SEG_LVL_MAX; j++) { - /*feature_value = 0*/ - Bool feature_enabled = gf_bs_read_int(bs, 1); - /*FeatureEnabled[i][j] = feature_enabled*/ - if (feature_enabled) { - int bits_to_read = segmentation_feature_bits[j]; - /*feature_value =*/ gf_bs_read_int(bs, bits_to_read); - if (segmentation_feature_signed[j] == 1) { - /*Bool feature_sign = */gf_bs_read_int(bs, 1); - /*if (feature_sign == 1) - feature_value *= -1*/ - } - } - /*FeatureData[i][j] = feature_value*/ - } - } - } - } -} - -static int calc_min_log2_tile_cols(int Sb64Cols) { - int minLog2 = 0; - while ((VP9_MAX_TILE_WIDTH_B64 << minLog2) < Sb64Cols) - minLog2++; - - return minLog2; -} - -static int calc_max_log2_tile_cols(int Sb64Cols) { - int maxLog2 = 1; - while ((Sb64Cols >> maxLog2) >= VP9_MIN_TILE_WIDTH_B64) - maxLog2++; - - return maxLog2 - 1; -} - -static void vp9_tile_info(GF_BitStream *bs, int Sb64Cols) -{ - Bool tile_rows_log2; - int minLog2TileCols = calc_min_log2_tile_cols(Sb64Cols); - int maxLog2TileCols = calc_max_log2_tile_cols(Sb64Cols); - int tile_cols_log2 = minLog2TileCols; - while (tile_cols_log2 < maxLog2TileCols) { - Bool increment_tile_cols_log2 = gf_bs_read_int(bs, 1); - if (increment_tile_cols_log2) - tile_cols_log2++; - else - break; - } - tile_rows_log2 = gf_bs_read_int(bs, 1); - if (tile_rows_log2) { - /*Bool increment_tile_rows_log2 = */gf_bs_read_int(bs, 1); - //tile_rows_log2 += increment_tile_rows_log2; - } -} - -static void vp9_frame_size_with_refs(GF_BitStream *bs, u8 refresh_frame_flags, u8 * ref_frame_idx, int * RefFrameWidth, int *RefFrameHeight, - int *FrameWidth, int *FrameHeight, int *RenderWidth, int *RenderHeight, int *Sb64Cols, int *Sb64Rows) -{ - Bool found_ref; - int i; - for (i = 0; i < 3; i++) { - found_ref = gf_bs_read_int(bs, 1); - if (found_ref) { - *FrameWidth = RefFrameWidth [ref_frame_idx[i]]; - *FrameHeight = RefFrameHeight[ref_frame_idx[i]]; - break; - } - } - if (found_ref == 0) { - vp9_frame_size(bs, FrameWidth, FrameHeight, Sb64Cols, Sb64Rows); - } - else { - vp9_compute_image_size(*FrameWidth, *FrameHeight, Sb64Cols, Sb64Rows); - } - - vp9_render_size(bs, *FrameWidth, *FrameHeight, RenderWidth, RenderHeight); -} - -static void vp9_read_interpolation_filter(GF_BitStream *bs) -{ - Bool is_filter_switchable = gf_bs_read_int(bs, 1); - if (!is_filter_switchable) { - /*raw_interpolation_filter = */gf_bs_read_int(bs, 2); - } -} - - -#define VP9_KEY_FRAME 0 - -GF_Err gf_media_vp9_parse_sample(GF_BitStream *bs, GF_VPConfig *vp9_cfg, Bool *key_frame, u32 *FrameWidth, u32 *FrameHeight, u32 *renderWidth, u32 *renderHeight) -{ - Bool FrameIsIntra = GF_FALSE, profile_low_bit, profile_high_bit, show_existing_frame = GF_FALSE, frame_type = GF_FALSE, show_frame = GF_FALSE, error_resilient_mode = GF_FALSE; - /*u8 frame_context_idx = 0, reset_frame_context = 0, frame_marker = 0*/; - int Sb64Cols = 0, Sb64Rows = 0, i; - u8 refresh_frame_flags = 0; - - assert(bs && key_frame); - - /*uncompressed header*/ - /*frame_marker = */gf_bs_read_int(bs, 2); - profile_low_bit = gf_bs_read_int(bs, 1); - profile_high_bit = gf_bs_read_int(bs, 1); - vp9_cfg->profile = (profile_high_bit << 1) + profile_low_bit; - if (vp9_cfg->profile == 3) { - Bool reserved_zero = gf_bs_read_int(bs, 1); - if (reserved_zero) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[VP9] uncompressed header reserved zero is not zero.\n")); - return GF_NON_COMPLIANT_BITSTREAM; - } - } - - show_existing_frame = gf_bs_read_int(bs, 1); - if (show_existing_frame == GF_TRUE) { - /*frame_to_show_map_idx = */gf_bs_read_int(bs, 3); - return GF_OK; - } - - frame_type = gf_bs_read_int(bs, 1); - show_frame = gf_bs_read_int(bs, 1); - error_resilient_mode = gf_bs_read_int(bs, 1); - if (frame_type == VP9_KEY_FRAME) { - if (!vp9_frame_sync_code(bs)) - return GF_NON_COMPLIANT_BITSTREAM; - if (vp9_color_config(bs, vp9_cfg) != GF_OK) - return GF_NON_COMPLIANT_BITSTREAM; - vp9_frame_size(bs, FrameWidth, FrameHeight, &Sb64Cols, &Sb64Rows); - vp9_render_size(bs, *FrameWidth, *FrameHeight, renderWidth, renderHeight); - refresh_frame_flags = 0xFF; - *key_frame = GF_TRUE; - FrameIsIntra = GF_TRUE; - } - else { - Bool intra_only = GF_FALSE; - *key_frame = GF_FALSE; - - if (show_frame == GF_FALSE) { - intra_only = gf_bs_read_int(bs, 1); - } - FrameIsIntra = intra_only; - - if (error_resilient_mode == GF_FALSE) { - /*reset_frame_context = */gf_bs_read_int(bs, 2); - } - - if (intra_only == GF_TRUE) { - if (!vp9_frame_sync_code(bs)) - return GF_NON_COMPLIANT_BITSTREAM; - - if (vp9_cfg->profile > 0) { - if (vp9_color_config(bs, vp9_cfg) != GF_OK) - return GF_NON_COMPLIANT_BITSTREAM; - } - else { - u8 color_space = CS_BT_601; - vp9_cfg->colour_primaries = VP9_CS_to_23001_8_colour_primaries[color_space]; - vp9_cfg->transfer_characteristics = VP9_CS_to_23001_8_transfer_characteristics[color_space]; - vp9_cfg->chroma_subsampling = 0; - vp9_cfg->bit_depth = 8; - } - refresh_frame_flags = gf_bs_read_int(bs, 8); - vp9_frame_size(bs, FrameWidth, FrameHeight, &Sb64Cols, &Sb64Rows); - vp9_render_size(bs, *FrameWidth, *FrameHeight, renderWidth, renderHeight); - } - else { - refresh_frame_flags = gf_bs_read_int(bs, 8); - u8 ref_frame_idx[3]; - for (i = 0; i < 3; i++) { - ref_frame_idx[i] = gf_bs_read_int(bs, 3); - /*ref_frame_sign_bias[LAST_FRAME + i] = */gf_bs_read_int(bs, 1); - } - vp9_frame_size_with_refs(bs, refresh_frame_flags, ref_frame_idx, vp9_cfg->RefFrameWidth, vp9_cfg->RefFrameHeight, FrameWidth, FrameHeight, renderWidth, renderHeight, &Sb64Cols, &Sb64Rows); - /*allow_high_precision_mv = */gf_bs_read_int(bs, 1); - vp9_read_interpolation_filter(bs); - } - } - - if (error_resilient_mode == 0) { - /*refresh_frame_context = */gf_bs_read_int(bs, 1); - /*frame_parallel_decoding_mode = */gf_bs_read_int(bs, 1); - } - - /*frame_context_idx = */gf_bs_read_int(bs, 2); - if (FrameIsIntra || error_resilient_mode) { - /*setup_past_independence + save_probs ...*/ - //frame_context_idx = 0; - } - - vp9_loop_filter_params(bs); - vp9_quantization_params(bs); - vp9_segmentation_params(bs); - vp9_tile_info(bs, Sb64Cols); - - /*header_size_in_bytes = */gf_bs_read_int(bs, 16); - - /*Reference frame update process (8.10 - partial)*/ - for (i = 0; i < VP9_NUM_REF_FRAMES; i++) { - if ((refresh_frame_flags >> i) & 1) { - vp9_cfg->RefFrameWidth[i] = *FrameWidth; - vp9_cfg->RefFrameHeight[i] = *FrameHeight; - } - } - - return GF_OK; -} - -GF_Err gf_av1_parse_obu_header(GF_BitStream *bs, ObuType *obu_type, Bool *obu_extension_flag, Bool *obu_has_size_field, u8 *temporal_id, u8 *spatial_id) -{ - Bool forbidden = gf_bs_read_int(bs, 1); - if (forbidden) { - return GF_NON_COMPLIANT_BITSTREAM; - } - - *obu_type = gf_bs_read_int(bs, 4); - *obu_extension_flag = gf_bs_read_int(bs, 1); - *obu_has_size_field = gf_bs_read_int(bs, 1); - if (gf_bs_read_int(bs, 1) /*obu_reserved_1bit*/) { - return GF_NON_COMPLIANT_BITSTREAM; - } - if (*obu_extension_flag) { - *temporal_id = gf_bs_read_int(bs, 3); - *spatial_id = gf_bs_read_int(bs, 2); - /*extension_header_reserved_3bits = */gf_bs_read_int(bs, 3); - } - - return GF_OK; -} - -#endif // GPAC_DISABLE_AV_PARSERS - -GF_EXPORT -const char *gf_av1_get_obu_name(ObuType obu_type) -{ - switch (obu_type) { - case OBU_SEQUENCE_HEADER: return "seq_header"; - case OBU_TEMPORAL_DELIMITER: return "delimiter"; - case OBU_FRAME_HEADER: return "frame_header"; - case OBU_TILE_GROUP: return "tile_group"; - case OBU_METADATA: return "metadata"; - case OBU_FRAME: return "frame"; - case OBU_REDUNDANT_FRAME_HEADER: return "redundant_frame_header"; - case OBU_TILE_LIST: return "tile_list"; - case OBU_PADDING: return "padding"; - case OBU_RESERVED_0: - case OBU_RESERVED_9: - case OBU_RESERVED_10: - case OBU_RESERVED_11: - case OBU_RESERVED_12: - case OBU_RESERVED_13: - case OBU_RESERVED_14: - return "reserved"; - default: return "unknown"; - } -} - -Bool av1_is_obu_header(ObuType obu_type) { - switch (obu_type) { - case OBU_SEQUENCE_HEADER: - case OBU_METADATA: - // TODO add check based on the metadata type - return GF_TRUE; - default: - return GF_FALSE; - } -} - -#ifndef GPAC_DISABLE_AV_PARSERS - -static Bool av1_is_obu_frame(AV1State *state, ObuType obu_type) -{ - switch (obu_type) { - case OBU_PADDING: - case OBU_REDUNDANT_FRAME_HEADER: - return GF_FALSE; - case OBU_TEMPORAL_DELIMITER: - return state->keep_temporal_delim ? GF_TRUE : GF_FALSE; - default: - return GF_TRUE; - } -} - -u64 gf_av1_leb128_read(GF_BitStream *bs, u8 *opt_Leb128Bytes) { - u64 value = 0; - u8 Leb128Bytes = 0, i = 0; - for (i = 0; i < 8; i++) { - u8 leb128_byte = gf_bs_read_u8(bs); - value |= ( ((u64) (leb128_byte & 0x7f)) << (i * 7)); - Leb128Bytes += 1; - if (!(leb128_byte & 0x80)) { - break; - } - } - - if (opt_Leb128Bytes) { - *opt_Leb128Bytes = Leb128Bytes; - } - return value; -} - -u32 gf_av1_leb128_size(u64 value) -{ - u32 gf_av1_leb128_size = 0; - do { - ++gf_av1_leb128_size; - } while ((value >>= 7) != 0); - - return gf_av1_leb128_size; -} - -u64 gf_av1_leb128_write(GF_BitStream *bs, u64 value) -{ - u32 i, leb_size = gf_av1_leb128_size(value); - for (i = 0; i < leb_size; ++i) { - u8 byte = value & 0x7f; - value >>= 7; - if (value != 0) byte |= 0x80; //more bytes follow - gf_bs_write_u8(bs, byte); - } - - return leb_size; -} - -#define OBU_BLOCK_SIZE 4096 -static void av1_add_obu_internal(GF_BitStream *bs, u64 pos, u64 obu_length, ObuType obu_type, GF_List **obu_list, AV1State *state) -{ - char block[OBU_BLOCK_SIZE]; - Bool has_size_field = 0, obu_extension_flag = 0; - u8 temporal_id, spatial_id; - GF_AV1_OBUArrayEntry *a = NULL; - - if (state && state->mem_mode) { - if (!state->bs) state->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - else gf_bs_reassign_buffer(state->bs, state->frame_obus, state->frame_obus_alloc); - } - else { - GF_SAFEALLOC(a, GF_AV1_OBUArrayEntry); - if (!a) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[AV1] Failed to allocate OBU\n")); - return; - } - } - - gf_bs_seek(bs, pos); - gf_av1_parse_obu_header(bs, &obu_type, &obu_extension_flag, &has_size_field, &temporal_id, &spatial_id); - gf_bs_seek(bs, pos); - - if (has_size_field) { - if (a) { - a->obu = gf_malloc((size_t)obu_length); - gf_bs_read_data(bs, a->obu, (u32)obu_length); - a->obu_length = obu_length; - } - else { - u32 remain = (u32)obu_length; - while (remain) { - u32 block_size = OBU_BLOCK_SIZE; - if (block_size > remain) block_size = remain; - gf_bs_read_data(bs, block, block_size); - gf_bs_write_data(state->bs, block, block_size); - remain -= block_size; - } - return; - } - } - else { - u8 i, hdr_size = obu_extension_flag ? 2 : 1; - const u32 leb_size = (u32)gf_av1_leb128_size(obu_length); - const u64 obu_size = obu_length - hdr_size; - - if (a) { - a->obu = gf_malloc((size_t)obu_length + leb_size); - a->obu_length = obu_length + leb_size; - for (i = 0; i < hdr_size; ++i) { - a->obu[i] = gf_bs_read_u8(bs); - /*add size field flag*/ - if (i == 0) a->obu[0] |= 0x02; - } - { - u32 out_size = 0; - u8 *output = NULL; - GF_BitStream *bsLeb128 = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - /*write size field*/ - gf_av1_leb128_write(bsLeb128, obu_size); - assert(gf_bs_get_position(bsLeb128) == leb_size); - gf_bs_get_content(bsLeb128, &output, &out_size); - gf_bs_del(bsLeb128); - memcpy(a->obu + hdr_size, output, out_size); - gf_free(output); - } - gf_bs_read_data(bs, a->obu + hdr_size + leb_size, (u32)(obu_size)); - assert(gf_bs_get_position(bs) == pos + obu_length); - } - else { - u32 remain; - for (i = 0; i < hdr_size; ++i) { - u8 hdr_b = gf_bs_read_u8(bs); - if (i == 0) hdr_b |= 0x02; /*add size field flag*/ - gf_bs_write_u8(state->bs, hdr_b); - } - /*add size field */ - gf_av1_leb128_write(state->bs, obu_size); - remain = (u32)obu_length - hdr_size; - while (remain) { - u32 block_size = OBU_BLOCK_SIZE; - if (block_size > remain) block_size = remain; - gf_bs_read_data(bs, block, block_size); - gf_bs_write_data(state->bs, block, block_size); - remain -= block_size; - } - assert(gf_bs_get_position(bs) == pos + obu_length); - return; - } - } - if (!obu_list) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[AV1] internal error, no OBU list cannot add\n")); - gf_free(a->obu); - gf_free(a); - return; - } - a->obu_type = obu_type; - if (! *obu_list) - *obu_list = gf_list_new(); - gf_list_add(*obu_list, a); -} - -static void av1_populate_state_from_obu(GF_BitStream *bs, u64 pos, u64 obu_length, ObuType obu_type, AV1State *state) -{ - if (av1_is_obu_header(obu_type)) { - av1_add_obu_internal(bs, pos, obu_length, obu_type, &state->frame_state.header_obus, NULL); - } - if (!state->skip_frames && av1_is_obu_frame(state, obu_type)) { - if (!state->mem_mode) { - av1_add_obu_internal(bs, pos, obu_length, obu_type, &state->frame_state.frame_obus, NULL); - } - else { - av1_add_obu_internal(bs, pos, obu_length, obu_type, NULL, state); - } - } -} - -GF_Err aom_av1_parse_temporal_unit_from_section5(GF_BitStream *bs, AV1State *state) -{ - if (!state) return GF_BAD_PARAM; - state->obu_type = -1; - - while (state->obu_type != OBU_TEMPORAL_DELIMITER) { - GF_Err e; - if (!gf_bs_available(bs)) - return state->unframed ? GF_BUFFER_TOO_SMALL : GF_OK; - - u64 pos = gf_bs_get_position(bs), obu_length = 0; - - e = gf_media_aom_av1_parse_obu(bs, &state->obu_type, &obu_length, NULL, state); - if (e) - return e; - - if (obu_length != gf_bs_get_position(bs) - pos) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[AV1] OBU (Section 5) frame size "LLU" different from consumed bytes "LLU".\n", obu_length, gf_bs_get_position(bs) - pos)); - return GF_NON_COMPLIANT_BITSTREAM; - } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] Section5 OBU detected (size "LLU")\n", obu_length)); - av1_populate_state_from_obu(bs, pos, obu_length, state->obu_type, state); - } - - return GF_OK; -} - -Bool gf_media_aom_probe_annexb(GF_BitStream *bs) -{ - Bool res = GF_TRUE; - u64 init_pos = gf_bs_get_position(bs); - u64 sz = gf_av1_leb128_read(bs, NULL); - if (!sz) res = GF_FALSE; - while (sz > 0) { - u8 Leb128Bytes = 0; - u64 frame_unit_size = gf_av1_leb128_read(bs, &Leb128Bytes); - - if (!frame_unit_size) { - res = GF_FALSE; - break; - } - - if (sz < Leb128Bytes + frame_unit_size) { - res = GF_FALSE; - break; - } - sz -= Leb128Bytes + frame_unit_size; - - while (frame_unit_size > 0) { - ObuType obu_type; - u64 pos, obu_length = gf_av1_leb128_read(bs, &Leb128Bytes); - if (frame_unit_size < Leb128Bytes + obu_length) { - res = GF_FALSE; - break; - } - pos = gf_bs_get_position(bs); - frame_unit_size -= Leb128Bytes; - - u8 tid, sid; - Bool extflag, has_size; - GF_Err e = gf_av1_parse_obu_header(bs, &obu_type, &extflag, &has_size, &tid, &sid); - if (e) { - res = GF_FALSE; - break; - } - - if (has_size) { - obu_length = (u32)gf_av1_leb128_read(bs, NULL); - } - else { - if (obu_length >= 1 + extflag) { - obu_length = obu_length - 1 - extflag; - } - else { - res = GF_FALSE; - break; - } - } - u32 hdr_size = (u32)(gf_bs_get_position(bs) - pos); - obu_length += hdr_size; - - if (frame_unit_size < obu_length) { - res = GF_FALSE; - break; - } - frame_unit_size -= obu_length; - gf_bs_skip_bytes(bs, obu_length - hdr_size); - } - if (!res) break; - } - gf_bs_seek(bs, init_pos); - return res; -} - -GF_Err aom_av1_parse_temporal_unit_from_annexb(GF_BitStream *bs, AV1State *state) -{ - GF_Err e; - u64 tupos; - u64 tusize, sz; - if (!bs || !state) return GF_BAD_PARAM; - - state->bs_overread = GF_FALSE; - tusize = sz = gf_av1_leb128_read(bs, NULL); - tupos = gf_bs_get_position(bs); - if (!sz) { - GF_LOG(GF_LOG_INFO, GF_LOG_CODING, ("[AV1] temporal unit size is 0, likely not annex B\n")); - return GF_NON_COMPLIANT_BITSTREAM; - } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] Annex B temporal unit detected (size "LLU") ***** \n", sz)); - while (sz > 0) { - u8 Leb128Bytes = 0; - u64 frame_unit_size = gf_av1_leb128_read(bs, &Leb128Bytes); - - if (state->bs_overread) { - return GF_BUFFER_TOO_SMALL; - } - if (sz < Leb128Bytes + frame_unit_size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] Annex B sz("LLU") < Leb128Bytes("LLU") + frame_unit_size("LLU")\n", sz, Leb128Bytes, frame_unit_size)); - return GF_NON_COMPLIANT_BITSTREAM; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] Annex B frame unit detected (size "LLU")\n", frame_unit_size)); - sz -= Leb128Bytes + frame_unit_size; - - while (frame_unit_size > 0) { - u64 pos, obu_length = gf_av1_leb128_read(bs, &Leb128Bytes); - - if (state->bs_overread) { - return GF_BUFFER_TOO_SMALL; - } - if (frame_unit_size < Leb128Bytes + obu_length) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] Annex B frame_unit_size("LLU") < Leb128Bytes("LLU") + obu_length("LLU")\n", frame_unit_size, Leb128Bytes, obu_length)); - return GF_NON_COMPLIANT_BITSTREAM; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] Annex B OBU detected (size "LLU")\n", obu_length)); - pos = gf_bs_get_position(bs); - frame_unit_size -= Leb128Bytes; - - e = gf_media_aom_av1_parse_obu(bs, &state->obu_type, &obu_length, NULL, state); - if (e) return e; - - if (obu_length != gf_bs_get_position(bs) - pos) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[AV1] Annex B frame size "LLU" different from consumed bytes "LLU".\n", obu_length, gf_bs_get_position(bs) - pos)); - return GF_NON_COMPLIANT_BITSTREAM; - } - - av1_populate_state_from_obu(bs, pos, obu_length, state->obu_type, state); - if (frame_unit_size < obu_length) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] Annex B frame_unit_size("LLU") < OBU size ("LLU")\n", frame_unit_size, obu_length)); - return GF_NON_COMPLIANT_BITSTREAM; - } - frame_unit_size -= obu_length; - } - } - assert(sz == 0); - if (tusize != gf_bs_get_position(bs) - tupos) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[AV1] Annex B TU size "LLU" different from consumed bytes "LLU".\n", tusize, gf_bs_get_position(bs) - tupos)); - return GF_NON_COMPLIANT_BITSTREAM; - } - return GF_OK; -} - -GF_Err aom_av1_parse_temporal_unit_from_ivf(GF_BitStream *bs, AV1State *state) -{ - u64 frame_size, pts_ignored; - GF_Err e; - if (gf_bs_available(bs)<12) return GF_EOS; - e = gf_media_parse_ivf_frame_header(bs, &frame_size, &pts_ignored); - if (e) return e; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[AV1] IVF frame detected (size "LLU")\n", frame_size)); - - if (gf_bs_available(bs) < frame_size) return GF_EOS; - - while (frame_size > 0) { - u64 obu_size = 0, pos = gf_bs_get_position(bs); - - e = gf_media_aom_av1_parse_obu(bs, &state->obu_type, &obu_size, NULL, state); - if (e != GF_OK) - return e; - - if (obu_size != gf_bs_get_position(bs) - pos) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[AV1] IVF frame size "LLU" different from consumed bytes "LLU".\n", obu_size, gf_bs_get_position(bs) - pos)); - return GF_NON_COMPLIANT_BITSTREAM; - } - - av1_populate_state_from_obu(bs, pos, obu_size, state->obu_type, state); - - frame_size -= obu_size; - } - return GF_OK; -} - -#define AV1_NUM_REF_FRAMES 8 -#define AV1_ALL_FRAMES ((1 << AV1_NUM_REF_FRAMES) - 1) - -#define AV1_SUPERRES_DENOM_MIN 9 -#define AV1_SUPERRES_DENOM_BITS 3 -#define AV1_SUPERRES_NUM 8 - -#define AV1_REFS_PER_FRAME 7 -#define AV1_PRIMARY_REF_NONE 7 - -#define MAX_TILE_WIDTH 4096 -#define MAX_TILE_AREA (4096 * 2304) - -static u32 aom_av1_tile_log2(u32 blkSize, u32 target) -{ - u32 k; - for (k = 0; (blkSize << k) < target; k++) { - } - return k; -} - -static u64 aom_av1_le(GF_BitStream *bs, u32 n) { - u32 i = 0; - u64 t = 0; - for (i = 0; i < n; i++) { - u8 byte = gf_bs_read_int(bs, 8); - t += (byte << (i * 8)); - } - return t; -} - - -static void av1_parse_tile_info(GF_BitStream *bs, AV1State *state) -{ - u32 i; - u32 MiCols = 2 * ((state->width + 7) >> 3); - u32 MiRows = 2 * ((state->height + 7) >> 3); - u32 sbCols = state->use_128x128_superblock ? ((MiCols + 31) >> 5) : ((MiCols + 15) >> 4); - u32 sbRows = state->use_128x128_superblock ? ((MiRows + 31) >> 5) : ((MiRows + 15) >> 4); - u32 sbShift = state->use_128x128_superblock ? 5 : 4; - u32 sbSize = sbShift + 2; - u32 maxTileWidthSb = MAX_TILE_WIDTH >> sbSize; - u32 maxTileAreaSb = MAX_TILE_AREA >> (2 * sbSize); - u32 minLog2tileCols = aom_av1_tile_log2(maxTileWidthSb, sbCols); - u32 maxLog2tileCols = aom_av1_tile_log2(1, MIN(sbCols, AV1_MAX_TILE_COLS)); - u32 maxLog2tileRows = aom_av1_tile_log2(1, MIN(sbRows, AV1_MAX_TILE_ROWS)); - u32 minLog2Tiles = MAX(minLog2tileCols, aom_av1_tile_log2(maxTileAreaSb, sbRows * sbCols)); - Bool uniform_tile_spacing_flag = gf_bs_read_int(bs, 1); - if (uniform_tile_spacing_flag) { - u32 startSb, tileWidthSb, tileHeightSb, minLog2tileRows; - state->tileColsLog2 = minLog2tileCols; - while (state->tileColsLog2 < maxLog2tileCols) { - Bool increment_tile_cols_log2 = gf_bs_read_int(bs, 1); - if (increment_tile_cols_log2 == 1) - state->tileColsLog2++; - else - break; - } - - tileWidthSb = (sbCols + (1 << state->tileColsLog2) - 1) >> state->tileColsLog2; - i = 0; - for (startSb = 0; startSb < sbCols; startSb += tileWidthSb) { - i += 1; - } - state->tileCols = i; - minLog2tileRows = MAX((int)(minLog2Tiles - state->tileColsLog2), 0); - state->tileRowsLog2 = minLog2tileRows; - while (state->tileRowsLog2 < maxLog2tileRows) { - Bool increment_tile_rows_log2 = gf_bs_read_int(bs, 1); - if (increment_tile_rows_log2 == 1) - state->tileRowsLog2++; - else - break; - } - - tileHeightSb = (sbRows + (1 << state->tileRowsLog2) - 1) >> state->tileRowsLog2; - i = 0; - for (startSb = 0; startSb < sbRows; startSb += tileHeightSb) { - i += 1; - } - state->tileRows = i; - } - else { - u32 startSb, maxTileHeightSb, widestTileSb; - widestTileSb = 0; - startSb = 0; - for (i = 0; startSb < sbCols; i++) { - u32 maxWidth = MIN((int)(sbCols - startSb), maxTileWidthSb); - u32 width_in_sbs_minus_1 = av1_read_ns(bs, maxWidth); - u32 sizeSb = width_in_sbs_minus_1 + 1; - widestTileSb = MAX(sizeSb, widestTileSb); - startSb += sizeSb; - } - if (!widestTileSb) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] widest tile is 0, broken bitstream\n")); - return; - } - state->tileCols = i; - state->tileColsLog2 = aom_av1_tile_log2(1, state->tileCols); - - if (minLog2Tiles > 0) - maxTileAreaSb = (sbRows * sbCols) >> (minLog2Tiles + 1); - else - maxTileAreaSb = sbRows * sbCols; - maxTileHeightSb = MAX(maxTileAreaSb / widestTileSb, 1); - - startSb = 0; - for (i = 0; startSb < sbRows; i++) { - u32 maxHeight = MIN((int)(sbRows - startSb), maxTileHeightSb); - u32 height_in_sbs_minus_1 = av1_read_ns(bs, maxHeight); - u32 sizeSb = height_in_sbs_minus_1 + 1; - startSb += sizeSb; - } - - state->tileRows = i; - state->tileRowsLog2 = aom_av1_tile_log2(1, state->tileRows); - } - if (state->tileColsLog2 > 0 || state->tileRowsLog2 > 0) { - /*context_update_tile_id = */gf_bs_read_int(bs, state->tileRowsLog2 + state->tileColsLog2); - state->tile_size_bytes = gf_bs_read_int(bs, 2) + 1; - } -} - -static void superres_params(GF_BitStream *bs, AV1State *state) -{ - u32 SuperresDenom; - Bool use_superres; - - if (state->enable_superres) { - use_superres = gf_bs_read_int(bs, 1); - } - else { - use_superres = GF_FALSE; - } - if (use_superres) { - u8 coded_denom = gf_bs_read_int(bs, AV1_SUPERRES_DENOM_BITS); - SuperresDenom = coded_denom + AV1_SUPERRES_DENOM_MIN; - } - else { - SuperresDenom = AV1_SUPERRES_NUM; - } - state->UpscaledWidth = state->width; - state->width = (state->UpscaledWidth * AV1_SUPERRES_NUM + (SuperresDenom / 2)) / SuperresDenom; -} - -static void av1_frame_size(GF_BitStream *bs, AV1State *state, Bool frame_size_override_flag) -{ - if (frame_size_override_flag) { - u32 frame_width_minus_1, frame_height_minus_1; - u8 n = state->frame_width_bits_minus_1 + 1; - frame_width_minus_1 = gf_bs_read_int(bs, n); - n = state->frame_height_bits_minus_1 + 1; - frame_height_minus_1 = gf_bs_read_int(bs, n); - state->width = frame_width_minus_1 + 1; - state->height = frame_height_minus_1 + 1; - } - superres_params(bs, state); - //compute_image_size(); //no bits -} - -static void av1_render_size(GF_BitStream *bs) -{ - Bool render_and_frame_size_different = gf_bs_read_int(bs, 1); - if (render_and_frame_size_different == GF_TRUE) { - /*render_width_minus_1 =*/ gf_bs_read_int(bs, 16); - /*render_height_minus_1 =*/ gf_bs_read_int(bs, 16); - //RenderWidth = render_width_minus_1 + 1; - //RenderHeight = render_height_minus_1 + 1; - } - else { - //RenderWidth = UpscaledWidth; - //RenderHeight = FrameHeight; - } -} - -static void read_interpolation_filter(GF_BitStream *bs) -{ - Bool is_filter_switchable = gf_bs_read_int(bs, 1); - if (!is_filter_switchable) { - /*interpolation_filter =*/ gf_bs_read_int(bs, 2); - } -} - -static void frame_size_with_refs(GF_BitStream *bs, AV1State *state, Bool frame_size_override_flag) -{ - Bool found_ref = GF_FALSE; - u32 i = 0; - for (i = 0; i < AV1_REFS_PER_FRAME; i++) { - found_ref = gf_bs_read_int(bs, 1); - if (found_ref == 1) { -#if 0 - UpscaledWidth = RefUpscaledWidth[ref_frame_idx[i]]; - FrameWidth = UpscaledWidth; - FrameHeight = RefFrameHeight[ref_frame_idx[i]]; - RenderWidth = RefRenderWidth[ref_frame_idx[i]]; - RenderHeight = RefRenderHeight[ref_frame_idx[i]]; -#endif - break; - } - } - if (found_ref == 0) { - av1_frame_size(bs, state, frame_size_override_flag); - av1_render_size(bs); - } - else { - superres_params(bs, state); - //compute_image_size(); - } -} - -static s32 av1_delta_q(GF_BitStream *bs) -{ - Bool delta_coded = gf_bs_read_int(bs, 1); - s32 delta_q = 0; - if (delta_coded) { - u32 signMask = 1 << (7 - 1); - delta_q = gf_bs_read_int(bs, 7); - if (delta_q & signMask) - delta_q = delta_q - 2 * signMask; - } - return delta_q; -} - -static u8 Segmentation_Feature_Bits[] = { 8,6,6,6,6,3,0,0 }; -static u8 Segmentation_Feature_Signed[] = { 1, 1, 1, 1, 1, 0, 0, 0 }; - -static u8 av1_get_qindex(Bool ignoreDeltaQ, u32 segmentId, u32 base_q_idx, u32 delta_q_present, u32 CurrentQIndex, Bool segmentation_enabled, u8 *features_SEG_LVL_ALT_Q_enabled, s32 *features_SEG_LVL_ALT_Q) -{ - //If seg_feature_active_idx( segmentId, SEG_LVL_ALT_Q ) is equal to 1 the following ordered steps apply: - if (segmentation_enabled && features_SEG_LVL_ALT_Q_enabled[segmentId]) { - //Set the variable data equal to FeatureData[ segmentId ][ SEG_LVL_ALT_Q ]. - s32 data = features_SEG_LVL_ALT_Q[segmentId]; - s32 qindex = base_q_idx + data; - //If ignoreDeltaQ is equal to 0 and delta_q_present is equal to 1, set qindex equal to CurrentQIndex + data. - if ((ignoreDeltaQ == 0) && (delta_q_present == 1)) qindex = CurrentQIndex + data; - //Return Clip3( 0, 255, qindex ). - if (qindex < 0) return 0; - else if (qindex > 255) return 255; - else return (u8)qindex; - } - //Otherwise, if ignoreDeltaQ is equal to 0 and delta_q_present is equal to 1, return CurrentQIndex. - if ((ignoreDeltaQ == 0) && (delta_q_present == 1)) return CurrentQIndex; - //otherwise - return base_q_idx; -} - -enum { - AV1_RESTORE_NONE = 0, - AV1_RESTORE_SWITCHABLE, - AV1_RESTORE_WIENER, - AV1_RESTORE_SGRPROJ -}; - -#define AV1_GMC_IDENTITY 0 -#define AV1_GMC_TRANSLATION 1 -#define AV1_GMC_ROTZOOM 2 -#define AV1_GMC_AFFINE 3 - -#define AV1_LAST_FRAME 1 -#define AV1_LAST2_FRAME 2 -#define AV1_LAST3_FRAME 3 -#define AV1_GOLDEN_FRAME 4 -#define AV1_BWDREF_FRAME 5 -#define AV1_ALTREF2_FRAME 6 -#define AV1_ALTREF_FRAME 7 - -#define GM_ABS_ALPHA_BITS 12 -#define GM_ALPHA_PREC_BITS 15 -#define GM_ABS_TRANS_ONLY_BITS 9 -#define GM_TRANS_ONLY_PREC_BITS 3 -#define GM_ABS_TRANS_BITS 12 -#define GM_TRANS_PREC_BITS 6 -#define WARPEDMODEL_PREC_BITS 16 - - -static u32 av1_decode_subexp(GF_BitStream *bs, s32 numSyms) -{ - s32 i = 0; - s32 mk = 0; - s32 k = 3; - while (1) { - s32 b2 = i ? k + i - 1 : k; - s32 a = 1 << b2; - if (numSyms <= mk + 3 * a) { - s32 subexp_final_bits = av1_read_ns(bs, numSyms - mk); - return subexp_final_bits + mk; - } - else { - s32 subexp_more_bits = gf_bs_read_int(bs, 1); - if (subexp_more_bits) { - i++; - mk += a; - } - else { - s32 subexp_bits = gf_bs_read_int(bs, b2); - return subexp_bits + mk; - } - } - } -} - -static GFINLINE s32 inverse_recenter(s32 r, u32 v) -{ - if ((s64)v > (s64)(2 * r)) - return v; - else if (v & 1) - return r - ((v + 1) >> 1); - else - return r + (v >> 1); -} - -static s32 av1_decode_unsigned_subexp_with_ref(GF_BitStream *bs, s32 mx, s32 r) -{ - u32 v = av1_decode_subexp(bs, mx); - if ((r < 0) && (-(-r << 1) <= mx)) { - return inverse_recenter(r, v); - } - else if ((r << 1) <= mx) { - return inverse_recenter(r, v); - } - else { - return mx - 1 - inverse_recenter(mx - 1 - r, v); - } -} -static s16 av1_decode_signed_subexp_with_ref(GF_BitStream *bs, s32 low, s32 high, s32 r) -{ - s16 x = av1_decode_unsigned_subexp_with_ref(bs, high - low, r - low); - return x + low; -} - -static void av1_read_global_param(AV1State *state, GF_BitStream *bs, u8 type, u8 ref, u8 idx) -{ - u8 absBits = GM_ABS_ALPHA_BITS; - u8 precBits = GM_ALPHA_PREC_BITS; - if (idx < 2) { - if (type == AV1_GMC_TRANSLATION) { - absBits = GM_ABS_TRANS_ONLY_BITS - (!state->frame_state.allow_high_precision_mv ? 1 : 0); - precBits = GM_TRANS_ONLY_PREC_BITS - (!state->frame_state.allow_high_precision_mv ? 1 : 0); - } - else { - absBits = GM_ABS_TRANS_BITS; - precBits = GM_TRANS_PREC_BITS; - } - } - s32 precDiff = WARPEDMODEL_PREC_BITS - precBits; - s32 round = (idx % 3) == 2 ? (1 << WARPEDMODEL_PREC_BITS) : 0; - s32 sub = (idx % 3) == 2 ? (1 << precBits) : 0; - s32 mx = (1 << absBits); - s32 r = (state->PrevGmParams.coefs[ref][idx] >> precDiff) - sub; - s32 val = av1_decode_signed_subexp_with_ref(bs, -mx, mx + 1, r); - - if (val < 0) { - val = -val; - state->GmParams.coefs[ref][idx] = (-(val << precDiff) + round); - } - else { - state->GmParams.coefs[ref][idx] = (val << precDiff) + round; - } -} - -static s32 av1_get_relative_dist(s32 a, s32 b, AV1State *state) -{ - if (!state->enable_order_hint) - return 0; - s32 diff = a - b; - s32 m = 1 << (state->OrderHintBits - 1); - diff = (diff & (m - 1)) - (diff & m); - return diff; -} - -static void av1_setup_past_independence(AV1State *state) -{ - u32 ref, i; - for (ref = AV1_LAST_FRAME; ref <= AV1_ALTREF_FRAME; ref++) { - for (i = 0; i <= 5; i++) { - state->PrevGmParams.coefs[ref][i] = ((i % 3 == 2) ? 1 << WARPEDMODEL_PREC_BITS : 0); - } - } -} - -static void av1_load_previous(AV1State *state, u8 primary_ref_frame, s8 *ref_frame_idx) -{ - s8 prevFrame = ref_frame_idx[primary_ref_frame]; - if (prevFrame < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] load_previous: prevFrame reference index %d is invalid\n", prevFrame)); - } - else { - state->PrevGmParams = state->SavedGmParams[prevFrame]; - // load_loop_filter_params( prevFrame ) - // load_segmentation_params( prevFrame ) - } -} - -static void av1_decode_frame_wrapup(AV1State *state) -{ - u32 i; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - if ((state->frame_state.refresh_frame_flags >> i) & 1) { - state->RefOrderHint[i] = state->frame_state.order_hint; - state->SavedGmParams[i] = state->GmParams; - state->RefFrameType[i] = state->frame_state.frame_type; - } - } - state->frame_state.seen_frame_header = GF_FALSE; - //Otherwise (show_existing_frame is equal to 1), if frame_type is equal to KEY_FRAME, the reference frame loading process as specified in section 7.21 is invoked - if ((state->frame_state.show_existing_frame) && (state->frame_state.frame_type == AV1_KEY_FRAME)) { - state->frame_state.order_hint = state->RefOrderHint[state->frame_state.frame_to_show_map_idx]; - //OrderHints[ j + LAST_FRAME ] is set equal to SavedOrderHints[state->frame_to_show_map_idx ][ j + LAST_FRAME ] for j = 0..REFS_PER_FRAME-1. - - //gm_params[ ref ][ j ] is set equal to SavedGmParams[ frame_to_show_map_idx ][ ref ][ j ] for ref = LAST_FRAME..ALTREF_FRAME, for j = 0..5. - state->GmParams = state->SavedGmParams[state->frame_state.frame_to_show_map_idx]; - - } -} - -static s32 find_latest_forward(u32 curFrameHint, u8 *shiftedOrderHints, u8 *usedFrame) -{ - u32 i; - s32 ref = -1; - s32 latestOrderHint = 0; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - s32 hint = shiftedOrderHints[i]; - if (!usedFrame[i] && ((u32)hint < curFrameHint) && (ref < 0 || hint >= latestOrderHint)) { - ref = i; - latestOrderHint = hint; - } - } - return ref; -} - -//see 7.8 of AV1 spec -static void av1_set_frame_refs(AV1State *state, u8 last_frame_idx, u8 gold_frame_idx, s8 *ref_frame_idx) -{ - u32 i; - u8 usedFrame[AV1_NUM_REF_FRAMES]; - u8 shiftedOrderHints[AV1_NUM_REF_FRAMES]; - - for (i = 0; i < AV1_REFS_PER_FRAME; i++) - ref_frame_idx[i] = -1; - - ref_frame_idx[AV1_LAST_FRAME - AV1_LAST_FRAME] = last_frame_idx; - ref_frame_idx[AV1_GOLDEN_FRAME - AV1_LAST_FRAME] = gold_frame_idx; - - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - usedFrame[i] = 0; - } - - usedFrame[last_frame_idx] = 1; - usedFrame[gold_frame_idx] = 1; - u32 curFrameHint = 1 << (state->OrderHintBits - 1); - - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - shiftedOrderHints[i] = curFrameHint + av1_get_relative_dist(state->RefOrderHint[i], state->frame_state.order_hint, state); - } - - u8 lastOrderHint = shiftedOrderHints[last_frame_idx]; - u8 goldOrderHint = shiftedOrderHints[gold_frame_idx]; - - //It is a requirement of bitstream conformance that lastOrderHint is strictly less than curFrameHint. - if (lastOrderHint >= curFrameHint) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] non conformant bitstream detected while setting up frame refs: lastOrderHint(%d) shall be stricly less than curFrameHint(%d)\n", lastOrderHint, curFrameHint)); - } - //It is a requirement of bitstream conformance that goldOrderHint is strictly less than curFrameHint. - if (goldOrderHint >= curFrameHint) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] non conformant bitstream detected while setting up frame refs: goldOrderHint(%d) shall be stricly less than curFrameHint(%d)\n", lastOrderHint, curFrameHint)); - } - - //find_latest_backward() { - s32 ref = -1; - s32 latestOrderHint = 0; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - s32 hint = shiftedOrderHints[i]; - if (!usedFrame[i] && ((u32)hint >= curFrameHint) && (ref < 0 || hint >= latestOrderHint)) { - ref = i; - latestOrderHint = hint; - } - } - if (ref >= 0) { - ref_frame_idx[AV1_ALTREF_FRAME - AV1_LAST_FRAME] = ref; - usedFrame[ref] = 1; - } - //find_earliest_backward() for BWDREF_FRAME - ref = -1; - s32 earliestOrderHint = 0; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - s32 hint = shiftedOrderHints[i]; - if (!usedFrame[i] && ((u32)hint >= curFrameHint) && (ref < 0 || hint < earliestOrderHint)) { - ref = i; - earliestOrderHint = hint; - } - } - if (ref >= 0) { - ref_frame_idx[AV1_BWDREF_FRAME - AV1_LAST_FRAME] = ref; - usedFrame[ref] = 1; - } - - //find_earliest_backward() for ALTREF2_FRAME - ref = -1; - earliestOrderHint = 0; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - s32 hint = shiftedOrderHints[i]; - if (!usedFrame[i] && ((u32)hint >= curFrameHint) && (ref < 0 || hint < earliestOrderHint)) { - ref = i; - earliestOrderHint = hint; - } - } - if (ref >= 0) { - ref_frame_idx[AV1_ALTREF2_FRAME - AV1_LAST_FRAME] = ref; - usedFrame[ref] = 1; - } - - //The remaining references are set to be forward references in anti-chronological order as follows: - - const u8 Ref_Frame_List[AV1_REFS_PER_FRAME - 2] = { - AV1_LAST2_FRAME, AV1_LAST3_FRAME, AV1_BWDREF_FRAME, AV1_ALTREF2_FRAME, AV1_ALTREF_FRAME - }; - - for (i = 0; i < AV1_REFS_PER_FRAME - 2; i++) { - u8 refFrame = Ref_Frame_List[i]; - if (ref_frame_idx[refFrame - AV1_LAST_FRAME] < 0) { - s32 last_ref = find_latest_forward(curFrameHint, shiftedOrderHints, usedFrame); - if (last_ref >= 0) { - ref_frame_idx[refFrame - AV1_LAST_FRAME] = last_ref; - usedFrame[last_ref] = 1; - } - } - } - //Finally, any remaining references are set to the reference frame with smallest output order as follows: - ref = -1; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - s32 hint = shiftedOrderHints[i]; - if (ref < 0 || hint < earliestOrderHint) { - ref = i; - earliestOrderHint = hint; - } - } - for (i = 0; i < AV1_REFS_PER_FRAME; i++) { - if (ref_frame_idx[i] < 0) { - ref_frame_idx[i] = ref; - } - } -} - - -static void av1_parse_uncompressed_header(GF_BitStream *bs, AV1State *state) -{ - Bool error_resilient_mode = GF_FALSE, allow_screen_content_tools = GF_FALSE, force_integer_mv = GF_FALSE; - Bool /*use_ref_frame_mvs = GF_FALSE,*/ FrameIsIntra = GF_FALSE, frame_size_override_flag = GF_FALSE; - Bool disable_cdf_update = GF_FALSE; - u8 showable_frame; - u8 primary_ref_frame; - u16 idLen = 0; - u32 idx; - s8 ref_frame_idx[AV1_REFS_PER_FRAME]; - AV1StateFrame *frame_state = &state->frame_state; - - if (state->frame_id_numbers_present_flag) { - idLen = (state->additional_frame_id_length_minus_1 + state->delta_frame_id_length_minus_2 + 3); - } - frame_state->refresh_frame_flags = 0; - - showable_frame = 0; - if (state->reduced_still_picture_header) { - frame_state->key_frame = GF_TRUE; - FrameIsIntra = GF_TRUE; - frame_state->frame_type = AV1_KEY_FRAME; - frame_state->show_frame = GF_TRUE; - frame_state->show_existing_frame = 0; - } - else { - frame_state->show_existing_frame = gf_bs_read_int(bs, 1); - if (frame_state->show_existing_frame == GF_TRUE) { - frame_state->frame_to_show_map_idx = gf_bs_read_int(bs, 3); - frame_state->frame_type = state->RefFrameType[frame_state->frame_to_show_map_idx]; - - if (state->decoder_model_info_present_flag && !state->equal_picture_interval) { - /*frame_presentation_time = */gf_bs_read_int(bs, state->frame_presentation_time_length); - } - - frame_state->refresh_frame_flags = 0; - if (state->frame_id_numbers_present_flag) { - /*display_frame_id = */gf_bs_read_int(bs, idLen); - } - if (frame_state->frame_type == AV1_KEY_FRAME) { - frame_state->refresh_frame_flags = AV1_ALL_FRAMES; - } - /* - if (film_grain_params_present) { - load_grain_params(frame_to_show_map_idx) - }*/ - return; - } - frame_state->frame_type = gf_bs_read_int(bs, 2); - FrameIsIntra = (frame_state->frame_type == AV1_INTRA_ONLY_FRAME || frame_state->frame_type == AV1_KEY_FRAME); - frame_state->show_frame = gf_bs_read_int(bs, 1); - if (frame_state->is_first_frame) { - frame_state->key_frame = frame_state->seen_seq_header && frame_state->show_frame && frame_state->frame_type == AV1_KEY_FRAME && frame_state->seen_frame_header; - } - if (frame_state->show_frame && state->decoder_model_info_present_flag && !state->equal_picture_interval) { - /*frame_presentation_time = */gf_bs_read_int(bs, state->frame_presentation_time_length); - } - if (frame_state->show_frame) { - showable_frame = frame_state->frame_type != AV1_KEY_FRAME; - - } - else { - showable_frame = gf_bs_read_int(bs, 1); - } - if (frame_state->frame_type == AV1_SWITCH_FRAME || (frame_state->frame_type == AV1_KEY_FRAME && frame_state->show_frame)) - error_resilient_mode = GF_TRUE; - else - error_resilient_mode = gf_bs_read_int(bs, 1); - } - - if ((frame_state->frame_type == AV1_KEY_FRAME) && frame_state->show_frame) { - u32 i; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - state->RefValid[i] = 0; - state->RefOrderHint[i] = 0; - } - for (i = 0; i < AV1_REFS_PER_FRAME; i++) { - state->OrderHints[AV1_LAST_FRAME + i] = 0; - } - } - - disable_cdf_update = gf_bs_read_int(bs, 1); - if (state->seq_force_screen_content_tools == 2/*SELECT_SCREEN_CONTENT_TOOLS*/) { - allow_screen_content_tools = gf_bs_read_int(bs, 1); - } - else { - allow_screen_content_tools = state->seq_force_screen_content_tools; - } - if (allow_screen_content_tools) { - if (state->seq_force_integer_mv == 2/*SELECT_INTEGER_MV*/) { - force_integer_mv = gf_bs_read_int(bs, 1); - } - else { - force_integer_mv = state->seq_force_integer_mv; - } - } - else { - force_integer_mv = 0; - } - if (FrameIsIntra) { - force_integer_mv = 1; - } - if (state->frame_id_numbers_present_flag) { - /*current_frame_id = */gf_bs_read_int(bs, idLen); - } - if (frame_state->frame_type == AV1_SWITCH_FRAME) - frame_size_override_flag = GF_TRUE; - else if (state->reduced_still_picture_header) - frame_size_override_flag = GF_FALSE; - else - frame_size_override_flag = gf_bs_read_int(bs, 1); - - frame_state->order_hint = gf_bs_read_int(bs, state->OrderHintBits); - if (FrameIsIntra || error_resilient_mode) { - primary_ref_frame = AV1_PRIMARY_REF_NONE; - } - else { - primary_ref_frame = gf_bs_read_int(bs, 3); - } - - if (state->decoder_model_info_present_flag) { - u8 buffer_removal_time_present_flag = gf_bs_read_int(bs, 1); - if (buffer_removal_time_present_flag) { - u32 opNum; - for (opNum = 0; opNum < state->operating_points_count; opNum++) { - if (state->decoder_model_present_for_this_op[opNum]) { - u8 opPtIdc = state->operating_point_idc[opNum]; - u8 inTemporalLayer = (opPtIdc >> state->temporal_id) & 1; - u8 inSpatialLayer = (opPtIdc >> (state->spatial_id + 8)) & 1; - if (opPtIdc == 0 || (inTemporalLayer && inSpatialLayer)) { - /*buffer_removal_time[opNum] = */gf_bs_read_int(bs, state->buffer_removal_time_length); - } - } - } - } - } - - if (frame_state->frame_type == AV1_SWITCH_FRAME || (frame_state->frame_type == AV1_KEY_FRAME && frame_state->show_frame)) { - frame_state->refresh_frame_flags = AV1_ALL_FRAMES; - } - else { - frame_state->refresh_frame_flags = gf_bs_read_int(bs, 8); - } - if (!FrameIsIntra || frame_state->refresh_frame_flags != AV1_ALL_FRAMES) { - if (error_resilient_mode && state->enable_order_hint) { - u32 i = 0; - for (i = 0; i < AV1_NUM_REF_FRAMES; i++) { - u8 ref_order_hint = gf_bs_read_int(bs, state->OrderHintBits); - if (ref_order_hint != state->RefOrderHint[i]) { - state->RefValid[i] = 0; - } - state->RefOrderHint[i] = ref_order_hint; - } - } - } - - u8 allow_intrabc = 0; - if (frame_state->frame_type == AV1_KEY_FRAME) { - av1_frame_size(bs, state, frame_size_override_flag); - av1_render_size(bs); - if (allow_screen_content_tools && state->UpscaledWidth == state->width) { - allow_intrabc = gf_bs_read_int(bs, 1); - } - } - else { - if (frame_state->frame_type == AV1_INTRA_ONLY_FRAME) { - av1_frame_size(bs, state, frame_size_override_flag); - av1_render_size(bs); - if (allow_screen_content_tools && state->UpscaledWidth == state->width) { - allow_intrabc = gf_bs_read_int(bs, 1); - } - } - else { - u32 i = 0; - Bool frame_refs_short_signaling = GF_FALSE; - if (state->enable_order_hint) { - frame_refs_short_signaling = gf_bs_read_int(bs, 1); - if (frame_refs_short_signaling) { - u8 last_frame_idx = gf_bs_read_int(bs, 3); - u8 gold_frame_idx = gf_bs_read_int(bs, 3); - av1_set_frame_refs(state, last_frame_idx, gold_frame_idx, ref_frame_idx); - } - } - for (i = 0; i < AV1_REFS_PER_FRAME; i++) { - if (!frame_refs_short_signaling) - ref_frame_idx[i] = gf_bs_read_int(bs, 3); - - if (state->frame_id_numbers_present_flag) { - u32 n = state->delta_frame_id_length_minus_2 + 2; - /*delta_frame_id_minus_1 =*/ gf_bs_read_int(bs, n); - //DeltaFrameId = delta_frame_id_minus_1 + 1; - //expectedFrameId[i] = ((current_frame_id + (1 << idLen) - DeltaFrameId) % (1 << idLen)); - } - } - if (frame_size_override_flag && !error_resilient_mode) { - frame_size_with_refs(bs, state, frame_size_override_flag); - } - else { - av1_frame_size(bs, state, frame_size_override_flag); - av1_render_size(bs); - } - frame_state->allow_high_precision_mv = 0; - if (!force_integer_mv) { - frame_state->allow_high_precision_mv = gf_bs_read_int(bs, 1); - } - - read_interpolation_filter(bs); - - /*is_motion_mode_switchable =*/ gf_bs_read_int(bs, 1); - if (!(error_resilient_mode || !state->enable_ref_frame_mvs)) { - /*use_ref_frame_mvs = */gf_bs_read_int(bs, 1); - } - } - } - - if (!FrameIsIntra) { - u32 i; - for (i = 0; i < AV1_REFS_PER_FRAME; i++) { - u8 refFrame = AV1_LAST_FRAME + i; - u8 ridx = ref_frame_idx[i]; - if (ridx >= 0) { - u8 hint = state->RefOrderHint[ridx]; - state->OrderHints[refFrame] = hint; - /* if ( !enable_order_hint ) { - RefFrameSignBias[ refFrame ] = 0; - } else { - RefFrameSignBias[ refFrame ] = get_relative_dist( hint, OrderHint) > 0; - } - */ - } - - } - } - - if (!(state->reduced_still_picture_header || disable_cdf_update)) - /*disable_frame_end_update_cdf = */gf_bs_read_int(bs, 1); - - if (primary_ref_frame == AV1_PRIMARY_REF_NONE) { - //init_non_coeff_cdfs(); - av1_setup_past_independence(state); - } - else { - //load_cdfs(ref_frame_idx[primary_ref_frame]); - av1_load_previous(state, primary_ref_frame, ref_frame_idx); - } - - av1_parse_tile_info(bs, state); - //quantization_params( ): - u8 base_q_idx = gf_bs_read_int(bs, 8); - s32 DeltaQUDc = 0; - s32 DeltaQUAc = 0; - s32 DeltaQVDc = 0; - s32 DeltaQVAc = 0; - s32 DeltaQYDc = av1_delta_q(bs); - if (!state->config->monochrome) { - u8 diff_uv_delta = 0; - if (state->separate_uv_delta_q) - diff_uv_delta = gf_bs_read_int(bs, 1); - - DeltaQUDc = av1_delta_q(bs); - DeltaQUAc = av1_delta_q(bs); - if (diff_uv_delta) { - DeltaQVDc = av1_delta_q(bs); - DeltaQVAc = av1_delta_q(bs); - } - } - if (/*using_qmatrix*/gf_bs_read_int(bs, 1)) { - /*qm_y = */gf_bs_read_int(bs, 4); - /*qm_y = */gf_bs_read_int(bs, 4); - if (!state->separate_uv_delta_q) { - /*qm_v = */gf_bs_read_int(bs, 4); - } - } - - u8 seg_features_SEG_LVL_ALT_Q_enabled[8] = { 0,0,0,0,0,0,0,0 }; - s32 seg_features_SEG_LVL_ALT_Q[8] = { 0,0,0,0,0,0,0,0 }; - - //segmentation_params( ): - u8 segmentation_enabled = gf_bs_read_int(bs, 1); - if (segmentation_enabled) { - /*u8 segmentation_temporal_update = 0;*/ - u8 segmentation_update_data = 1; - if (primary_ref_frame != AV1_PRIMARY_REF_NONE) { - u8 segmentation_update_map = gf_bs_read_int(bs, 1); - if (segmentation_update_map == 1) - /*segmentation_temporal_update = */gf_bs_read_int(bs, 1); - segmentation_update_data = gf_bs_read_int(bs, 1); - } - if (segmentation_update_data == 1) { - u32 i, j; - for (i = 0; i < 8/*=MAX_SEGMENTS*/; i++) { - for (j = 0; j < 8 /*=SEG_LVL_MAX*/; j++) { - if (/*feature_enabled = */gf_bs_read_int(bs, 1) == 1) { - s32 val; - u32 bitsToRead = Segmentation_Feature_Bits[j]; - //this is SEG_LVL_ALT_Q - if (!j) seg_features_SEG_LVL_ALT_Q_enabled[i] = 1; - - if (Segmentation_Feature_Signed[j] == 1) { - val = gf_bs_read_int(bs, 1 + bitsToRead); - } - else { - val = gf_bs_read_int(bs, bitsToRead); - } - if (!j) seg_features_SEG_LVL_ALT_Q[i] = val; - } - } - } - //ignore all init steps - } - - } - - //delta_q_params(): - /*u8 delta_q_res = 0;*/ - u8 delta_q_present = 0; - if (base_q_idx > 0) { - delta_q_present = gf_bs_read_int(bs, 1); - } - if (delta_q_present) { - /*delta_q_res = */gf_bs_read_int(bs, 2); - } - - //delta_lf_params(): - u8 delta_lf_present = 0; - /*u8 delta_lf_res = 0; - u8 delta_lf_multi = 0;*/ - if (delta_q_present) { - if (!allow_intrabc) { - delta_lf_present = gf_bs_read_int(bs, 1); - } - if (delta_lf_present) { - /*delta_lf_res = */gf_bs_read_int(bs, 2); - /*delta_lf_multi = */gf_bs_read_int(bs, 1); - } - } - - //init lossless stuff! - u8 CodedLossless = 1; - for (idx = 0; idx < 8; idx++) { - u8 qindex = av1_get_qindex(GF_TRUE, idx, base_q_idx, delta_q_present, 0/*CurrentQIndex always ignored at this level of parsin*/, segmentation_enabled, seg_features_SEG_LVL_ALT_Q_enabled, seg_features_SEG_LVL_ALT_Q); - Bool LosslessArray = (qindex == 0) && (DeltaQYDc == 0) && (DeltaQUAc == 0) && (DeltaQUDc == 0) && (DeltaQVAc == 0) && (DeltaQVDc == 0); - if (!LosslessArray) - CodedLossless = 0; - } - Bool AllLossless = CodedLossless && (state->width == state->UpscaledWidth); - - //loop_filter_params(): - if (!CodedLossless && !allow_intrabc) { - u8 loop_filter_level_0 = gf_bs_read_int(bs, 6); - u8 loop_filter_level_1 = gf_bs_read_int(bs, 6); - if (!state->config->monochrome) { - if (loop_filter_level_0 || loop_filter_level_1) { - /*u8 loop_filter_level_2 = */gf_bs_read_int(bs, 6); - /*u8 loop_filter_level_3 = */gf_bs_read_int(bs, 6); - } - } - /*u8 loop_filter_sharpness = */gf_bs_read_int(bs, 3); - u8 loop_filter_delta_enabled = gf_bs_read_int(bs, 1); - if (loop_filter_delta_enabled == 1) { - u8 loop_filter_delta_update = gf_bs_read_int(bs, 1); - if (loop_filter_delta_update) { - u32 i; - for (i = 0; i < 8/*TOTAL_REFS_PER_FRAME*/; i++) { - u8 update_ref_delta = gf_bs_read_int(bs, 1); - if (update_ref_delta == 1) { - /*u8 loop_filter_ref_deltas_i = */gf_bs_read_int(bs, 1 + 6); - } - } - for (i = 0; i < 2; i++) { - u8 update_mode_delta = gf_bs_read_int(bs, 1); - if (update_mode_delta) { - /*u8 loop_filter_mode_deltas_i = */gf_bs_read_int(bs, 1 + 6); - } - } - } - } - } - //cdef_params( ): - if (!CodedLossless && !allow_intrabc && state->enable_cdef) { - /*u8 cdef_damping_minus_3 = */gf_bs_read_int(bs, 2); - u8 cdef_bits = gf_bs_read_int(bs, 2); - u32 i, num_cd = 1 << cdef_bits; - for (i = 0; i < num_cd; i++) { - /*u8 cdef_y_pri_strength_i = */gf_bs_read_int(bs, 4); - /*u8 cdef_y_sec_strength_i = */gf_bs_read_int(bs, 2); - if (!state->config->monochrome) { - /*u8 cdef_uv_pri_strength_i = */gf_bs_read_int(bs, 4); - /*u8 cdef_uv_sec_strength_i = */gf_bs_read_int(bs, 2); - } - } - } - - //lr_params( ) : - if (!AllLossless && !allow_intrabc && state->enable_restoration) { - u32 i, nb_planes = state->config->monochrome ? 1 : 3; - u8 UsesLr = 0; - u8 usesChromaLr = 0; - for (i = 0; i < nb_planes; i++) { - u8 lr_type = gf_bs_read_int(bs, 2); - //FrameRestorationType[i] = Remap_Lr_Type[lr_type] - if (lr_type != AV1_RESTORE_NONE) { - UsesLr = 1; - if (i > 0) { - usesChromaLr = 1; - } - } - } - if (UsesLr) { - if (state->use_128x128_superblock) { - /*u8 lr_unit_shift_minus_1 = */gf_bs_read_int(bs, 1); - } - else { - u8 lr_unit_shift = gf_bs_read_int(bs, 1); - if (lr_unit_shift) { - /*u8 lr_unit_extra_shift = */gf_bs_read_int(bs, 1); - //lr_unit_shift += lr_unit_extra_shift; - } - } - if (state->config->chroma_subsampling_x && state->config->chroma_subsampling_y && usesChromaLr) { - /*u8 lr_uv_shift = */gf_bs_read_int(bs, 1); - } - } - } - //read_tx_mode(): - if (CodedLossless == 1) { - } - else { - /*tx_mode_select = */gf_bs_read_int(bs, 1); - } - - //frame_reference_mode( ): - u8 reference_select = 0; - if (FrameIsIntra) { - } - else { - reference_select = gf_bs_read_int(bs, 1); - } - - //skip_mode_params( ): - u8 skipModeAllowed = 0; - if (FrameIsIntra || !reference_select || !state->enable_order_hint) { - } - else { - u32 i; - s32 forwardIdx = -1; - s32 backwardIdx = -1; - s32 forwardHint = 0; - s32 backwardHint = 0; - for (i = 0; i < AV1_REFS_PER_FRAME; i++) { - u8 refHint = state->RefOrderHint[ref_frame_idx[i]]; - if (av1_get_relative_dist(refHint, frame_state->order_hint, state) < 0) { - if (forwardIdx < 0 || av1_get_relative_dist(refHint, forwardHint, state) > 0) { - forwardIdx = i; - forwardHint = refHint; - } - } - else if (av1_get_relative_dist(refHint, frame_state->order_hint, state) > 0) { - if (backwardIdx < 0 || av1_get_relative_dist(refHint, backwardHint, state) < 0) { - backwardIdx = i; - backwardHint = refHint; - } - } - } - if (forwardIdx < 0) { - skipModeAllowed = 0; - } - else if (backwardIdx >= 0) { - skipModeAllowed = 1; - //SkipModeFrame[0] = AV1_LAST_FRAME + MIN(forwardIdx, backwardIdx); - //SkipModeFrame[1] = AV1_LAST_FRAME + MAX(forwardIdx, backwardIdx); - } - else { - s32 secondForwardIdx = -1; - s32 secondForwardHint = 0; - for (i = 0; i < AV1_REFS_PER_FRAME; i++) { - u8 refHint = state->RefOrderHint[ref_frame_idx[i]]; - if (av1_get_relative_dist(refHint, forwardHint, state) < 0) { - if (secondForwardIdx < 0 || av1_get_relative_dist(refHint, secondForwardHint, state) > 0) { - secondForwardIdx = i; - secondForwardHint = refHint; - } - } - } - if (secondForwardIdx < 0) { - skipModeAllowed = 0; - } - else { - skipModeAllowed = 1; - //SkipModeFrame[ 0 ] = LAST_FRAME + Min(forwardIdx, secondForwardIdx) - //SkipModeFrame[ 1 ] = LAST_FRAME + Max(forwardIdx, secondForwardIdx) - } - } - } - if (skipModeAllowed) { - /*skip_mode_present = */gf_bs_read_int(bs, 1); - } - - - if (FrameIsIntra || error_resilient_mode || !state->enable_warped_motion) { - - } - else { - /*allow_warped_motion = */gf_bs_read_int(bs, 1); - } - - /*reduced_tx = */gf_bs_read_int(bs, 1); - - //global_motion_params( ) - u32 ref; - for (ref = AV1_LAST_FRAME; ref <= AV1_ALTREF_FRAME; ref++) { - u32 i; - for (i = 0; i < 6; i++) { - state->GmParams.coefs[ref][i] = ((i % 3 == 2) ? 1 << WARPEDMODEL_PREC_BITS : 0); - } - } - if (!FrameIsIntra) { - u32 refs; - for (refs = AV1_LAST_FRAME; refs <= AV1_ALTREF_FRAME; refs++) { - u8 type = AV1_GMC_IDENTITY; - Bool is_global = gf_bs_read_int(bs, 1); - if (is_global) { - Bool is_rot_zoom = gf_bs_read_int(bs, 1); - if (is_rot_zoom) { - type = AV1_GMC_ROTZOOM; - } - else { - Bool is_trans = gf_bs_read_int(bs, 1); - type = is_trans ? AV1_GMC_TRANSLATION : AV1_GMC_AFFINE; - - } - } - - if (type >= AV1_GMC_ROTZOOM) { - av1_read_global_param(state, bs, type, refs, 2); - av1_read_global_param(state, bs, type, refs, 3); - if (type == AV1_GMC_AFFINE) { - av1_read_global_param(state, bs, type, refs, 4); - av1_read_global_param(state, bs, type, refs, 5); - } - else { - state->GmParams.coefs[refs][4] = -state->GmParams.coefs[refs][3]; - state->GmParams.coefs[refs][5] = state->GmParams.coefs[refs][2]; - - } - } - if (type >= AV1_GMC_TRANSLATION) { - av1_read_global_param(state, bs, type, refs, 0); - av1_read_global_param(state, bs, type, refs, 1); - } - } - } - - //film_grain_params() - if (!state->film_grain_params_present || (!state->frame_state.show_frame && !showable_frame)) { - } - else { - u8 apply_grain = gf_bs_read_int(bs, 1); - if (apply_grain) { - /*u8 grain_seed = */gf_bs_read_int(bs, 16); - u8 update_grain = 1; - if (state->frame_state.frame_type == AV1_INTER_FRAME) { - update_grain = gf_bs_read_int(bs, 1); - } - if (!update_grain) { - /*u8 film_grain_params_ref_idx = */gf_bs_read_int(bs, 3); - } - else { - u32 i, num_y_points = gf_bs_read_int(bs, 4); - for (i = 0; i < num_y_points; i++) { - /*u8 point_y_value = */gf_bs_read_int(bs, 8); - /*u8 point_y_scaling = */gf_bs_read_int(bs, 8); - } - u8 chroma_scaling_from_luma = 0; - if (!state->config->monochrome) chroma_scaling_from_luma = gf_bs_read_int(bs, 1); - - u8 num_cb_points = 0; - u8 num_cr_points = 0; - if (state->config->monochrome || chroma_scaling_from_luma || - ((state->config->chroma_subsampling_x == 1) && (state->config->chroma_subsampling_y == 1) && (num_y_points == 0)) - ) { - } - else { - num_cb_points = gf_bs_read_int(bs, 4); - for (i = 0; i < num_cb_points; i++) { - /*point_cb_value[ i ] = */gf_bs_read_int(bs, 8); - /*point_cb_scaling[ i ] = */gf_bs_read_int(bs, 8); - } - num_cr_points = gf_bs_read_int(bs, 4); - for (i = 0; i < num_cr_points; i++) { - /*point_cb_value[ i ] = */gf_bs_read_int(bs, 8); - /*point_cb_scaling[ i ] = */gf_bs_read_int(bs, 8); - } - } - /*u8 grain_scaling_minus_8 = */gf_bs_read_int(bs, 2); - u8 ar_coeff_lag = gf_bs_read_int(bs, 2); - u16 numPosLuma = 2 * ar_coeff_lag * (ar_coeff_lag + 1); - u16 numPosChroma = numPosLuma; - if (num_y_points) { - numPosChroma = numPosLuma + 1; - for (i = 0; i < numPosLuma; i++) { - /*ar_coeffs_y_plus_128[ i ] = */gf_bs_read_int(bs, 8); - } - } - if (chroma_scaling_from_luma || num_cb_points) { - for (i = 0; i < numPosChroma; i++) { - /*ar_coeffs_cb_plus_128[ i ] =*/gf_bs_read_int(bs, 8); - } - } - if (chroma_scaling_from_luma || num_cr_points) { - for (i = 0; i < numPosChroma; i++) { - /*ar_coeffs_cr_plus_128[ i ] =*/gf_bs_read_int(bs, 8); - } - } - /*u8 ar_coeff_shift_minus_6 = */gf_bs_read_int(bs, 2); - /*u8 grain_scale_shift = */gf_bs_read_int(bs, 2); - if (num_cb_points) { - /*u8 cb_mult = */gf_bs_read_int(bs, 8); - /*u8 cb_luma_mult = */gf_bs_read_int(bs, 8); - /*u8 cb_offset = */gf_bs_read_int(bs, 9); - } - if (num_cr_points) { - /*u8 cr_mult = */gf_bs_read_int(bs, 8); - /*u8 cr_luma_mult = */gf_bs_read_int(bs, 8); - /*u8 cr_offset = */gf_bs_read_int(bs, 9); - } - /*u8 overlap_flag = */gf_bs_read_int(bs, 1); - /*u8 clip_to_restricted_range = */gf_bs_read_int(bs, 1); - } - } - } - - //end of uncompressed header !! -} - -GF_EXPORT -void gf_av1_init_state(AV1State *state) -{ - if (!state) return; - memset(state, 0, sizeof(AV1State)); - state->color_primaries = 2; - state->transfer_characteristics = 2; - state->matrix_coefficients = 2; -} - -GF_EXPORT -void gf_av1_reset_state(AV1State *state, Bool is_destroy) -{ - GF_List *l1, *l2; - - if (state->frame_state.header_obus) { - while (gf_list_count(state->frame_state.header_obus)) { - GF_AV1_OBUArrayEntry *a = (GF_AV1_OBUArrayEntry*)gf_list_pop_back(state->frame_state.header_obus); - if (a->obu) gf_free(a->obu); - gf_free(a); - } - } - - if (state->frame_state.frame_obus) { - while (gf_list_count(state->frame_state.frame_obus)) { - GF_AV1_OBUArrayEntry *a = (GF_AV1_OBUArrayEntry*)gf_list_pop_back(state->frame_state.frame_obus); - if (a->obu) gf_free(a->obu); - gf_free(a); - } - } - l1 = state->frame_state.frame_obus; - l2 = state->frame_state.header_obus; - memset(&state->frame_state, 0, sizeof(AV1StateFrame)); - state->frame_state.is_first_frame = GF_TRUE; - - if (is_destroy) { - gf_list_del(l1); - gf_list_del(l2); - if (state->bs) { - if (gf_bs_get_position(state->bs)) { - u32 size; - gf_bs_get_content_no_truncate(state->bs, &state->frame_obus, &size, &state->frame_obus_alloc); - } - gf_bs_del(state->bs); - } - state->bs = NULL; - } - else { - state->frame_state.frame_obus = l1; - state->frame_state.header_obus = l2; - if (state->bs) - gf_bs_seek(state->bs, 0); - } -} - -static GF_Err av1_parse_tile_group(GF_BitStream *bs, AV1State *state, u64 obu_start, u64 obu_size) -{ - u32 TileNum, tg_start = 0, tg_end = 0; - Bool numTiles = state->tileCols * state->tileRows; - Bool tile_start_and_end_present_flag = GF_FALSE; - GF_Err e = GF_OK; - if (numTiles > 1) - tile_start_and_end_present_flag = gf_bs_read_int(bs, 1); - - if (numTiles == 1 || !tile_start_and_end_present_flag) { - tg_start = 0; - tg_end = numTiles - 1; - /*state->frame_state.tg[0].start_idx = 0; - state->frame_state.tg[0].end_idx = numTiles - 1;*/ - } - else { - u32 tileBits = state->tileColsLog2 + state->tileRowsLog2; - /*state->frame_state.tg[state->frame_state.tg_idx].start_idx*/ tg_start = gf_bs_read_int(bs, tileBits); - /*state->frame_state.tg[state->frame_state.tg_idx].end_idx*/ tg_end = gf_bs_read_int(bs, tileBits); - } - /*state->frame_state.tg_idx++;*/ - - gf_bs_align(bs); - - if (tg_end >= GF_ARRAY_LENGTH(state->frame_state.tiles)) - return GF_NON_COMPLIANT_BITSTREAM; - - state->frame_state.nb_tiles_in_obu = 0; - for (TileNum = tg_start; TileNum <= tg_end; TileNum++) { - u32 tile_start_offset, tile_size; - /*u32 tileRow = TileNum / state->tileCols; - u32 tileCol = TileNum % state->tileCols;*/ - Bool lastTile = TileNum == tg_end; - u64 pos = gf_bs_get_position(bs); - if (lastTile) { - tile_start_offset = (u32)(pos - obu_start); - tile_size = (u32)(obu_size - (pos - obu_start)); - } - else { - u64 tile_size_minus_1 = aom_av1_le(bs, state->tile_size_bytes); - pos = gf_bs_get_position(bs); - tile_start_offset = (u32)(pos - obu_start); - tile_size = (u32)(tile_size_minus_1 + 1/* + state->tile_size_bytes*/); - } - - - if (tile_start_offset + tile_size > obu_size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AV1] Error parsing tile group, tile %d start %d + size %d exceeds OBU length %d\n", TileNum, tile_start_offset, tile_size, obu_size)); - e = GF_NON_COMPLIANT_BITSTREAM; - break; - } - - state->frame_state.tiles[state->frame_state.nb_tiles_in_obu].obu_start_offset = tile_start_offset; - state->frame_state.tiles[state->frame_state.nb_tiles_in_obu].size = tile_size; - gf_bs_skip_bytes(bs, tile_size); - state->frame_state.nb_tiles_in_obu++; - } - if (tg_end == numTiles - 1) { - av1_decode_frame_wrapup(state); - } - return e; -} - -static void av1_parse_frame_header(GF_BitStream *bs, AV1State *state) -{ - AV1StateFrame *frame_state = &state->frame_state; - if (frame_state->seen_frame_header == GF_FALSE) { - u64 pos = gf_bs_get_position(bs); - state->frame_state.show_existing_frame = GF_FALSE; - frame_state->seen_frame_header = GF_TRUE; - av1_parse_uncompressed_header(bs, state); - state->frame_state.is_first_frame = GF_FALSE; - state->frame_state.uncompressed_header_bytes = (u32) (gf_bs_get_position(bs) - pos); - - if (state->frame_state.show_existing_frame) { - av1_decode_frame_wrapup(state); - frame_state->seen_frame_header = GF_FALSE; - } - else { - //TileNum = 0; - frame_state->seen_frame_header = GF_TRUE; - } - } -} - -static GF_Err av1_parse_frame(GF_BitStream *bs, AV1State *state, u64 obu_start, u64 obu_size) -{ - av1_parse_frame_header(bs, state); - //byte alignment - gf_bs_align(bs); - return av1_parse_tile_group(bs, state, obu_start, obu_size); -} - -static void on_aom_av1_eos(void *_state) -{ - AV1State *state = (AV1State *)_state; - state->bs_overread = GF_TRUE; -} - -GF_EXPORT -GF_Err gf_media_aom_av1_parse_obu(GF_BitStream *bs, ObuType *obu_type, u64 *obu_size, u32 *obu_hdr_size, AV1State *state) -{ - GF_Err e = GF_OK; - u32 hdr_size; - u64 pos = gf_bs_get_position(bs); - - if (!bs || !obu_type || !state) - return GF_BAD_PARAM; - - state->bs_overread = GF_FALSE; - gf_bs_set_eos_callback(bs, on_aom_av1_eos, state); - - state->obu_extension_flag = state->obu_has_size_field = 0; - state->temporal_id = state->spatial_id = 0; - state->frame_state.uncompressed_header_bytes = 0; - e = gf_av1_parse_obu_header(bs, obu_type, &state->obu_extension_flag, &state->obu_has_size_field, &state->temporal_id, &state->spatial_id); - if (e) - return e; - - if (state->obu_has_size_field) { - *obu_size = (u32)gf_av1_leb128_read(bs, NULL); - } - else { - if (*obu_size >= 1 + state->obu_extension_flag) { - *obu_size = *obu_size - 1 - state->obu_extension_flag; - } - else { - GF_LOG(state->config ? GF_LOG_WARNING : GF_LOG_DEBUG, GF_LOG_CODING, ("[AV1] computed OBU size "LLD" (input value = "LLU"). Skipping.\n", *obu_size - 1 - state->obu_extension_flag, *obu_size)); - return GF_NON_COMPLIANT_BITSTREAM; - } - } - hdr_size = (u32)(gf_bs_get_position(bs) - pos); - if ((gf_bs_available(bs) < *obu_size) || state->bs_overread) { - gf_bs_seek(bs, pos); - return GF_BUFFER_TOO_SMALL; - } - *obu_size += hdr_size; - if (obu_hdr_size) *obu_hdr_size = hdr_size; - - - if (*obu_type != OBU_SEQUENCE_HEADER && *obu_type != OBU_TEMPORAL_DELIMITER && - state->OperatingPointIdc != 0 && state->obu_extension_flag == 1) - { - u32 inTemporalLayer = (state->OperatingPointIdc >> state->temporal_id) & 1; - u32 inSpatialLayer = (state->OperatingPointIdc >> (state->spatial_id + 8)) & 1; - if (!inTemporalLayer || !inSpatialLayer) { - *obu_type = -1; - gf_bs_seek(bs, pos + *obu_size); - return GF_OK; - } - } - - e = GF_OK; - switch (*obu_type) { - case OBU_SEQUENCE_HEADER: - av1_parse_sequence_header_obu(bs, state); - if (gf_bs_get_position(bs) > pos + *obu_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Sequence header parsing consumed too many bytes !\n")); - e = GF_NON_COMPLIANT_BITSTREAM; - } - gf_bs_seek(bs, pos + *obu_size); - break; - - case OBU_METADATA: -#if 0 - //TODO + sample groups - const ObuMetadataType metadata_type = (u32)read_leb128(bs, NULL); we should check for 16 bits limit(AV1MetadataSampleGroupEntry) for ISOBMFF bindings, see https ://github.com/AOMediaCodec/av1-isobmff/pull/86#issuecomment-416659538 - if (metadata_type == OBU_METADATA_TYPE_ITUT_T35) { - } - else if (metadata_type == OBU_METADATA_TYPE_HDR_CLL) { - } - else if (metadata_type == OBU_METADATA_TYPE_HDR_MDCV) { - } - else if (metadata_type == OBU_METADATA_TYPE_SCALABILITY) { - } - else if (metadata_type == METADATA_TYPE_TIMECODE) { - } -#endif - GF_LOG(GF_LOG_INFO, GF_LOG_CODING, ("[AV1] parsing for metadata is not implemented. Forwarding.\n")); - - if (gf_bs_get_position(bs) > pos + *obu_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Metadata parsing consumed too many bytes !\n")); - e = GF_NON_COMPLIANT_BITSTREAM; - } - gf_bs_seek(bs, pos + *obu_size); - break; - - case OBU_FRAME_HEADER: - case OBU_REDUNDANT_FRAME_HEADER: - if (state->config) { - av1_parse_frame_header(bs, state); - if (gf_bs_get_position(bs) > pos + *obu_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Frame header parsing consumed too many bytes !\n")); - e = GF_NON_COMPLIANT_BITSTREAM; - } - } - gf_bs_seek(bs, pos + *obu_size); - break; - case OBU_FRAME: - e = av1_parse_frame(bs, state, pos, *obu_size); - if (gf_bs_get_position(bs) != pos + *obu_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Frame parsing did not consume the right number of bytes !\n")); - e = GF_NON_COMPLIANT_BITSTREAM; - } - gf_bs_seek(bs, pos + *obu_size); - break; - case OBU_TILE_GROUP: - if (state->config) { - e = av1_parse_tile_group(bs, state, pos, *obu_size); - if (gf_bs_get_position(bs) != pos + *obu_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] Tile group parsing did not consume the right number of bytes !\n")); - e = GF_NON_COMPLIANT_BITSTREAM; - } - } - gf_bs_seek(bs, pos + *obu_size); - break; - case OBU_TEMPORAL_DELIMITER: - state->frame_state.seen_frame_header = GF_FALSE; - case OBU_PADDING: - gf_bs_seek(bs, pos + *obu_size); - break; - default: - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[AV1] unknown OBU type %u (size "LLU"). Skipping.\n", *obu_type, *obu_size)); - gf_bs_seek(bs, pos + *obu_size); - break; - } - return e; -} - - -GF_EXPORT -GF_Err gf_media_prores_parse_bs(GF_BitStream *bs, GF_ProResFrameInfo *prores_frame) -{ - u32 i, j; - u64 start, pos; - memset(prores_frame, 0, sizeof(GF_ProResFrameInfo)); - - start = gf_bs_get_position(bs); - if (gf_bs_available(bs) < 10) - return GF_BUFFER_TOO_SMALL; - - prores_frame->frame_size = gf_bs_read_u32(bs); - prores_frame->frame_identifier = gf_bs_read_u32(bs); - if (prores_frame->frame_identifier != GF_4CC('i','c','p','f')) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[ProRes] Invalid frame identifier, expected \"icpf\" got \"%s\"\n", gf_4cc_to_str(prores_frame->frame_identifier) )); - gf_bs_seek(bs, start); - return GF_NON_COMPLIANT_BITSTREAM; - } - /*parse frame header*/ - pos = gf_bs_get_position(bs); - prores_frame->frame_hdr_size = gf_bs_read_u16(bs); - if (gf_bs_available(bs) + 2 < prores_frame->frame_hdr_size) { - gf_bs_seek(bs, start); - return GF_BUFFER_TOO_SMALL; - } - gf_bs_read_u8(bs); - prores_frame->version = gf_bs_read_u8(bs); - prores_frame->encoder_id = gf_bs_read_u32(bs); - prores_frame->width = gf_bs_read_u16(bs); - prores_frame->height = gf_bs_read_u16(bs); - prores_frame->chroma_format = gf_bs_read_int(bs, 2); - gf_bs_read_int(bs, 2); - prores_frame->interlaced_mode = gf_bs_read_int(bs, 2); - gf_bs_read_int(bs, 2); - prores_frame->aspect_ratio_information = gf_bs_read_int(bs, 4); - prores_frame->framerate_code = gf_bs_read_int(bs, 4); - prores_frame->color_primaries = gf_bs_read_u8(bs); - prores_frame->transfer_characteristics = gf_bs_read_u8(bs); - prores_frame->matrix_coefficients = gf_bs_read_u8(bs); - gf_bs_read_int(bs, 4); - prores_frame->alpha_channel_type = gf_bs_read_int(bs, 4); - gf_bs_read_int(bs, 14); - prores_frame->load_luma_quant_matrix = gf_bs_read_int(bs, 1); - prores_frame->load_chroma_quant_matrix = gf_bs_read_int(bs, 1); - if (prores_frame->load_luma_quant_matrix) { - for (i=0; i<8; i++) { - for (j=0; j<8; j++) { - prores_frame->luma_quant_matrix[i][j] = gf_bs_read_u8(bs); - } - } - } - if (prores_frame->load_chroma_quant_matrix) { - for (i=0; i<8; i++) { - for (j=0; j<8; j++) { - prores_frame->chroma_quant_matrix[i][j] = gf_bs_read_u8(bs); - } - } - } - pos = gf_bs_get_position(bs) - pos; - if (pos != prores_frame->frame_hdr_size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[ProRes] Invalid frame header size, expected %d got %d\n", prores_frame->frame_hdr_size, (u32) pos)); - gf_bs_seek(bs, start); - return GF_NON_COMPLIANT_BITSTREAM; - } - prores_frame->nb_pic = ((prores_frame->interlaced_mode==1) || (prores_frame->interlaced_mode==2)) ? 2 : 1; - gf_bs_seek(bs, start); - - return GF_OK; -} - -#endif /*GPAC_DISABLE_AV_PARSERS*/ - -GF_EXPORT -u8 gf_mp3_version(u32 hdr) -{ - return ((hdr >> 19) & 0x3); -} - -GF_EXPORT -const char *gf_mp3_version_name(u32 hdr) -{ - u32 v = gf_mp3_version(hdr); - switch (v) { - case 0: - return "MPEG-2.5"; - case 1: - return "Reserved"; - case 2: - return "MPEG-2"; - case 3: - return "MPEG-1"; - default: - return "Unknown"; - } -} - -#ifndef GPAC_DISABLE_AV_PARSERS - -GF_EXPORT -u8 gf_mp3_layer(u32 hdr) -{ - return 4 - (((hdr >> 17) & 0x3)); -} - -GF_EXPORT -u8 gf_mp3_num_channels(u32 hdr) -{ - if (((hdr >> 6) & 0x3) == 3) return 1; - return 2; -} - -GF_EXPORT -u16 gf_mp3_sampling_rate(u32 hdr) -{ - u16 res; - /* extract the necessary fields from the MP3 header */ - u8 version = gf_mp3_version(hdr); - u8 sampleRateIndex = (hdr >> 10) & 0x3; - - switch (sampleRateIndex) { - case 0: - res = 44100; - break; - case 1: - res = 48000; - break; - case 2: - res = 32000; - break; - default: - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[MPEG-1/2 Audio] Samplerate index not valid\n")); - return 0; - } - /*reserved or MPEG-1*/ - if (version & 1) return res; - - /*MPEG-2*/ - res /= 2; - /*MPEG-2.5*/ - if (version == 0) res /= 2; - return res; -} - -GF_EXPORT -u16 gf_mp3_window_size(u32 hdr) -{ - u8 version = gf_mp3_version(hdr); - u8 layer = gf_mp3_layer(hdr); - - if (layer == 3) { - if (version == 3) return 1152; - return 576; - } - if (layer == 2) return 1152; - return 384; -} - -GF_EXPORT -u8 gf_mp3_object_type_indication(u32 hdr) -{ - switch (gf_mp3_version(hdr)) { - case 3: - return GF_CODECID_MPEG_AUDIO; - case 2: - case 0: - return GF_CODECID_MPEG2_PART3; - default: - return 0x00; - } -} - -/*aligned bitrate parsing with libMAD*/ - -static -u32 const bitrate_table[5][15] = { - /* MPEG-1 */ - { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ - 256000, 288000, 320000, 352000, 384000, 416000, 448000 - }, - { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ - 128000, 160000, 192000, 224000, 256000, 320000, 384000 - }, - { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ - 112000, 128000, 160000, 192000, 224000, 256000, 320000 - }, - - /* MPEG-2 LSF */ - { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ - 128000, 144000, 160000, 176000, 192000, 224000, 256000 - }, - { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */ - 64000, 80000, 96000, 112000, 128000, 144000, 160000 - } /* II & III */ -}; - - -u32 gf_mp3_bit_rate(u32 hdr) -{ - u8 version = gf_mp3_version(hdr); - u8 layer = gf_mp3_layer(hdr); - u8 bitRateIndex = (hdr >> 12) & 0xF; - u32 lidx; - /*MPEG-1*/ - if (version & 1) { - if (!layer) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[MPEG-1/2 Audio] layer index not valid\n")); - return 0; - } - lidx = layer - 1; - } - /*MPEG-2/2.5*/ - else { - lidx = 3 + (layer >> 1); - } - if (lidx>4) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[MPEG-1/2 Audio] layer index not valid\n")); - return 0; - } - return bitrate_table[lidx][bitRateIndex]; -} - - - -GF_EXPORT -u16 gf_mp3_frame_size(u32 hdr) -{ - u8 version = gf_mp3_version(hdr); - u8 layer = gf_mp3_layer(hdr); - u32 pad = ((hdr >> 9) & 0x1) ? 1 : 0; - u32 bitrate = gf_mp3_bit_rate(hdr); - u32 samplerate = gf_mp3_sampling_rate(hdr); - - u32 frameSize = 0; - if (!samplerate || !bitrate) return 0; - - if (layer == 1) { - frameSize = ((12 * bitrate / samplerate) + pad) * 4; - } - else { - u32 slots_per_frame = 144; - if ((layer == 3) && !(version & 1)) slots_per_frame = 72; - frameSize = (slots_per_frame * bitrate / samplerate) + pad; - } - return (u16)frameSize; -} - - -GF_EXPORT -u32 gf_mp3_get_next_header(FILE* in) -{ - u8 b, state = 0; - u32 dropped = 0; - unsigned char bytes[4]; - bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0; - - while (1) { - if (gf_fread(&b, 1, in) == 0) return 0; - - if (state == 3) { - bytes[state] = b; - return GF_4CC((u32)bytes[0], bytes[1], bytes[2], bytes[3]); - } - if (state == 2) { - if (((b & 0xF0) == 0) || ((b & 0xF0) == 0xF0) || ((b & 0x0C) == 0x0C)) { - if (bytes[1] == 0xFF) state = 1; - else state = 0; - } - else { - bytes[state] = b; - state = 3; - } - } - if (state == 1) { - if (((b & 0xE0) == 0xE0) && ((b & 0x18) != 0x08) && ((b & 0x06) != 0)) { - bytes[state] = b; - state = 2; - } - else { - state = 0; - } - } - - if (state == 0) { - if (b == 0xFF) { - bytes[state] = b; - state = 1; - } - else { - if ((dropped == 0) && ((b & 0xE0) == 0xE0) && ((b & 0x18) != 0x08) && ((b & 0x06) != 0)) { - bytes[0] = (u8)0xFF; - bytes[1] = b; - state = 2; - } - else { - dropped++; - } - } - } - } - return 0; -} - -GF_EXPORT -u32 gf_mp3_get_next_header_mem(const u8 *buffer, u32 size, u32 *pos) -{ - u32 cur; - u8 b, state = 0; - u32 dropped = 0; - unsigned char bytes[4]; - bytes[0] = bytes[1] = bytes[2] = bytes[3] = 0; - - cur = 0; - *pos = 0; - while (cur < size) { - b = (u8)buffer[cur]; - cur++; - - if (state == 3) { - u32 val; - bytes[state] = b; - val = GF_4CC((u32)bytes[0], bytes[1], bytes[2], bytes[3]); - if (gf_mp3_frame_size(val)) { - *pos = dropped; - return val; - } - state = 0; - dropped = cur; - } - if (state == 2) { - if (((b & 0xF0) == 0) || ((b & 0xF0) == 0xF0) || ((b & 0x0C) == 0x0C)) { - if (bytes[1] == 0xFF) { - state = 1; - dropped += 1; - } - else { - state = 0; - dropped = cur; - } - } - else { - bytes[state] = b; - state = 3; - } - } - if (state == 1) { - if (((b & 0xE0) == 0xE0) && ((b & 0x18) != 0x08) && ((b & 0x06) != 0)) { - bytes[state] = b; - state = 2; - } - else { - state = 0; - dropped = cur; - } - } - - if (state == 0) { - if (b == 0xFF) { - bytes[state] = b; - state = 1; - } - else { - dropped++; - } - } - } - return 0; -} - -#endif /*GPAC_DISABLE_AV_PARSERS*/ - - -GF_EXPORT -Bool gf_avc_is_rext_profile(u8 profile_idc) -{ - switch (profile_idc) { - case 100: - case 110: - case 122: - case 244: - case 44: - case 83: - case 86: - case 118: - case 128: - case 138: - case 139: - case 134: - case 135: - return GF_TRUE; - default: - return GF_FALSE; - } -} - -GF_EXPORT -const char *gf_avc_get_profile_name(u8 video_prof) -{ - switch (video_prof) { - case 0x42: - return "Baseline"; - case 0x4D: - return "Main"; - case 0x53: - return "Scalable Baseline"; - case 0x56: - return "Scalable High"; - case 0x58: - return "Extended"; - case 0x64: - return "High"; - case 0x6E: - return "High 10"; - case 0x7A: - return "High 4:2:2"; - case 0x90: - case 0xF4: - return "High 4:4:4"; - default: - return "Unknown"; - } -} - -GF_EXPORT -const char *gf_hevc_get_profile_name(u8 video_prof) -{ - switch (video_prof) { - case 0x01: - return "Main"; - case 0x02: - return "Main 10"; - case 0x03: - return "Main Still Picture"; - default: - return "Unknown"; - } -} -GF_EXPORT -const char *gf_avc_hevc_get_chroma_format_name(u8 chroma_format) -{ - switch (chroma_format) { - case 1: - return "YUV 4:2:0"; - case 2: - return "YUV 4:2:2"; - case 3: - return "YUV 4:4:4"; - default: - return "Unknown"; - } -} - -#ifndef GPAC_DISABLE_AV_PARSERS - - -static u8 avc_golomb_bits[256] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 -}; - -u32 gf_bs_get_ue(GF_BitStream *bs) -{ - u8 coded; - u32 bits = 0, read = 0; - while (1) { - read = gf_bs_peek_bits(bs, 8, 0); - if (read) break; - //check whether we still have bits once the peek is done since we may have less than 8 bits available - if (!gf_bs_available(bs)) { - //log moved as debug, erro log thrown by gf_bs_read_* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[AVC/HEVC] Not enough bits in bitstream !!\n")); - return 0; - } - gf_bs_read_int(bs, 8); - bits += 8; - } - coded = avc_golomb_bits[read]; - gf_bs_read_int(bs, coded); - bits += coded; - return gf_bs_read_int(bs, bits + 1) - 1; -} - -s32 gf_bs_get_se(GF_BitStream *bs) -{ - u32 v = gf_bs_get_ue(bs); - if ((v & 0x1) == 0) return (s32)(0 - (v >> 1)); - return (v + 1) >> 1; -} - -void gf_bs_set_ue(GF_BitStream *bs, u32 num) { - s32 length = 1; - s32 temp = ++num; - - while (temp != 1) { - temp >>= 1; - length += 2; - } - - gf_bs_write_int(bs, 0, length >> 1); - gf_bs_write_int(bs, num, (length + 1) >> 1); -} - -void gf_bs_set_se(GF_BitStream *bs, s32 num) -{ - u32 v; - if (num <= 0) - v = (-1 * num) << 1; - else - v = (num << 1) - 1; - - gf_bs_set_ue(bs, v); -} - -u32 gf_media_nalu_is_start_code(GF_BitStream *bs) -{ - u8 s1, s2, s3, s4; - Bool is_sc = 0; - u64 pos = gf_bs_get_position(bs); - s1 = gf_bs_read_int(bs, 8); - s2 = gf_bs_read_int(bs, 8); - if (!s1 && !s2) { - s3 = gf_bs_read_int(bs, 8); - if (s3 == 0x01) is_sc = 3; - else if (!s3) { - s4 = gf_bs_read_int(bs, 8); - if (s4 == 0x01) is_sc = 4; - } - } - gf_bs_seek(bs, pos + is_sc); - return is_sc; -} - -/*read that amount of data at each IO access rather than fetching byte by byte...*/ -#define AVC_CACHE_SIZE 4096 - -static u32 gf_media_nalu_locate_start_code_bs(GF_BitStream *bs, Bool locate_trailing) -{ - u32 v, bpos, nb_cons_zeros = 0; - char avc_cache[AVC_CACHE_SIZE]; - u64 end, cache_start, load_size; - u64 start = gf_bs_get_position(bs); - if (start < 3) return 0; - - load_size = 0; - bpos = 0; - cache_start = 0; - end = 0; - v = 0xffffffff; - while (!end) { - /*refill cache*/ - if (bpos == (u32)load_size) { - if (!gf_bs_available(bs)) break; - load_size = gf_bs_available(bs); - if (load_size > AVC_CACHE_SIZE) load_size = AVC_CACHE_SIZE; - bpos = 0; - cache_start = gf_bs_get_position(bs); - gf_bs_read_data(bs, avc_cache, (u32)load_size); - } - v = ( (v<<8) & 0xFFFFFF00) | ((u32) avc_cache[bpos]); - bpos++; - - if (locate_trailing) { - if ((v & 0x000000FF) == 0) nb_cons_zeros++; - else nb_cons_zeros = 0; - } - - if (v == 0x00000001) end = cache_start + bpos - 4; - else if ((v & 0x00FFFFFF) == 0x00000001) end = cache_start + bpos - 3; - } - - gf_bs_seek(bs, start); - if (!end) end = gf_bs_get_size(bs); - if (locate_trailing) { - if (nb_cons_zeros >= 3) - return (u32)(end - start - nb_cons_zeros); - } - return (u32)(end - start); -} - -GF_EXPORT -u32 gf_media_nalu_next_start_code_bs(GF_BitStream *bs) -{ - return gf_media_nalu_locate_start_code_bs(bs, 0); -} - -GF_EXPORT -u32 gf_media_nalu_next_start_code(const u8 *data, u32 data_len, u32 *sc_size) -{ - u32 avail = data_len; - const u8 *cur = data; - - while (cur) { - u32 v, bpos; - u8 *next_zero = memchr(cur, 0, avail); - if (!next_zero) return data_len; - - v = 0xffffff00; - bpos = (u32)(next_zero - data) + 1; - while (1) { - u8 cval; - if (bpos == (u32)data_len) - return data_len; - - cval = data[bpos]; - v = ((v << 8) & 0xFFFFFF00) | ((u32)cval); - bpos++; - if (v == 0x00000001) { - *sc_size = 4; - return bpos - 4; - } - else if ((v & 0x00FFFFFF) == 0x00000001) { - *sc_size = 3; - return bpos - 3; - } - if (cval) - break; - } - if (bpos >= data_len) - break; - cur = data + bpos; - avail = data_len - bpos; - } - return data_len; -} - -Bool gf_media_avc_slice_is_intra(AVCState *avc) -{ - switch (avc->s_info.slice_type) { - case GF_AVC_TYPE_I: - case GF_AVC_TYPE2_I: - case GF_AVC_TYPE_SI: - case GF_AVC_TYPE2_SI: - return 1; - default: - return 0; - } -} - -#if 0 //unused -Bool gf_media_avc_slice_is_IDR(AVCState *avc) -{ - if (avc->sei.recovery_point.valid) - { - avc->sei.recovery_point.valid = 0; - return 1; - } - if (avc->s_info.nal_unit_type != GF_AVC_NALU_IDR_SLICE) - return 0; - return gf_media_avc_slice_is_intra(avc); -} -#endif - -struct sar_ { - u32 w, h; -}; - -static const struct sar_ avc_sar[] = { - { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, - { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 }, - { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 }, - { 64, 33 }, { 160,99 }, { 4, 3 }, { 3, 2 }, - { 2, 1 } -}; - - -/*ISO 14496-10 (N11084) E.1.2*/ -static void avc_parse_hrd_parameters(GF_BitStream *bs, AVC_HRD *hrd) -{ - int i, cpb_cnt_minus1; - - cpb_cnt_minus1 = gf_bs_get_ue(bs); /*cpb_cnt_minus1*/ - if (cpb_cnt_minus1 > 31) - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] invalid cpb_cnt_minus1 value: %d (expected in [0;31])\n", cpb_cnt_minus1)); - gf_bs_read_int(bs, 4); /*bit_rate_scale*/ - gf_bs_read_int(bs, 4); /*cpb_size_scale*/ - - /*for( SchedSelIdx = 0; SchedSelIdx <= cpb_cnt_minus1; SchedSelIdx++ ) {*/ - for (i = 0; i <= cpb_cnt_minus1; i++) { - gf_bs_get_ue(bs); /*bit_rate_value_minus1[ SchedSelIdx ]*/ - gf_bs_get_ue(bs); /*cpb_size_value_minus1[ SchedSelIdx ]*/ - gf_bs_read_int(bs, 1); /*cbr_flag[ SchedSelIdx ]*/ - } - gf_bs_read_int(bs, 5); /*initial_cpb_removal_delay_length_minus1*/ - hrd->cpb_removal_delay_length_minus1 = gf_bs_read_int(bs, 5); /*cpb_removal_delay_length_minus1*/ - hrd->dpb_output_delay_length_minus1 = gf_bs_read_int(bs, 5); /*dpb_output_delay_length_minus1*/ - hrd->time_offset_length = gf_bs_read_int(bs, 5); /*time_offset_length*/ - - return; -} - -/*returns the nal_size without emulation prevention bytes*/ -u32 gf_media_nalu_emulation_bytes_add_count(u8 *buffer, u32 nal_size) -{ - u32 i = 0, emulation_bytes_count = 0; - u8 num_zero = 0; - - while (i < nal_size) { - /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 - other than the following sequences shall not occur at any byte-aligned position: - \96 0x00000300 - \96 0x00000301 - \96 0x00000302 - \96 0x00000303" - */ - if (num_zero == 2 && (u8)buffer[i] < 0x04) { - /*emulation code found*/ - num_zero = 0; - emulation_bytes_count++; - if (!buffer[i]) - num_zero = 1; - } - else { - if (!buffer[i]) - num_zero++; - else - num_zero = 0; - } - i++; - } - return emulation_bytes_count; -} - -u32 gf_media_nalu_add_emulation_bytes(const u8 *buffer_src, u8 *buffer_dst, u32 nal_size) -{ - u32 i = 0, emulation_bytes_count = 0; - u8 num_zero = 0; - - while (i < nal_size) { - /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 - other than the following sequences shall not occur at any byte-aligned position: - 0x00000300 - 0x00000301 - 0x00000302 - 0x00000303" - */ - if (num_zero == 2 && (u8)buffer_src[i] < 0x04) { - /*add emulation code*/ - num_zero = 0; - buffer_dst[i + emulation_bytes_count] = 0x03; - emulation_bytes_count++; - if (!buffer_src[i]) - num_zero = 1; - } - else { - if (!buffer_src[i]) - num_zero++; - else - num_zero = 0; - } - buffer_dst[i + emulation_bytes_count] = buffer_src[i]; - i++; - } - return nal_size + emulation_bytes_count; -} - -/*returns the nal_size without emulation prevention bytes*/ -u32 gf_media_nalu_emulation_bytes_remove_count(const u8 *buffer, u32 nal_size) -{ - u32 i = 0, emulation_bytes_count = 0; - u8 num_zero = 0; - if (!buffer || !nal_size) return 0; - - while (i < nal_size) - { - /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 - other than the following sequences shall not occur at any byte-aligned position: - \96 0x00000300 - \96 0x00000301 - \96 0x00000302 - \96 0x00000303" - */ - if (num_zero == 2 - && buffer[i] == 0x03 - && i + 1 < nal_size /*next byte is readable*/ - && (u8)buffer[i + 1] < 0x04) - { - /*emulation code found*/ - num_zero = 0; - emulation_bytes_count++; - i++; - } - - if (!buffer[i]) - num_zero++; - else - num_zero = 0; - - i++; - } - - return emulation_bytes_count; -} - -/*nal_size is updated to allow better error detection*/ -GF_EXPORT -u32 gf_media_nalu_remove_emulation_bytes(const u8 *buffer_src, u8 *buffer_dst, u32 nal_size) -{ - u32 i = 0, emulation_bytes_count = 0; - u8 num_zero = 0; - - while (i < nal_size) - { - /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 - other than the following sequences shall not occur at any byte-aligned position: - 0x00000300 - 0x00000301 - 0x00000302 - 0x00000303" - */ - if (num_zero == 2 - && buffer_src[i] == 0x03 - && i + 1 < nal_size /*next byte is readable*/ - && (u8)buffer_src[i + 1] < 0x04) - { - /*emulation code found*/ - num_zero = 0; - emulation_bytes_count++; - i++; - } - - buffer_dst[i - emulation_bytes_count] = buffer_src[i]; - - if (!buffer_src[i]) - num_zero++; - else - num_zero = 0; - - i++; - } - - return nal_size - emulation_bytes_count; -} - -static s32 gf_media_avc_read_sps_bs_internal(GF_BitStream *bs, AVCState *avc, u32 subseq_sps, u32 *vui_flag_pos, u32 nal_hdr) -{ - AVC_SPS *sps; - s32 mb_width, mb_height, sps_id = -1; - u32 profile_idc, level_idc, pcomp, i, chroma_format_idc, cl = 0, cr = 0, ct = 0, cb = 0, luma_bd, chroma_bd; - u8 separate_colour_plane_flag = 0; - - if (!vui_flag_pos) { - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - } - - if (!bs) { - return -1; - } - - if (!nal_hdr) { - /*nal_hdr =*/ gf_bs_read_int(bs, 8); - } - profile_idc = gf_bs_read_int(bs, 8); - - pcomp = gf_bs_read_int(bs, 8); - /*sanity checks*/ - if (pcomp & 0x3) - return -1; - - level_idc = gf_bs_read_int(bs, 8); - - /*SubsetSps is used to be sure that AVC SPS are not going to be scratched - by subset SPS. According to the SVC standard, subset SPS can have the same sps_id - than its base layer, but it does not refer to the same SPS. */ - sps_id = gf_bs_get_ue(bs) + GF_SVC_SSPS_ID_SHIFT * subseq_sps; - if (sps_id >= 32) { - return -1; - } - if (sps_id < 0) { - return -1; - } - - luma_bd = chroma_bd = 0; - sps = &avc->sps[sps_id]; - chroma_format_idc = sps->ChromaArrayType = 1; - sps->state |= subseq_sps ? AVC_SUBSPS_PARSED : AVC_SPS_PARSED; - - /*High Profile and SVC*/ - switch (profile_idc) { - case 100: - case 110: - case 122: - case 244: - case 44: - /*sanity checks: note1 from 7.4.2.1.1 of iso/iec 14496-10-N11084*/ - if (pcomp & 0xE0) - return -1; - case 83: - case 86: - case 118: - case 128: - chroma_format_idc = gf_bs_get_ue(bs); - sps->ChromaArrayType = chroma_format_idc; - if (chroma_format_idc == 3) { - separate_colour_plane_flag = gf_bs_read_int(bs, 1); - /* - Depending on the value of separate_colour_plane_flag, the value of the variable ChromaArrayType is assigned as follows. - \96 If separate_colour_plane_flag is equal to 0, ChromaArrayType is set equal to chroma_format_idc. - \96 Otherwise (separate_colour_plane_flag is equal to 1), ChromaArrayType is set equal to 0. - */ - if (separate_colour_plane_flag) sps->ChromaArrayType = 0; - } - luma_bd = gf_bs_get_ue(bs); - chroma_bd = gf_bs_get_ue(bs); - /*qpprime_y_zero_transform_bypass_flag = */ gf_bs_read_int(bs, 1); - /*seq_scaling_matrix_present_flag*/ - if (gf_bs_read_int(bs, 1)) { - u32 k; - for (k = 0; k < 8; k++) { - if (gf_bs_read_int(bs, 1)) { - u32 z, last = 8, next = 8; - u32 sl = k < 6 ? 16 : 64; - for (z = 0; z < sl; z++) { - if (next) { - s32 delta = gf_bs_get_se(bs); - next = (last + delta + 256) % 256; - } - last = next ? next : last; - } - } - } - } - break; - } - - sps->profile_idc = profile_idc; - sps->level_idc = level_idc; - sps->prof_compat = pcomp; - sps->log2_max_frame_num = gf_bs_get_ue(bs) + 4; - sps->poc_type = gf_bs_get_ue(bs); - sps->chroma_format = chroma_format_idc; - sps->luma_bit_depth_m8 = luma_bd; - sps->chroma_bit_depth_m8 = chroma_bd; - - if (sps->poc_type == 0) { - sps->log2_max_poc_lsb = gf_bs_get_ue(bs) + 4; - } - else if (sps->poc_type == 1) { - sps->delta_pic_order_always_zero_flag = gf_bs_read_int(bs, 1); - sps->offset_for_non_ref_pic = gf_bs_get_se(bs); - sps->offset_for_top_to_bottom_field = gf_bs_get_se(bs); - sps->poc_cycle_length = gf_bs_get_ue(bs); - if (sps->poc_cycle_length > GF_ARRAY_LENGTH(sps->offset_for_ref_frame)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[avc-h264] offset_for_ref_frame overflow from poc_cycle_length\n")); - return -1; - } - for (i = 0; i < sps->poc_cycle_length; i++) sps->offset_for_ref_frame[i] = gf_bs_get_se(bs); - } - if (sps->poc_type > 2) { - return -1; - } - sps->max_num_ref_frames = gf_bs_get_ue(bs); - sps->gaps_in_frame_num_value_allowed_flag = gf_bs_read_int(bs, 1); - mb_width = gf_bs_get_ue(bs) + 1; - mb_height = gf_bs_get_ue(bs) + 1; - - sps->frame_mbs_only_flag = gf_bs_read_int(bs, 1); - - sps->width = mb_width * 16; - sps->height = (2 - sps->frame_mbs_only_flag) * mb_height * 16; - - if (!sps->frame_mbs_only_flag) sps->mb_adaptive_frame_field_flag = gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 1); /*direct_8x8_inference_flag*/ - - if (gf_bs_read_int(bs, 1)) { /*crop*/ - int CropUnitX, CropUnitY, SubWidthC = -1, SubHeightC = -1; - - if (chroma_format_idc == 1) { - SubWidthC = 2; SubHeightC = 2; - } - else if (chroma_format_idc == 2) { - SubWidthC = 2; SubHeightC = 1; - } - else if ((chroma_format_idc == 3) && (separate_colour_plane_flag == 0)) { - SubWidthC = 1; SubHeightC = 1; - } - - if (sps->ChromaArrayType == 0) { - assert(SubWidthC == -1); - CropUnitX = 1; - CropUnitY = 2 - sps->frame_mbs_only_flag; - } - else { - CropUnitX = SubWidthC; - CropUnitY = SubHeightC * (2 - sps->frame_mbs_only_flag); - } - - cl = gf_bs_get_ue(bs); /*crop_left*/ - cr = gf_bs_get_ue(bs); /*crop_right*/ - ct = gf_bs_get_ue(bs); /*crop_top*/ - cb = gf_bs_get_ue(bs); /*crop_bottom*/ - - sps->width -= CropUnitX * (cl + cr); - sps->height -= CropUnitY * (ct + cb); - cl *= CropUnitX; - cr *= CropUnitX; - ct *= CropUnitY; - cb *= CropUnitY; - } - sps->crop.left = cl; - sps->crop.right = cr; - sps->crop.top = ct; - sps->crop.bottom = cb; - - if (vui_flag_pos) { - *vui_flag_pos = (u32)gf_bs_get_bit_offset(bs); - } - /*vui_parameters_present_flag*/ - sps->vui_parameters_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui_parameters_present_flag) { - sps->vui.aspect_ratio_info_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui.aspect_ratio_info_present_flag) { - s32 aspect_ratio_idc = gf_bs_read_int(bs, 8); - if (aspect_ratio_idc == 255) { - sps->vui.par_num = gf_bs_read_int(bs, 16); /*AR num*/ - sps->vui.par_den = gf_bs_read_int(bs, 16); /*AR den*/ - } - else if (aspect_ratio_idc < sizeof(avc_sar) / sizeof(struct sar_)) { - sps->vui.par_num = avc_sar[aspect_ratio_idc].w; - sps->vui.par_den = avc_sar[aspect_ratio_idc].h; - } - else { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] Unknown aspect_ratio_idc: your video may have a wrong aspect ratio. Contact the GPAC team!\n")); - } - } - sps->vui.overscan_info_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui.overscan_info_present_flag) - gf_bs_read_int(bs, 1); /* overscan_appropriate_flag */ - - /* default values */ - sps->vui.video_format = 5; - sps->vui.colour_primaries = 2; - sps->vui.transfer_characteristics = 2; - sps->vui.matrix_coefficients = 2; - /* now read values if possible */ - sps->vui.video_signal_type_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui.video_signal_type_present_flag) { - sps->vui.video_format = gf_bs_read_int(bs, 3); - sps->vui.video_full_range_flag = gf_bs_read_int(bs, 1); - sps->vui.colour_description_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui.colour_description_present_flag) { - sps->vui.colour_primaries = gf_bs_read_int(bs, 8); - sps->vui.transfer_characteristics = gf_bs_read_int(bs, 8); - sps->vui.matrix_coefficients = gf_bs_read_int(bs, 8); - } - } - - if (gf_bs_read_int(bs, 1)) { /* chroma_location_info_present_flag */ - gf_bs_get_ue(bs); /* chroma_sample_location_type_top_field */ - gf_bs_get_ue(bs); /* chroma_sample_location_type_bottom_field */ - } - - sps->vui.timing_info_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui.timing_info_present_flag) { - sps->vui.num_units_in_tick = gf_bs_read_int(bs, 32); - sps->vui.time_scale = gf_bs_read_int(bs, 32); - sps->vui.fixed_frame_rate_flag = gf_bs_read_int(bs, 1); - } - - sps->vui.nal_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui.nal_hrd_parameters_present_flag) - avc_parse_hrd_parameters(bs, &sps->vui.hrd); - - sps->vui.vcl_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); - if (sps->vui.vcl_hrd_parameters_present_flag) - avc_parse_hrd_parameters(bs, &sps->vui.hrd); - - if (sps->vui.nal_hrd_parameters_present_flag || sps->vui.vcl_hrd_parameters_present_flag) - sps->vui.low_delay_hrd_flag = gf_bs_read_int(bs, 1); - - sps->vui.pic_struct_present_flag = gf_bs_read_int(bs, 1); - } - /*end of seq_parameter_set_data*/ - - if (subseq_sps) { - if ((profile_idc == 83) || (profile_idc == 86)) { - u8 extended_spatial_scalability_idc; - /*parsing seq_parameter_set_svc_extension*/ - - /*inter_layer_deblocking_filter_control_present_flag=*/ gf_bs_read_int(bs, 1); - extended_spatial_scalability_idc = gf_bs_read_int(bs, 2); - if (sps->ChromaArrayType == 1 || sps->ChromaArrayType == 2) { - /*chroma_phase_x_plus1_flag*/ gf_bs_read_int(bs, 1); - } - if (sps->ChromaArrayType == 1) { - /*chroma_phase_y_plus1*/ gf_bs_read_int(bs, 2); - } - if (extended_spatial_scalability_idc == 1) { - if (sps->ChromaArrayType > 0) { - /*seq_ref_layer_chroma_phase_x_plus1_flag*/gf_bs_read_int(bs, 1); - /*seq_ref_layer_chroma_phase_y_plus1*/gf_bs_read_int(bs, 2); - } - /*seq_scaled_ref_layer_left_offset*/ gf_bs_get_se(bs); - /*seq_scaled_ref_layer_top_offset*/gf_bs_get_se(bs); - /*seq_scaled_ref_layer_right_offset*/gf_bs_get_se(bs); - /*seq_scaled_ref_layer_bottom_offset*/gf_bs_get_se(bs); - } - if (/*seq_tcoeff_level_prediction_flag*/gf_bs_read_int(bs, 1)) { - /*adaptive_tcoeff_level_prediction_flag*/ gf_bs_read_int(bs, 1); - } - /*slice_header_restriction_flag*/gf_bs_read_int(bs, 1); - - /*svc_vui_parameters_present*/ - if (gf_bs_read_int(bs, 1)) { - u32 vui_ext_num_entries_minus1 = gf_bs_get_ue(bs); - - for (i = 0; i <= vui_ext_num_entries_minus1; i++) { - u8 vui_ext_nal_hrd_parameters_present_flag, vui_ext_vcl_hrd_parameters_present_flag, vui_ext_timing_info_present_flag; - /*u8 vui_ext_dependency_id =*/ gf_bs_read_int(bs, 3); - /*u8 vui_ext_quality_id =*/ gf_bs_read_int(bs, 4); - /*u8 vui_ext_temporal_id =*/ gf_bs_read_int(bs, 3); - vui_ext_timing_info_present_flag = gf_bs_read_int(bs, 1); - if (vui_ext_timing_info_present_flag) { - /*u32 vui_ext_num_units_in_tick = */gf_bs_read_int(bs, 32); - /*u32 vui_ext_time_scale = */gf_bs_read_int(bs, 32); - /*u8 vui_ext_fixed_frame_rate_flag = */gf_bs_read_int(bs, 1); - } - vui_ext_nal_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); - if (vui_ext_nal_hrd_parameters_present_flag) { - //hrd_parameters( ) - } - vui_ext_vcl_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); - if (vui_ext_vcl_hrd_parameters_present_flag) { - //hrd_parameters( ) - } - if (vui_ext_nal_hrd_parameters_present_flag || vui_ext_vcl_hrd_parameters_present_flag) { - /*vui_ext_low_delay_hrd_flag*/gf_bs_read_int(bs, 1); - } - /*vui_ext_pic_struct_present_flag*/gf_bs_read_int(bs, 1); - } - } - } - else if ((profile_idc == 118) || (profile_idc == 128)) { - GF_LOG(GF_LOG_INFO, GF_LOG_CODING, ("[avc-h264] MVC parsing not implemented - skipping parsing end of Subset SPS\n")); - return sps_id; - } - - if (gf_bs_read_int(bs, 1)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] skipping parsing end of Subset SPS (additional_extension2)\n")); - return sps_id; - } - } - return sps_id; -} - -GF_EXPORT -s32 gf_media_avc_read_sps_bs(GF_BitStream *bs, AVCState *avc, u32 subseq_sps, u32 *vui_flag_pos) -{ - return gf_media_avc_read_sps_bs_internal(bs, avc, subseq_sps, vui_flag_pos, 0); -} - -GF_EXPORT -s32 gf_media_avc_read_sps(const u8 *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, u32 *vui_flag_pos) -{ - s32 sps_id = -1; - GF_BitStream *bs; - char *sps_data_without_emulation_bytes = NULL; - u32 sps_data_without_emulation_bytes_size = 0; - - if (vui_flag_pos) { - /*SPS still contains emulation bytes*/ - sps_data_without_emulation_bytes = gf_malloc(sps_size * sizeof(char)); - sps_data_without_emulation_bytes_size = gf_media_nalu_remove_emulation_bytes(sps_data, sps_data_without_emulation_bytes, sps_size); - bs = gf_bs_new(sps_data_without_emulation_bytes, sps_data_without_emulation_bytes_size, GF_BITSTREAM_READ); - - *vui_flag_pos = 0; - } - else { - bs = gf_bs_new(sps_data, sps_size, GF_BITSTREAM_READ); - } - - if (!bs) { - sps_id = -1; - goto exit; - } - - sps_id = gf_media_avc_read_sps_bs(bs, avc, subseq_sps, vui_flag_pos); - -exit: - gf_bs_del(bs); - if (sps_data_without_emulation_bytes) gf_free(sps_data_without_emulation_bytes); - return sps_id; -} - -static s32 gf_media_avc_read_pps_bs_internal(GF_BitStream *bs, AVCState *avc, u32 nal_hdr) -{ - s32 pps_id; - AVC_PPS *pps; - - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - if (!nal_hdr) { - /*nal_hdr = */gf_bs_read_u8(bs); - } - pps_id = gf_bs_get_ue(bs); - if (pps_id >= 255) { - return -1; - } - pps = &avc->pps[pps_id]; - pps->id = pps_id; - - if (!pps->status) pps->status = 1; - pps->sps_id = gf_bs_get_ue(bs); - if (pps->sps_id >= 32) { - pps->sps_id = 0; - return -1; - } - /*sps_id may be refer to regular SPS or subseq sps, depending on the coded slice refering to the pps*/ - if (!avc->sps[pps->sps_id].state && !avc->sps[pps->sps_id + GF_SVC_SSPS_ID_SHIFT].state) { - return -1; - } - avc->pps_active_idx = pps->id; /*set active sps*/ - avc->sps_active_idx = pps->sps_id; /*set active sps*/ - pps->entropy_coding_mode_flag = gf_bs_read_int(bs, 1); - pps->pic_order_present = gf_bs_read_int(bs, 1); - pps->slice_group_count = gf_bs_get_ue(bs) + 1; - if (pps->slice_group_count > 1) { - u32 iGroup; - pps->mb_slice_group_map_type = gf_bs_get_ue(bs); - if (pps->mb_slice_group_map_type == 0) { - for (iGroup = 0; iGroup <= pps->slice_group_count - 1; iGroup++) - /*run_length_minus1[iGroup] = */ gf_bs_get_ue(bs); - } - else if (pps->mb_slice_group_map_type == 2) { - for (iGroup = 0; iGroup < pps->slice_group_count - 1; iGroup++) { - /*top_left[iGroup] = */ gf_bs_get_ue(bs); - /*bottom_right[iGroup] = */ gf_bs_get_ue(bs); - } - } - else if (pps->mb_slice_group_map_type == 3 || pps->mb_slice_group_map_type == 4 || pps->mb_slice_group_map_type == 5) { - /*slice_group_change_direction_flag =*/ gf_bs_read_int(bs, 1); - /*slice_group_change_rate_minus1 = */ gf_bs_get_ue(bs); - } - else if (pps->mb_slice_group_map_type == 6) { - u32 i; - pps->pic_size_in_map_units_minus1 = gf_bs_get_ue(bs); - for (i = 0; i <= pps->pic_size_in_map_units_minus1; i++) { - /*slice_group_id[i] = */ gf_bs_read_int(bs, (u32)ceil(log(pps->slice_group_count) / log(2))); - } - } - } - pps->num_ref_idx_l0_default_active_minus1 = gf_bs_get_ue(bs); - pps->num_ref_idx_l1_default_active_minus1 = gf_bs_get_ue(bs); - - /* - if ((pps->ref_count[0] > 32) || (pps->ref_count[1] > 32)) goto exit; - */ - - pps->weighted_pred_flag = gf_bs_read_int(bs, 1); - /*pps->weighted_bipred_idc = */gf_bs_read_int(bs, 2); - /*pps->init_qp = */gf_bs_get_se(bs) /*+ 26*/; - /*pps->init_qs= */gf_bs_get_se(bs) /*+ 26*/; - /*pps->chroma_qp_index_offset = */gf_bs_get_se(bs); - pps->deblocking_filter_control_present_flag = gf_bs_read_int(bs, 1); - /*pps->constrained_intra_pred = */gf_bs_read_int(bs, 1); - pps->redundant_pic_cnt_present = gf_bs_read_int(bs, 1); - - return pps_id; -} - -GF_EXPORT -s32 gf_media_avc_read_pps_bs(GF_BitStream *bs, AVCState *avc) -{ - return gf_media_avc_read_pps_bs_internal(bs, avc, 0); -} - -GF_EXPORT -s32 gf_media_avc_read_pps(const u8 *pps_data, u32 pps_size, AVCState *avc) -{ - GF_BitStream *bs; - s32 pps_id; - - /*PPS still contains emulation bytes*/ - bs = gf_bs_new(pps_data, pps_size, GF_BITSTREAM_READ); - if (!bs) { - return -1; - } - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - pps_id = gf_media_avc_read_pps_bs(bs, avc); - gf_bs_del(bs); - return pps_id; -} - -#if 0 //unused - -s32 gf_media_avc_read_sps_ext(const char *spse_data, u32 spse_size) -{ - GF_BitStream *bs; - s32 sps_id; - - bs = gf_bs_new(spse_data, spse_size, GF_BITSTREAM_READ); - sps_id = gf_media_avc_read_sps_ext_bs(bs); - - gf_bs_del(bs); - return sps_id; -} -#endif - -static s32 SVC_ReadNal_header_extension(GF_BitStream *bs, SVC_NALUHeader *NalHeader) -{ - gf_bs_read_int(bs, 1); //reserved_one_bits - NalHeader->idr_pic_flag = gf_bs_read_int(bs, 1); //idr_flag - NalHeader->priority_id = gf_bs_read_int(bs, 6); //priority_id - gf_bs_read_int(bs, 1); //no_inter_layer_pred_flag - NalHeader->dependency_id = gf_bs_read_int(bs, 3); //DependencyId - NalHeader->quality_id = gf_bs_read_int(bs, 4); //quality_id - NalHeader->temporal_id = gf_bs_read_int(bs, 3); //temporal_id - gf_bs_read_int(bs, 1); //use_ref_base_pic_flag - gf_bs_read_int(bs, 1); //discardable_flag - gf_bs_read_int(bs, 1); //output_flag - gf_bs_read_int(bs, 2); //reserved_three_2bits - return 1; -} - -static void ref_pic_list_modification(GF_BitStream *bs, u32 slice_type) { - if (slice_type % 5 != 2 && slice_type % 5 != 4) { - if (/*ref_pic_list_modification_flag_l0*/ gf_bs_read_int(bs, 1)) { - u32 modification_of_pic_nums_idc; - do { - modification_of_pic_nums_idc = gf_bs_get_ue(bs); - if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1) { - /*abs_diff_pic_num_minus1 =*/ gf_bs_get_ue(bs); - } - else if (modification_of_pic_nums_idc == 2) { - /*long_term_pic_num =*/ gf_bs_get_ue(bs); - } - } while ((modification_of_pic_nums_idc != 3) && gf_bs_available(bs)); - } - } - if (slice_type % 5 == 1) { - if (/*ref_pic_list_modification_flag_l1*/ gf_bs_read_int(bs, 1)) { - u32 modification_of_pic_nums_idc; - do { - modification_of_pic_nums_idc = gf_bs_get_ue(bs); - if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1) { - /*abs_diff_pic_num_minus1 =*/ gf_bs_get_ue(bs); - } - else if (modification_of_pic_nums_idc == 2) { - /*long_term_pic_num =*/ gf_bs_get_ue(bs); - } - } while ((modification_of_pic_nums_idc != 3) && gf_bs_available(bs)); - } - } -} - -static void pred_weight_table(GF_BitStream *bs, u32 slice_type, u32 ChromaArrayType, u32 num_ref_idx_l0_active_minus1, u32 num_ref_idx_l1_active_minus1) { - u32 i, j; - /*luma_log2_weight_denom =*/ gf_bs_get_ue(bs); - if (ChromaArrayType != 0) { - /*chroma_log2_weight_denom =*/ gf_bs_get_ue(bs); - } - for (i = 0; i <= num_ref_idx_l0_active_minus1; i++) { - if (/*luma_weight_l0_flag*/ gf_bs_read_int(bs, 1)) { - /*luma_weight_l0[i] =*/ gf_bs_get_se(bs); - /*luma_offset_l0[i] =*/ gf_bs_get_se(bs); - } - if (ChromaArrayType != 0) { - if (/*chroma_weight_l0_flag*/ gf_bs_read_int(bs, 1)) - for (j = 0; j < 2; j++) { - /*chroma_weight_l0[i][j] =*/ gf_bs_get_se(bs); - /*chroma_offset_l0[i][j] =*/ gf_bs_get_se(bs); - } - } - } - if (slice_type % 5 == 1) { - for (i = 0; i <= num_ref_idx_l1_active_minus1; i++) { - if (/*luma_weight_l1_flag*/ gf_bs_read_int(bs, 1)) { - /*luma_weight_l1[i] =*/ gf_bs_get_se(bs); - /*luma_offset_l1[i] =*/ gf_bs_get_se(bs); - } - if (ChromaArrayType != 0) { - if (/*chroma_weight_l1_flag*/ gf_bs_read_int(bs, 1)) { - for (j = 0; j < 2; j++) { - /*chroma_weight_l1[i][j] =*/ gf_bs_get_se(bs); - /*chroma_offset_l1[i][j] =*/ gf_bs_get_se(bs); - } - } - } - } - } -} - -static void dec_ref_pic_marking(GF_BitStream *bs, Bool IdrPicFlag) { - if (IdrPicFlag) { - /*no_output_of_prior_pics_flag =*/ gf_bs_read_int(bs, 1); - /*long_term_reference_flag =*/ gf_bs_read_int(bs, 1); - } - else { - if (/*adaptive_ref_pic_marking_mode_flag*/ gf_bs_read_int(bs, 1)) { - u32 memory_management_control_operation; - do { - memory_management_control_operation = gf_bs_get_ue(bs); - if (memory_management_control_operation == 1 || memory_management_control_operation == 3) - /*difference_of_pic_nums_minus1 =*/ gf_bs_get_ue(bs); - if (memory_management_control_operation == 2) - /*long_term_pic_num =*/ gf_bs_get_ue(bs); - if (memory_management_control_operation == 3 || memory_management_control_operation == 6) - /*long_term_frame_idx =*/ gf_bs_get_ue(bs); - if (memory_management_control_operation == 4) - /*max_long_term_frame_idx_plus1 =*/ gf_bs_get_ue(bs); - } while (memory_management_control_operation != 0); - } - } -} - -static s32 avc_parse_slice(GF_BitStream *bs, AVCState *avc, Bool svc_idr_flag, AVCSliceInfo *si) -{ - s32 pps_id, num_ref_idx_l0_active_minus1 = 0, num_ref_idx_l1_active_minus1 = 0; - - /*s->current_picture.reference= h->nal_ref_idc != 0;*/ - /*first_mb_in_slice = */gf_bs_get_ue(bs); - si->slice_type = gf_bs_get_ue(bs); - if (si->slice_type > 9) return -1; - - pps_id = gf_bs_get_ue(bs); - if (pps_id > 255) return -1; - si->pps = &avc->pps[pps_id]; - if (!si->pps->slice_group_count) return -2; - si->sps = &avc->sps[si->pps->sps_id]; - if (!si->sps->log2_max_frame_num) return -2; - avc->sps_active_idx = si->pps->sps_id; - avc->pps_active_idx = pps_id; - - si->frame_num = gf_bs_read_int(bs, si->sps->log2_max_frame_num); - - si->field_pic_flag = 0; - si->bottom_field_flag = 0; - if (!si->sps->frame_mbs_only_flag) { - si->field_pic_flag = gf_bs_read_int(bs, 1); - if (si->field_pic_flag) - si->bottom_field_flag = gf_bs_read_int(bs, 1); - } - - if ((si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) || svc_idr_flag) - si->idr_pic_id = gf_bs_get_ue(bs); - - if (si->sps->poc_type == 0) { - si->poc_lsb = gf_bs_read_int(bs, si->sps->log2_max_poc_lsb); - if (si->pps->pic_order_present && !si->field_pic_flag) { - si->delta_poc_bottom = gf_bs_get_se(bs); - } - } - else if ((si->sps->poc_type == 1) && !si->sps->delta_pic_order_always_zero_flag) { - si->delta_poc[0] = gf_bs_get_se(bs); - if ((si->pps->pic_order_present == 1) && !si->field_pic_flag) - si->delta_poc[1] = gf_bs_get_se(bs); - } - - if (si->pps->redundant_pic_cnt_present) { - si->redundant_pic_cnt = gf_bs_get_ue(bs); - } - - if (si->slice_type % 5 == GF_AVC_TYPE_B) { - /*direct_spatial_mv_pred_flag = */gf_bs_read_int(bs, 1); - } - - num_ref_idx_l0_active_minus1 = si->pps->num_ref_idx_l0_default_active_minus1; - num_ref_idx_l1_active_minus1 = si->pps->num_ref_idx_l1_default_active_minus1; - - if (si->slice_type % 5 == GF_AVC_TYPE_P || si->slice_type % 5 == GF_AVC_TYPE_SP || si->slice_type % 5 == GF_AVC_TYPE_B) { - Bool num_ref_idx_active_override_flag = gf_bs_read_int(bs, 1); - if (num_ref_idx_active_override_flag) { - num_ref_idx_l0_active_minus1 = gf_bs_get_ue(bs); - if (si->slice_type % 5 == GF_AVC_TYPE_B) { - num_ref_idx_l1_active_minus1 = gf_bs_get_ue(bs); - } - } - } - - if (si->nal_unit_type == 20 || si->nal_unit_type == 21) { - //ref_pic_list_mvc_modification(); /* specified in Annex H */ - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[avc-h264] unimplemented ref_pic_list_mvc_modification() in slide header\n")); - assert(0); - return -1; - } - else { - ref_pic_list_modification(bs, si->slice_type); - } - - if ((si->pps->weighted_pred_flag && (si->slice_type % 5 == GF_AVC_TYPE_P || si->slice_type % 5 == GF_AVC_TYPE_SP)) - || (si->pps->weighted_bipred_idc == 1 && si->slice_type % 5 == GF_AVC_TYPE_B)) { - pred_weight_table(bs, si->slice_type, si->sps->ChromaArrayType, num_ref_idx_l0_active_minus1, num_ref_idx_l1_active_minus1); - } - - if (si->nal_ref_idc != 0) { - dec_ref_pic_marking(bs, (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE)); - } - - if (si->pps->entropy_coding_mode_flag && si->slice_type % 5 != GF_AVC_TYPE_I && si->slice_type % 5 != GF_AVC_TYPE_SI) { - /*cabac_init_idc = */gf_bs_get_ue(bs); - } - - /*slice_qp_delta = */gf_bs_get_se(bs); - if (si->slice_type % 5 == GF_AVC_TYPE_SP || si->slice_type % 5 == GF_AVC_TYPE_SI) { - if (si->slice_type % 5 == GF_AVC_TYPE_SP) { - /*sp_for_switch_flag = */gf_bs_read_int(bs, 1); - } - /*slice_qs_delta = */gf_bs_get_se(bs); - } - - if (si->pps->deblocking_filter_control_present_flag) { - if (/*disable_deblocking_filter_idc*/ gf_bs_get_ue(bs) != 1) { - /*slice_alpha_c0_offset_div2 =*/ gf_bs_get_se(bs); - /*slice_beta_offset_div2 =*/ gf_bs_get_se(bs); - } - } - - if (si->pps->slice_group_count > 1 && si->pps->mb_slice_group_map_type >= 3 && si->pps->mb_slice_group_map_type <= 5) { - /*slice_group_change_cycle = */gf_bs_read_int(bs, (u32)ceil(log1p((si->pps->pic_size_in_map_units_minus1 + 1) / (si->pps->slice_group_change_rate_minus1 + 1) ) / log(2))); - } - - return 0; -} - - -static s32 svc_parse_slice(GF_BitStream *bs, AVCState *avc, AVCSliceInfo *si) -{ - s32 pps_id; - - /*s->current_picture.reference= h->nal_ref_idc != 0;*/ - /*first_mb_in_slice = */gf_bs_get_ue(bs); - si->slice_type = gf_bs_get_ue(bs); - if (si->slice_type > 9) return -1; - - pps_id = gf_bs_get_ue(bs); - if (pps_id > 255) - return -1; - si->pps = &avc->pps[pps_id]; - si->pps->id = pps_id; - if (!si->pps->slice_group_count) - return -2; - si->sps = &avc->sps[si->pps->sps_id + GF_SVC_SSPS_ID_SHIFT]; - if (!si->sps->log2_max_frame_num) - return -2; - - si->frame_num = gf_bs_read_int(bs, si->sps->log2_max_frame_num); - - si->field_pic_flag = 0; - if (si->sps->frame_mbs_only_flag) { - /*s->picture_structure= PICT_FRAME;*/ - } - else { - si->field_pic_flag = gf_bs_read_int(bs, 1); - if (si->field_pic_flag) si->bottom_field_flag = gf_bs_read_int(bs, 1); - } - if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE || si->NalHeader.idr_pic_flag) - si->idr_pic_id = gf_bs_get_ue(bs); - - if (si->sps->poc_type == 0) { - si->poc_lsb = gf_bs_read_int(bs, si->sps->log2_max_poc_lsb); - if (si->pps->pic_order_present && !si->field_pic_flag) { - si->delta_poc_bottom = gf_bs_get_se(bs); - } - } - else if ((si->sps->poc_type == 1) && !si->sps->delta_pic_order_always_zero_flag) { - si->delta_poc[0] = gf_bs_get_se(bs); - if ((si->pps->pic_order_present == 1) && !si->field_pic_flag) - si->delta_poc[1] = gf_bs_get_se(bs); - } - if (si->pps->redundant_pic_cnt_present) { - si->redundant_pic_cnt = gf_bs_get_ue(bs); - } - return 0; -} - - -static s32 avc_parse_recovery_point_sei(GF_BitStream *bs, AVCState *avc) -{ - AVCSeiRecoveryPoint *rp = &avc->sei.recovery_point; - - rp->frame_cnt = gf_bs_get_ue(bs); - rp->exact_match_flag = gf_bs_read_int(bs, 1); - rp->broken_link_flag = gf_bs_read_int(bs, 1); - rp->changing_slice_group_idc = gf_bs_read_int(bs, 2); - rp->valid = 1; - - return 0; -} - -/*for interpretation see ISO 14496-10 N.11084, table D-1*/ -static s32 avc_parse_pic_timing_sei(GF_BitStream *bs, AVCState *avc) -{ - int sps_id = avc->sps_active_idx; - const char NumClockTS[] = { 1, 1, 1, 2, 2, 3, 3, 2, 3 }; - AVCSeiPicTiming *pt = &avc->sei.pic_timing; - - if (sps_id < 0) { - /*sps_active_idx equals -1 when no sps has been detected. In this case SEI should not be decoded.*/ - assert(0); - return 1; - } - if (avc->sps[sps_id].vui.nal_hrd_parameters_present_flag || avc->sps[sps_id].vui.vcl_hrd_parameters_present_flag) { /*CpbDpbDelaysPresentFlag, see 14496-10(2003) E.11*/ - gf_bs_read_int(bs, 1 + avc->sps[sps_id].vui.hrd.cpb_removal_delay_length_minus1); /*cpb_removal_delay*/ - gf_bs_read_int(bs, 1 + avc->sps[sps_id].vui.hrd.dpb_output_delay_length_minus1); /*dpb_output_delay*/ - } - - /*ISO 14496-10 (2003), D.8.2: we need to get pic_struct in order to know if we display top field first or bottom field first*/ - if (avc->sps[sps_id].vui.pic_struct_present_flag) { - int i; - pt->pic_struct = gf_bs_read_int(bs, 4); - if (pt->pic_struct > 8) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[avc-h264] invalid pic_struct value %d\n", pt->pic_struct)); - return 1; - } - - for (i = 0; i < NumClockTS[pt->pic_struct]; i++) { - if (gf_bs_read_int(bs, 1)) {/*clock_timestamp_flag[i]*/ - Bool full_timestamp_flag; - gf_bs_read_int(bs, 2); /*ct_type*/ - gf_bs_read_int(bs, 1); /*nuit_field_based_flag*/ - gf_bs_read_int(bs, 5); /*counting_type*/ - full_timestamp_flag = gf_bs_read_int(bs, 1);/*full_timestamp_flag*/ - gf_bs_read_int(bs, 1); /*discontinuity_flag*/ - gf_bs_read_int(bs, 1); /*cnt_dropped_flag*/ - gf_bs_read_int(bs, 8); /*n_frames*/ - if (full_timestamp_flag) { - gf_bs_read_int(bs, 6); /*seconds_value*/ - gf_bs_read_int(bs, 6); /*minutes_value*/ - gf_bs_read_int(bs, 5); /*hours_value*/ - } - else { - if (gf_bs_read_int(bs, 1)) { /*seconds_flag*/ - gf_bs_read_int(bs, 6); /*seconds_value*/ - if (gf_bs_read_int(bs, 1)) { /*minutes_flag*/ - gf_bs_read_int(bs, 6); /*minutes_value*/ - if (gf_bs_read_int(bs, 1)) { /*hours_flag*/ - gf_bs_read_int(bs, 5); /*hours_value*/ - } - } - } - if (avc->sps[sps_id].vui.hrd.time_offset_length > 0) - gf_bs_read_int(bs, avc->sps[sps_id].vui.hrd.time_offset_length); /*time_offset*/ - } - } - } - } - - return 0; -} - - -#if !defined(GPAC_DISABLE_HEVC) -static void avc_parse_itu_t_t35_sei(GF_BitStream* bs, AVCSeiItuTT35DolbyVision *dovi) -{ - u8 itu_t_t35_country_code = gf_bs_read_u8(bs); - u16 terminal_provider_code = gf_bs_read_u16(bs); - u32 user_id = gf_bs_read_u32(bs); - u8 data_type_code = gf_bs_read_u8(bs); - if (itu_t_t35_country_code == 0xB5 && terminal_provider_code == 0x31 && user_id == 0x47413934 && (data_type_code == 0x8 || data_type_code == 0x9)) { - dovi->rpu_flag = GF_TRUE; - } -} -#endif - -static void avc_compute_poc(AVCSliceInfo *si) -{ - enum { - AVC_PIC_FRAME, - AVC_PIC_FIELD_TOP, - AVC_PIC_FIELD_BOTTOM, - } pic_type; - s32 field_poc[2] = { 0,0 }; - s32 max_frame_num; - - if (!si->sps) return; - - max_frame_num = 1 << (si->sps->log2_max_frame_num); - - /* picture type */ - if (si->sps->frame_mbs_only_flag || !si->field_pic_flag) pic_type = AVC_PIC_FRAME; - else if (si->bottom_field_flag) pic_type = AVC_PIC_FIELD_BOTTOM; - else pic_type = AVC_PIC_FIELD_TOP; - - /* frame_num_offset */ - if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) { - si->poc_lsb_prev = 0; - si->poc_msb_prev = 0; - si->frame_num_offset = 0; - } - else { - if (si->frame_num < si->frame_num_prev) - si->frame_num_offset = si->frame_num_offset_prev + max_frame_num; - else - si->frame_num_offset = si->frame_num_offset_prev; - } - - /*ISO 14496-10 N.11084 8.2.1.1*/ - if (si->sps->poc_type == 0) - { - const u32 max_poc_lsb = 1 << (si->sps->log2_max_poc_lsb); - - /*ISO 14496-10 N.11084 eq (8-3)*/ - if ((si->poc_lsb < si->poc_lsb_prev) && - (si->poc_lsb_prev - si->poc_lsb >= max_poc_lsb / 2)) - si->poc_msb = si->poc_msb_prev + max_poc_lsb; - else if ((si->poc_lsb > si->poc_lsb_prev) && - (si->poc_lsb - si->poc_lsb_prev > max_poc_lsb / 2)) - si->poc_msb = si->poc_msb_prev - max_poc_lsb; - else - si->poc_msb = si->poc_msb_prev; - - /*ISO 14496-10 N.11084 eq (8-4)*/ - if (pic_type != AVC_PIC_FIELD_BOTTOM) - field_poc[0] = si->poc_msb + si->poc_lsb; - - /*ISO 14496-10 N.11084 eq (8-5)*/ - if (pic_type != AVC_PIC_FIELD_TOP) { - if (!si->field_pic_flag) - field_poc[1] = field_poc[0] + si->delta_poc_bottom; - else - field_poc[1] = si->poc_msb + si->poc_lsb; - } - } - /*ISO 14496-10 N.11084 8.2.1.2*/ - else if (si->sps->poc_type == 1) - { - u32 i; - s32 abs_frame_num, expected_delta_per_poc_cycle, expected_poc; - - if (si->sps->poc_cycle_length) - abs_frame_num = si->frame_num_offset + si->frame_num; - else - abs_frame_num = 0; - - if (!si->nal_ref_idc && (abs_frame_num > 0)) abs_frame_num--; - - expected_delta_per_poc_cycle = 0; - for (i = 0; i < si->sps->poc_cycle_length; i++) - expected_delta_per_poc_cycle += si->sps->offset_for_ref_frame[i]; - - if (abs_frame_num > 0) { - const u32 poc_cycle_cnt = (abs_frame_num - 1) / si->sps->poc_cycle_length; - const u32 frame_num_in_poc_cycle = (abs_frame_num - 1) % si->sps->poc_cycle_length; - - expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle; - for (i = 0; i <= frame_num_in_poc_cycle; i++) - expected_poc += si->sps->offset_for_ref_frame[i]; - } - else { - expected_poc = 0; - } - - if (!si->nal_ref_idc) expected_poc += si->sps->offset_for_non_ref_pic; - - field_poc[0] = expected_poc + si->delta_poc[0]; - field_poc[1] = field_poc[0] + si->sps->offset_for_top_to_bottom_field; - if (pic_type == AVC_PIC_FRAME) field_poc[1] += si->delta_poc[1]; - } - /*ISO 14496-10 N.11084 8.2.1.3*/ - else if (si->sps->poc_type == 2) - { - int poc; - if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) { - poc = 0; - } - else { - const int abs_frame_num = si->frame_num_offset + si->frame_num; - poc = 2 * abs_frame_num; - if (!si->nal_ref_idc) poc -= 1; - } - field_poc[0] = poc; - field_poc[1] = poc; - } - - /*ISO 14496-10 N.11084 eq (8-1)*/ - if (pic_type == AVC_PIC_FRAME) - si->poc = MIN(field_poc[0], field_poc[1]); - else if (pic_type == AVC_PIC_FIELD_TOP) - si->poc = field_poc[0]; - else - si->poc = field_poc[1]; -} - -GF_EXPORT -s32 gf_media_avc_parse_nalu(GF_BitStream *bs, AVCState *avc) -{ - u8 idr_flag; - s32 slice, ret; - u32 nal_hdr; - AVCSliceInfo n_state; - - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - nal_hdr = gf_bs_read_u8(bs); - - slice = 0; - memcpy(&n_state, &avc->s_info, sizeof(AVCSliceInfo)); - avc->last_nal_type_parsed = n_state.nal_unit_type = nal_hdr & 0x1F; - n_state.nal_ref_idc = (nal_hdr >> 5) & 0x3; - - idr_flag = 0; - - switch (n_state.nal_unit_type) { - case GF_AVC_NALU_ACCESS_UNIT: - case GF_AVC_NALU_END_OF_SEQ: - case GF_AVC_NALU_END_OF_STREAM: - ret = 1; - break; - - case GF_AVC_NALU_SVC_SLICE: - SVC_ReadNal_header_extension(bs, &n_state.NalHeader); - // slice buffer - read the info and compare. - /*ret = */svc_parse_slice(bs, avc, &n_state); - if (avc->s_info.nal_ref_idc) { - n_state.poc_lsb_prev = avc->s_info.poc_lsb; - n_state.poc_msb_prev = avc->s_info.poc_msb; - } - avc_compute_poc(&n_state); - - if (avc->s_info.poc != n_state.poc) { - memcpy(&avc->s_info, &n_state, sizeof(AVCSliceInfo)); - return 1; - } - memcpy(&avc->s_info, &n_state, sizeof(AVCSliceInfo)); - return 0; - - case GF_AVC_NALU_SVC_PREFIX_NALU: - SVC_ReadNal_header_extension(bs, &n_state.NalHeader); - return 0; - - case GF_AVC_NALU_IDR_SLICE: - case GF_AVC_NALU_NON_IDR_SLICE: - case GF_AVC_NALU_DP_A_SLICE: - case GF_AVC_NALU_DP_B_SLICE: - case GF_AVC_NALU_DP_C_SLICE: - slice = 1; - /* slice buffer - read the info and compare.*/ - ret = avc_parse_slice(bs, avc, idr_flag, &n_state); - if (ret < 0) return ret; - ret = 0; - if ( - ((avc->s_info.nal_unit_type > GF_AVC_NALU_IDR_SLICE) || (avc->s_info.nal_unit_type < GF_AVC_NALU_NON_IDR_SLICE)) - && (avc->s_info.nal_unit_type != GF_AVC_NALU_SVC_SLICE) - ) { - break; - } - if (avc->s_info.frame_num != n_state.frame_num) { - ret = 1; - break; - } - - if (avc->s_info.field_pic_flag != n_state.field_pic_flag) { - ret = 1; - break; - } - if ((avc->s_info.nal_ref_idc != n_state.nal_ref_idc) && - (!avc->s_info.nal_ref_idc || !n_state.nal_ref_idc)) { - ret = 1; - break; - } - assert(avc->s_info.sps); - - if (avc->s_info.sps->poc_type == n_state.sps->poc_type) { - if (!avc->s_info.sps->poc_type) { - if (!n_state.bottom_field_flag && (avc->s_info.poc_lsb != n_state.poc_lsb)) { - ret = 1; - break; - } - if (avc->s_info.delta_poc_bottom != n_state.delta_poc_bottom) { - ret = 1; - break; - } - } - else if (avc->s_info.sps->poc_type == 1) { - if (avc->s_info.delta_poc[0] != n_state.delta_poc[0]) { - ret = 1; - break; - } - if (avc->s_info.delta_poc[1] != n_state.delta_poc[1]) { - ret = 1; - break; - } - } - } - - if (n_state.nal_unit_type == GF_AVC_NALU_IDR_SLICE) { - if (avc->s_info.nal_unit_type != GF_AVC_NALU_IDR_SLICE) { /*IdrPicFlag differs in value*/ - ret = 1; - break; - } - else if (avc->s_info.idr_pic_id != n_state.idr_pic_id) { /*both IDR and idr_pic_id differs*/ - ret = 1; - break; - } - } - break; - case GF_AVC_NALU_SEQ_PARAM: - avc->last_ps_idx = gf_media_avc_read_sps_bs_internal(bs, avc, 0, NULL, nal_hdr); - if (avc->last_ps_idx < 0) return -1; - return 0; - - case GF_AVC_NALU_PIC_PARAM: - avc->last_ps_idx = gf_media_avc_read_pps_bs_internal(bs, avc, nal_hdr); - if (avc->last_ps_idx < 0) return -1; - return 0; - case GF_AVC_NALU_SVC_SUBSEQ_PARAM: - avc->last_ps_idx = gf_media_avc_read_sps_bs_internal(bs, avc, 1, NULL, nal_hdr); - if (avc->last_ps_idx < 0) return -1; - return 0; - case GF_AVC_NALU_SEQ_PARAM_EXT: - avc->last_ps_idx = (s32) gf_bs_get_ue(bs); - if (avc->last_ps_idx < 0) return -1; - return 0; - - case GF_AVC_NALU_SEI: - case GF_AVC_NALU_FILLER_DATA: - return 0; - - default: - if (avc->s_info.nal_unit_type <= GF_AVC_NALU_IDR_SLICE) ret = 1; - //To detect change of AU when multiple sps and pps in stream - else if ((nal_hdr & 0x1F) == GF_AVC_NALU_SEI && avc->s_info.nal_unit_type == GF_AVC_NALU_SVC_SLICE) - ret = 1; - else if ((nal_hdr & 0x1F) == GF_AVC_NALU_SEQ_PARAM && avc->s_info.nal_unit_type == GF_AVC_NALU_SVC_SLICE) - ret = 1; - else - ret = 0; - break; - } - - /* save _prev values */ - if (ret && avc->s_info.sps) { - n_state.frame_num_offset_prev = avc->s_info.frame_num_offset; - if ((avc->s_info.sps->poc_type != 2) || (avc->s_info.nal_ref_idc != 0)) - n_state.frame_num_prev = avc->s_info.frame_num; - if (avc->s_info.nal_ref_idc) { - n_state.poc_lsb_prev = avc->s_info.poc_lsb; - n_state.poc_msb_prev = avc->s_info.poc_msb; - } - } - if (slice) - avc_compute_poc(&n_state); - memcpy(&avc->s_info, &n_state, sizeof(AVCSliceInfo)); - return ret; -} - - -u32 gf_media_avc_reformat_sei(u8 *buffer, u32 nal_size, Bool isobmf_rewrite, AVCState *avc) -{ - u32 ptype, psize, hdr, var; - u32 start; - GF_BitStream *bs; - GF_BitStream *bs_dest = NULL; - u8 nhdr; - Bool sei_removed = GF_FALSE; - char store; - - hdr = buffer[0]; - if ((hdr & 0x1F) != GF_AVC_NALU_SEI) return 0; - - if (isobmf_rewrite) bs_dest = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - - bs = gf_bs_new(buffer, nal_size, GF_BITSTREAM_READ); - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - nhdr = gf_bs_read_int(bs, 8); - if (bs_dest) gf_bs_write_int(bs_dest, nhdr, 8); - - /*parse SEI*/ - while (gf_bs_available(bs)) { - Bool do_copy; - ptype = 0; - while (1) { - u8 v = gf_bs_read_int(bs, 8); - ptype += v; - if (v != 0xFF) break; - } - - psize = 0; - while (1) { - u8 v = gf_bs_read_int(bs, 8); - psize += v; - if (v != 0xFF) break; - } - - start = (u32)gf_bs_get_position(bs); - - do_copy = 1; - - if (start + psize >= nal_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] SEI user message type %d size error (%d but %d remain), keeping full SEI untouched\n", ptype, psize, nal_size - start)); - if (bs_dest) gf_bs_del(bs_dest); - return nal_size; - } - switch (ptype) { - /*remove SEI messages forbidden in MP4*/ - case 3: /*filler data*/ - case 10: /*sub_seq info*/ - case 11: /*sub_seq_layer char*/ - case 12: /*sub_seq char*/ - do_copy = 0; - sei_removed = GF_TRUE; - break; - case 5: /*user unregistered */ - store = buffer[start + psize]; - buffer[start + psize] = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[avc-h264] SEI user message %s\n", buffer + start + 16)); - buffer[start + psize] = store; - break; - - case 6: /*recovery point*/ - avc_parse_recovery_point_sei(bs, avc); - break; - - case 1: /*pic_timing*/ - avc_parse_pic_timing_sei(bs, avc); - break; - - case 0: /*buffering period*/ - case 2: /*pan scan rect*/ - case 4: /*user registered ITU t35*/ - case 7: /*def_rec_pic_marking_repetition*/ - case 8: /*spare_pic*/ - case 9: /*scene info*/ - case 13: /*full frame freeze*/ - case 14: /*full frame freeze release*/ - case 15: /*full frame snapshot*/ - case 16: /*progressive refinement segment start*/ - case 17: /*progressive refinement segment end*/ - case 18: /*motion constrained slice group*/ - default: /*add all unknown SEIs*/ - break; - } - - if (do_copy && bs_dest) { - var = ptype; - while (var >= 255) { - gf_bs_write_int(bs_dest, 0xFF, 8); - var -= 255; - } - gf_bs_write_int(bs_dest, var, 8); - - var = psize; - while (var >= 255) { - gf_bs_write_int(bs_dest, 0xFF, 8); - var -= 255; - } - gf_bs_write_int(bs_dest, var, 8); - gf_bs_seek(bs, start); - - //bs_read_data does not skip EPB, read byte per byte - var = psize; - while (var) { - gf_bs_write_u8(bs_dest, gf_bs_read_u8(bs)); - var--; - } - } - else { - gf_bs_seek(bs, start); - - //bs_skip_bytes does not skip EPB, skip byte per byte - while (psize) { - gf_bs_read_u8(bs); - psize--; - } - } - - if (gf_bs_available(bs) <= 2) { - var = gf_bs_read_int(bs, 8); - if (var != 0x80) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] SEI user message has less than 2 bytes remaining but no end of sei found\n")); - } - if (bs_dest) gf_bs_write_int(bs_dest, 0x80, 8); - break; - } - } - gf_bs_del(bs); - //we cannot compare final size and original size since original may have EPB and final does not yet have them - if (bs_dest && sei_removed) { - u8 *dst_no_epb = NULL; - u32 dst_no_epb_size = 0; - gf_bs_get_content(bs_dest, &dst_no_epb, &dst_no_epb_size); - nal_size = gf_media_nalu_add_emulation_bytes(buffer, dst_no_epb, dst_no_epb_size); - } - if (bs_dest) gf_bs_del(bs_dest); - return nal_size; -} - - -static u8 avc_get_sar_idx(u32 w, u32 h) -{ - u32 i; - for (i = 0; i < 14; i++) { - if ((avc_sar[i].w == w) && (avc_sar[i].h == h)) return i; - } - return 0xFF; -} - -GF_Err gf_media_avc_change_par(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d) -{ - GF_BitStream *orig, *mod; - AVCState avc; - u32 i, bit_offset, flag; - s32 idx; - GF_AVCConfigSlot *slc; - orig = NULL; - - memset(&avc, 0, sizeof(AVCState)); - avc.sps_active_idx = -1; - - i = 0; - while ((slc = (GF_AVCConfigSlot *)gf_list_enum(avcc->sequenceParameterSets, &i))) { - u8 *no_emulation_buf = NULL; - u32 no_emulation_buf_size = 0, emulation_bytes = 0; - idx = gf_media_avc_read_sps(slc->data, slc->size, &avc, 0, &bit_offset); - if (idx < 0) { - if (orig) - gf_bs_del(orig); - continue; - } - - /*SPS still contains emulation bytes*/ - no_emulation_buf = gf_malloc((slc->size - 1) * sizeof(char)); - no_emulation_buf_size = gf_media_nalu_remove_emulation_bytes(slc->data + 1, no_emulation_buf, slc->size - 1); - - orig = gf_bs_new(no_emulation_buf, no_emulation_buf_size, GF_BITSTREAM_READ); - gf_bs_read_data(orig, no_emulation_buf, no_emulation_buf_size); - gf_bs_seek(orig, 0); - mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - - /*copy over till vui flag*/ - assert(bit_offset >= 8); - while (bit_offset - 8/*bit_offset doesn't take care of the first byte (NALU type)*/) { - flag = gf_bs_read_int(orig, 1); - gf_bs_write_int(mod, flag, 1); - bit_offset--; - } - /*check VUI*/ - flag = gf_bs_read_int(orig, 1); - gf_bs_write_int(mod, 1, 1); /*vui_parameters_present_flag*/ - if (flag) { - /*aspect_ratio_info_present_flag*/ - if (gf_bs_read_int(orig, 1)) { - s32 aspect_ratio_idc = gf_bs_read_int(orig, 8); - if (aspect_ratio_idc == 255) { - gf_bs_read_int(orig, 16); /*AR num*/ - gf_bs_read_int(orig, 16); /*AR den*/ - } - } - } - if ((ar_d < 0) || (ar_n < 0)) { - /*no AR signaled*/ - gf_bs_write_int(mod, 0, 1); - } - else { - u32 sarx; - gf_bs_write_int(mod, 1, 1); - sarx = avc_get_sar_idx((u32)ar_n, (u32)ar_d); - gf_bs_write_int(mod, sarx, 8); - if (sarx == 0xFF) { - gf_bs_write_int(mod, ar_n, 16); - gf_bs_write_int(mod, ar_d, 16); - } - } - /*no VUI in input bitstream, set all vui flags to 0*/ - if (!flag) { - gf_bs_write_int(mod, 0, 1); /*overscan_info_present_flag */ - gf_bs_write_int(mod, 0, 1); /*video_signal_type_present_flag */ - gf_bs_write_int(mod, 0, 1); /*chroma_location_info_present_flag */ - gf_bs_write_int(mod, 0, 1); /*timing_info_present_flag*/ - gf_bs_write_int(mod, 0, 1); /*nal_hrd_parameters_present*/ - gf_bs_write_int(mod, 0, 1); /*vcl_hrd_parameters_present*/ - gf_bs_write_int(mod, 0, 1); /*pic_struct_present*/ - gf_bs_write_int(mod, 0, 1); /*bitstream_restriction*/ - } - - /*finally copy over remaining*/ - while (gf_bs_bits_available(orig)) { - flag = gf_bs_read_int(orig, 1); - gf_bs_write_int(mod, flag, 1); - } - gf_bs_del(orig); - orig = NULL; - gf_free(no_emulation_buf); - - /*set anti-emulation*/ - gf_bs_get_content(mod, &no_emulation_buf, &flag); - emulation_bytes = gf_media_nalu_emulation_bytes_add_count(no_emulation_buf, flag); - if (flag + emulation_bytes + 1 > slc->size) - slc->data = (char*)gf_realloc(slc->data, flag + emulation_bytes + 1); - slc->size = gf_media_nalu_add_emulation_bytes(no_emulation_buf, slc->data + 1, flag) + 1; - - gf_bs_del(mod); - gf_free(no_emulation_buf); - } - return GF_OK; -} - -GF_EXPORT -GF_Err gf_avc_get_sps_info(u8 *sps_data, u32 sps_size, u32 *sps_id, u32 *width, u32 *height, s32 *par_n, s32 *par_d) -{ - AVCState avc; - s32 idx; - memset(&avc, 0, sizeof(AVCState)); - avc.sps_active_idx = -1; - - idx = gf_media_avc_read_sps(sps_data, sps_size, &avc, 0, NULL); - if (idx < 0) { - return GF_NON_COMPLIANT_BITSTREAM; - } - if (sps_id) *sps_id = idx; - - if (width) *width = avc.sps[idx].width; - if (height) *height = avc.sps[idx].height; - if (par_n) *par_n = avc.sps[idx].vui.par_num ? avc.sps[idx].vui.par_num : (u32)-1; - if (par_d) *par_d = avc.sps[idx].vui.par_den ? avc.sps[idx].vui.par_den : (u32)-1; - - return GF_OK; -} - -GF_EXPORT -GF_Err gf_avc_get_pps_info(u8 *pps_data, u32 pps_size, u32 *pps_id, u32 *sps_id) -{ - GF_BitStream *bs; - GF_Err e = GF_OK; - - bs = gf_bs_new(pps_data, pps_size, GF_BITSTREAM_READ); - if (!bs) { - e = GF_NON_COMPLIANT_BITSTREAM; - goto exit; - } - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - /*nal hdr*/ gf_bs_read_int(bs, 8); - - *pps_id = gf_bs_get_ue(bs); - *sps_id = gf_bs_get_ue(bs); - -exit: - gf_bs_del(bs); - return e; -} - -#ifndef GPAC_DISABLE_HEVC - -/********** -HEVC parsing -**********/ - -Bool gf_media_hevc_slice_is_intra(HEVCState *hevc) -{ - switch (hevc->s_info.nal_unit_type) { - case GF_HEVC_NALU_SLICE_BLA_W_LP: - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_N_LP: - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_IDR_N_LP: - case GF_HEVC_NALU_SLICE_CRA: - return GF_TRUE; - default: - return GF_FALSE; - } -} - -Bool gf_media_hevc_slice_is_IDR(HEVCState *hevc) -{ - if (hevc->sei.recovery_point.valid) - { - hevc->sei.recovery_point.valid = 0; - return GF_TRUE; - } - switch (hevc->s_info.nal_unit_type) { - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_IDR_N_LP: - return GF_TRUE; - default: - return GF_FALSE; - } -} - -static Bool parse_short_term_ref_pic_set(GF_BitStream *bs, HEVC_SPS *sps, u32 idx_rps) -{ - u32 i; - Bool inter_ref_pic_set_prediction_flag = 0; - if (idx_rps != 0) - inter_ref_pic_set_prediction_flag = gf_bs_read_int(bs, 1); - - if (inter_ref_pic_set_prediction_flag) { - HEVC_ReferencePictureSets *ref_ps, *rps; - u32 delta_idx_minus1 = 0; - u32 ref_idx; - u32 delta_rps_sign; - u32 abs_delta_rps_minus1, nb_ref_pics; - s32 deltaRPS; - u32 k = 0, k0 = 0, k1 = 0; - if (idx_rps == sps->num_short_term_ref_pic_sets) - delta_idx_minus1 = gf_bs_get_ue(bs); - - assert(delta_idx_minus1 <= idx_rps - 1); - ref_idx = idx_rps - 1 - delta_idx_minus1; - delta_rps_sign = gf_bs_read_int(bs, 1); - abs_delta_rps_minus1 = gf_bs_get_ue(bs); - deltaRPS = (1 - (delta_rps_sign << 1)) * (abs_delta_rps_minus1 + 1); - - rps = &sps->rps[idx_rps]; - ref_ps = &sps->rps[ref_idx]; - nb_ref_pics = ref_ps->num_negative_pics + ref_ps->num_positive_pics; - for (i = 0; i <= nb_ref_pics; i++) { - s32 ref_idc; - s32 used_by_curr_pic_flag = gf_bs_read_int(bs, 1); - ref_idc = used_by_curr_pic_flag ? 1 : 0; - if (!used_by_curr_pic_flag) { - used_by_curr_pic_flag = gf_bs_read_int(bs, 1); - ref_idc = used_by_curr_pic_flag << 1; - } - if ((ref_idc == 1) || (ref_idc == 2)) { - s32 deltaPOC = deltaRPS; - if (i < nb_ref_pics) - deltaPOC += ref_ps->delta_poc[i]; - - rps->delta_poc[k] = deltaPOC; - - if (deltaPOC < 0) k0++; - else k1++; - - k++; - } - } - rps->num_negative_pics = k0; - rps->num_positive_pics = k1; - } - else { - s32 prev = 0, poc; - sps->rps[idx_rps].num_negative_pics = gf_bs_get_ue(bs); - sps->rps[idx_rps].num_positive_pics = gf_bs_get_ue(bs); - if (sps->rps[idx_rps].num_negative_pics > 16) - return GF_FALSE; - if (sps->rps[idx_rps].num_positive_pics > 16) - return GF_FALSE; - for (i = 0; i < sps->rps[idx_rps].num_negative_pics; i++) { - u32 delta_poc_s0_minus1 = gf_bs_get_ue(bs); - poc = prev - delta_poc_s0_minus1 - 1; - prev = poc; - sps->rps[idx_rps].delta_poc[i] = poc; - /*used_by_curr_pic_s1_flag[ i ] = */gf_bs_read_int(bs, 1); - } - for (i = 0; i < sps->rps[idx_rps].num_positive_pics; i++) { - u32 delta_poc_s1_minus1 = gf_bs_get_ue(bs); - poc = prev + delta_poc_s1_minus1 + 1; - prev = poc; - sps->rps[idx_rps].delta_poc[i] = poc; - /*used_by_curr_pic_s1_flag[ i ] = */gf_bs_read_int(bs, 1); - } - } - return GF_TRUE; -} - -void hevc_pred_weight_table(GF_BitStream *bs, HEVCState *hevc, HEVCSliceInfo *si, HEVC_PPS *pps, HEVC_SPS *sps, u32 num_ref_idx_l0_active, u32 num_ref_idx_l1_active) -{ - u32 i, num_ref_idx; - Bool first_pass = GF_TRUE; - u8 luma_weights[20], chroma_weights[20]; - u32 ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc; - - num_ref_idx = num_ref_idx_l0_active; - - /*luma_log2_weight_denom=*/gf_bs_get_ue(bs); - if (ChromaArrayType != 0) - /*delta_chroma_log2_weight_denom=*/gf_bs_get_se(bs); - -parse_weights: - for (i = 0; i < num_ref_idx; i++) { - luma_weights[i] = gf_bs_read_int(bs, 1); - //infered to be 0 if not present - chroma_weights[i] = 0; - } - if (ChromaArrayType != 0) { - for (i = 0; i < num_ref_idx; i++) { - chroma_weights[i] = gf_bs_read_int(bs, 1); - } - } - for (i = 0; i < num_ref_idx; i++) { - if (luma_weights[i]) { - /*delta_luma_weight_l0[ i ]=*/gf_bs_get_se(bs); - /*luma_offset_l0[ i ]=*/gf_bs_get_se(bs); - } - if (chroma_weights[i]) { - /*delta_chroma_weight_l0[ i ][ 0 ]=*/gf_bs_get_se(bs); - /*delta_chroma_offset_l0[ i ][ 0 ]=*/gf_bs_get_se(bs); - - /*delta_chroma_weight_l0[ i ][ 1 ]=*/gf_bs_get_se(bs); - /*delta_chroma_offset_l0[ i ][ 1 ]=*/gf_bs_get_se(bs); - } - } - - if (si->slice_type == GF_HEVC_SLICE_TYPE_B) { - if (!first_pass) return; - first_pass = GF_FALSE; - num_ref_idx = num_ref_idx_l1_active; - goto parse_weights; - } -} - -static -Bool ref_pic_lists_modification(GF_BitStream *bs, u32 slice_type, u32 num_ref_idx_l0_active, u32 num_ref_idx_l1_active) -{ - //u32 i; - Bool ref_pic_list_modification_flag_l0 = gf_bs_read_int(bs, 1); - if (ref_pic_list_modification_flag_l0) { - /*for (i=0; ifirst_slice_segment_in_pic_flag = gf_bs_read_int(bs, 1); - - switch (si->nal_unit_type) { - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_IDR_N_LP: - IDRPicFlag = GF_TRUE; - RapPicFlag = GF_TRUE; - break; - case GF_HEVC_NALU_SLICE_BLA_W_LP: - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_N_LP: - case GF_HEVC_NALU_SLICE_CRA: - RapPicFlag = GF_TRUE; - break; - } - - if (RapPicFlag) { - /*Bool no_output_of_prior_pics_flag = */gf_bs_read_int(bs, 1); - } - - pps_id = gf_bs_get_ue(bs); - if (pps_id >= 64) - return -1; - - pps = &hevc->pps[pps_id]; - sps = &hevc->sps[pps->sps_id]; - si->sps = sps; - si->pps = pps; - - if (!si->first_slice_segment_in_pic_flag && pps->dependent_slice_segments_enabled_flag) { - si->dependent_slice_segment_flag = gf_bs_read_int(bs, 1); - } - else { - si->dependent_slice_segment_flag = GF_FALSE; - } - - if (!si->first_slice_segment_in_pic_flag) { - si->slice_segment_address = gf_bs_read_int(bs, sps->bitsSliceSegmentAddress); - } - else { - si->slice_segment_address = 0; - } - - if (!si->dependent_slice_segment_flag) { - Bool deblocking_filter_override_flag = 0; - Bool slice_temporal_mvp_enabled_flag = 0; - Bool slice_sao_luma_flag = 0; - Bool slice_sao_chroma_flag = 0; - Bool slice_deblocking_filter_disabled_flag = 0; - - //"slice_reserved_undetermined_flag[]" - gf_bs_read_int(bs, pps->num_extra_slice_header_bits); - - si->slice_type = gf_bs_get_ue(bs); - - if (pps->output_flag_present_flag) - /*pic_output_flag = */gf_bs_read_int(bs, 1); - - if (sps->separate_colour_plane_flag == 1) - /*colour_plane_id = */gf_bs_read_int(bs, 2); - - if (IDRPicFlag) { - si->poc_lsb = 0; - - //if not asked to parse full header, abort since we know the poc - if (!hevc->full_slice_header_parse) return 0; - - } - else { - si->poc_lsb = gf_bs_read_int(bs, sps->log2_max_pic_order_cnt_lsb); - - //if not asked to parse full header, abort once we have the poc - if (!hevc->full_slice_header_parse) return 0; - - if (/*short_term_ref_pic_set_sps_flag =*/gf_bs_read_int(bs, 1) == 0) { - Bool ret = parse_short_term_ref_pic_set(bs, sps, sps->num_short_term_ref_pic_sets); - if (!ret) - return -1; - } - else if (sps->num_short_term_ref_pic_sets > 1) { - u32 numbits = 0; - - while ((u32)(1 << numbits) < sps->num_short_term_ref_pic_sets) - numbits++; - if (numbits > 0) - /*s32 short_term_ref_pic_set_idx = */gf_bs_read_int(bs, numbits); - /*else - short_term_ref_pic_set_idx = 0;*/ - } - if (sps->long_term_ref_pics_present_flag) { - u8 DeltaPocMsbCycleLt[32]; - u32 num_long_term_sps = 0; - u32 num_long_term_pics = 0; - - memset(DeltaPocMsbCycleLt, 0, sizeof(u8) * 32); - - if (sps->num_long_term_ref_pic_sps > 0) { - num_long_term_sps = gf_bs_get_ue(bs); - } - num_long_term_pics = gf_bs_get_ue(bs); - - for (i = 0; i < num_long_term_sps + num_long_term_pics; i++) { - if (i < num_long_term_sps) { - if (sps->num_long_term_ref_pic_sps > 1) - /*u8 lt_idx_sps = */gf_bs_read_int(bs, gf_get_bit_size(sps->num_long_term_ref_pic_sps)); - } - else { - /*PocLsbLt[ i ] = */ gf_bs_read_int(bs, sps->log2_max_pic_order_cnt_lsb); - /*UsedByCurrPicLt[ i ] = */ gf_bs_read_int(bs, 1); - } - if (/*delta_poc_msb_present_flag[ i ] = */ gf_bs_read_int(bs, 1)) { - if (i == 0 || i == num_long_term_sps) - DeltaPocMsbCycleLt[i] = gf_bs_get_ue(bs); - else - DeltaPocMsbCycleLt[i] = gf_bs_get_ue(bs) + DeltaPocMsbCycleLt[i - 1]; - } - } - } - if (sps->temporal_mvp_enable_flag) - slice_temporal_mvp_enabled_flag = gf_bs_read_int(bs, 1); - } - if (sps->sample_adaptive_offset_enabled_flag) { - u32 ChromaArrayType = sps->separate_colour_plane_flag ? 0 : sps->chroma_format_idc; - slice_sao_luma_flag = gf_bs_read_int(bs, 1); - if (ChromaArrayType != 0) - slice_sao_chroma_flag = gf_bs_read_int(bs, 1); - } - - if (si->slice_type == GF_HEVC_SLICE_TYPE_P || si->slice_type == GF_HEVC_SLICE_TYPE_B) { - //u32 NumPocTotalCurr; - num_ref_idx_l0_active = pps->num_ref_idx_l0_default_active; - num_ref_idx_l1_active = 0; - if (si->slice_type == GF_HEVC_SLICE_TYPE_B) - num_ref_idx_l1_active = pps->num_ref_idx_l1_default_active; - - if ( /*num_ref_idx_active_override_flag =*/gf_bs_read_int(bs, 1)) { - num_ref_idx_l0_active = 1 + gf_bs_get_ue(bs); - if (si->slice_type == GF_HEVC_SLICE_TYPE_B) - num_ref_idx_l1_active = 1 + gf_bs_get_ue(bs); - } - - if (pps->lists_modification_present_flag /*TODO: && NumPicTotalCurr > 1*/) { - if (!ref_pic_lists_modification(bs, si->slice_type, num_ref_idx_l0_active, num_ref_idx_l1_active)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[hevc] ref_pic_lists_modification( ) not implemented\n")); - return -1; - } - } - - if (si->slice_type == GF_HEVC_SLICE_TYPE_B) - /*mvd_l1_zero_flag=*/gf_bs_read_int(bs, 1); - if (pps->cabac_init_present_flag) - /*cabac_init_flag=*/gf_bs_read_int(bs, 1); - - if (slice_temporal_mvp_enabled_flag) { - // When collocated_from_l0_flag is not present, it is inferred to be equal to 1. - Bool collocated_from_l0_flag = 1; - if (si->slice_type == GF_HEVC_SLICE_TYPE_B) - collocated_from_l0_flag = gf_bs_read_int(bs, 1); - - if ((collocated_from_l0_flag && (num_ref_idx_l0_active > 1)) - || (!collocated_from_l0_flag && (num_ref_idx_l1_active > 1)) - ) { - /*collocated_ref_idx=*/gf_bs_get_ue(bs); - } - } - - if ((pps->weighted_pred_flag && si->slice_type == GF_HEVC_SLICE_TYPE_P) - || (pps->weighted_bipred_flag && si->slice_type == GF_HEVC_SLICE_TYPE_B) - ) { - hevc_pred_weight_table(bs, hevc, si, pps, sps, num_ref_idx_l0_active, num_ref_idx_l1_active); - } - /*five_minus_max_num_merge_cand=*/gf_bs_get_ue(bs); - } - si->slice_qp_delta_start_bits = (s32) (gf_bs_get_position(bs) - 1) * 8 + gf_bs_get_bit_position(bs); - /*slice_qp_delta = */si->slice_qp_delta = gf_bs_get_se(bs); - - if (pps->slice_chroma_qp_offsets_present_flag) { - /*slice_cb_qp_offset=*/gf_bs_get_se(bs); - /*slice_cr_qp_offset=*/gf_bs_get_se(bs); - } - if (pps->deblocking_filter_override_enabled_flag) { - deblocking_filter_override_flag = gf_bs_read_int(bs, 1); - } - - if (deblocking_filter_override_flag) { - slice_deblocking_filter_disabled_flag = gf_bs_read_int(bs, 1); - if (!slice_deblocking_filter_disabled_flag) { - /*slice_beta_offset_div2=*/ gf_bs_get_se(bs); - /*slice_tc_offset_div2=*/gf_bs_get_se(bs); - } - } - if (pps->loop_filter_across_slices_enabled_flag - && (slice_sao_luma_flag || slice_sao_chroma_flag || !slice_deblocking_filter_disabled_flag) - ) { - /*slice_loop_filter_across_slices_enabled_flag = */gf_bs_read_int(bs, 1); - } - } - //dependent slice segment - else { - //if not asked to parse full header, abort - if (!hevc->full_slice_header_parse) return 0; - } - - si->entry_point_start_bits = ((u32)gf_bs_get_position(bs) - 1) * 8 + gf_bs_get_bit_position(bs); - - if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) { - u32 num_entry_point_offsets = gf_bs_get_ue(bs); - if (num_entry_point_offsets > 0) { - u32 offset = gf_bs_get_ue(bs) + 1; - u32 segments = offset >> 4; - s32 remain = (offset & 15); - - for (i = 0; i < num_entry_point_offsets; i++) { - //u32 res = 0; - for (j = 0; j < segments; j++) { - //res <<= 16; - /*res +=*/ gf_bs_read_int(bs, 16); - } - if (remain) { - //res <<= remain; - /* res += */ gf_bs_read_int(bs, remain); - } - // entry_point_offset = val + 1; // +1; // +1 to get the size - } - } - } - - if (pps->slice_segment_header_extension_present_flag) { - u32 size_ext = gf_bs_get_ue(bs); - while (size_ext) { - gf_bs_read_int(bs, 8); - size_ext--; - } - } - - si->header_size_bits = (gf_bs_get_position(bs) - 1) * 8 + gf_bs_get_bit_position(bs); // av_parser.c modified on 16 jan. 2019 - - if (gf_bs_read_int(bs, 1) == 0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("Error parsing slice header: byte_align not found at end of header !\n")); - } - - gf_bs_align(bs); - si->payload_start_offset = (s32)gf_bs_get_position(bs); - return 0; -} - -void gf_media_hevc_parse_sei(char *buffer, u32 nal_size, HEVCState *hevc) -{ - u32 ptype, psize, hdr; - u64 start; - GF_BitStream *bs; - - hdr = buffer[0]; - if (((hdr & 0x7e) >> 1) != GF_HEVC_NALU_SEI_PREFIX) return; - - bs = gf_bs_new(buffer, nal_size, GF_BITSTREAM_READ); - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - gf_bs_read_int(bs, 16); - - /*parse SEI*/ - while (gf_bs_available(bs)) { - ptype = 0; - while (gf_bs_peek_bits(bs, 8, 0)==0xFF) { - gf_bs_read_int(bs, 8); - ptype += 255; - } - ptype += gf_bs_read_int(bs, 8); - psize = 0; - while (gf_bs_peek_bits(bs, 8, 0)==0xFF) { - gf_bs_read_int(bs, 8); - psize += 255; - } - psize += gf_bs_read_int(bs, 8); - - start = gf_bs_get_position(bs); - if (start+psize >= nal_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[hevc-h265] SEI user message type %d size error (%d but %d remain), skipping SEI message\n", ptype, psize, nal_size-start)); - break; - } - - switch (ptype) { - case 4: /*user registered ITU-T T35*/ - { - GF_BitStream * itu_t_t35_bs = gf_bs_new(buffer + start, psize, GF_BITSTREAM_READ); - avc_parse_itu_t_t35_sei(itu_t_t35_bs, &hevc->sei.dovi); - gf_bs_del(itu_t_t35_bs); - } - default: break; - } - - gf_bs_skip_bytes(bs, (u64) psize); - gf_bs_align(bs); - if (gf_bs_available(bs) <= 2) - break; - } - gf_bs_del(bs); -} - -static void hevc_compute_poc(HEVCSliceInfo *si) -{ - u32 max_poc_lsb = 1 << (si->sps->log2_max_pic_order_cnt_lsb); - - /*POC reset for IDR frames, NOT for CRA*/ - switch (si->nal_unit_type) { - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_IDR_N_LP: - si->poc_lsb_prev = 0; - si->poc_msb_prev = 0; - break; - } - - if ((si->poc_lsb < si->poc_lsb_prev) && (si->poc_lsb_prev - si->poc_lsb >= max_poc_lsb / 2)) - si->poc_msb = si->poc_msb_prev + max_poc_lsb; - else if ((si->poc_lsb > si->poc_lsb_prev) && (si->poc_lsb - si->poc_lsb_prev > max_poc_lsb / 2)) - si->poc_msb = si->poc_msb_prev - max_poc_lsb; - else - si->poc_msb = si->poc_msb_prev; - - switch (si->nal_unit_type) { - case GF_HEVC_NALU_SLICE_BLA_W_LP: - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_N_LP: - si->poc_msb = 0; - break; - } - si->poc = si->poc_msb + si->poc_lsb; -} - - -static Bool hevc_parse_nal_header(GF_BitStream *bs, u8 *nal_unit_type, u8 *temporal_id, u8 *layer_id) -{ - u32 val; - val = gf_bs_read_int(bs, 1); - if (val) return GF_FALSE; - - val = gf_bs_read_int(bs, 6); - if (nal_unit_type) *nal_unit_type = val; - - val = gf_bs_read_int(bs, 6); - if (layer_id) *layer_id = val; - - val = gf_bs_read_int(bs, 3); - if (!val) - return GF_FALSE; - val -= 1; - if (temporal_id) *temporal_id = val; - return GF_TRUE; -} - - -void profile_tier_level(GF_BitStream *bs, Bool ProfilePresentFlag, u8 MaxNumSubLayersMinus1, HEVC_ProfileTierLevel *ptl) -{ - u32 i; - if (ProfilePresentFlag) { - ptl->profile_space = gf_bs_read_int(bs, 2); - ptl->tier_flag = gf_bs_read_int(bs, 1); - ptl->profile_idc = gf_bs_read_int(bs, 5); - - ptl->profile_compatibility_flag = gf_bs_read_int(bs, 32); - - ptl->general_progressive_source_flag = gf_bs_read_int(bs, 1); - ptl->general_interlaced_source_flag = gf_bs_read_int(bs, 1); - ptl->general_non_packed_constraint_flag = gf_bs_read_int(bs, 1); - ptl->general_frame_only_constraint_flag = gf_bs_read_int(bs, 1); - ptl->general_reserved_44bits = gf_bs_read_long_int(bs, 44); - } - ptl->level_idc = gf_bs_read_int(bs, 8); - for (i = 0; i < MaxNumSubLayersMinus1; i++) { - ptl->sub_ptl[i].profile_present_flag = gf_bs_read_int(bs, 1); - ptl->sub_ptl[i].level_present_flag = gf_bs_read_int(bs, 1); - } - if (MaxNumSubLayersMinus1 > 0) { - for (i = MaxNumSubLayersMinus1; i < 8; i++) { - /*reserved_zero_2bits*/gf_bs_read_int(bs, 2); - } - } - - for (i = 0; i < MaxNumSubLayersMinus1; i++) { - if (ptl->sub_ptl[i].profile_present_flag) { - ptl->sub_ptl[i].profile_space = gf_bs_read_int(bs, 2); - ptl->sub_ptl[i].tier_flag = gf_bs_read_int(bs, 1); - ptl->sub_ptl[i].profile_idc = gf_bs_read_int(bs, 5); - ptl->sub_ptl[i].profile_compatibility_flag = gf_bs_read_int(bs, 32); - /*ptl->sub_ptl[i].progressive_source_flag =*/ gf_bs_read_int(bs, 1); - /*ptl->sub_ptl[i].interlaced_source_flag =*/ gf_bs_read_int(bs, 1); - /*ptl->sub_ptl[i].non_packed_constraint_flag =*/ gf_bs_read_int(bs, 1); - /*ptl->sub_ptl[i].frame_only_constraint_flag =*/ gf_bs_read_int(bs, 1); - /*ptl->sub_ptl[i].reserved_44bits =*/ gf_bs_read_long_int(bs, 44); - } - if (ptl->sub_ptl[i].level_present_flag) - ptl->sub_ptl[i].level_idc = gf_bs_read_int(bs, 8); - } -} - -static u32 scalability_type_to_idx(HEVC_VPS *vps, u32 scalability_type) -{ - u32 idx = 0, type; - for (type = 0; type < scalability_type; type++) { - idx += (vps->scalability_mask[type] ? 1 : 0); - } - return idx; -} - -#define LHVC_VIEW_ORDER_INDEX 1 -#define LHVC_SCALABILITY_INDEX 2 - -static u32 lhvc_get_scalability_id(HEVC_VPS *vps, u32 layer_id_in_vps, u32 scalability_type) -{ - u32 idx; - if (!vps->scalability_mask[scalability_type]) return 0; - idx = scalability_type_to_idx(vps, scalability_type); - return vps->dimension_id[layer_id_in_vps][idx]; -} - -static u32 lhvc_get_view_index(HEVC_VPS *vps, u32 id) -{ - return lhvc_get_scalability_id(vps, vps->layer_id_in_vps[id], LHVC_VIEW_ORDER_INDEX); -} - -static u32 lhvc_get_num_views(HEVC_VPS *vps) -{ - u32 numViews = 1, i; - for (i = 0; i < vps->max_layers; i++) { - u32 layer_id = vps->layer_id_in_nuh[i]; - if (i > 0 && (lhvc_get_view_index(vps, layer_id) != lhvc_get_scalability_id(vps, i - 1, LHVC_VIEW_ORDER_INDEX))) { - numViews++; - } - } - return numViews; -} - -static void lhvc_parse_rep_format(HEVC_RepFormat *fmt, GF_BitStream *bs) -{ - u8 chroma_bitdepth_present_flag; - fmt->pic_width_luma_samples = gf_bs_read_int(bs, 16); - fmt->pic_height_luma_samples = gf_bs_read_int(bs, 16); - chroma_bitdepth_present_flag = gf_bs_read_int(bs, 1); - if (chroma_bitdepth_present_flag) { - fmt->chroma_format_idc = gf_bs_read_int(bs, 2); - - if (fmt->chroma_format_idc == 3) - fmt->separate_colour_plane_flag = gf_bs_read_int(bs, 1); - fmt->bit_depth_luma = 8 + gf_bs_read_int(bs, 4); - fmt->bit_depth_chroma = 8 + gf_bs_read_int(bs, 4); - } - if (/*conformance_window_vps_flag*/ gf_bs_read_int(bs, 1)) { - /*conf_win_vps_left_offset*/gf_bs_get_ue(bs); - /*conf_win_vps_right_offset*/gf_bs_get_ue(bs); - /*conf_win_vps_top_offset*/gf_bs_get_ue(bs); - /*conf_win_vps_bottom_offset*/gf_bs_get_ue(bs); - } -} - - -static Bool hevc_parse_vps_extension(HEVC_VPS *vps, GF_BitStream *bs) -{ - u8 splitting_flag, vps_nuh_layer_id_present_flag, view_id_len; - u32 i, j, num_scalability_types, num_add_olss, num_add_layer_set, num_indepentdent_layers, nb_bits, default_output_layer_idc = 0; - u8 dimension_id_len[16], dim_bit_offset[16]; - u8 /*avc_base_layer_flag, */NumLayerSets, /*default_one_target_output_layer_flag, */rep_format_idx_present_flag, ols_ids_to_ls_idx; - u8 layer_set_idx_for_ols_minus1[MAX_LHVC_LAYERS]; - u8 nb_output_layers_in_output_layer_set[MAX_LHVC_LAYERS + 1]; - u8 ols_highest_output_layer_id[MAX_LHVC_LAYERS + 1]; - - u32 k, d, r, p, iNuhLId, jNuhLId; - u8 num_direct_ref_layers[64], num_pred_layers[64], num_layers_in_tree_partition[MAX_LHVC_LAYERS]; - u8 dependency_flag[MAX_LHVC_LAYERS][MAX_LHVC_LAYERS], id_pred_layers[64][MAX_LHVC_LAYERS]; - // u8 num_ref_layers[64]; - // u8 tree_partition_layer_id[MAX_LHVC_LAYERS][MAX_LHVC_LAYERS]; - // u8 id_ref_layers[64][MAX_LHVC_LAYERS]; - // u8 id_direct_ref_layers[64][MAX_LHVC_LAYERS]; - u8 layer_id_in_list_flag[64]; - Bool OutputLayerFlag[MAX_LHVC_LAYERS][MAX_LHVC_LAYERS]; - - vps->vps_extension_found = 1; - if ((vps->max_layers > 1) && vps->base_layer_internal_flag) - profile_tier_level(bs, 0, vps->max_sub_layers - 1, &vps->ext_ptl[0]); - - splitting_flag = gf_bs_read_int(bs, 1); - num_scalability_types = 0; - for (i = 0; i < 16; i++) { - vps->scalability_mask[i] = gf_bs_read_int(bs, 1); - num_scalability_types += vps->scalability_mask[i]; - } - if (num_scalability_types >= 16) { - num_scalability_types = 16; - } - dimension_id_len[0] = 0; - for (i = 0; i < (num_scalability_types - splitting_flag); i++) { - dimension_id_len[i] = 1 + gf_bs_read_int(bs, 3); - } - - if (splitting_flag) { - for (i = 0; i < num_scalability_types; i++) { - dim_bit_offset[i] = 0; - for (j = 0; j < i; j++) - dim_bit_offset[i] += dimension_id_len[j]; - } - dimension_id_len[num_scalability_types - 1] = 1 + (5 - dim_bit_offset[num_scalability_types - 1]); - dim_bit_offset[num_scalability_types] = 6; - } - - vps_nuh_layer_id_present_flag = gf_bs_read_int(bs, 1); - vps->layer_id_in_nuh[0] = 0; - vps->layer_id_in_vps[0] = 0; - for (i = 1; i < vps->max_layers; i++) { - if (vps_nuh_layer_id_present_flag) { - vps->layer_id_in_nuh[i] = gf_bs_read_int(bs, 6); - } - else { - vps->layer_id_in_nuh[i] = i; - } - vps->layer_id_in_vps[vps->layer_id_in_nuh[i]] = i; - - if (!splitting_flag) { - for (j = 0; j < num_scalability_types; j++) { - vps->dimension_id[i][j] = gf_bs_read_int(bs, dimension_id_len[j]); - } - } - } - - if (splitting_flag) { - for (i = 0; i < vps->max_layers; i++) - for (j = 0; j < num_scalability_types; j++) - vps->dimension_id[i][j] = ((vps->layer_id_in_nuh[i] & ((1 << dim_bit_offset[j + 1]) - 1)) >> dim_bit_offset[j]); - } - else { - for (j = 0; j < num_scalability_types; j++) - vps->dimension_id[0][j] = 0; - } - - view_id_len = gf_bs_read_int(bs, 4); - if (view_id_len > 0) { - for (i = 0; i < lhvc_get_num_views(vps); i++) { - /*m_viewIdVal[i] = */ gf_bs_read_int(bs, view_id_len); - } - } - - for (i = 1; i < vps->max_layers; i++) { - for (j = 0; j < i; j++) { - vps->direct_dependency_flag[i][j] = gf_bs_read_int(bs, 1); - } - } - - //we do the test on MAX_LHVC_LAYERS and break in the loop to avoid a wrong GCC 4.8 warning on array bounds - for (i = 0; i < MAX_LHVC_LAYERS; i++) { - if (i >= vps->max_layers) break; - for (j = 0; j < vps->max_layers; j++) { - dependency_flag[i][j] = vps->direct_dependency_flag[i][j]; - for (k = 0; k < i; k++) - if (vps->direct_dependency_flag[i][k] && vps->direct_dependency_flag[k][j]) - dependency_flag[i][j] = 1; - } - } - - for (i = 0; i < vps->max_layers; i++) { - iNuhLId = vps->layer_id_in_nuh[i]; - d = r = p = 0; - for (j = 0; j < vps->max_layers; j++) { - jNuhLId = vps->layer_id_in_nuh[j]; - if (vps->direct_dependency_flag[i][j]) { - // id_direct_ref_layers[iNuhLId][d] = jNuhLId; - d++; - } - if (dependency_flag[i][j]) { - // id_ref_layers[iNuhLId][r] = jNuhLId; - r++; - } - - if (dependency_flag[j][i]) - id_pred_layers[iNuhLId][p++] = jNuhLId; - } - num_direct_ref_layers[iNuhLId] = d; - // num_ref_layers[iNuhLId] = r; - num_pred_layers[iNuhLId] = p; - } - - memset(layer_id_in_list_flag, 0, 64 * sizeof(u8)); - k = 0; //num_indepentdent_layers - for (i = 0; i < vps->max_layers; i++) { - iNuhLId = vps->layer_id_in_nuh[i]; - if (!num_direct_ref_layers[iNuhLId]) { - u32 h = 1; - //tree_partition_layer_id[k][0] = iNuhLId; - for (j = 0; j < num_pred_layers[iNuhLId]; j++) { - u32 predLId = id_pred_layers[iNuhLId][j]; - if (!layer_id_in_list_flag[predLId]) { - //tree_partition_layer_id[k][h++] = predLId; - layer_id_in_list_flag[predLId] = 1; - } - } - num_layers_in_tree_partition[k++] = h; - } - } - num_indepentdent_layers = k; - - num_add_layer_set = 0; - if (num_indepentdent_layers > 1) - num_add_layer_set = gf_bs_get_ue(bs); - - for (i = 0; i < num_add_layer_set; i++) - for (j = 1; j < num_indepentdent_layers; j++) { - nb_bits = 1; - while ((1 << nb_bits) < (num_layers_in_tree_partition[j] + 1)) - nb_bits++; - /*highest_layer_idx_plus1[i][j]*/gf_bs_read_int(bs, nb_bits); - } - - - if (/*vps_sub_layers_max_minus1_present_flag*/gf_bs_read_int(bs, 1)) { - for (i = 0; i < vps->max_layers; i++) { - /*sub_layers_vps_max_minus1[ i ]*/gf_bs_read_int(bs, 3); - } - } - - if (/*max_tid_ref_present_flag = */gf_bs_read_int(bs, 1)) { - for (i = 0; i < (vps->max_layers - 1); i++) { - for (j = i + 1; j < vps->max_layers; j++) { - if (vps->direct_dependency_flag[j][i]) - /*max_tid_il_ref_pics_plus1[ i ][ j ]*/gf_bs_read_int(bs, 3); - } - } - } - /*default_ref_layers_active_flag*/gf_bs_read_int(bs, 1); - - vps->num_profile_tier_level = 1 + gf_bs_get_ue(bs); - if (vps->num_profile_tier_level > MAX_LHVC_LAYERS) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Wrong number of PTLs in VPS %d\n", vps->num_profile_tier_level)); - vps->num_profile_tier_level = 1; - return GF_FALSE; - } - - for (i = vps->base_layer_internal_flag ? 2 : 1; i < vps->num_profile_tier_level; i++) { - Bool vps_profile_present_flag = gf_bs_read_int(bs, 1); - profile_tier_level(bs, vps_profile_present_flag, vps->max_sub_layers - 1, &vps->ext_ptl[i - 1]); - } - - NumLayerSets = vps->num_layer_sets + num_add_layer_set; - num_add_olss = 0; - - if (NumLayerSets > 1) { - num_add_olss = gf_bs_get_ue(bs); - default_output_layer_idc = gf_bs_read_int(bs, 2); - default_output_layer_idc = default_output_layer_idc < 2 ? default_output_layer_idc : 2; - } - vps->num_output_layer_sets = num_add_olss + NumLayerSets; - - - layer_set_idx_for_ols_minus1[0] = 1; - vps->output_layer_flag[0][0] = 1; - - for (i = 0; i < vps->num_output_layer_sets; i++) { - if ((NumLayerSets > 2) && (i >= NumLayerSets)) { - nb_bits = 1; - while ((1 << nb_bits) < (NumLayerSets - 1)) - nb_bits++; - layer_set_idx_for_ols_minus1[i] = gf_bs_read_int(bs, nb_bits); - } - else - layer_set_idx_for_ols_minus1[i] = 0; - ols_ids_to_ls_idx = i < NumLayerSets ? i : layer_set_idx_for_ols_minus1[i] + 1; - - if ((i > (vps->num_layer_sets - 1)) || (default_output_layer_idc == 2)) { - for (j = 0; j < vps->num_layers_in_id_list[ols_ids_to_ls_idx]; j++) - vps->output_layer_flag[i][j] = gf_bs_read_int(bs, 1); - } - - if ((default_output_layer_idc == 0) || (default_output_layer_idc == 1)) { - for (j = 0; j < vps->num_layers_in_id_list[ols_ids_to_ls_idx]; j++) { - if ((default_output_layer_idc == 0) || (vps->LayerSetLayerIdList[i][j] == vps->LayerSetLayerIdListMax[i])) - OutputLayerFlag[i][j] = GF_TRUE; - else - OutputLayerFlag[i][j] = GF_FALSE; - } - } - - for (j = 0; j < vps->num_layers_in_id_list[ols_ids_to_ls_idx]; j++) { - if (OutputLayerFlag[i][j]) { - u32 curLayerID; - vps->necessary_layers_flag[i][j] = GF_TRUE; - curLayerID = vps->LayerSetLayerIdList[i][j]; - for (k = 0; k < j; k++) { - u32 refLayerId = vps->LayerSetLayerIdList[i][k]; - if (dependency_flag[vps->layer_id_in_vps[curLayerID]][vps->layer_id_in_vps[refLayerId]]) - vps->necessary_layers_flag[i][k] = GF_TRUE; - } - } - } - vps->num_necessary_layers[i] = 0; - for (j = 0; j < vps->num_layers_in_id_list[ols_ids_to_ls_idx]; j++) { - if (vps->necessary_layers_flag[i][j]) - vps->num_necessary_layers[i] += 1; - } - - if (i == 0) { - if (vps->base_layer_internal_flag) { - if (vps->max_layers > 1) - vps->profile_tier_level_idx[0][0] = 1; - else - vps->profile_tier_level_idx[0][0] = 0; - } - continue; - } - nb_bits = 1; - while ((u32)(1 << nb_bits) < vps->num_profile_tier_level) - nb_bits++; - for (j = 0; j < vps->num_layers_in_id_list[ols_ids_to_ls_idx]; j++) - if (vps->necessary_layers_flag[i][j] && vps->num_profile_tier_level) - vps->profile_tier_level_idx[i][j] = gf_bs_read_int(bs, nb_bits); - else - vps->profile_tier_level_idx[i][j] = 0; - - - nb_output_layers_in_output_layer_set[i] = 0; - for (j = 0; j < vps->num_layers_in_id_list[ols_ids_to_ls_idx]; j++) { - nb_output_layers_in_output_layer_set[i] += OutputLayerFlag[i][j]; - if (OutputLayerFlag[i][j]) { - ols_highest_output_layer_id[i] = vps->LayerSetLayerIdList[ols_ids_to_ls_idx][j]; - } - } - if (nb_output_layers_in_output_layer_set[i] == 1 && ols_highest_output_layer_id[i] > 0) - vps->alt_output_layer_flag[i] = gf_bs_read_int(bs, 1); - } - - vps->num_rep_formats = 1 + gf_bs_get_ue(bs); - if (vps->num_rep_formats > 16) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Wrong number of rep formats in VPS %d\n", vps->num_rep_formats)); - vps->num_rep_formats = 0; - return GF_FALSE; - } - - for (i = 0; i < vps->num_rep_formats; i++) { - lhvc_parse_rep_format(&vps->rep_formats[i], bs); - } - if (vps->num_rep_formats > 1) - rep_format_idx_present_flag = gf_bs_read_int(bs, 1); - else - rep_format_idx_present_flag = 0; - - vps->rep_format_idx[0] = 0; - nb_bits = 1; - while ((u32)(1 << nb_bits) < vps->num_rep_formats) - nb_bits++; - for (i = vps->base_layer_internal_flag ? 1 : 0; i < vps->max_layers; i++) { - if (rep_format_idx_present_flag) { - vps->rep_format_idx[i] = gf_bs_read_int(bs, nb_bits); - } - else { - vps->rep_format_idx[i] = i < vps->num_rep_formats - 1 ? i : vps->num_rep_formats - 1; - } - } - //TODO - we don't use the rest ... - - return GF_TRUE; -} - -static void sub_layer_hrd_parameters(GF_BitStream *bs, int subLayerId, u32 cpb_cnt, Bool sub_pic_hrd_params_present_flag) -{ - u32 i; - if (!gf_bs_available(bs)) return; - - for (i = 0; i <= cpb_cnt; i++) { - /*bit_rate_value_minus1[i] = */gf_bs_get_ue(bs); - /*cpb_size_value_minus1[i] = */gf_bs_get_ue(bs); - if (sub_pic_hrd_params_present_flag) { - /*cpb_size_du_value_minus1[i] = */gf_bs_get_ue(bs); - /*bit_rate_du_value_minus1[i] = */gf_bs_get_ue(bs); - } - /*cbr_flag[i] = */gf_bs_read_int(bs, 1); - } -} - -static void hevc_parse_hrd_parameters(GF_BitStream *bs, Bool commonInfPresentFlag, int maxNumSubLayersMinus1) -{ - int i; - Bool nal_hrd_parameters_present_flag = GF_FALSE; - Bool vcl_hrd_parameters_present_flag = GF_FALSE; - Bool sub_pic_hrd_params_present_flag = GF_FALSE; - if (commonInfPresentFlag) { - nal_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); - vcl_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); - if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) { - sub_pic_hrd_params_present_flag = gf_bs_read_int(bs, 1); - if (sub_pic_hrd_params_present_flag) { - /*tick_divisor_minus2 = */gf_bs_read_int(bs, 8); - /*du_cpb_removal_delay_increment_length_minus1 = */gf_bs_read_int(bs, 5); - /*sub_pic_cpb_params_in_pic_timing_sei_flag = */gf_bs_read_int(bs, 1); - /*dpb_output_delay_du_length_minus1 = */gf_bs_read_int(bs, 5); - } - /*bit_rate_scale = */gf_bs_read_int(bs, 4); - /*cpb_size_scale = */gf_bs_read_int(bs, 4); - if (sub_pic_hrd_params_present_flag) { - /*cpb_size_du_scale = */gf_bs_read_int(bs, 4); - } - /*initial_cpb_removal_delay_length_minus1 = */gf_bs_read_int(bs, 5); - /*au_cpb_removal_delay_length_minus1 = */gf_bs_read_int(bs, 5); - /*dpb_output_delay_length_minus1 = */gf_bs_read_int(bs, 5); - } - } - for (i = 0; i <= maxNumSubLayersMinus1; i++) { - Bool fixed_pic_rate_general_flag_i = gf_bs_read_int(bs, 1); - Bool fixed_pic_rate_within_cvs_flag_i = GF_TRUE; - Bool low_delay_hrd_flag_i = GF_FALSE; - u32 cpb_cnt_minus1_i = 0; - if (!fixed_pic_rate_general_flag_i) { - fixed_pic_rate_within_cvs_flag_i = gf_bs_read_int(bs, 1); - } - if (fixed_pic_rate_within_cvs_flag_i) - /*elemental_duration_in_tc_minus1[i] = */gf_bs_get_ue(bs); - else - low_delay_hrd_flag_i = gf_bs_read_int(bs, 1); - if (!low_delay_hrd_flag_i) { - cpb_cnt_minus1_i = gf_bs_get_ue(bs); - } - if (nal_hrd_parameters_present_flag) { - sub_layer_hrd_parameters(bs, i, cpb_cnt_minus1_i, sub_pic_hrd_params_present_flag); - } - if (vcl_hrd_parameters_present_flag) { - sub_layer_hrd_parameters(bs, i, cpb_cnt_minus1_i, sub_pic_hrd_params_present_flag); - } - } -} - -static s32 gf_media_hevc_read_vps_bs_internal(GF_BitStream *bs, HEVCState *hevc, Bool stop_at_vps_ext) -{ - u8 vps_sub_layer_ordering_info_present_flag, vps_extension_flag; - u32 i, j; - s32 vps_id; - HEVC_VPS *vps; - u8 layer_id_included_flag[MAX_LHVC_LAYERS][64]; - - //nalu header already parsed - vps_id = gf_bs_read_int(bs, 4); - - if (vps_id >= 16) return -1; - - vps = &hevc->vps[vps_id]; - vps->bit_pos_vps_extensions = -1; - if (!vps->state) { - vps->id = vps_id; - vps->state = 1; - } - - vps->base_layer_internal_flag = gf_bs_read_int(bs, 1); - vps->base_layer_available_flag = gf_bs_read_int(bs, 1); - vps->max_layers = 1 + gf_bs_read_int(bs, 6); - if (vps->max_layers > MAX_LHVC_LAYERS) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] sorry, %d layers in VPS but only %d supported\n", vps->max_layers, MAX_LHVC_LAYERS)); - return -1; - } - vps->max_sub_layers = gf_bs_read_int(bs, 3) + 1; - vps->temporal_id_nesting = gf_bs_read_int(bs, 1); - /* vps_reserved_ffff_16bits = */ gf_bs_read_int(bs, 16); - profile_tier_level(bs, 1, vps->max_sub_layers - 1, &vps->ptl); - - vps_sub_layer_ordering_info_present_flag = gf_bs_read_int(bs, 1); - for (i = (vps_sub_layer_ordering_info_present_flag ? 0 : vps->max_sub_layers - 1); i < vps->max_sub_layers; i++) { - /*vps_max_dec_pic_buffering_minus1[i] = */gf_bs_get_ue(bs); - /*vps_max_num_reorder_pics[i] = */gf_bs_get_ue(bs); - /*vps_max_latency_increase_plus1[i] = */gf_bs_get_ue(bs); - } - vps->max_layer_id = gf_bs_read_int(bs, 6); - if (vps->max_layer_id > MAX_LHVC_LAYERS) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] VPS max layer ID %u but GPAC only supports %u\n", vps->max_layer_id, MAX_LHVC_LAYERS)); - return -1; - } - vps->num_layer_sets = gf_bs_get_ue(bs) + 1; - if (vps->num_layer_sets > MAX_LHVC_LAYERS) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Wrong number of layer sets in VPS %d\n", vps->num_layer_sets)); - return -1; - } - for (i = 1; i < vps->num_layer_sets; i++) { - for (j = 0; j <= vps->max_layer_id; j++) { - layer_id_included_flag[i][j] = gf_bs_read_int(bs, 1); - } - } - vps->num_layers_in_id_list[0] = 1; - for (i = 1; i < vps->num_layer_sets; i++) { - u32 n, m; - n = 0; - for (m = 0; m <= vps->max_layer_id; m++) { - if (layer_id_included_flag[i][m]) { - vps->LayerSetLayerIdList[i][n++] = m; - if (vps->LayerSetLayerIdListMax[i] < m) - vps->LayerSetLayerIdListMax[i] = m; - } - } - vps->num_layers_in_id_list[i] = n; - } - if (/*vps_timing_info_present_flag*/gf_bs_read_int(bs, 1)) { - u32 vps_num_hrd_parameters; - /*u32 vps_num_units_in_tick = */gf_bs_read_int(bs, 32); - /*u32 vps_time_scale = */gf_bs_read_int(bs, 32); - if (/*vps_poc_proportional_to_timing_flag*/gf_bs_read_int(bs, 1)) { - /*vps_num_ticks_poc_diff_one_minus1*/gf_bs_get_ue(bs); - } - vps_num_hrd_parameters = gf_bs_get_ue(bs); - for (i = 0; i < vps_num_hrd_parameters; i++) { - Bool cprms_present_flag = GF_TRUE; - /*hrd_layer_set_idx[i] = */gf_bs_get_ue(bs); - if (i > 0) - cprms_present_flag = gf_bs_read_int(bs, 1); - hevc_parse_hrd_parameters(bs, cprms_present_flag, vps->max_sub_layers - 1); - } - } - if (stop_at_vps_ext) { - return vps_id; - } - - vps_extension_flag = gf_bs_read_int(bs, 1); - if (vps_extension_flag) { - Bool res; - gf_bs_align(bs); - res = hevc_parse_vps_extension(vps, bs); - if (res != GF_TRUE) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Failed to parse VPS extensions\n")); - return -1; - } - if (/*vps_extension2_flag*/gf_bs_read_int(bs, 1)) { -#if 0 - while (gf_bs_available(bs)) { - /*vps_extension_data_flag */ gf_bs_read_int(bs, 1); - } -#endif - - } - } - return vps_id; -} - -GF_EXPORT -s32 gf_media_hevc_read_vps_ex(u8 *data, u32 *size, HEVCState *hevc, Bool remove_extensions) -{ - GF_BitStream *bs; - char *data_without_emulation_bytes = NULL; - u32 data_without_emulation_bytes_size = 0; - s32 vps_id = -1; - - /*still contains emulation bytes*/ - data_without_emulation_bytes_size = remove_extensions ? gf_media_nalu_emulation_bytes_remove_count(data, (*size)) : 0; - if (!data_without_emulation_bytes_size) { - bs = gf_bs_new(data, (*size), GF_BITSTREAM_READ); - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - } - //when removing VPS ext, we have to get the full buffer without emulation prevention bytes becuase we do a bit-by-bit copy of the vps - else { - data_without_emulation_bytes = gf_malloc((*size) * sizeof(char)); - data_without_emulation_bytes_size = gf_media_nalu_remove_emulation_bytes(data, data_without_emulation_bytes, (*size)); - bs = gf_bs_new(data_without_emulation_bytes, data_without_emulation_bytes_size, GF_BITSTREAM_READ); - } - if (!bs) goto exit; - - - if (!hevc_parse_nal_header(bs, NULL, NULL, NULL)) goto exit; - - vps_id = gf_media_hevc_read_vps_bs_internal(bs, hevc, remove_extensions); - if (vps_id < 0) goto exit; - - if (remove_extensions) { - u8 *new_vps; - u32 new_vps_size, emulation_bytes; - u32 bit_pos = gf_bs_get_bit_offset(bs); - GF_BitStream *w_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - gf_bs_seek(bs, 0); - gf_bs_write_u8(w_bs, gf_bs_read_u8(bs) ); - gf_bs_write_u8(w_bs, gf_bs_read_u8(bs) ); - gf_bs_write_u8(w_bs, gf_bs_read_u8(bs) ); - gf_bs_write_u8(w_bs, gf_bs_read_u8(bs) ); - gf_bs_write_u16(w_bs, gf_bs_read_u16(bs) ); - bit_pos -= 48; - while (bit_pos) { - u32 v = gf_bs_read_int(bs, 1); - gf_bs_write_int(w_bs, v, 1); - bit_pos--; - } - /*vps extension flag*/ - gf_bs_write_int(w_bs, 0, 1); - new_vps = NULL; - gf_bs_get_content(w_bs, &new_vps, &new_vps_size); - gf_bs_del(w_bs); - - emulation_bytes = gf_media_nalu_emulation_bytes_add_count(new_vps, new_vps_size); - if (emulation_bytes + new_vps_size > *size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("Buffer too small to rewrite VPS - skipping rewrite\n")); - } - else { - *size = gf_media_nalu_add_emulation_bytes(new_vps, data, new_vps_size); - } - if (new_vps) - gf_free(new_vps); - } - -exit: - if (bs) - gf_bs_del(bs); - if (data_without_emulation_bytes) gf_free(data_without_emulation_bytes); - return vps_id; -} - -GF_EXPORT -s32 gf_media_hevc_read_vps(u8 *data, u32 size, HEVCState *hevc) -{ - return gf_media_hevc_read_vps_ex(data, &size, hevc, GF_FALSE); -} - -GF_EXPORT -s32 gf_media_hevc_read_vps_bs(GF_BitStream *bs, HEVCState *hevc) -{ - if (!bs || !hevc) return -1; - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - if (!hevc_parse_nal_header(bs, NULL, NULL, NULL)) return -1; - return gf_media_hevc_read_vps_bs_internal(bs, hevc, GF_FALSE); -} - -static void hevc_scaling_list_data(GF_BitStream *bs) -{ - u32 i, sizeId, matrixId; - for (sizeId = 0; sizeId < 4; sizeId++) { - for (matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) { - u32 scaling_list_pred_mode_flag_sizeId_matrixId = gf_bs_read_int(bs, 1); - if (!scaling_list_pred_mode_flag_sizeId_matrixId) { - /*scaling_list_pred_matrix_id_delta[ sizeId ][ matrixId ] =*/ gf_bs_get_ue(bs); - } - else { - //u32 nextCoef = 8; - u32 coefNum = MIN(64, (1 << (4 + (sizeId << 1)))); - if (sizeId > 1) { - /*scaling_list_dc_coef_minus8[ sizeId - 2 ][ matrixId ] = */gf_bs_get_se(bs); - } - for (i = 0; i < coefNum; i++) { - /*scaling_list_delta_coef = */gf_bs_get_se(bs); - } - } - } - } -} - - -static const struct { - u32 w, h; -} hevc_sar[17] = -{ - { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, - { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 }, - { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 }, - { 64, 33 }, { 160,99 }, { 4,3}, { 3,2}, { 2,1} -}; - -static s32 gf_media_hevc_read_sps_bs_internal(GF_BitStream *bs, HEVCState *hevc, u8 layer_id, u32 *vui_flag_pos) -{ - s32 vps_id, sps_id = -1; - u32 i, nb_CTUs, depth; - HEVC_SPS *sps; - HEVC_VPS *vps; - HEVC_ProfileTierLevel ptl; - Bool multiLayerExtSpsFlag; - u8 sps_ext_or_max_sub_layers_minus1, max_sub_layers_minus1; - - if (vui_flag_pos) *vui_flag_pos = 0; - - //nalu header already parsed - vps_id = gf_bs_read_int(bs, 4); - if (vps_id >= 16) { - return -1; - } - memset(&ptl, 0, sizeof(ptl)); - max_sub_layers_minus1 = 0; - sps_ext_or_max_sub_layers_minus1 = 0; - if (layer_id == 0) - max_sub_layers_minus1 = gf_bs_read_int(bs, 3); - else - sps_ext_or_max_sub_layers_minus1 = gf_bs_read_int(bs, 3); - multiLayerExtSpsFlag = (layer_id != 0) && (sps_ext_or_max_sub_layers_minus1 == 7); - if (!multiLayerExtSpsFlag) { - /*temporal_id_nesting_flag = */gf_bs_read_int(bs, 1); - profile_tier_level(bs, 1, max_sub_layers_minus1, &ptl); - } - - sps_id = gf_bs_get_ue(bs); - if ((sps_id < 0) || (sps_id >= 16)) { - return -1; - } - - sps = &hevc->sps[sps_id]; - if (!sps->state) { - sps->state = 1; - sps->id = sps_id; - sps->vps_id = vps_id; - } - sps->ptl = ptl; - vps = &hevc->vps[vps_id]; - sps->max_sub_layers_minus1 = 0; - sps->sps_ext_or_max_sub_layers_minus1 = 0; - - /* default values */ - sps->colour_primaries = 2; - sps->transfer_characteristic = 2; - sps->matrix_coeffs = 2; - - //sps_rep_format_idx = 0; - if (multiLayerExtSpsFlag) { - sps->update_rep_format_flag = gf_bs_read_int(bs, 1); - if (sps->update_rep_format_flag) { - sps->rep_format_idx = gf_bs_read_int(bs, 8); - } - else { - sps->rep_format_idx = vps->rep_format_idx[layer_id]; - } - sps->width = vps->rep_formats[sps->rep_format_idx].pic_width_luma_samples; - sps->height = vps->rep_formats[sps->rep_format_idx].pic_height_luma_samples; - sps->chroma_format_idc = vps->rep_formats[sps->rep_format_idx].chroma_format_idc; - sps->bit_depth_luma = vps->rep_formats[sps->rep_format_idx].bit_depth_luma; - sps->bit_depth_chroma = vps->rep_formats[sps->rep_format_idx].bit_depth_chroma; - sps->separate_colour_plane_flag = vps->rep_formats[sps->rep_format_idx].separate_colour_plane_flag; - - //TODO this is crude ... - sps->ptl = vps->ext_ptl[0]; - } - else { - sps->chroma_format_idc = gf_bs_get_ue(bs); - if (sps->chroma_format_idc == 3) - sps->separate_colour_plane_flag = gf_bs_read_int(bs, 1); - sps->width = gf_bs_get_ue(bs); - sps->height = gf_bs_get_ue(bs); - if ((sps->cw_flag = gf_bs_read_int(bs, 1))) { - u32 SubWidthC, SubHeightC; - - if (sps->chroma_format_idc == 1) { - SubWidthC = SubHeightC = 2; - } - else if (sps->chroma_format_idc == 2) { - SubWidthC = 2; - SubHeightC = 1; - } - else { - SubWidthC = SubHeightC = 1; - } - - sps->cw_left = gf_bs_get_ue(bs); - sps->cw_right = gf_bs_get_ue(bs); - sps->cw_top = gf_bs_get_ue(bs); - sps->cw_bottom = gf_bs_get_ue(bs); - - sps->width -= SubWidthC * (sps->cw_left + sps->cw_right); - sps->height -= SubHeightC * (sps->cw_top + sps->cw_bottom); - } - sps->bit_depth_luma = 8 + gf_bs_get_ue(bs); - sps->bit_depth_chroma = 8 + gf_bs_get_ue(bs); - } - - sps->log2_max_pic_order_cnt_lsb = 4 + gf_bs_get_ue(bs); - - if (!multiLayerExtSpsFlag) { - sps->sub_layer_ordering_info_present_flag = gf_bs_read_int(bs, 1); - for (i = sps->sub_layer_ordering_info_present_flag ? 0 : sps->max_sub_layers_minus1; i <= sps->max_sub_layers_minus1; i++) { - /*max_dec_pic_buffering = */ gf_bs_get_ue(bs); - /*num_reorder_pics = */ gf_bs_get_ue(bs); - /*max_latency_increase = */ gf_bs_get_ue(bs); - } - } - - sps->log2_min_luma_coding_block_size = 3 + gf_bs_get_ue(bs); - sps->log2_diff_max_min_luma_coding_block_size = gf_bs_get_ue(bs); - sps->max_CU_width = (1 << (sps->log2_min_luma_coding_block_size + sps->log2_diff_max_min_luma_coding_block_size)); - sps->max_CU_height = (1 << (sps->log2_min_luma_coding_block_size + sps->log2_diff_max_min_luma_coding_block_size)); - - sps->log2_min_transform_block_size = 2 + gf_bs_get_ue(bs); - sps->log2_max_transform_block_size = sps->log2_min_transform_block_size + gf_bs_get_ue(bs); - - depth = 0; - sps->max_transform_hierarchy_depth_inter = gf_bs_get_ue(bs); - sps->max_transform_hierarchy_depth_intra = gf_bs_get_ue(bs); - while ((u32)(sps->max_CU_width >> sps->log2_diff_max_min_luma_coding_block_size) > (u32)(1 << (sps->log2_min_transform_block_size + depth))) - { - depth++; - } - sps->max_CU_depth = sps->log2_diff_max_min_luma_coding_block_size + depth; - - nb_CTUs = ((sps->width + sps->max_CU_width - 1) / sps->max_CU_width) * ((sps->height + sps->max_CU_height - 1) / sps->max_CU_height); - sps->bitsSliceSegmentAddress = 0; - while (nb_CTUs > (u32)(1 << sps->bitsSliceSegmentAddress)) { - sps->bitsSliceSegmentAddress++; - } - - sps->scaling_list_enable_flag = gf_bs_read_int(bs, 1); - if (sps->scaling_list_enable_flag) { - sps->infer_scaling_list_flag = 0; - sps->scaling_list_ref_layer_id = 0; - if (multiLayerExtSpsFlag) { - sps->infer_scaling_list_flag = gf_bs_read_int(bs, 1); - } - if (sps->infer_scaling_list_flag) { - sps->scaling_list_ref_layer_id = gf_bs_read_int(bs, 6); - } - else { - sps->scaling_list_data_present_flag = gf_bs_read_int(bs, 1); - if (sps->scaling_list_data_present_flag) { - hevc_scaling_list_data(bs); - } - } - } - sps->asymmetric_motion_partitions_enabled_flag = gf_bs_read_int(bs, 1); - sps->sample_adaptive_offset_enabled_flag = gf_bs_read_int(bs, 1); - if ( (sps->pcm_enabled_flag = gf_bs_read_int(bs, 1)) ) { - sps->pcm_sample_bit_depth_luma_minus1 = gf_bs_read_int(bs, 4); - sps->pcm_sample_bit_depth_chroma_minus1 = gf_bs_read_int(bs, 4); - sps->log2_min_pcm_luma_coding_block_size_minus3 = gf_bs_get_ue(bs); - sps->log2_diff_max_min_pcm_luma_coding_block_size = gf_bs_get_ue(bs); - sps->pcm_loop_filter_disable_flag = gf_bs_read_int(bs, 1); - } - sps->num_short_term_ref_pic_sets = gf_bs_get_ue(bs); - if (sps->num_short_term_ref_pic_sets > 64) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Invalid number of short term reference picture sets %d\n", sps->num_short_term_ref_pic_sets)); - return -1; - } - - for (i = 0; i < sps->num_short_term_ref_pic_sets; i++) { - Bool ret = parse_short_term_ref_pic_set(bs, sps, i); - /*cannot parse short_term_ref_pic_set, skip VUI parsing*/ - if (!ret) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] Invalid short_term_ref_pic_set\n")); - return -1; - } - } - sps->long_term_ref_pics_present_flag = gf_bs_read_int(bs, 1); - if (sps->long_term_ref_pics_present_flag) { - sps->num_long_term_ref_pic_sps = gf_bs_get_ue(bs); - for (i = 0; i < sps->num_long_term_ref_pic_sps; i++) { - /*lt_ref_pic_poc_lsb_sps=*/gf_bs_read_int(bs, sps->log2_max_pic_order_cnt_lsb); - /*used_by_curr_pic_lt_sps_flag*/gf_bs_read_int(bs, 1); - } - } - sps->temporal_mvp_enable_flag = gf_bs_read_int(bs, 1); - sps->strong_intra_smoothing_enable_flag = gf_bs_read_int(bs, 1); - - if (vui_flag_pos) - *vui_flag_pos = (u32)gf_bs_get_bit_offset(bs); - - if ((sps->vui_parameters_present_flag = gf_bs_read_int(bs, 1)) ) { - sps->aspect_ratio_info_present_flag = gf_bs_read_int(bs, 1); - if (sps->aspect_ratio_info_present_flag) { - sps->sar_idc = gf_bs_read_int(bs, 8); - if (sps->sar_idc == 255) { - sps->sar_width = gf_bs_read_int(bs, 16); - sps->sar_height = gf_bs_read_int(bs, 16); - } - else if (sps->sar_idc < 17) { - sps->sar_width = hevc_sar[sps->sar_idc].w; - sps->sar_height = hevc_sar[sps->sar_idc].h; - } - } - - if ((sps->overscan_info_present = gf_bs_read_int(bs, 1))) - sps->overscan_appropriate = gf_bs_read_int(bs, 1); - - sps->video_signal_type_present_flag = gf_bs_read_int(bs, 1); - if (sps->video_signal_type_present_flag) { - sps->video_format = gf_bs_read_int(bs, 3); - sps->video_full_range_flag = gf_bs_read_int(bs, 1); - if ((sps->colour_description_present_flag = gf_bs_read_int(bs, 1))) { - sps->colour_primaries = gf_bs_read_int(bs, 8); - sps->transfer_characteristic = gf_bs_read_int(bs, 8); - sps->matrix_coeffs = gf_bs_read_int(bs, 8); - } - } - - if ((sps->chroma_loc_info_present_flag = gf_bs_read_int(bs, 1))) { - sps->chroma_sample_loc_type_top_field = gf_bs_get_ue(bs); - sps->chroma_sample_loc_type_bottom_field = gf_bs_get_ue(bs); - } - - sps->neutra_chroma_indication_flag = gf_bs_read_int(bs, 1); - sps->field_seq_flag = gf_bs_read_int(bs, 1); - sps->frame_field_info_present_flag = gf_bs_read_int(bs, 1); - - if ((sps->default_display_window_flag = gf_bs_read_int(bs, 1))) { - sps->left_offset = gf_bs_get_ue(bs); - sps->right_offset = gf_bs_get_ue(bs); - sps->top_offset = gf_bs_get_ue(bs); - sps->bottom_offset = gf_bs_get_ue(bs); - } - - sps->has_timing_info = gf_bs_read_int(bs, 1); - if (sps->has_timing_info) { - sps->num_units_in_tick = gf_bs_read_int(bs, 32); - sps->time_scale = gf_bs_read_int(bs, 32); - sps->poc_proportional_to_timing_flag = gf_bs_read_int(bs, 1); - if (sps->poc_proportional_to_timing_flag) - sps->num_ticks_poc_diff_one_minus1 = gf_bs_get_ue(bs); - if ((sps->hrd_parameters_present_flag = gf_bs_read_int(bs, 1))) { - // GF_LOG(GF_LOG_INFO, GF_LOG_CODING, ("[HEVC] HRD param parsing not implemented\n")); - return sps_id; - } - } - - if (/*bitstream_restriction_flag=*/gf_bs_read_int(bs, 1)) { - /*tiles_fixed_structure_flag = */gf_bs_read_int(bs, 1); - /*motion_vectors_over_pic_boundaries_flag = */gf_bs_read_int(bs, 1); - /*restricted_ref_pic_lists_flag = */gf_bs_read_int(bs, 1); - /*min_spatial_segmentation_idc = */gf_bs_get_ue(bs); - /*max_bytes_per_pic_denom = */gf_bs_get_ue(bs); - /*max_bits_per_min_cu_denom = */gf_bs_get_ue(bs); - /*log2_max_mv_length_horizontal = */gf_bs_get_ue(bs); - /*log2_max_mv_length_vertical = */gf_bs_get_ue(bs); - } - } - - if (/*sps_extension_flag*/gf_bs_read_int(bs, 1)) { -#if 0 - while (gf_bs_available(bs)) { - /*sps_extension_data_flag */ gf_bs_read_int(bs, 1); - } -#endif - - } - - return sps_id; -} - -GF_EXPORT -s32 gf_media_hevc_read_sps_ex(char *data, u32 size, HEVCState *hevc, u32 *vui_flag_pos) -{ - GF_BitStream *bs; - s32 sps_id = -1; - u8 layer_id; - - if (vui_flag_pos) *vui_flag_pos = 0; - - bs = gf_bs_new(data, size, GF_BITSTREAM_READ); - if (!bs) goto exit; - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - if (!hevc_parse_nal_header(bs, NULL, NULL, &layer_id)) goto exit; - sps_id = gf_media_hevc_read_sps_bs_internal(bs, hevc, layer_id, vui_flag_pos); - -exit: - if (bs) gf_bs_del(bs); - return sps_id; -} - -GF_EXPORT -s32 gf_media_hevc_read_sps(u8 *data, u32 size, HEVCState *hevc) -{ - return gf_media_hevc_read_sps_ex(data, size, hevc, NULL); -} - -GF_EXPORT -s32 gf_media_hevc_read_sps_bs(GF_BitStream *bs, HEVCState *hevc) -{ - u8 layer_id; - if (!bs || !hevc) return -1; - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - if (!hevc_parse_nal_header(bs, NULL, NULL, &layer_id)) return -1; - return gf_media_hevc_read_sps_bs_internal(bs, hevc, layer_id, NULL); -} - - -static s32 gf_media_hevc_read_pps_bs_internal(GF_BitStream *bs, HEVCState *hevc) -{ - u32 i; - s32 pps_id; - HEVC_PPS *pps; - - //NAL header already read - pps_id = gf_bs_get_ue(bs); - - if ((pps_id < 0) || (pps_id >= 64)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] wrong PPS ID %d in PPS\n", pps_id)); - return -1; - } - pps = &hevc->pps[pps_id]; - - if (!pps->state) { - pps->id = pps_id; - pps->state = 1; - } - pps->sps_id = gf_bs_get_ue(bs); - if (pps->sps_id > 16) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[HEVC] wrong SPS ID %d in PPS\n", pps->sps_id)); - return -1; - } - hevc->sps_active_idx = pps->sps_id; /*set active sps*/ - pps->dependent_slice_segments_enabled_flag = gf_bs_read_int(bs, 1); - - pps->output_flag_present_flag = gf_bs_read_int(bs, 1); - pps->num_extra_slice_header_bits = gf_bs_read_int(bs, 3); - pps->sign_data_hiding_flag = gf_bs_read_int(bs, 1); - pps->cabac_init_present_flag = gf_bs_read_int(bs, 1); - pps->num_ref_idx_l0_default_active = 1 + gf_bs_get_ue(bs); - pps->num_ref_idx_l1_default_active = 1 + gf_bs_get_ue(bs); - pps->pic_init_qp_minus26 = gf_bs_get_se(bs); - pps->constrained_intra_pred_flag = gf_bs_read_int(bs, 1); - pps->transform_skip_enabled_flag = gf_bs_read_int(bs, 1); - if ((pps->cu_qp_delta_enabled_flag = gf_bs_read_int(bs, 1))) - pps->diff_cu_qp_delta_depth = gf_bs_get_ue(bs); - - pps->pic_cb_qp_offset = gf_bs_get_se(bs); - pps->pic_cr_qp_offset = gf_bs_get_se(bs); - pps->slice_chroma_qp_offsets_present_flag = gf_bs_read_int(bs, 1); - pps->weighted_pred_flag = gf_bs_read_int(bs, 1); - pps->weighted_bipred_flag = gf_bs_read_int(bs, 1); - pps->transquant_bypass_enable_flag = gf_bs_read_int(bs, 1); - pps->tiles_enabled_flag = gf_bs_read_int(bs, 1); - pps->entropy_coding_sync_enabled_flag = gf_bs_read_int(bs, 1); - if (pps->tiles_enabled_flag) { - pps->num_tile_columns = 1 + gf_bs_get_ue(bs); - pps->num_tile_rows = 1 + gf_bs_get_ue(bs); - pps->uniform_spacing_flag = gf_bs_read_int(bs, 1); - if (!pps->uniform_spacing_flag) { - for (i = 0; i < pps->num_tile_columns - 1; i++) { - pps->column_width[i] = 1 + gf_bs_get_ue(bs); - } - for (i = 0; i < pps->num_tile_rows - 1; i++) { - pps->row_height[i] = 1 + gf_bs_get_ue(bs); - } - } - pps->loop_filter_across_tiles_enabled_flag = gf_bs_read_int(bs, 1); - } - pps->loop_filter_across_slices_enabled_flag = gf_bs_read_int(bs, 1); - if ((pps->deblocking_filter_control_present_flag = gf_bs_read_int(bs, 1))) { - pps->deblocking_filter_override_enabled_flag = gf_bs_read_int(bs, 1); - if (! (pps->pic_disable_deblocking_filter_flag = gf_bs_read_int(bs, 1))) { - pps->beta_offset_div2 = gf_bs_get_se(bs); - pps->tc_offset_div2 = gf_bs_get_se(bs); - } - } - if ((pps->pic_scaling_list_data_present_flag = gf_bs_read_int(bs, 1))) { - hevc_scaling_list_data(bs); - } - pps->lists_modification_present_flag = gf_bs_read_int(bs, 1); - pps->log2_parallel_merge_level_minus2 = gf_bs_get_ue(bs); - pps->slice_segment_header_extension_present_flag = gf_bs_read_int(bs, 1); - if ( /*pps_extension_flag= */gf_bs_read_int(bs, 1)) { -#if 0 - while (gf_bs_available(bs)) { - /*pps_extension_data_flag */ gf_bs_read_int(bs, 1); - } -#endif - - } - return pps_id; -} - - -GF_EXPORT -s32 gf_media_hevc_read_pps(u8 *data, u32 size, HEVCState *hevc) -{ - GF_BitStream *bs; - s32 pps_id = -1; - - bs = gf_bs_new(data, size, GF_BITSTREAM_READ); - if (!bs) goto exit; - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - if (!hevc_parse_nal_header(bs, NULL, NULL, NULL)) goto exit; - - pps_id = gf_media_hevc_read_pps_bs_internal(bs, hevc); - -exit: - if (bs) gf_bs_del(bs); - return pps_id; -} - -GF_EXPORT -s32 gf_media_hevc_read_pps_bs(GF_BitStream *bs, HEVCState *hevc) -{ - if (!bs || !hevc) return -1; - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - if (!hevc_parse_nal_header(bs, NULL, NULL, NULL)) return -1; - return gf_media_hevc_read_pps_bs_internal(bs, hevc); -} - -GF_EXPORT -s32 gf_media_hevc_parse_nalu_bs(GF_BitStream *bs, HEVCState *hevc, u8 *nal_unit_type, u8 *temporal_id, u8 *layer_id) -{ - Bool is_slice = GF_FALSE; - s32 ret = -1; - HEVCSliceInfo n_state; - - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - memcpy(&n_state, &hevc->s_info, sizeof(HEVCSliceInfo)); - if (!hevc_parse_nal_header(bs, nal_unit_type, temporal_id, layer_id)) return -1; - - n_state.nal_unit_type = *nal_unit_type; - - switch (n_state.nal_unit_type) { - case GF_HEVC_NALU_ACCESS_UNIT: - case GF_HEVC_NALU_END_OF_SEQ: - case GF_HEVC_NALU_END_OF_STREAM: - ret = 1; - break; - - /*slice_segment_layer_rbsp*/ - case GF_HEVC_NALU_SLICE_TRAIL_N: - case GF_HEVC_NALU_SLICE_TRAIL_R: - case GF_HEVC_NALU_SLICE_TSA_N: - case GF_HEVC_NALU_SLICE_TSA_R: - case GF_HEVC_NALU_SLICE_STSA_N: - case GF_HEVC_NALU_SLICE_STSA_R: - case GF_HEVC_NALU_SLICE_BLA_W_LP: - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_N_LP: - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_IDR_N_LP: - case GF_HEVC_NALU_SLICE_CRA: - case GF_HEVC_NALU_SLICE_RADL_N: - case GF_HEVC_NALU_SLICE_RADL_R: - case GF_HEVC_NALU_SLICE_RASL_N: - case GF_HEVC_NALU_SLICE_RASL_R: - is_slice = GF_TRUE; - /* slice - read the info and compare.*/ - ret = hevc_parse_slice_segment(bs, hevc, &n_state); - if (ret < 0) return ret; - - hevc_compute_poc(&n_state); - - ret = 0; - - if (hevc->s_info.poc != n_state.poc) { - ret = 1; - break; - } - if (n_state.first_slice_segment_in_pic_flag) { - if (!(*layer_id) || (n_state.prev_layer_id_plus1 && ((*layer_id) <= n_state.prev_layer_id_plus1 - 1))) { - ret = 1; - break; - } - } - break; - case GF_HEVC_NALU_SEQ_PARAM: - hevc->last_parsed_sps_id = gf_media_hevc_read_sps_bs_internal(bs, hevc, *layer_id, NULL); - ret = (hevc->last_parsed_sps_id>=0) ? 0 : -1; - break; - case GF_HEVC_NALU_PIC_PARAM: - hevc->last_parsed_pps_id = gf_media_hevc_read_pps_bs_internal(bs, hevc); - ret = (hevc->last_parsed_pps_id>=0) ? 0 : -1; - break; - case GF_HEVC_NALU_VID_PARAM: - hevc->last_parsed_vps_id = gf_media_hevc_read_vps_bs_internal(bs, hevc, GF_FALSE); - ret = (hevc->last_parsed_vps_id>=0) ? 0 : -1; - break; - default: - ret = 0; - break; - } - - /* save _prev values */ - if ((ret>0) && hevc->s_info.sps) { - n_state.frame_num_offset_prev = hevc->s_info.frame_num_offset; - n_state.frame_num_prev = hevc->s_info.frame_num; - - n_state.poc_lsb_prev = hevc->s_info.poc_lsb; - n_state.poc_msb_prev = hevc->s_info.poc_msb; - if (is_slice) - n_state.prev_layer_id_plus1 = *layer_id + 1; - } - if (is_slice) hevc_compute_poc(&n_state); - memcpy(&hevc->s_info, &n_state, sizeof(HEVCSliceInfo)); - - return ret; -} - -GF_EXPORT -s32 gf_media_hevc_parse_nalu(u8 *data, u32 size, HEVCState *hevc, u8 *nal_unit_type, u8 *temporal_id, u8 *layer_id) -{ - GF_BitStream *bs = NULL; - s32 ret = -1; - - if (!hevc) { - if (nal_unit_type) (*nal_unit_type) = (data[0] & 0x7E) >> 1; - if (layer_id) { - u8 id = data[0] & 1; - id <<= 5; - id |= (data[1] >> 3) & 0x1F; - (*layer_id) = id; - } - if (temporal_id) (*temporal_id) = (data[1] & 0x7); - return -1; - } - - bs = gf_bs_new(data, size, GF_BITSTREAM_READ); - if (!bs) return -1; - gf_bs_enable_emulation_byte_removal(bs, GF_TRUE); - - ret = gf_media_hevc_parse_nalu_bs(bs, hevc, nal_unit_type, temporal_id, layer_id); - - gf_bs_del(bs); - return ret; -} - -static u8 hevc_get_sar_idx(u32 w, u32 h) -{ - u32 i; - for (i = 0; i < 14; i++) { - if ((avc_sar[i].w == w) && (avc_sar[i].h == h)) return i; - } - return 0xFF; -} - -GF_Err gf_media_hevc_change_par(GF_HEVCConfig *hvcc, s32 ar_n, s32 ar_d) -{ - GF_BitStream *orig, *mod; - HEVCState hevc; - u32 i, bit_offset, flag; - s32 idx; - GF_HEVCParamArray *spss; - GF_AVCConfigSlot *slc; - orig = NULL; - - memset(&hevc, 0, sizeof(HEVCState)); - hevc.sps_active_idx = -1; - - i = 0; - spss = NULL; - while ((spss = (GF_HEVCParamArray *)gf_list_enum(hvcc->param_array, &i))) { - if (spss->type == GF_HEVC_NALU_SEQ_PARAM) - break; - spss = NULL; - } - if (!spss) return GF_NON_COMPLIANT_BITSTREAM; - - i = 0; - while ((slc = (GF_AVCConfigSlot *)gf_list_enum(spss->nalus, &i))) { - u8 *no_emulation_buf; - u32 no_emulation_buf_size, emulation_bytes; - - /*SPS may still contains emulation bytes*/ - no_emulation_buf = gf_malloc((slc->size) * sizeof(char)); - no_emulation_buf_size = gf_media_nalu_remove_emulation_bytes(slc->data, no_emulation_buf, slc->size); - - idx = gf_media_hevc_read_sps_ex(no_emulation_buf, no_emulation_buf_size, &hevc, &bit_offset); - if (idx < 0) { - if (orig) - gf_bs_del(orig); - gf_free(no_emulation_buf); - continue; - } - - orig = gf_bs_new(no_emulation_buf, no_emulation_buf_size, GF_BITSTREAM_READ); - mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - - /*copy over till vui flag*/ - assert(bit_offset >= 0); - while (bit_offset) { - flag = gf_bs_read_int(orig, 1); - gf_bs_write_int(mod, flag, 1); - bit_offset--; - } - - /*check VUI*/ - flag = gf_bs_read_int(orig, 1); - gf_bs_write_int(mod, 1, 1); /*vui_parameters_present_flag*/ - if (flag) { - /*aspect_ratio_info_present_flag*/ - if (gf_bs_read_int(orig, 1)) { - s32 aspect_ratio_idc = gf_bs_read_int(orig, 8); - if (aspect_ratio_idc == 255) { - gf_bs_read_int(orig, 16); /*AR num*/ - gf_bs_read_int(orig, 16); /*AR den*/ - } - } - } - if ((ar_d < 0) || (ar_n < 0)) { - /*no AR signaled*/ - gf_bs_write_int(mod, 0, 1); - } - else { - u32 sarx; - gf_bs_write_int(mod, 1, 1); - sarx = hevc_get_sar_idx((u32)ar_n, (u32)ar_d); - gf_bs_write_int(mod, sarx, 8); - if (sarx == 0xFF) { - gf_bs_write_int(mod, ar_n, 16); - gf_bs_write_int(mod, ar_d, 16); - } - } - /*no VUI in input bitstream, set all vui flags to 0*/ - if (!flag) { - gf_bs_write_int(mod, 0, 1); /*overscan_info_present_flag */ - gf_bs_write_int(mod, 0, 1); /*video_signal_type_present_flag */ - gf_bs_write_int(mod, 0, 1); /*chroma_location_info_present_flag */ - - gf_bs_write_int(mod, 0, 1); /*neutra_chroma_indication_flag */; - gf_bs_write_int(mod, 0, 1); /*field_seq_flag */; - gf_bs_write_int(mod, 0, 1); /*frame_field_info_present_flag*/; - gf_bs_write_int(mod, 0, 1); /*default_display_window_flag*/; - - gf_bs_write_int(mod, 0, 1); /*timing_info_present_flag*/ - gf_bs_write_int(mod, 0, 1); /*bitstream_restriction*/ - } - - /*finally copy over remaining*/ - while (gf_bs_bits_available(orig)) { - flag = gf_bs_read_int(orig, 1); - gf_bs_write_int(mod, flag, 1); - } - gf_bs_del(orig); - orig = NULL; - gf_free(no_emulation_buf); - - /*set anti-emulation*/ - gf_bs_get_content(mod, &no_emulation_buf, &no_emulation_buf_size); - emulation_bytes = gf_media_nalu_emulation_bytes_add_count(no_emulation_buf, no_emulation_buf_size); - if (no_emulation_buf_size + emulation_bytes > slc->size) - slc->data = (char*)gf_realloc(slc->data, no_emulation_buf_size + emulation_bytes); - - slc->size = gf_media_nalu_add_emulation_bytes(no_emulation_buf, slc->data, no_emulation_buf_size); - - gf_bs_del(mod); - gf_free(no_emulation_buf); - } - return GF_OK; -} - -GF_EXPORT -GF_Err gf_hevc_get_sps_info_with_state(HEVCState *hevc, u8 *sps_data, u32 sps_size, u32 *sps_id, u32 *width, u32 *height, s32 *par_n, s32 *par_d) -{ - s32 idx; - idx = gf_media_hevc_read_sps(sps_data, sps_size, hevc); - if (idx < 0) { - return GF_NON_COMPLIANT_BITSTREAM; - } - if (sps_id) *sps_id = idx; - - if (width) *width = hevc->sps[idx].width; - if (height) *height = hevc->sps[idx].height; - if (par_n) *par_n = hevc->sps[idx].aspect_ratio_info_present_flag ? hevc->sps[idx].sar_width : (u32)-1; - if (par_d) *par_d = hevc->sps[idx].aspect_ratio_info_present_flag ? hevc->sps[idx].sar_height : (u32)-1; - return GF_OK; -} - -GF_EXPORT -GF_Err gf_hevc_get_sps_info(u8 *sps_data, u32 sps_size, u32 *sps_id, u32 *width, u32 *height, s32 *par_n, s32 *par_d) -{ - HEVCState hevc; - memset(&hevc, 0, sizeof(HEVCState)); - hevc.sps_active_idx = -1; - return gf_hevc_get_sps_info_with_state(&hevc, sps_data, sps_size, sps_id, width, height, par_n, par_d); -} - - -#endif //GPAC_DISABLE_HEVC - -static u32 AC3_FindSyncCode(u8 *buf, u32 buflen) -{ - u32 end = buflen - 6; - u32 offset = 0; - while (offset <= end) { - if (buf[offset] == 0x0b && buf[offset + 1] == 0x77) { - return offset; - } - offset++; - } - return buflen; -} - - -static Bool AC3_FindSyncCodeBS(GF_BitStream *bs) -{ - u8 b1; - u64 pos = gf_bs_get_position(bs); - u64 end = gf_bs_get_size(bs); - - pos += 1; - b1 = gf_bs_read_u8(bs); - while (pos + 1 <= end) { - u8 b2 = gf_bs_read_u8(bs); - if ((b1 == 0x0b) && (b2 == 0x77)) { - gf_bs_seek(bs, pos - 1); - return GF_TRUE; - } - pos++; - b1 = b2; - } - return GF_FALSE; -} - -static const u32 ac3_sizecod_to_bitrate[] = { - 32000, 40000, 48000, 56000, 64000, 80000, 96000, - 112000, 128000, 160000, 192000, 224000, 256000, - 320000, 384000, 448000, 512000, 576000, 640000 -}; - -static const u32 ac3_sizecod2_to_framesize[] = { - 96, 120, 144, 168, 192, 240, 288, 336, 384, 480, 576, 672, - 768, 960, 1152, 1344, 1536, 1728, 1920 -}; - -static const u32 ac3_sizecod1_to_framesize[] = { - 69, 87, 104, 121, 139, 174, 208, 243, 278, 348, 417, 487, - 557, 696, 835, 975, 1114, 1253, 1393 -}; -static const u32 ac3_sizecod0_to_framesize[] = { - 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, - 512, 640, 768, 896, 1024, 1152, 1280 -}; - -static const u32 ac3_mod_to_chans[] = { - 2, 1, 2, 3, 3, 4, 4, 5 -}; - -GF_EXPORT -u32 gf_ac3_get_channels(u32 acmod) -{ - u32 nb_ch; - nb_ch = ac3_mod_to_chans[acmod]; - return nb_ch; -} - -GF_EXPORT -u32 gf_ac3_get_bitrate(u32 brcode) -{ - return ac3_sizecod_to_bitrate[brcode]; -} - -Bool gf_ac3_parser(u8 *buf, u32 buflen, u32 *pos, GF_AC3Header *hdr, Bool full_parse) -{ - GF_BitStream *bs; - Bool ret; - - if (buflen < 6) return GF_FALSE; - (*pos) = AC3_FindSyncCode(buf, buflen); - if (*pos >= buflen) return GF_FALSE; - - bs = gf_bs_new((const char*)(buf + *pos), buflen, GF_BITSTREAM_READ); - ret = gf_ac3_parser_bs(bs, hdr, full_parse); - gf_bs_del(bs); - - return ret; -} - -GF_EXPORT -Bool gf_ac3_parser_bs(GF_BitStream *bs, GF_AC3Header *hdr, Bool full_parse) -{ - u32 fscod, frmsizecod, bsid, ac3_mod, freq, framesize, bsmod, syncword; - u64 pos; - if (!hdr || (gf_bs_available(bs) < 6)) return GF_FALSE; - if (!AC3_FindSyncCodeBS(bs)) return GF_FALSE; - - pos = gf_bs_get_position(bs); - - syncword = gf_bs_read_u16(bs); - if (syncword != 0x0B77) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[AC3] Wrong sync word detected (0x%X - expecting 0x0B77).\n", syncword)); - return GF_FALSE; - } - gf_bs_read_u16(bs); //crc1 - fscod = gf_bs_read_int(bs, 2); - frmsizecod = gf_bs_read_int(bs, 6); - bsid = gf_bs_read_int(bs, 5); - bsmod = gf_bs_read_int(bs, 3); - ac3_mod = gf_bs_read_int(bs, 3); - if (frmsizecod >= 2 * sizeof(ac3_sizecod_to_bitrate) / sizeof(u32)) - return GF_FALSE; - - hdr->bitrate = ac3_sizecod_to_bitrate[frmsizecod / 2]; - if (bsid > 8) hdr->bitrate = hdr->bitrate >> (bsid - 8); - - switch (fscod) { - case 0: - if (frmsizecod >= 2 * sizeof(ac3_sizecod0_to_framesize) / sizeof(u32)) - return GF_FALSE; - freq = 48000; - framesize = ac3_sizecod0_to_framesize[frmsizecod / 2] * 2; - break; - case 1: - if (frmsizecod >= 2 * sizeof(ac3_sizecod1_to_framesize) / sizeof(u32)) - return GF_FALSE; - freq = 44100; - framesize = (ac3_sizecod1_to_framesize[frmsizecod / 2] + (frmsizecod & 0x1)) * 2; - break; - case 2: - if (frmsizecod >= 2 * sizeof(ac3_sizecod2_to_framesize) / sizeof(u32)) - return GF_FALSE; - freq = 32000; - framesize = ac3_sizecod2_to_framesize[frmsizecod / 2] * 2; - break; - default: - return GF_FALSE; - } - hdr->sample_rate = freq; - hdr->framesize = framesize; - - if (full_parse) { - hdr->streams[0].bsid = bsid; - hdr->streams[0].bsmod = bsmod; - hdr->streams[0].acmod = ac3_mod; - hdr->streams[0].lfon = 0; - hdr->streams[0].fscod = fscod; - hdr->streams[0].brcode = frmsizecod / 2; - } - if (ac3_mod >= 2 * sizeof(ac3_mod_to_chans) / sizeof(u32)) - return GF_FALSE; - - hdr->channels = ac3_mod_to_chans[ac3_mod]; - if ((ac3_mod & 0x1) && (ac3_mod != 1)) gf_bs_read_int(bs, 2); - if (ac3_mod & 0x4) gf_bs_read_int(bs, 2); - if (ac3_mod == 0x2) gf_bs_read_int(bs, 2); - /*LFEon*/ - if (gf_bs_read_int(bs, 1)) { - hdr->channels += 1; - hdr->streams[0].lfon = 1; - } - - gf_bs_seek(bs, pos); - - return GF_TRUE; -} - -GF_EXPORT -Bool gf_eac3_parser_bs(GF_BitStream *bs, GF_AC3Header *hdr, Bool full_parse) -{ - u32 fscod, bsid, ac3_mod, freq, framesize, syncword, substreamid, lfon, channels, numblkscod, strmtyp, frmsiz; - u64 pos; - u16 chanmap; - static u32 numblks[4] = {1, 2, 3, 6}; - - if (!hdr || (gf_bs_available(bs) < 6)) - return GF_FALSE; - if (!AC3_FindSyncCodeBS(bs)) - return GF_FALSE; - - pos = gf_bs_get_position(bs); - framesize = 0; - numblkscod = 0; - memset(hdr, 0, sizeof(GF_AC3Header)); - -block: - syncword = gf_bs_read_u16(bs); - if (syncword != 0x0B77) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[E-AC3] Wrong sync word detected (0x%X - expecting 0x0B77).\n", syncword)); - return GF_FALSE; - } - - strmtyp = gf_bs_read_int(bs, 2); - substreamid = gf_bs_read_int(bs, 3); - //next main (independent) AU, done with this frame - if ((strmtyp!=0x1) && ((hdr->substreams >> substreamid) & 0x1)) { - hdr->framesize = framesize; - gf_bs_seek(bs, pos); - return GF_TRUE; - } - - frmsiz = gf_bs_read_int(bs, 11); - framesize += 2 * (1 + frmsiz); - fscod = gf_bs_read_int(bs, 2); - if (fscod == 0x3) { - fscod = gf_bs_read_int(bs, 2); - numblkscod += 6; - } - else { - numblkscod += gf_bs_read_int(bs, 2); - } - assert(numblkscod <= 9); - - - if ((hdr->substreams >> substreamid) & 0x1) { - //we still have sync frames following - if (substreamid) { - if (gf_bs_seek(bs, pos + framesize) != GF_OK) { - gf_bs_seek(bs, pos); - return GF_FALSE; - } - if ((gf_bs_available(bs) < 6) || !AC3_FindSyncCodeBS(bs)) { - gf_bs_seek(bs, pos); - return GF_FALSE; - } - goto block; - } - } - - hdr->substreams |= (1 << substreamid); - - switch (fscod) { - case 0: - freq = 48000; - break; - case 1: - freq = 44100; - break; - case 2: - freq = 32000; - break; - default: - return GF_FALSE; - } - - ac3_mod = gf_bs_read_int(bs, 3); - lfon = gf_bs_read_int(bs, 1); - bsid = gf_bs_read_int(bs, 5); - if (!substreamid && (bsid != 16/*E-AC3*/)) - return GF_FALSE; - /*dialnorm=*/gf_bs_read_int(bs, 5); - if (/*compre=*/gf_bs_read_int(bs, 1)) { - /*compr=*/gf_bs_read_int(bs, 8); - } - if (ac3_mod==0) { - /*dialnorm2=*/gf_bs_read_int(bs, 5); - if (/*compr2e=*/gf_bs_read_int(bs, 1)) { - /*compr2=*/gf_bs_read_int(bs, 8); - } - } - chanmap = 0; - if (strmtyp==0x1) { - if (/*chanmape=*/gf_bs_read_int(bs, 1)) { - chanmap = gf_bs_read_int(bs, 16); - } - } - - channels = ac3_mod_to_chans[ac3_mod]; - if (lfon) - channels += 1; - - hdr->bitrate = 0; - hdr->sample_rate = freq; - hdr->framesize = framesize; - if (strmtyp != 1) { - hdr->channels = channels; - hdr->streams[substreamid].lfon = lfon; - if (full_parse) { - hdr->streams[substreamid].bsid = bsid; - hdr->streams[substreamid].bsmod = 0; - hdr->streams[substreamid].acmod = ac3_mod; - hdr->streams[substreamid].fscod = fscod; - hdr->streams[substreamid].brcode = 0; - } - hdr->nb_streams++; - //not clear if this is only for the independent streams - hdr->data_rate += ((frmsiz+1) * freq) / (numblks[numblkscod]*16) / 1000; - - if (lfon) - hdr->channels += 1; - - } else { - hdr->streams[substreamid].num_dep_sub = substreamid; - hdr->streams[substreamid].chan_loc |= chanmap; - } - - if (numblkscod < 6) { //we need 6 blocks to make a sample - if (gf_bs_seek(bs, pos + framesize) != GF_OK) { - gf_bs_seek(bs, pos); - return GF_FALSE; - } - - if ((gf_bs_available(bs) < 6) || !AC3_FindSyncCodeBS(bs)) - return GF_FALSE; - goto block; - } - - gf_bs_seek(bs, pos); - - return GF_TRUE; -} - -#endif /*GPAC_DISABLE_AV_PARSERS*/ - -u32 gf_id3_read_size(GF_BitStream *bs) -{ - u32 size = 0; - gf_bs_read_int(bs, 1); - size |= gf_bs_read_int(bs, 7); - size<<=7; - gf_bs_read_int(bs, 1); - size |= gf_bs_read_int(bs, 7); - size<<=7; - gf_bs_read_int(bs, 1); - size |= gf_bs_read_int(bs, 7); - size<<=7; - gf_bs_read_int(bs, 1); - size |= gf_bs_read_int(bs, 7); - return size; -} - - -#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined (GPAC_DISABLE_OGG) - -/* - Vorbis parser -*/ - -static u32 vorbis_book_maptype1_quantvals(u32 entries, u32 dim) -{ - u32 vals = (u32)floor(pow(entries, 1.0 / dim)); - while (1) { - u32 acc = 1; - u32 acc1 = 1; - u32 i; - for (i = 0; i < dim; i++) { - acc *= vals; - acc1 *= vals + 1; - } - if (acc <= entries && acc1 > entries) return (vals); - else { - if (acc > entries) vals--; - else vals++; - } - } -} - -static u32 ilog(u32 v, Bool dec) -{ - u32 ret = 0; - if (dec && v) --v; - while (v) { - ret++; - v >>= 1; - } - return (ret); -} - -static u32 icount(u32 v) -{ - u32 ret = 0; - while (v) { - ret += v & 1; - v >>= 1; - } - return(ret); -} - - -GF_EXPORT -Bool gf_vorbis_parse_header(GF_VorbisParser *vp, u8 *data, u32 data_len) -{ - u32 pack_type, i, j, k, times, nb_part, nb_books, nb_modes; - u32 l; - char szNAME[8]; - oggpack_buffer opb; - - oggpack_readinit(&opb, (u8*)data, data_len); - pack_type = oggpack_read(&opb, 8); - i = 0; - while (i < 6) { - szNAME[i] = oggpack_read(&opb, 8); - i++; - } - szNAME[i] = 0; - if (strcmp(szNAME, "vorbis")) { - return GF_FALSE; - } - - switch (pack_type) { - case 0x01: - vp->version = oggpack_read(&opb, 32); - if (vp->version != 0) { - return GF_FALSE; - } - vp->channels = oggpack_read(&opb, 8); - vp->sample_rate = oggpack_read(&opb, 32); - vp->max_r = oggpack_read(&opb, 32); - vp->avg_r = oggpack_read(&opb, 32); - vp->low_r = oggpack_read(&opb, 32); - - vp->min_block = 1<max_block = 1<sample_rate < 1 || vp->channels < 1 || vp->min_block < 8 || vp->max_block < vp->min_block - || oggpack_read(&opb, 1) != 1) { - return GF_FALSE; - } - vp->nb_init=1; - return GF_TRUE; - - case 0x03: - /*trash comments*/ - vp->nb_init++; - return GF_TRUE; - case 0x05: - /*need at least bitstream header to make sure we're parsing the right thing*/ - if (!vp->nb_init) return GF_FALSE; - break; - default: - return GF_FALSE; - } - /*OK parse codebook*/ - nb_books = oggpack_read(&opb, 8) + 1; - /*skip vorbis static books*/ - for (i = 0; i < nb_books; i++) { - u32 map_type, qb, qq; - u32 entries, dim; - oggpack_read(&opb, 24); - dim = oggpack_read(&opb, 16); - entries = oggpack_read(&opb, 24); - if ((s32)entries < 0) entries = 0; - if (oggpack_read(&opb, 1) == 0) { - if (oggpack_read(&opb, 1)) { - for (j = 0; j < entries; j++) { - if (oggpack_read(&opb, 1)) { - oggpack_read(&opb, 5); - } - } - } - else { - for (j = 0; j < entries; j++) - oggpack_read(&opb, 5); - } - } - else { - oggpack_read(&opb, 5); - for (j = 0; j < entries;) { - u32 num = oggpack_read(&opb, ilog(entries - j, GF_FALSE)); - for (k = 0; k < num && j < entries; k++, j++) { - } - } - } - switch ((map_type = oggpack_read(&opb, 4))) { - case 0: - break; - case 1: - case 2: - oggpack_read(&opb, 32); - oggpack_read(&opb, 32); - qq = oggpack_read(&opb, 4) + 1; - oggpack_read(&opb, 1); - if (map_type == 1) qb = vorbis_book_maptype1_quantvals(entries, dim); - else if (map_type == 2) qb = entries * dim; - else qb = 0; - for (j = 0; j < qb; j++) oggpack_read(&opb, qq); - break; - } - } - times = oggpack_read(&opb, 6) + 1; - for (i = 0; i < times; i++) oggpack_read(&opb, 16); - times = oggpack_read(&opb, 6) + 1; - for (i = 0; i < times; i++) { - u32 type = oggpack_read(&opb, 16); - if (type) { - u32 *parts, *class_dims, count, rangebits; - u32 max_class = 0; - nb_part = oggpack_read(&opb, 5); - parts = (u32*)gf_malloc(sizeof(u32) * nb_part); - for (j = 0; j < nb_part; j++) { - parts[j] = oggpack_read(&opb, 4); - if (max_class < parts[j]) max_class = parts[j]; - } - class_dims = (u32*)gf_malloc(sizeof(u32) * (max_class + 1)); - for (j = 0; j < max_class + 1; j++) { - u32 class_sub; - class_dims[j] = oggpack_read(&opb, 3) + 1; - class_sub = oggpack_read(&opb, 2); - if (class_sub) oggpack_read(&opb, 8); - for (k = 0; k < (u32)(1 << class_sub); k++) oggpack_read(&opb, 8); - } - oggpack_read(&opb, 2); - rangebits = oggpack_read(&opb, 4); - count = 0; - for (j = 0, k = 0; j < nb_part; j++) { - count += class_dims[parts[j]]; - for (; k < count; k++) oggpack_read(&opb, rangebits); - } - gf_free(parts); - gf_free(class_dims); - } - else { - oggpack_read(&opb, 8 + 16 + 16 + 6 + 8); - nb_books = oggpack_read(&opb, 4) + 1; - for (j = 0; j < nb_books; j++) - oggpack_read(&opb, 8); - } - } - times = oggpack_read(&opb, 6) + 1; - for (i = 0; i < times; i++) { - u32 acc = 0; - oggpack_read(&opb, 16);/*type*/ - oggpack_read(&opb, 24); - oggpack_read(&opb, 24); - oggpack_read(&opb, 24); - nb_part = oggpack_read(&opb, 6) + 1; - oggpack_read(&opb, 8); - for (j = 0; j < nb_part; j++) { - u32 cascade = oggpack_read(&opb, 3); - if (oggpack_read(&opb, 1)) cascade |= (oggpack_read(&opb, 5) << 3); - acc += icount(cascade); - } - for (j = 0; j < acc; j++) oggpack_read(&opb, 8); - } - times = oggpack_read(&opb, 6) + 1; - for (i = 0; i < times; i++) { - u32 sub_maps = 1; - oggpack_read(&opb, 16); - if (oggpack_read(&opb, 1)) sub_maps = oggpack_read(&opb, 4) + 1; - if (oggpack_read(&opb, 1)) { - u32 nb_steps = oggpack_read(&opb, 8) + 1; - for (j = 0; j < nb_steps; j++) { - oggpack_read(&opb, ilog(vp->channels, GF_TRUE)); - oggpack_read(&opb, ilog(vp->channels, GF_TRUE)); - } - } - oggpack_read(&opb, 2); - if (sub_maps>1) { - for(l=0; lchannels; l++) - oggpack_read(&opb, 4); - } - for (j = 0; j < sub_maps; j++) { - oggpack_read(&opb, 8); - oggpack_read(&opb, 8); - oggpack_read(&opb, 8); - } - } - nb_modes = oggpack_read(&opb, 6) + 1; - for (i = 0; i < nb_modes; i++) { - vp->mode_flag[i] = oggpack_read(&opb, 1); - oggpack_read(&opb, 16); - oggpack_read(&opb, 16); - oggpack_read(&opb, 8); - } - - vp->modebits = 0; - j = nb_modes; - while (j > 1) { - vp->modebits++; - j >>= 1; - } - - return GF_TRUE; -} - -GF_EXPORT -u32 gf_vorbis_check_frame(GF_VorbisParser *vp, u8 *data, u32 data_length) -{ - s32 block_size; - oggpack_buffer opb; - if (!vp) return 0; - oggpack_readinit(&opb, (unsigned char*)data, data_length); - /*not audio*/ - if (oggpack_read(&opb, 1) != 0) return 0; - block_size = oggpack_read(&opb, vp->modebits); - if (block_size == -1) return 0; - return ((vp->mode_flag[block_size]) ? vp->max_block : vp->min_block) / (2); -} - -/*call with vorbis header packets - initializes the parser on success, leave it to NULL otherwise -returns 1 if success, 0 if error.*/ -Bool gf_opus_parse_header(GF_OpusParser *opus, u8 *data, u32 data_len) -{ - char tag[9]; - GF_BitStream *bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ); - gf_bs_read_data(bs, tag, 8); - tag[8]=0; - - if (memcmp(data, "OpusHead", sizeof(char)*8)) { - gf_bs_del(bs); - return GF_FALSE; - } - /*Identification Header*/ - opus->version = gf_bs_read_u8(bs); /*version*/ - if (opus->version != 1) { - gf_bs_del(bs); - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Opus] Unsupported version %d\n", opus->version)); - return GF_FALSE; - } - opus->OutputChannelCount = gf_bs_read_u8(bs); - opus->PreSkip = gf_bs_read_u16_le(bs); - opus->InputSampleRate = gf_bs_read_u32_le(bs); - opus->OutputGain = gf_bs_read_u16_le(bs); - opus->ChannelMappingFamily = gf_bs_read_u8(bs); - if (opus->ChannelMappingFamily != 0) { - opus->StreamCount = gf_bs_read_u8(bs); - opus->CoupledCount = gf_bs_read_u8(bs); - gf_bs_read_data(bs, (char *) opus->ChannelMapping, opus->OutputChannelCount); - } - gf_bs_del(bs); - return GF_TRUE; -} - -/*returns 0 if init error or not a vorbis frame, otherwise returns the number of audio samples -in this frame*/ -u32 gf_opus_check_frame(GF_OpusParser *op, u8 *data, u32 data_length) -{ - u32 block_size; - - if (!memcmp(data, "OpusHead", sizeof(char)*8)) - return 0; - if (!memcmp(data, "OpusTags", sizeof(char)*8)) - return 0; - - /*consider the whole packet as Ogg packets and ISOBMFF samples for Opus are framed similarly*/ - static const int OpusFrameDurIn48k[] = { 480, 960, 1920, 2880, 480, 960, 1920, 2880, 480, 960, 1920, 2880, - 480, 960, 480, 960, - 120, 240, 480, 960, 120, 240, 480, 960, 120, 240, 480, 960, 120, 240, 480, 960, - }; - int TOC_config = (data[0] & 0xf8) >> 3; - //int s = (data[0] & 0x04) >> 2; - block_size = OpusFrameDurIn48k[TOC_config]; - - int c = data[0] & 0x03; - if (c == 1 || c == 2) { - block_size *= 2; - } else if (c == 3) { - /*unknown number of frames*/ - int num_frames = data[1] & 0x3f; - block_size *= num_frames; - } - return block_size; -} - -#endif /*!defined(GPAC_DISABLE_AV_PARSERS) && !defined (GPAC_DISABLE_OGG)*/ - -u64 gf_mpegh_escaped_value(GF_BitStream *bs, u32 nBits1, u32 nBits2, u32 nBits3) -{ - u64 value = gf_bs_read_int(bs, nBits1); - if (value == (1< -#include -#include - -#ifndef GPAC_DISABLE_ISOM - - -Bool gf_isom_is_nalu_based_entry(GF_MediaBox *mdia, GF_SampleEntryBox *_entry) -{ - GF_MPEGVisualSampleEntryBox *entry; - if (!gf_isom_is_video_handler_type(mdia->handler->handlerType)) - return GF_FALSE; - if (!_entry) return GF_FALSE; - entry = (GF_MPEGVisualSampleEntryBox*)_entry; - - switch (_entry->type) { - case GF_ISOM_BOX_TYPE_AVC1: - case GF_ISOM_BOX_TYPE_AVC2: - case GF_ISOM_BOX_TYPE_AVC3: - case GF_ISOM_BOX_TYPE_AVC4: - case GF_ISOM_BOX_TYPE_SVC1: - case GF_ISOM_BOX_TYPE_SVC2: - case GF_ISOM_BOX_TYPE_MVC1: - case GF_ISOM_BOX_TYPE_MVC2: - case GF_ISOM_BOX_TYPE_HVC1: - case GF_ISOM_BOX_TYPE_HEV1: - case GF_ISOM_BOX_TYPE_HVC2: - case GF_ISOM_BOX_TYPE_HEV2: - case GF_ISOM_BOX_TYPE_LHV1: - case GF_ISOM_BOX_TYPE_LHE1: - case GF_ISOM_BOX_TYPE_MHV1: - case GF_ISOM_BOX_TYPE_MHC1: - case GF_ISOM_BOX_TYPE_HVT1: - case GF_ISOM_BOX_TYPE_LHT1: - return GF_TRUE; - case GF_ISOM_BOX_TYPE_GNRV: - case GF_ISOM_BOX_TYPE_GNRA: - case GF_ISOM_BOX_TYPE_GNRM: - return GF_FALSE; - default: - break; - } - - if (!gf_isom_is_video_handler_type(entry->internal_type)) - return GF_FALSE; - - if (entry->avc_config || entry->svc_config || entry->mvc_config || entry->hevc_config || entry->lhvc_config) { - GF_ProtectionSchemeInfoBox *schi = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(entry->child_boxes, GF_ISOM_BOX_TYPE_SINF); - if (!schi || !schi->scheme_type) return GF_TRUE; - switch (schi->scheme_type->scheme_type) { - case GF_ISOM_CENC_SCHEME: - case GF_ISOM_CBC_SCHEME: - case GF_ISOM_CENS_SCHEME: - case GF_ISOM_CBCS_SCHEME: - return GF_TRUE; - default: - break; - } - } - return GF_FALSE; -} - - -static void rewrite_nalus_list(GF_List *nalus, GF_BitStream *bs, Bool rewrite_start_codes, u32 nal_unit_size_field) -{ - u32 i, count = gf_list_count(nalus); - for (i=0; isize, 8*nal_unit_size_field); - gf_bs_write_data(bs, sl->data, sl->size); - } -} - - -static GF_Err process_extractor(GF_ISOFile *file, GF_MediaBox *mdia, u32 sampleNumber, u64 sampleDTS, u32 nal_size, u16 nal_hdr, u32 nal_unit_size_field, Bool is_hevc, Bool rewrite_ps, Bool rewrite_start_codes, u32 extractor_mode) -{ - GF_Err e; - u32 di, ref_track_index, ref_track_num, data_offset, data_length, cur_extract_mode, ref_extract_mode, ref_nalu_size, nb_bytes_nalh; - GF_TrackReferenceTypeBox *dpnd; - GF_TrackBox *ref_trak; - s8 sample_offset; - u32 last_byte, ref_sample_num, prev_ref_sample_num; - Bool header_written = GF_FALSE; - nb_bytes_nalh = is_hevc ? 2 : 1; - - switch (extractor_mode) { - case 0: - last_byte = (u32) gf_bs_get_position(mdia->nalu_parser) + nal_size - (is_hevc ? 2 : 1); - if (!is_hevc) gf_bs_read_int(mdia->nalu_parser, 24); //1 byte for HEVC , 3 bytes for AVC of NALUHeader in extractor - while (gf_bs_get_position(mdia->nalu_parser) < last_byte) { - u32 xmode = 0; - //hevc extractors use constructors - if (is_hevc) xmode = gf_bs_read_u8(mdia->nalu_parser); - if (xmode) { - u8 done=0, len = gf_bs_read_u8(mdia->nalu_parser); - while (donenalu_parser); - done++; - if (header_written) { - gf_bs_write_u8(mdia->nalu_out_bs, c); - } else if (done==nal_unit_size_field) { - if (rewrite_start_codes) { - gf_bs_write_int(mdia->nalu_out_bs, 1, 32); - } else { - gf_bs_write_u8(mdia->nalu_out_bs, c); - } - header_written = GF_TRUE; - } else if (!rewrite_start_codes) { - gf_bs_write_u8(mdia->nalu_out_bs, c); - } - } - continue; - } - - ref_track_index = gf_bs_read_u8(mdia->nalu_parser); - sample_offset = (s8) gf_bs_read_int(mdia->nalu_parser, 8); - data_offset = gf_bs_read_int(mdia->nalu_parser, nal_unit_size_field*8); - data_length = gf_bs_read_int(mdia->nalu_parser, nal_unit_size_field*8); - - Track_FindRef(mdia->mediaTrack, GF_ISOM_REF_SCAL, &dpnd); - ref_track_num = 0; - if (dpnd && ref_track_index && (ref_track_index<=dpnd->trackIDCount)) - ref_track_num = gf_isom_get_track_by_id(file, dpnd->trackIDs[ref_track_index-1]); - - if (!ref_track_num) { - GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("ISOBMF: Extractor target track is not present in file - skipping.\n")); - return GF_OK; - } - - cur_extract_mode = gf_isom_get_nalu_extract_mode(file, ref_track_num); - - //we must be in inspect mode only otherwise the reference sample will not be the one stored on file (change in start codes, PS inserted or other NALUs inserted) - //and this will corrupt extraction (wrong data offsets) - ref_extract_mode = GF_ISOM_NALU_EXTRACT_INSPECT; - gf_isom_set_nalu_extract_mode(file, ref_track_num, ref_extract_mode); - - ref_trak = gf_isom_get_track_from_file(file, ref_track_num); - if (!ref_trak) return GF_ISOM_INVALID_FILE; - - if (!mdia->extracted_samp) { - mdia->extracted_samp = gf_isom_sample_new(); - if (!mdia->extracted_samp) return GF_IO_ERR; - } - if (!mdia->extracted_bs) { - mdia->extracted_bs = gf_bs_new("a", 1, GF_BITSTREAM_READ); - if (!mdia->extracted_bs) return GF_IO_ERR; - } - - e = stbl_findEntryForTime(ref_trak->Media->information->sampleTable, sampleDTS, 0, &ref_sample_num, &prev_ref_sample_num); - if (e) return e; - if (!ref_sample_num) ref_sample_num = prev_ref_sample_num; - if (!ref_sample_num) return GF_ISOM_INVALID_FILE; - if ((sample_offset<0) && (ref_sample_num > (u32) -sample_offset)) return GF_ISOM_INVALID_FILE; - ref_sample_num = (u32) ( (s32) ref_sample_num + sample_offset); - - e = Media_GetSample(ref_trak->Media, ref_sample_num, &mdia->extracted_samp, &di, GF_FALSE, NULL); - if (e) return e; - if (!mdia->extracted_samp->alloc_size) - mdia->extracted_samp->alloc_size = mdia->extracted_samp->dataLength; -#if 0 - if (!header_written && rewrite_start_codes) { - gf_bs_write_int(dst_bs, 1, 32); - if (is_hevc) { - gf_bs_write_int(dst_bs, 0, 1); - gf_bs_write_int(dst_bs, GF_HEVC_NALU_ACCESS_UNIT, 6); - gf_bs_write_int(dst_bs, 0, 9); - /*pic-type - by default we signal all slice types possible*/ - gf_bs_write_int(dst_bs, 2, 3); - gf_bs_write_int(dst_bs, 0, 5); - } else { - gf_bs_write_int(dst_bs, (ref_samp->data[0] & 0x60) | GF_AVC_NALU_ACCESS_UNIT, 8); - gf_bs_write_int(dst_bs, 0xF0 , 8); /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/; - } - } -#endif - gf_bs_reassign_buffer(mdia->extracted_bs, mdia->extracted_samp->data + data_offset, mdia->extracted_samp->dataLength - data_offset); - - if (mdia->extracted_samp->dataLength - data_offset >= data_length) { - - while (data_length && gf_bs_available(mdia->extracted_bs)) { - if (!header_written) { - ref_nalu_size = gf_bs_read_int(mdia->extracted_bs, 8*nal_unit_size_field); - - assert(data_length>nal_unit_size_field); - data_length -= nal_unit_size_field; - if (data_length > gf_bs_available(mdia->extracted_bs)) { - data_length = (u32)gf_bs_available(mdia->extracted_bs); - } - } else { - ref_nalu_size = data_length; - } - - if (ref_nalu_size > mdia->tmp_nal_copy_buffer_alloc) { - mdia->tmp_nal_copy_buffer_alloc = ref_nalu_size; - mdia->tmp_nal_copy_buffer = (char*) gf_realloc(mdia->tmp_nal_copy_buffer, sizeof(char) * ref_nalu_size ); - } - gf_bs_read_data(mdia->extracted_bs, mdia->tmp_nal_copy_buffer, ref_nalu_size); - - if (!header_written) { - if (rewrite_start_codes) - gf_bs_write_u32(mdia->nalu_out_bs, 1); - else - gf_bs_write_int(mdia->nalu_out_bs, ref_nalu_size, 8*nal_unit_size_field); - } - assert(data_length >= ref_nalu_size); - gf_bs_write_data(mdia->nalu_out_bs, mdia->tmp_nal_copy_buffer, ref_nalu_size); - data_length -= ref_nalu_size; - - header_written = GF_FALSE; - - } - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("ISOBMF: Extractor size is larger than refered sample size - skipping.\n")); - } - gf_isom_set_nalu_extract_mode(file, ref_track_num, cur_extract_mode); - - if (!is_hevc) break; - } - break; - case 1: - //skip to end of this NALU - gf_bs_skip_bytes(mdia->nalu_parser, nal_size - nb_bytes_nalh); - break; - case 2: - if (nal_size - nb_bytes_nalh > mdia->tmp_nal_copy_buffer_alloc) { - mdia->tmp_nal_copy_buffer_alloc = nal_size - nb_bytes_nalh; - mdia->tmp_nal_copy_buffer = (char*) gf_realloc(mdia->tmp_nal_copy_buffer, sizeof(char) * (nal_size - nb_bytes_nalh) ); - } - gf_bs_read_data(mdia->nalu_parser, mdia->tmp_nal_copy_buffer, nal_size - nb_bytes_nalh); - if (rewrite_start_codes) - gf_bs_write_u32(mdia->nalu_out_bs, 1); - else - gf_bs_write_int(mdia->nalu_out_bs, nal_size, 8*nal_unit_size_field); - - gf_bs_write_u8(mdia->nalu_out_bs, nal_hdr); - gf_bs_write_data(mdia->nalu_out_bs, mdia->tmp_nal_copy_buffer, nal_size - nb_bytes_nalh); - break; - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_HEVC -/* returns the SAP type as defined in the 14496-12 specification */ -static GF_ISOSAPType sap_type_from_nal_type(u8 nal_type) { - switch (nal_type) { - case GF_HEVC_NALU_SLICE_CRA: - return SAP_TYPE_3; - case GF_HEVC_NALU_SLICE_IDR_N_LP: - case GF_HEVC_NALU_SLICE_BLA_N_LP: - return SAP_TYPE_1; - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_W_LP: - return SAP_TYPE_2; - default: - return RAP_NO; - } -} -#endif - -static GF_ISOSAPType is_sample_idr(GF_MediaBox *mdia, GF_ISOSample *sample, GF_MPEGVisualSampleEntryBox *entry) -{ - Bool is_hevc = GF_FALSE; - u32 nalu_size_field = 0; - if (entry->avc_config && entry->avc_config->config) nalu_size_field = entry->avc_config->config->nal_unit_size; - else if (entry->svc_config && entry->svc_config->config) nalu_size_field = entry->svc_config->config->nal_unit_size; - else if (entry->mvc_config && entry->mvc_config->config) nalu_size_field = entry->mvc_config->config->nal_unit_size; - else if (entry->hevc_config && entry->hevc_config->config) { - nalu_size_field = entry->hevc_config->config->nal_unit_size; - is_hevc = GF_TRUE; - } - else if (entry->lhvc_config && entry->lhvc_config->config) { - nalu_size_field = entry->lhvc_config->config->nal_unit_size; - is_hevc = GF_TRUE; - } - if (!nalu_size_field) return RAP_NO; - - if (!mdia->nalu_parser) - mdia->nalu_parser = gf_bs_new(sample->data, sample->dataLength, GF_BITSTREAM_READ); - else - gf_bs_reassign_buffer(mdia->nalu_parser, sample->data, sample->dataLength); - - if (!mdia->nalu_parser) return RAP_NO; - - while (gf_bs_available(mdia->nalu_parser)) { - u8 nal_type; - u32 size = gf_bs_read_int(mdia->nalu_parser, 8*nalu_size_field); - - if (is_hevc) { -#ifndef GPAC_DISABLE_HEVC - u16 nal_hdr = gf_bs_read_u16(mdia->nalu_parser); - nal_type = (nal_hdr&0x7E00) >> 9; - - switch (nal_type) { - case GF_HEVC_NALU_SLICE_CRA: - return SAP_TYPE_3; - case GF_HEVC_NALU_SLICE_IDR_N_LP: - case GF_HEVC_NALU_SLICE_BLA_N_LP: - return SAP_TYPE_1; - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_W_LP: - return SAP_TYPE_2; - case GF_HEVC_NALU_ACCESS_UNIT: - case GF_HEVC_NALU_FILLER_DATA: - case GF_HEVC_NALU_SEI_PREFIX: - case GF_HEVC_NALU_VID_PARAM: - case GF_HEVC_NALU_SEQ_PARAM: - case GF_HEVC_NALU_PIC_PARAM: - break; - default: - return RAP_NO; - } - gf_bs_skip_bytes(mdia->nalu_parser, size - 2); -#endif - } else { - u8 nal_hdr = gf_bs_read_u8(mdia->nalu_parser); - nal_type = nal_hdr & 0x1F; - - switch (nal_type) { - /* case GF_AVC_NALU_SEQ_PARAM: - case GF_AVC_NALU_PIC_PARAM: - case GF_AVC_NALU_SEQ_PARAM_EXT: - case GF_AVC_NALU_SVC_SUBSEQ_PARAM: - */ - case GF_AVC_NALU_IDR_SLICE: - return SAP_TYPE_1; - case GF_AVC_NALU_ACCESS_UNIT: - case GF_AVC_NALU_FILLER_DATA: - case GF_AVC_NALU_SEI: - break; - default: - return RAP_NO; - } - gf_bs_skip_bytes(mdia->nalu_parser, size - 1); - } - } - return RAP_NO; -} - -static void nalu_merge_ps(GF_BitStream *ps_bs, Bool rewrite_start_codes, u32 nal_unit_size_field, GF_MPEGVisualSampleEntryBox *entry, Bool is_hevc, Bool *has_vps) -{ - u32 i, count; - if (is_hevc) { - if (entry->hevc_config) { - count = gf_list_count(entry->hevc_config->config->param_array); - for (i=0; ihevc_config->config->param_array, i); - if (ar->type == GF_HEVC_NALU_VID_PARAM) { - if (! *has_vps) *has_vps = GF_TRUE; - else continue; - } - rewrite_nalus_list(ar->nalus, ps_bs, rewrite_start_codes, nal_unit_size_field); - } - } - if (entry->lhvc_config) { - count = gf_list_count(entry->lhvc_config->config->param_array); - for (i=0; ilhvc_config->config->param_array, i); - if (ar->type == GF_HEVC_NALU_VID_PARAM) { - if (! *has_vps) *has_vps = GF_TRUE; - else continue; - } - rewrite_nalus_list(ar->nalus, ps_bs, rewrite_start_codes, nal_unit_size_field); - } - } - } else { - if (entry->avc_config) { - rewrite_nalus_list(entry->avc_config->config->sequenceParameterSets, ps_bs, rewrite_start_codes, nal_unit_size_field); - rewrite_nalus_list(entry->avc_config->config->sequenceParameterSetExtensions, ps_bs, rewrite_start_codes, nal_unit_size_field); - rewrite_nalus_list(entry->avc_config->config->pictureParameterSets, ps_bs, rewrite_start_codes, nal_unit_size_field); - } - - /*add svc config */ - if (entry->svc_config) { - rewrite_nalus_list(entry->svc_config->config->sequenceParameterSets, ps_bs, rewrite_start_codes, nal_unit_size_field); - rewrite_nalus_list(entry->svc_config->config->pictureParameterSets, ps_bs, rewrite_start_codes, nal_unit_size_field); - } - /*add mvc config */ - if (entry->mvc_config) { - rewrite_nalus_list(entry->mvc_config->config->sequenceParameterSets, ps_bs, rewrite_start_codes, nal_unit_size_field); - rewrite_nalus_list(entry->mvc_config->config->pictureParameterSets, ps_bs, rewrite_start_codes, nal_unit_size_field); - } - } -} - - -GF_Err gf_isom_nalu_sample_rewrite(GF_MediaBox *mdia, GF_ISOSample *sample, u32 sampleNumber, GF_MPEGVisualSampleEntryBox *entry) -{ - Bool is_hevc = GF_FALSE; - //if only one sync given in the sample sync table, insert sps/pps/vps before cra/bla in hevc -// Bool check_cra_bla = (mdia->information->sampleTable->SyncSample && mdia->information->sampleTable->SyncSample->nb_entries>1) ? 0 : 1; - Bool check_cra_bla = GF_TRUE; - Bool insert_nalu_delim = GF_TRUE; - Bool force_sei_inspect = GF_FALSE; - GF_Err e = GF_OK; - GF_BitStream *sei_suffix_bs = NULL; - Bool ps_transfered = GF_FALSE; - u32 nal_size, nal_unit_size_field, extractor_mode; - Bool rewrite_ps, rewrite_start_codes, insert_vdrd_code; - u8 nal_type; - u32 nal_hdr, sabt_ref, i, track_num; - u32 temporal_id = 0; - GF_ISOFile *file = mdia->mediaTrack->moov->mov; - GF_TrackReferenceTypeBox *scal = NULL; - - Track_FindRef(mdia->mediaTrack, GF_ISOM_REF_SCAL, &scal); - - rewrite_ps = (mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG) ? GF_TRUE : GF_FALSE; - rewrite_start_codes = (mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_ANNEXB_FLAG) ? GF_TRUE : GF_FALSE; - insert_vdrd_code = (mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_VDRD_FLAG) ? GF_TRUE : GF_FALSE; - if (!entry->svc_config && !entry->mvc_config && !entry->lhvc_config) insert_vdrd_code = GF_FALSE; - extractor_mode = mdia->mediaTrack->extractor_mode&0x0000FFFF; - - if (mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_TILE_ONLY) { - insert_nalu_delim = GF_FALSE; - } - - track_num = 1 + gf_list_find(mdia->mediaTrack->moov->trackList, mdia->mediaTrack); - - if ( (extractor_mode != GF_ISOM_NALU_EXTRACT_INSPECT) && !(mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_TILE_ONLY) ) { - u32 ref_track, di; - //aggregate all sabt samples with the same DTS - if (entry->lhvc_config && !entry->hevc_config && !(mdia->mediaTrack->extractor_mode & GF_ISOM_NALU_EXTRACT_LAYER_ONLY)) { - if (gf_isom_get_reference_count(mdia->mediaTrack->moov->mov, track_num, GF_ISOM_REF_SCAL) <= 0) { - //FIXME - for now we only support two layers (base + enh) in implicit - if ( gf_isom_get_reference_count(mdia->mediaTrack->moov->mov, track_num, GF_ISOM_REF_BASE) >= 1) { - GF_ISOSample *base_samp; - gf_isom_get_reference(mdia->mediaTrack->moov->mov, track_num, GF_ISOM_REF_BASE, 1, &ref_track); - switch (gf_isom_get_media_subtype(mdia->mediaTrack->moov->mov , ref_track, 1)) { - case GF_ISOM_SUBTYPE_HVC1: - case GF_ISOM_SUBTYPE_HVC2: - case GF_ISOM_SUBTYPE_HEV1: - case GF_ISOM_SUBTYPE_HEV2: - - if (!mdia->extracted_samp) { - mdia->extracted_samp = gf_isom_sample_new(); - if (!mdia->extracted_samp) return GF_OUT_OF_MEM; - } - - base_samp = gf_isom_get_sample_ex(mdia->mediaTrack->moov->mov, ref_track, sampleNumber + mdia->mediaTrack->sample_count_at_seg_start, &di, mdia->extracted_samp, NULL); - if (base_samp && base_samp->data) { - if (!sample->alloc_size || (sample->alloc_sizedataLength+base_samp->dataLength) ) { - sample->data = gf_realloc(sample->data, sample->dataLength+base_samp->dataLength); - if (sample->alloc_size) sample->alloc_size = sample->dataLength+base_samp->dataLength; - } - memmove(sample->data + base_samp->dataLength, sample->data , sample->dataLength); - memcpy(sample->data, base_samp->data, base_samp->dataLength); - sample->dataLength += base_samp->dataLength; - } - Track_FindRef(mdia->mediaTrack, GF_ISOM_REF_BASE, &scal); - break; - } - } - } - } - - sabt_ref = gf_isom_get_reference_count(mdia->mediaTrack->moov->mov, track_num, GF_ISOM_REF_SABT); - if ((s32) sabt_ref > 0) { - force_sei_inspect = GF_TRUE; - for (i=0; imediaTrack->moov->mov, track_num, GF_ISOM_REF_SABT, i+1, &ref_track); - - if (!mdia->extracted_samp) { - mdia->extracted_samp = gf_isom_sample_new(); - if (!mdia->extracted_samp) return GF_OUT_OF_MEM; - } - - tile_samp = gf_isom_get_sample_ex(mdia->mediaTrack->moov->mov, ref_track, sampleNumber + mdia->mediaTrack->sample_count_at_seg_start, &di, mdia->extracted_samp, NULL); - if (tile_samp && tile_samp ->data) { - if (!sample->alloc_size || (sample->alloc_sizedataLength+tile_samp->dataLength) ) { - sample->data = gf_realloc(sample->data, sample->dataLength+tile_samp->dataLength); - if (sample->alloc_size) sample->alloc_size = sample->dataLength+tile_samp->dataLength; - } - memcpy(sample->data + sample->dataLength, tile_samp->data, tile_samp->dataLength); - sample->dataLength += tile_samp->dataLength; - } - } - } - } - - if ( gf_isom_get_reference_count(mdia->mediaTrack->moov->mov, track_num, GF_ISOM_REF_TBAS) >= 1) { - u32 ref_track; - u32 idx = gf_list_find(mdia->information->sampleTable->SampleDescription->child_boxes, entry); - GF_TrackBox *tbas; - gf_isom_get_reference(mdia->mediaTrack->moov->mov, track_num, GF_ISOM_REF_TBAS, 1, &ref_track); - tbas = (GF_TrackBox *)gf_list_get(mdia->mediaTrack->moov->trackList, ref_track-1); - entry = gf_list_get(tbas->Media->information->sampleTable->SampleDescription->child_boxes, idx); - } - - - if (sample->IsRAP < SAP_TYPE_2) { - if (mdia->information->sampleTable->no_sync_found || (!sample->IsRAP && check_cra_bla) ) { - sample->IsRAP = is_sample_idr(mdia, sample, entry); - } - } - if (!sample->IsRAP) - rewrite_ps = GF_FALSE; - - if (extractor_mode != GF_ISOM_NALU_EXTRACT_LAYER_ONLY) - insert_vdrd_code = GF_FALSE; - - if (!entry) return GF_BAD_PARAM; - - //this is a compatible HEVC, don't insert VDRD, insert NALU delim - if (entry->lhvc_config && entry->hevc_config) - insert_vdrd_code = GF_FALSE; - - if (extractor_mode == GF_ISOM_NALU_EXTRACT_INSPECT) { - if (!rewrite_ps && !rewrite_start_codes) - return GF_OK; - } - - nal_unit_size_field = 0; - /*if svc rewrite*/ - if (entry->svc_config && entry->svc_config->config) - nal_unit_size_field = entry->svc_config->config->nal_unit_size; - /*if mvc rewrite*/ - if (entry->mvc_config && entry->mvc_config->config) - nal_unit_size_field = entry->mvc_config->config->nal_unit_size; - - /*if lhvc rewrite*/ - else if (entry->lhvc_config && entry->lhvc_config->config) { - is_hevc = GF_TRUE; - nal_unit_size_field = entry->lhvc_config->config->nal_unit_size; - } - - /*otherwise do nothing*/ - else if (!rewrite_ps && !rewrite_start_codes && !scal && !force_sei_inspect) { - return GF_OK; - } - - if (!nal_unit_size_field) { - if (entry->avc_config && entry->avc_config->config) - nal_unit_size_field = entry->avc_config->config->nal_unit_size; - else if (entry->lhvc_config && entry->lhvc_config->config) { - nal_unit_size_field = entry->lhvc_config->config->nal_unit_size; - is_hevc = GF_TRUE; - } - else if (entry->hevc_config && entry->hevc_config->config) { - nal_unit_size_field = entry->hevc_config->config->nal_unit_size; - is_hevc = GF_TRUE; - } - } - - if (!nal_unit_size_field) return GF_ISOM_INVALID_FILE; - - //setup PS rewriter - if (!mdia->nalu_ps_bs) - mdia->nalu_ps_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - gf_bs_seek(mdia->nalu_ps_bs, 0); - - //setup sample reader - if (mdia->in_sample_buffer_allocdataLength) { - mdia->in_sample_buffer_alloc = sample->dataLength; - mdia->in_sample_buffer = gf_realloc(mdia->in_sample_buffer, sample->dataLength); - } - memcpy(mdia->in_sample_buffer, sample->data, sample->dataLength); - - if (!mdia->nalu_parser) { - mdia->nalu_parser = gf_bs_new(mdia->in_sample_buffer, sample->dataLength, GF_BITSTREAM_READ); - if (!mdia->nalu_parser && sample->data) return GF_ISOM_INVALID_FILE; - } else { - e = gf_bs_reassign_buffer(mdia->nalu_parser, mdia->in_sample_buffer, sample->dataLength); - if (e) return e; - } - //setup ouput - if (!mdia->nalu_out_bs) { - u8 *output; - u32 outSize; - mdia->nalu_out_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - gf_bs_get_content(mdia->nalu_out_bs, &output, &outSize); - } - - gf_bs_reassign_buffer(mdia->nalu_out_bs, sample->data, sample->alloc_size ? sample->alloc_size : sample->dataLength); - - /*rewrite start code with NALU delim*/ - if (rewrite_start_codes) { - - //we are SVC, don't write NALU delim, only insert VDRD NALU - if (insert_vdrd_code) { - if (is_hevc) { - //spec is not clear here, we don't insert an NALU AU delimiter before the layer starts since it breaks openHEVC -// insert_nalu_delim=0; - } else { - gf_bs_write_int(mdia->nalu_out_bs, 1, 32); - gf_bs_write_int(mdia->nalu_out_bs, GF_AVC_NALU_VDRD , 8); - insert_nalu_delim=0; - } - } - - //AVC/HEVC base, insert NALU delim - if (insert_nalu_delim) { - gf_bs_write_int(mdia->nalu_out_bs, 1, 32); - if (is_hevc) { -#ifndef GPAC_DISABLE_HEVC - gf_bs_write_int(mdia->nalu_out_bs, 0, 1); - gf_bs_write_int(mdia->nalu_out_bs, GF_HEVC_NALU_ACCESS_UNIT, 6); - gf_bs_write_int(mdia->nalu_out_bs, insert_vdrd_code ? 1 : 0, 6); //we should pick the layerID of the following nalus ... - gf_bs_write_int(mdia->nalu_out_bs, 1, 3); //nuh_temporal_id_plus1 - cannot be 0, we use 1 by default, and overwrite it if needed at the end - - /*pic-type - by default we signal all slice types possible*/ - gf_bs_write_int(mdia->nalu_out_bs, 2, 3); - gf_bs_write_int(mdia->nalu_out_bs, 0, 5); -#endif - } else { - gf_bs_write_int(mdia->nalu_out_bs, (sample->data[0] & 0x60) | GF_AVC_NALU_ACCESS_UNIT, 8); - gf_bs_write_int(mdia->nalu_out_bs, 0xF0 , 8); /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/; - } - } - } - - if (rewrite_ps) { - Bool has_vps = GF_FALSE; - //in inspect mode or single-layer mode just use the xPS from this layer - if (extractor_mode == GF_ISOM_NALU_EXTRACT_DEFAULT) { - if (scal) { - for (i=0; itrackIDCount; i++) { - GF_TrackBox *a_track = GetTrackbyID(mdia->mediaTrack->moov, scal->trackIDs[i]); - GF_MPEGVisualSampleEntryBox *an_entry = NULL; - if (a_track && a_track->Media && a_track->Media->information && a_track->Media->information->sampleTable && a_track->Media->information->sampleTable->SampleDescription) - an_entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(a_track->Media->information->sampleTable->SampleDescription->child_boxes, 0); - - if (an_entry) - nalu_merge_ps(mdia->nalu_ps_bs, rewrite_start_codes, nal_unit_size_field, an_entry, is_hevc, &has_vps); - } - } - } - nalu_merge_ps(mdia->nalu_ps_bs, rewrite_start_codes, nal_unit_size_field, entry, is_hevc, &has_vps); - - - if (is_hevc) { - /*little optimization if we are not asked to start codes: copy over the sample*/ - if (!rewrite_start_codes && !entry->lhvc_config && !scal) { - if (! ps_transfered) { - nal_type = (sample->data[nal_unit_size_field] & 0x7E) >> 1; - //temp fix - if we detect xPS in the beginning of the sample do NOT copy the ps bitstream - //this is not correct since we are not sure whether they are the same xPS or not, but it crashes openHEVC ... - switch (nal_type) { -#ifndef GPAC_DISABLE_HEVC - case GF_HEVC_NALU_VID_PARAM: - case GF_HEVC_NALU_SEQ_PARAM: - case GF_HEVC_NALU_PIC_PARAM: - break; -#endif - default: - gf_bs_transfer(mdia->nalu_out_bs, mdia->nalu_ps_bs, GF_TRUE); - break; - } - } - gf_bs_write_data(mdia->nalu_out_bs, mdia->in_sample_buffer, sample->dataLength); - gf_bs_get_content_no_truncate(mdia->nalu_out_bs, &sample->data, &sample->dataLength, &sample->alloc_size); - - return GF_OK; - } - } - } else { - ps_transfered = GF_TRUE; - } - - /*little optimization if we are not asked to rewrite extractors or start codes: copy over the sample*/ - if (!scal && !rewrite_start_codes && !rewrite_ps && !force_sei_inspect) { - if (! ps_transfered) - { - gf_bs_transfer(mdia->nalu_out_bs, mdia->nalu_ps_bs, GF_TRUE); - } - gf_bs_write_data(mdia->nalu_out_bs, mdia->in_sample_buffer, sample->dataLength); - gf_bs_get_content_no_truncate(mdia->nalu_out_bs, &sample->data, &sample->dataLength, &sample->alloc_size); - return GF_OK; - } - - if (!mdia->tmp_nal_copy_buffer) { - mdia->tmp_nal_copy_buffer = gf_malloc(sizeof(char) * 4096); - mdia->tmp_nal_copy_buffer_alloc = 4096; - } - - - while (gf_bs_available(mdia->nalu_parser)) { - nal_size = gf_bs_read_int(mdia->nalu_parser, 8*nal_unit_size_field); - if (gf_bs_get_position(mdia->nalu_parser) + nal_size > sample->dataLength) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("Sample %u (size %u) rewrite: corrupted NAL Unit (size %u)\n", sampleNumber, sample->dataLength, nal_size)); - goto exit; - } - if (nal_size > mdia->tmp_nal_copy_buffer_alloc) { - mdia->tmp_nal_copy_buffer_alloc = nal_size; - mdia->tmp_nal_copy_buffer = (char*) gf_realloc(mdia->tmp_nal_copy_buffer, sizeof(char)*nal_size); - } - if (is_hevc) { - nal_hdr = gf_bs_read_u16(mdia->nalu_parser); - nal_type = (nal_hdr&0x7E00) >> 9; - } else { - nal_hdr = gf_bs_read_u8(mdia->nalu_parser); - nal_type = nal_hdr & 0x1F; - } - - if (is_hevc) { -#ifndef GPAC_DISABLE_HEVC - GF_BitStream *write_to_bs = mdia->nalu_out_bs; -#endif - - if (!ps_transfered) { - gf_bs_transfer(mdia->nalu_out_bs, mdia->nalu_ps_bs, GF_TRUE); - ps_transfered = GF_TRUE; - } - -#ifndef GPAC_DISABLE_HEVC - /*we already wrote this stuff*/ - if (nal_type==GF_HEVC_NALU_ACCESS_UNIT) { - gf_bs_skip_bytes(mdia->nalu_parser, nal_size-2); - continue; - } - switch (nal_type) { - //extractor - case 49: - e = process_extractor(file, mdia, sampleNumber, sample->DTS, nal_size, nal_hdr, nal_unit_size_field, GF_TRUE, rewrite_ps, rewrite_start_codes, extractor_mode); - if (e) goto exit; - break; - - case GF_HEVC_NALU_SLICE_TSA_N: - case GF_HEVC_NALU_SLICE_STSA_N: - case GF_HEVC_NALU_SLICE_TSA_R: - case GF_HEVC_NALU_SLICE_STSA_R: - if (temporal_id < (nal_hdr & 0x7)) - temporal_id = (nal_hdr & 0x7); - /*rewrite nal*/ - gf_bs_read_data(mdia->nalu_parser, mdia->tmp_nal_copy_buffer, nal_size-2); - if (rewrite_start_codes) - gf_bs_write_u32(mdia->nalu_out_bs, 1); - else - gf_bs_write_int(mdia->nalu_out_bs, nal_size, 8*nal_unit_size_field); - - gf_bs_write_u16(mdia->nalu_out_bs, nal_hdr); - gf_bs_write_data(mdia->nalu_out_bs, mdia->tmp_nal_copy_buffer, nal_size-2); - break; - - case GF_HEVC_NALU_SLICE_BLA_W_LP: - case GF_HEVC_NALU_SLICE_BLA_W_DLP: - case GF_HEVC_NALU_SLICE_BLA_N_LP: - case GF_HEVC_NALU_SLICE_IDR_W_DLP: - case GF_HEVC_NALU_SLICE_IDR_N_LP: - case GF_HEVC_NALU_SLICE_CRA: - //insert xPS before CRA/BLA - if (check_cra_bla && !sample->IsRAP) { - sample->IsRAP = sap_type_from_nal_type(nal_type); - if (sei_suffix_bs) gf_bs_del(sei_suffix_bs); - return gf_isom_nalu_sample_rewrite(mdia, sample, sampleNumber, entry); - } - default: - /*rewrite nal*/ - if (nal_size<2) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid nal size %d in sample %d\n", nal_type, sampleNumber)); - e = GF_NON_COMPLIANT_BITSTREAM; - goto exit; - } - - gf_bs_read_data(mdia->nalu_parser, mdia->tmp_nal_copy_buffer, nal_size-2); - - if (nal_type==GF_HEVC_NALU_SEI_SUFFIX) { - if (!sei_suffix_bs) sei_suffix_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - write_to_bs = sei_suffix_bs; - } - - if (rewrite_start_codes) - gf_bs_write_u32(write_to_bs, 1); - else - gf_bs_write_int(write_to_bs, nal_size, 8*nal_unit_size_field); - - gf_bs_write_u16(write_to_bs, nal_hdr); - gf_bs_write_data(write_to_bs, mdia->tmp_nal_copy_buffer, nal_size-2); - } -#endif - - //done with HEVC - continue; - } - - switch(nal_type) { - case GF_AVC_NALU_ACCESS_UNIT: - /*we already wrote this stuff*/ - gf_bs_skip_bytes(mdia->nalu_parser, nal_size-1); - continue; - //extractor - case 31: - e = process_extractor(file, mdia, sampleNumber, sample->DTS, nal_size, nal_hdr, nal_unit_size_field, GF_FALSE, rewrite_ps, rewrite_start_codes, extractor_mode); - if (e) goto exit; - break; -// case GF_AVC_NALU_SEI: - case GF_AVC_NALU_SEQ_PARAM: - case GF_AVC_NALU_PIC_PARAM: - case GF_AVC_NALU_SEQ_PARAM_EXT: - case GF_AVC_NALU_SVC_SUBSEQ_PARAM: - // we will rewrite the sps/pps if and only if there is no sps/pps in bistream - if (!ps_transfered) { - ps_transfered = GF_TRUE; - } - default: - if (!ps_transfered) { - gf_bs_transfer(mdia->nalu_out_bs, mdia->nalu_ps_bs, GF_TRUE); - ps_transfered = GF_TRUE; - } - gf_bs_read_data(mdia->nalu_parser, mdia->tmp_nal_copy_buffer, nal_size-1); - if (rewrite_start_codes) - gf_bs_write_u32(mdia->nalu_out_bs, 1); - else - gf_bs_write_int(mdia->nalu_out_bs, nal_size, 8*nal_unit_size_field); - - gf_bs_write_u8(mdia->nalu_out_bs, nal_hdr); - gf_bs_write_data(mdia->nalu_out_bs, mdia->tmp_nal_copy_buffer, nal_size-1); - } - } - - if (sei_suffix_bs) { - gf_bs_transfer(mdia->nalu_out_bs, sei_suffix_bs, GF_FALSE); - } - /*done*/ - gf_bs_get_content_no_truncate(mdia->nalu_out_bs, &sample->data, &sample->dataLength, &sample->alloc_size); - - /*rewrite temporal ID of AU Ddelim NALU (first one)*/ - if (rewrite_start_codes && is_hevc && temporal_id) { - sample->data[6] = (sample->data[6] & 0xF8) | (temporal_id+1); - } - - -exit: - if (sei_suffix_bs) - gf_bs_del(sei_suffix_bs); - - return e; -} - -GF_HEVCConfig *HEVC_DuplicateConfig(GF_HEVCConfig *cfg) -{ - u8 *data; - u32 data_size; - GF_HEVCConfig *new_cfg; - GF_BitStream *bs; - - if (!cfg) return NULL; - bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - gf_odf_hevc_cfg_write_bs(cfg, bs); - - gf_bs_get_content(bs, &data, &data_size); - gf_bs_del(bs); - bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ); - - new_cfg = gf_odf_hevc_cfg_read_bs(bs, cfg->is_lhvc); - new_cfg->is_lhvc = cfg->is_lhvc; - gf_bs_del(bs); - gf_free(data); - return new_cfg; -} - -static GF_AVCConfig *AVC_DuplicateConfig(GF_AVCConfig *cfg) -{ - u32 i, count; - GF_AVCConfigSlot *p1, *p2; - GF_AVCConfig *cfg_new; - if (!cfg) - return NULL; - cfg_new = gf_odf_avc_cfg_new(); - cfg_new->AVCLevelIndication = cfg->AVCLevelIndication; - cfg_new->AVCProfileIndication = cfg->AVCProfileIndication; - cfg_new->configurationVersion = cfg->configurationVersion; - cfg_new->nal_unit_size = cfg->nal_unit_size; - cfg_new->profile_compatibility = cfg->profile_compatibility; - cfg_new->complete_representation = cfg->complete_representation; - cfg_new->chroma_bit_depth = cfg->chroma_bit_depth; - cfg_new->luma_bit_depth = cfg->luma_bit_depth; - cfg_new->chroma_format = cfg->chroma_format; - - count = gf_list_count(cfg->sequenceParameterSets); - for (i=0; isequenceParameterSets, i); - p2 = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - p2->size = p1->size; - p2->id = p1->id; - p2->data = (char *)gf_malloc(sizeof(char)*p1->size); - memcpy(p2->data, p1->data, sizeof(char)*p1->size); - gf_list_add(cfg_new->sequenceParameterSets, p2); - } - - count = gf_list_count(cfg->pictureParameterSets); - for (i=0; ipictureParameterSets, i); - p2 = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - p2->size = p1->size; - p2->id = p1->id; - p2->data = (char*)gf_malloc(sizeof(char)*p1->size); - memcpy(p2->data, p1->data, sizeof(char)*p1->size); - gf_list_add(cfg_new->pictureParameterSets, p2); - } - - if (cfg->sequenceParameterSetExtensions) { - cfg_new->sequenceParameterSetExtensions = gf_list_new(); - count = gf_list_count(cfg->sequenceParameterSetExtensions); - for (i=0; isequenceParameterSetExtensions, i); - p2 = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); - p2->size = p1->size; - p2->id = p1->id; - p2->data = (char*)gf_malloc(sizeof(char)*p1->size); - memcpy(p2->data, p1->data, sizeof(char)*p1->size); - gf_list_add(cfg_new->sequenceParameterSetExtensions, p2); - } - } - return cfg_new; -} - -static void merge_avc_config(GF_AVCConfig *dst_cfg, GF_AVCConfig *src_cfg) -{ - GF_AVCConfig *cfg; - if (!src_cfg || !dst_cfg) return; - cfg = AVC_DuplicateConfig(src_cfg); - if (!cfg) return; - - while (gf_list_count(cfg->sequenceParameterSets)) { - GF_AVCConfigSlot *p = (GF_AVCConfigSlot*)gf_list_get(cfg->sequenceParameterSets, 0); - gf_list_rem(cfg->sequenceParameterSets, 0); - gf_list_insert(dst_cfg->sequenceParameterSets, p, 0); - } - while (gf_list_count(cfg->pictureParameterSets)) { - GF_AVCConfigSlot *p = (GF_AVCConfigSlot*)gf_list_get(cfg->pictureParameterSets, 0); - gf_list_rem(cfg->pictureParameterSets, 0); - gf_list_insert(dst_cfg->pictureParameterSets, p, 0); - } - gf_odf_avc_cfg_del(cfg); -} - -void merge_hevc_config(GF_HEVCConfig *dst_cfg, GF_HEVCConfig *src_cfg, Bool force_insert) -{ - GF_HEVCConfig *cfg = HEVC_DuplicateConfig(src_cfg); - //merge all xPS - u32 i, j, count = cfg->param_array ? gf_list_count(cfg->param_array) : 0; - for (i=0; iparam_array ? gf_list_count(dst_cfg->param_array) : 0; - GF_HEVCParamArray *ar = (GF_HEVCParamArray*)gf_list_get(cfg->param_array, i); - for (j=0; jparam_array, j); - if (ar_h->type==ar->type) { - break; - } - ar_h = NULL; - } - if (!ar_h) { - gf_list_add(dst_cfg->param_array, ar); - gf_list_rem(cfg->param_array, i); - count--; - i--; - } else { - while (gf_list_count(ar->nalus)) { - GF_AVCConfigSlot *p = (GF_AVCConfigSlot*)gf_list_get(ar->nalus, 0); - gf_list_rem(ar->nalus, 0); - if (force_insert) - gf_list_insert(ar_h->nalus, p, 0); - else - gf_list_add(ar_h->nalus, p); - } - - } - } - gf_odf_hevc_cfg_del(cfg); - -#define CHECK_CODE(__code) if (dst_cfg->__code < src_cfg->__code) dst_cfg->__code = src_cfg->__code; - - CHECK_CODE(configurationVersion) - CHECK_CODE(profile_idc) - CHECK_CODE(profile_space) - CHECK_CODE(tier_flag) - CHECK_CODE(general_profile_compatibility_flags) - CHECK_CODE(progressive_source_flag) - CHECK_CODE(interlaced_source_flag) - CHECK_CODE(constraint_indicator_flags) - CHECK_CODE(level_idc) - CHECK_CODE(min_spatial_segmentation_idc) - -} - -void merge_all_config(GF_AVCConfig *avc_cfg, GF_HEVCConfig *hevc_cfg, GF_MediaBox *mdia) -{ - u32 i; - GF_TrackReferenceTypeBox *scal = NULL; - Track_FindRef(mdia->mediaTrack, GF_ISOM_REF_SCAL, &scal); - - if (!scal) return; - - for (i=0; itrackIDCount; i++) { - GF_TrackBox *a_track = GetTrackbyID(mdia->mediaTrack->moov, scal->trackIDs[i]); - GF_MPEGVisualSampleEntryBox *an_entry = NULL; - if (a_track && a_track->Media && a_track->Media->information && a_track->Media->information->sampleTable && a_track->Media->information->sampleTable->SampleDescription) - an_entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(a_track->Media->information->sampleTable->SampleDescription->child_boxes, 0); - - if (!an_entry) continue; - - if (avc_cfg && an_entry->svc_config && an_entry->svc_config->config) - merge_avc_config(avc_cfg, an_entry->svc_config->config); - - if (avc_cfg && an_entry->mvc_config && an_entry->mvc_config->config) - merge_avc_config(avc_cfg, an_entry->mvc_config->config); - - if (avc_cfg && an_entry->avc_config && an_entry->avc_config->config) - merge_avc_config(avc_cfg, an_entry->avc_config->config); - - if (hevc_cfg && an_entry->lhvc_config && an_entry->lhvc_config->config) - merge_hevc_config(hevc_cfg, an_entry->lhvc_config->config, GF_TRUE); - - if (hevc_cfg && an_entry->hevc_config && an_entry->hevc_config->config) - merge_hevc_config(hevc_cfg, an_entry->hevc_config->config, GF_TRUE); - } - - if (hevc_cfg) hevc_cfg->is_lhvc = GF_FALSE; -} - -void AVC_RewriteESDescriptorEx(GF_MPEGVisualSampleEntryBox *avc, GF_MediaBox *mdia) -{ - GF_BitRateBox *btrt = gf_isom_sample_entry_get_bitrate((GF_SampleEntryBox *)avc, GF_FALSE); - - if (avc->emul_esd) gf_odf_desc_del((GF_Descriptor *)avc->emul_esd); - avc->emul_esd = gf_odf_desc_esd_new(2); - avc->emul_esd->decoderConfig->streamType = GF_STREAM_VISUAL; - /*AVC OTI is 0x21, AVC parameter set stream OTI (not supported in gpac) is 0x22, SVC OTI is 0x24*/ - /*if we have only SVC stream, set objectTypeIndication to AVC OTI; else set it to AVC OTI*/ - if (avc->svc_config && !avc->avc_config) - avc->emul_esd->decoderConfig->objectTypeIndication = GF_CODECID_SVC; - else if (avc->mvc_config && !avc->avc_config) - avc->emul_esd->decoderConfig->objectTypeIndication = GF_CODECID_MVC; - else - avc->emul_esd->decoderConfig->objectTypeIndication = GF_CODECID_AVC; - - if (btrt) { - avc->emul_esd->decoderConfig->bufferSizeDB = btrt->bufferSizeDB; - avc->emul_esd->decoderConfig->avgBitrate = btrt->avgBitrate; - avc->emul_esd->decoderConfig->maxBitrate = btrt->maxBitrate; - } - GF_MPEG4ExtensionDescriptorsBox *mdesc = (GF_MPEG4ExtensionDescriptorsBox *) gf_isom_box_find_child(avc->child_boxes, GF_ISOM_BOX_TYPE_M4DS); - if (mdesc) { - u32 i=0; - GF_Descriptor *desc,*clone; - i=0; - while ((desc = (GF_Descriptor *)gf_list_enum(mdesc->descriptors, &i))) { - clone = NULL; - gf_odf_desc_copy(desc, &clone); - if (gf_odf_desc_add_desc((GF_Descriptor *)avc->emul_esd, clone) != GF_OK) - gf_odf_desc_del(clone); - } - } - if (avc->avc_config) { - GF_AVCConfig *avcc = avc->avc_config->config ? AVC_DuplicateConfig(avc->avc_config->config) : NULL; - /*merge SVC config*/ - if (avc->svc_config) { - merge_avc_config(avcc, avc->svc_config->config); - } - /*merge MVC config*/ - if (avc->mvc_config) { - merge_avc_config(avcc, avc->mvc_config->config); - } - if (avcc) { - if (mdia) merge_all_config(avcc, NULL, mdia); - - gf_odf_avc_cfg_write(avcc, &avc->emul_esd->decoderConfig->decoderSpecificInfo->data, &avc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); - gf_odf_avc_cfg_del(avcc); - } - } else if (avc->svc_config) { - GF_AVCConfig *svcc = AVC_DuplicateConfig(avc->svc_config->config); - - if (mdia) merge_all_config(svcc, NULL, mdia); - - gf_odf_avc_cfg_write(svcc, &avc->emul_esd->decoderConfig->decoderSpecificInfo->data, &avc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); - gf_odf_avc_cfg_del(svcc); - } - else if (avc->mvc_config) { - GF_AVCConfig *mvcc = AVC_DuplicateConfig(avc->mvc_config->config); - - if (mdia) merge_all_config(mvcc, NULL, mdia); - - gf_odf_avc_cfg_write(mvcc, &avc->emul_esd->decoderConfig->decoderSpecificInfo->data, &avc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); - gf_odf_avc_cfg_del(mvcc); - } -} - -void AVC_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *avc) -{ - AVC_RewriteESDescriptorEx(avc, NULL); -} - -void HEVC_RewriteESDescriptorEx(GF_MPEGVisualSampleEntryBox *hevc, GF_MediaBox *mdia) -{ - GF_BitRateBox *btrt = gf_isom_sample_entry_get_bitrate((GF_SampleEntryBox *)hevc, GF_FALSE); - - if (hevc->emul_esd) gf_odf_desc_del((GF_Descriptor *)hevc->emul_esd); - hevc->emul_esd = gf_odf_desc_esd_new(2); - hevc->emul_esd->decoderConfig->streamType = GF_STREAM_VISUAL; - hevc->emul_esd->decoderConfig->objectTypeIndication = GF_CODECID_HEVC; - - if (btrt) { - hevc->emul_esd->decoderConfig->bufferSizeDB = btrt->bufferSizeDB; - hevc->emul_esd->decoderConfig->avgBitrate = btrt->avgBitrate; - hevc->emul_esd->decoderConfig->maxBitrate = btrt->maxBitrate; - } - GF_MPEG4ExtensionDescriptorsBox *mdesc = (GF_MPEG4ExtensionDescriptorsBox *) gf_isom_box_find_child(hevc->child_boxes, GF_ISOM_BOX_TYPE_M4DS); - if (mdesc) { - u32 i=0; - GF_Descriptor *desc,*clone; - i=0; - while ((desc = (GF_Descriptor *)gf_list_enum(mdesc->descriptors, &i))) { - clone = NULL; - gf_odf_desc_copy(desc, &clone); - if (gf_odf_desc_add_desc((GF_Descriptor *)hevc->emul_esd, clone) != GF_OK) - gf_odf_desc_del(clone); - } - } - - if (hevc->hevc_config || hevc->lhvc_config) { - GF_HEVCConfig *hcfg = HEVC_DuplicateConfig(hevc->hevc_config ? hevc->hevc_config->config : hevc->lhvc_config->config); - - if (hevc->hevc_config && hevc->lhvc_config) { - //merge LHVC config to HEVC conf, so we add entry rather than insert - merge_hevc_config(hcfg, hevc->lhvc_config->config, GF_FALSE); - } - - if (mdia) merge_all_config(NULL, hcfg, mdia); - - if (hcfg) { - if (mdia && ((mdia->mediaTrack->extractor_mode&0x0000FFFF) != GF_ISOM_NALU_EXTRACT_INSPECT)) { - hcfg->is_lhvc=GF_FALSE; - } - - gf_odf_hevc_cfg_write(hcfg, &hevc->emul_esd->decoderConfig->decoderSpecificInfo->data, &hevc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); - gf_odf_hevc_cfg_del(hcfg); - } - } -} -void HEVC_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *hevc) -{ - HEVC_RewriteESDescriptorEx(hevc, NULL); -} - -GF_Err AVC_HEVC_UpdateESD(GF_MPEGVisualSampleEntryBox *avc, GF_ESD *esd) -{ - GF_BitRateBox *btrt = gf_isom_sample_entry_get_bitrate((GF_SampleEntryBox *)avc, GF_TRUE); - - GF_MPEG4ExtensionDescriptorsBox *mdesc = (GF_MPEG4ExtensionDescriptorsBox *) gf_isom_box_find_child(avc->child_boxes, GF_ISOM_BOX_TYPE_M4DS); - if (mdesc) { - gf_isom_box_del_parent(&avc->child_boxes, (GF_Box *) mdesc); - } - btrt->avgBitrate = esd->decoderConfig->avgBitrate; - btrt->maxBitrate = esd->decoderConfig->maxBitrate; - btrt->bufferSizeDB = esd->decoderConfig->bufferSizeDB; - - if (gf_list_count(esd->IPIDataSet) - || gf_list_count(esd->IPMPDescriptorPointers) - || esd->langDesc - || gf_list_count(esd->extensionDescriptors) - || esd->ipiPtr || esd->qos || esd->RegDescriptor) { - - mdesc = (GF_MPEG4ExtensionDescriptorsBox *) gf_isom_box_new_parent(&avc->child_boxes, GF_ISOM_BOX_TYPE_M4DS); - if (!mdesc) return GF_OUT_OF_MEM; - - if (esd->RegDescriptor) { - gf_list_add(mdesc->descriptors, esd->RegDescriptor); - esd->RegDescriptor = NULL; - } - if (esd->qos) { - gf_list_add(mdesc->descriptors, esd->qos); - esd->qos = NULL; - } - if (esd->ipiPtr) { - gf_list_add(mdesc->descriptors, esd->ipiPtr); - esd->ipiPtr= NULL; - } - - while (gf_list_count(esd->IPIDataSet)) { - GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPIDataSet, 0); - gf_list_rem(esd->IPIDataSet, 0); - gf_list_add(mdesc->descriptors, desc); - } - while (gf_list_count(esd->IPMPDescriptorPointers)) { - GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPMPDescriptorPointers, 0); - gf_list_rem(esd->IPMPDescriptorPointers, 0); - gf_list_add(mdesc->descriptors, desc); - } - if (esd->langDesc) { - gf_list_add(mdesc->descriptors, esd->langDesc); - esd->langDesc = NULL; - } - while (gf_list_count(esd->extensionDescriptors)) { - GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->extensionDescriptors, 0); - gf_list_rem(esd->extensionDescriptors, 0); - gf_list_add(mdesc->descriptors, desc); - } - } - - - if (!avc->lhvc_config && (esd->decoderConfig->objectTypeIndication==GF_CODECID_HEVC)) { - if (!avc->hevc_config) { - avc->hevc_config = (GF_HEVCConfigurationBox *)gf_isom_box_new_parent(&avc->child_boxes, GF_ISOM_BOX_TYPE_HVCC); - if (!avc->hevc_config) return GF_OUT_OF_MEM; - } - if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { - if (avc->hevc_config->config) gf_odf_hevc_cfg_del(avc->hevc_config->config); - avc->hevc_config->config = gf_odf_hevc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_FALSE); - } - } - else if (!avc->svc_config && !avc->mvc_config && (esd->decoderConfig->objectTypeIndication==GF_CODECID_AVC)) { - if (!avc->avc_config) { - avc->avc_config = (GF_AVCConfigurationBox *)gf_isom_box_new_parent(&avc->child_boxes, GF_ISOM_BOX_TYPE_AVCC); - if (!avc->avc_config) return GF_OUT_OF_MEM; - } - if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { - if (avc->avc_config->config) gf_odf_avc_cfg_del(avc->avc_config->config); - avc->avc_config->config = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); - } - } - - gf_odf_desc_del((GF_Descriptor *)esd); - if (avc->hevc_config) { - HEVC_RewriteESDescriptor(avc); - } else { - AVC_RewriteESDescriptor(avc); - } - return GF_OK; -} - -#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_HEVC) -void gf_media_hevc_parse_ps(GF_HEVCConfig* hevccfg, HEVCState* hevc, u32 nal_type) -{ - u32 i, j; - if (!hevccfg) return; - - for (i = 0; i < gf_list_count(hevccfg->param_array); i++) { - GF_HEVCParamArray* ar = gf_list_get(hevccfg->param_array, i); - if (ar->type != nal_type) continue; - for (j = 0; j < gf_list_count(ar->nalus); j++) { - u8 ntype, tid, lid; - GF_AVCConfigSlot* sl = gf_list_get(ar->nalus, j); - gf_media_hevc_parse_nalu(sl->data, sl->size, hevc, &ntype, &tid, &lid); - } - } -} -#endif - - -static GF_Err gf_isom_check_mvc(GF_ISOFile *the_file, GF_TrackBox *trak, GF_MPEGVisualSampleEntryBox *entry) -{ - u32 i; - GF_Box *mvci; - GF_MultiviewGroupBox *mvcg; - GF_ViewIdentifierBox *vwid; - - if (entry->mvc_config) {} - else if (entry->avc_config && entry->avc_config->config && entry->avc_config->config->sequenceParameterSetExtensions) {} - else - return GF_OK; - - mvci = gf_isom_box_find_child(trak->Media->information->child_boxes, GF_ISOM_BOX_TYPE_MVCI); - if (!mvci) { - mvci = gf_isom_box_new_parent(&trak->Media->information->child_boxes, GF_ISOM_BOX_TYPE_MVCI); - if (!mvci) return GF_OUT_OF_MEM; - } - mvcg = (GF_MultiviewGroupBox *) gf_isom_box_find_child(mvci->child_boxes, GF_ISOM_BOX_TYPE_MVCG); - if (!mvcg) { - mvcg = (GF_MultiviewGroupBox *)gf_isom_box_new_parent(&mvci->child_boxes, GF_ISOM_BOX_TYPE_MVCG); - if (!mvcg) return GF_OUT_OF_MEM; - } - //this is very crude, we should try to parse the bitstream to fill these - mvcg->num_entries = 0; - if (mvcg->entries) { - gf_free(mvcg->entries); - mvcg->entries = NULL; - } - if (entry->avc_config) { - if (gf_list_count(entry->avc_config->config->sequenceParameterSets)) - mvcg->num_entries += 1; - mvcg->num_entries += gf_list_count(entry->avc_config->config->sequenceParameterSetExtensions); - } - if (entry->mvc_config) { - mvcg->num_entries += gf_list_count(entry->mvc_config->config->sequenceParameterSets); - } - mvcg->entries = gf_malloc(sizeof(MVCIEntry)*mvcg->num_entries); - if (!mvcg->entries) return GF_OUT_OF_MEM; - memset(mvcg->entries, 0, sizeof(MVCIEntry)*mvcg->num_entries); - for (i=0; inum_entries; i++) { - mvcg->entries[i].entry_type = 2; - mvcg->entries[i].output_view_id = i; - } - vwid = (GF_ViewIdentifierBox *) gf_isom_box_find_child(entry->child_boxes, GF_ISOM_BOX_TYPE_VWID); - if (!vwid) { - vwid = (GF_ViewIdentifierBox *)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_VWID); - if (!mvcg) return GF_OUT_OF_MEM; - } - if (vwid->views) gf_free(vwid->views); - vwid->num_views = mvcg->num_entries; - vwid->views = gf_malloc(sizeof(ViewIDEntry)*vwid->num_views); - if (!vwid->views) return GF_OUT_OF_MEM; - memset(vwid->views, 0, sizeof(ViewIDEntry)*vwid->num_views); - - for (i=0; inum_views; i++) { - vwid->views[i].base_view_type = i ? 0 : 1; - vwid->views[i].view_id = i; - vwid->views[i].view_order_index = i; - } - - return GF_OK; -} - -static GF_AV1Config* AV1_DuplicateConfig(GF_AV1Config const * const cfg) { - u32 i = 0; - GF_AV1Config *out = gf_malloc(sizeof(GF_AV1Config)); - - out->marker = cfg->marker; - out->version = cfg->version; - out->seq_profile = cfg->seq_profile; - out->seq_level_idx_0 = cfg->seq_level_idx_0; - out->seq_tier_0 = cfg->seq_tier_0; - out->high_bitdepth = cfg->high_bitdepth; - out->twelve_bit = cfg->twelve_bit; - out->monochrome = cfg->monochrome; - out->chroma_subsampling_x = cfg->chroma_subsampling_x; - out->chroma_subsampling_y = cfg->chroma_subsampling_y; - out->chroma_sample_position = cfg->chroma_sample_position; - - out->initial_presentation_delay_present = cfg->initial_presentation_delay_present; - out->initial_presentation_delay_minus_one = cfg->initial_presentation_delay_minus_one; - out->obu_array = gf_list_new(); - for (i = 0; iobu_array); ++i) { - GF_AV1_OBUArrayEntry *dst = gf_malloc(sizeof(GF_AV1_OBUArrayEntry)), *src = gf_list_get(cfg->obu_array, i); - dst->obu_length = src->obu_length; - dst->obu_type = src->obu_type; - dst->obu = gf_malloc((size_t)dst->obu_length); - memcpy(dst->obu, src->obu, (size_t)src->obu_length); - gf_list_add(out->obu_array, dst); - } - return out; -} - -void AV1_RewriteESDescriptorEx(GF_MPEGVisualSampleEntryBox *av1, GF_MediaBox *mdia) -{ - GF_BitRateBox *btrt = gf_isom_sample_entry_get_bitrate((GF_SampleEntryBox *)av1, GF_FALSE); - - if (av1->emul_esd) gf_odf_desc_del((GF_Descriptor *)av1->emul_esd); - av1->emul_esd = gf_odf_desc_esd_new(2); - av1->emul_esd->decoderConfig->streamType = GF_STREAM_VISUAL; - av1->emul_esd->decoderConfig->objectTypeIndication = GF_CODECID_AV1; - - if (btrt) { - av1->emul_esd->decoderConfig->bufferSizeDB = btrt->bufferSizeDB; - av1->emul_esd->decoderConfig->avgBitrate = btrt->avgBitrate; - av1->emul_esd->decoderConfig->maxBitrate = btrt->maxBitrate; - } - if (av1->av1_config) { - GF_AV1Config *av1_cfg = AV1_DuplicateConfig(av1->av1_config->config); - if (av1_cfg) { - gf_odf_av1_cfg_write(av1_cfg, &av1->emul_esd->decoderConfig->decoderSpecificInfo->data, &av1->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); - gf_odf_av1_cfg_del(av1_cfg); - } - } -} - -void AV1_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *av1) -{ - AV1_RewriteESDescriptorEx(av1, NULL); -} - - - -static GF_VPConfig* VP_DuplicateConfig(GF_VPConfig const * const cfg) -{ - GF_VPConfig *out = gf_odf_vp_cfg_new(); - if (out) { - out->profile = cfg->profile; - out->level = cfg->level; - out->bit_depth = cfg->bit_depth; - out->chroma_subsampling = cfg->chroma_subsampling; - out->video_fullRange_flag = cfg->video_fullRange_flag; - out->colour_primaries = cfg->colour_primaries; - out->transfer_characteristics = cfg->transfer_characteristics; - out->matrix_coefficients = cfg->matrix_coefficients; - } - - return out; -} - -void VP9_RewriteESDescriptorEx(GF_MPEGVisualSampleEntryBox *vp9, GF_MediaBox *mdia) -{ - GF_BitRateBox *btrt = gf_isom_sample_entry_get_bitrate((GF_SampleEntryBox *)vp9, GF_FALSE); - - if (vp9->emul_esd) gf_odf_desc_del((GF_Descriptor *)vp9->emul_esd); - vp9->emul_esd = gf_odf_desc_esd_new(2); - vp9->emul_esd->decoderConfig->streamType = GF_STREAM_VISUAL; - if (vp9->type == GF_ISOM_BOX_TYPE_VP08) - vp9->emul_esd->decoderConfig->objectTypeIndication = GF_CODECID_VP8; - else - vp9->emul_esd->decoderConfig->objectTypeIndication = GF_CODECID_VP9; - - if (btrt) { - vp9->emul_esd->decoderConfig->bufferSizeDB = btrt->bufferSizeDB; - vp9->emul_esd->decoderConfig->avgBitrate = btrt->avgBitrate; - vp9->emul_esd->decoderConfig->maxBitrate = btrt->maxBitrate; - } - - if (vp9->vp_config) { - GF_VPConfig *vp9_cfg = VP_DuplicateConfig(vp9->vp_config->config); - if (vp9_cfg) { - gf_odf_vp_cfg_write(vp9_cfg, &vp9->emul_esd->decoderConfig->decoderSpecificInfo->data, &vp9->emul_esd->decoderConfig->decoderSpecificInfo->dataLength, GF_FALSE); - gf_odf_vp_cfg_del(vp9_cfg); - } - } -} - -void VP9_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *vp9) -{ - VP9_RewriteESDescriptorEx(vp9, NULL); -} - - - -static GF_DOVIDecoderConfigurationRecord* DOVI_DuplicateConfig(GF_DOVIDecoderConfigurationRecord *cfg) -{ - GF_DOVIDecoderConfigurationRecord* out = NULL; - GF_SAFEALLOC(out, GF_DOVIDecoderConfigurationRecord); - if (!out) return NULL; - - out->dv_version_major = cfg->dv_version_major; - out->dv_version_minor = cfg->dv_version_minor; - out->dv_profile = cfg->dv_profile; - out->dv_level = cfg->dv_level; - out->rpu_present_flag = cfg->rpu_present_flag; - out->el_present_flag = cfg->el_present_flag; - out->bl_present_flag = cfg->bl_present_flag; - - return out; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_EXPORT -GF_Err gf_isom_avc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex) -{ - GF_TrackBox *trak; - GF_Err e; - GF_SampleDescriptionBox *stsd; - u32 dataRefIndex; - GF_MPEGVisualSampleEntryBox *entry; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM; - - //get or create the data ref - e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - if (!dataRefIndex) { - e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - } - if (!the_file->keep_utc && !gf_sys_is_test_mode() ) - trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); - - stsd = trak->Media->information->sampleTable->SampleDescription; - - //create a new entry - entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new_parent(&stsd->child_boxes, GF_ISOM_BOX_TYPE_AVC1); - if (!entry) return GF_OUT_OF_MEM; - *outDescriptionIndex = gf_list_count(stsd->child_boxes); - - entry->avc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_AVCC); - if (!entry->avc_config) return GF_OUT_OF_MEM; - entry->avc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->avc_config->config) return GF_OUT_OF_MEM; - entry->dataReferenceIndex = dataRefIndex; - AVC_RewriteESDescriptor(entry); - return e; -} - -static GF_Err gf_isom_avc_config_update_ex(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg, u32 op_type, Bool keep_xps) -{ - GF_TrackBox *trak; - GF_Err e; - u32 i; - GF_MPEGVisualSampleEntryBox *entry; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return GF_BAD_PARAM; - entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return GF_BAD_PARAM; - switch (entry->type) { - case GF_ISOM_BOX_TYPE_AVC1: - case GF_ISOM_BOX_TYPE_AVC2: - case GF_ISOM_BOX_TYPE_AVC3: - case GF_ISOM_BOX_TYPE_AVC4: - case GF_ISOM_BOX_TYPE_SVC1: - case GF_ISOM_BOX_TYPE_MVC1: - break; - default: - return GF_BAD_PARAM; - } - - switch (op_type) { - /*AVCC replacement*/ - case 0: - if (!cfg) return GF_BAD_PARAM; - if (!entry->avc_config) { - entry->avc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_AVCC); - if (!entry->avc_config) return GF_OUT_OF_MEM; - } - if (entry->avc_config->config) gf_odf_avc_cfg_del(entry->avc_config->config); - entry->avc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->avc_config->config) return GF_OUT_OF_MEM; - entry->type = GF_ISOM_BOX_TYPE_AVC1; - break; - /*SVCC replacement*/ - case 1: - if (!cfg) return GF_BAD_PARAM; - if (!entry->svc_config) { - entry->svc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_SVCC); - if (!entry->svc_config) return GF_OUT_OF_MEM; - } - if (entry->svc_config->config) gf_odf_avc_cfg_del(entry->svc_config->config); - entry->svc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->svc_config->config) return GF_OUT_OF_MEM; - entry->type = GF_ISOM_BOX_TYPE_AVC1; - break; - /*SVCC replacement and AVC removal*/ - case 2: - if (!cfg) return GF_BAD_PARAM; - if (entry->avc_config) { - gf_isom_box_del_parent(&entry->child_boxes, (GF_Box*)entry->avc_config); - entry->avc_config = NULL; - } - if (!entry->svc_config) { - entry->svc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_SVCC); - if (!entry->svc_config) return GF_OUT_OF_MEM; - } - if (entry->svc_config->config) gf_odf_avc_cfg_del(entry->svc_config->config); - entry->svc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->svc_config->config) return GF_OUT_OF_MEM; - entry->type = GF_ISOM_BOX_TYPE_SVC1; - break; - /*AVCC removal and switch to avc3*/ - case 3: - if (!entry->avc_config || !entry->avc_config->config) - return GF_BAD_PARAM; - if (!keep_xps) { - for (i=0; i<3; i++) { - GF_AVCConfigurationBox *a_cfg = entry->avc_config; - if (i==1) a_cfg = entry->svc_config; - else if (i==2) a_cfg = entry->mvc_config; - if (!a_cfg) continue; - - - while (gf_list_count(a_cfg->config->sequenceParameterSets)) { - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_list_get(a_cfg->config->sequenceParameterSets, 0); - gf_list_rem(a_cfg->config->sequenceParameterSets, 0); - if (sl->data) gf_free(sl->data); - gf_free(sl); - } - - while (gf_list_count(a_cfg->config->pictureParameterSets)) { - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_list_get(a_cfg->config->pictureParameterSets, 0); - gf_list_rem(a_cfg->config->pictureParameterSets, 0); - if (sl->data) gf_free(sl->data); - gf_free(sl); - } - - while (gf_list_count(a_cfg->config->sequenceParameterSetExtensions)) { - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_list_get(a_cfg->config->sequenceParameterSetExtensions, 0); - gf_list_rem(a_cfg->config->sequenceParameterSetExtensions, 0); - if (sl->data) gf_free(sl->data); - gf_free(sl); - } - } - } - - if (entry->type == GF_ISOM_BOX_TYPE_AVC1) - entry->type = GF_ISOM_BOX_TYPE_AVC3; - else if (entry->type == GF_ISOM_BOX_TYPE_AVC2) - entry->type = GF_ISOM_BOX_TYPE_AVC4; - break; - /*MVCC replacement*/ - case 4: - if (!cfg) return GF_BAD_PARAM; - if (!entry->mvc_config) { - entry->mvc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_MVCC); - if (!entry->mvc_config) return GF_OUT_OF_MEM; - } - if (entry->mvc_config->config) gf_odf_avc_cfg_del(entry->mvc_config->config); - entry->mvc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->mvc_config->config) return GF_OUT_OF_MEM; - entry->type = GF_ISOM_BOX_TYPE_AVC1; - e = gf_isom_check_mvc(the_file, trak, entry); - if (e) return e; - break; - /*MVCC replacement and AVC removal*/ - case 5: - if (!cfg) return GF_BAD_PARAM; - if (entry->avc_config) { - gf_isom_box_del_parent(&entry->child_boxes, (GF_Box*)entry->avc_config); - entry->avc_config = NULL; - } - if (!entry->mvc_config) { - entry->mvc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_MVCC); - if (!entry->mvc_config) return GF_OUT_OF_MEM; - } - if (entry->mvc_config->config) gf_odf_avc_cfg_del(entry->mvc_config->config); - entry->mvc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->mvc_config->config) return GF_OUT_OF_MEM; - entry->type = GF_ISOM_BOX_TYPE_MVC1; - e = gf_isom_check_mvc(the_file, trak, entry); - if (e) return e; - break; - } - AVC_RewriteESDescriptor(entry); - return GF_OK; -} - -GF_EXPORT -GF_Err gf_isom_avc_set_inband_config(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, Bool keep_xps) -{ - return gf_isom_avc_config_update_ex(the_file, trackNumber, DescriptionIndex, NULL, 3, keep_xps); -} - -GF_EXPORT -GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg) -{ - return gf_isom_avc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, 0, GF_FALSE); -} - -GF_EXPORT -GF_Err gf_isom_svc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg, Bool is_add) -{ - return gf_isom_avc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, is_add ? 1 : 2, GF_FALSE); -} - -GF_Err gf_isom_mvc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg, Bool is_add) -{ - return gf_isom_avc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, is_add ? 4 : 5, GF_FALSE); -} - -static GF_Err gf_isom_svc_mvc_config_del(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, Bool is_mvc) -{ - GF_TrackBox *trak; - GF_Err e; - GF_MPEGVisualSampleEntryBox *entry; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return GF_BAD_PARAM; - entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return GF_BAD_PARAM; - switch (entry->type) { - case GF_ISOM_BOX_TYPE_AVC1: - case GF_ISOM_BOX_TYPE_AVC2: - case GF_ISOM_BOX_TYPE_AVC3: - case GF_ISOM_BOX_TYPE_AVC4: - case GF_ISOM_BOX_TYPE_SVC1: - case GF_ISOM_BOX_TYPE_MVC1: - break; - default: - return GF_BAD_PARAM; - } - - if (is_mvc && entry->mvc_config) { - gf_isom_box_del_parent(&entry->child_boxes, (GF_Box*)entry->mvc_config); - entry->mvc_config = NULL; - } - else if (!is_mvc && entry->svc_config) { - gf_isom_box_del_parent(&entry->child_boxes, (GF_Box*)entry->svc_config); - entry->svc_config = NULL; - } - AVC_RewriteESDescriptor(entry); - return GF_OK; -} - -GF_Err gf_isom_svc_config_del(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - return gf_isom_svc_mvc_config_del(the_file, trackNumber, DescriptionIndex, GF_FALSE); -} - -GF_Err gf_isom_mvc_config_del(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - return gf_isom_svc_mvc_config_del(the_file, trackNumber, DescriptionIndex, GF_TRUE); -} - - -GF_EXPORT -GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber) -{ - GF_TrackBox *trak; - GF_Err e; - GF_MPEGVisualSampleEntryBox *entry; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media) return GF_BAD_PARAM; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, 0); - if (!entry) return GF_OK; - switch (entry->type) { - case GF_ISOM_BOX_TYPE_AVC1: - case GF_ISOM_BOX_TYPE_AVC2: - case GF_ISOM_BOX_TYPE_AVC3: - case GF_ISOM_BOX_TYPE_AVC4: - case GF_ISOM_BOX_TYPE_SVC1: - case GF_ISOM_BOX_TYPE_MVC1: - case GF_ISOM_BOX_TYPE_HVC1: - case GF_ISOM_BOX_TYPE_HEV1: - case GF_ISOM_BOX_TYPE_HVT1: - break; - default: - return GF_OK; - } - - if (!entry->ipod_ext) { - entry->ipod_ext = (GF_UnknownUUIDBox *) gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_UUID); - if (!entry->ipod_ext) return GF_OUT_OF_MEM; - } - memcpy(entry->ipod_ext->uuid, GF_ISOM_IPOD_EXT, sizeof(u8)*16); - entry->ipod_ext->dataSize = 0; - return GF_OK; -} - -static GF_Err gf_isom_svc_mvc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, Bool is_mvc, char *URLname, char *URNname, u32 *outDescriptionIndex) -{ - GF_TrackBox *trak; - GF_Err e; - u32 dataRefIndex; - GF_SampleDescriptionBox *stsd; - GF_MPEGVisualSampleEntryBox *entry; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM; - - //get or create the data ref - e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); - if (e) return e; - if (!dataRefIndex) { - e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); - if (e) return e; - } - if (!the_file->keep_utc) - trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); - - stsd = trak->Media->information->sampleTable->SampleDescription; - //create a new entry - if (is_mvc) { - entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new_parent(&stsd->child_boxes, GF_ISOM_BOX_TYPE_MVC1); - if (!entry) return GF_OUT_OF_MEM; - entry->mvc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_MVCC); - if (!entry->mvc_config) return GF_OUT_OF_MEM; - entry->mvc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->mvc_config->config) return GF_OUT_OF_MEM; - } else { - entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new_parent(&stsd->child_boxes,GF_ISOM_BOX_TYPE_SVC1); - if (!entry) return GF_OUT_OF_MEM; - entry->svc_config = (GF_AVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes,GF_ISOM_BOX_TYPE_SVCC); - if (!entry->svc_config) return GF_OUT_OF_MEM; - entry->svc_config->config = AVC_DuplicateConfig(cfg); - if (!entry->svc_config->config) return GF_OUT_OF_MEM; - } - entry->dataReferenceIndex = dataRefIndex; - *outDescriptionIndex = gf_list_count(stsd->child_boxes); - AVC_RewriteESDescriptor(entry); - return e; -} - -GF_EXPORT -GF_Err gf_isom_svc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex) -{ - return gf_isom_svc_mvc_config_new(the_file, trackNumber, cfg, GF_FALSE, (char *) URLname, (char *) URNname,outDescriptionIndex); -} - -GF_EXPORT -GF_Err gf_isom_mvc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex) -{ - return gf_isom_svc_mvc_config_new(the_file, trackNumber, cfg, GF_TRUE, (char *) URLname, (char *) URNname,outDescriptionIndex); -} - - -GF_EXPORT -GF_Err gf_isom_hevc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_HEVCConfig *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex) -{ - GF_TrackBox *trak; - GF_Err e; - u32 dataRefIndex; - GF_SampleDescriptionBox *stsd; - GF_MPEGVisualSampleEntryBox *entry; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM; - - //get or create the data ref - e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - if (!dataRefIndex) { - e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - } - if (!the_file->keep_utc) - trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); - - stsd = trak->Media->information->sampleTable->SampleDescription; - //create a new entry - entry = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new_parent(&stsd->child_boxes, GF_ISOM_BOX_TYPE_HVC1); - if (!entry) return GF_OUT_OF_MEM; - entry->hevc_config = (GF_HEVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_HVCC); - if (!entry->hevc_config) return GF_OUT_OF_MEM; - entry->hevc_config->config = HEVC_DuplicateConfig(cfg); - if (!entry->hevc_config->config) return GF_OUT_OF_MEM; - entry->dataReferenceIndex = dataRefIndex; - *outDescriptionIndex = gf_list_count(stsd->child_boxes); - HEVC_RewriteESDescriptor(entry); - return e; -} - -GF_EXPORT -GF_Err gf_isom_vp_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_VPConfig *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex, u32 vpx_type) -{ - GF_TrackBox *trak; - GF_Err e; - u32 dataRefIndex; - GF_SampleDescriptionBox *stsd; - GF_MPEGVisualSampleEntryBox *entry; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM; - - //get or create the data ref - e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - if (!dataRefIndex) { - e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - } - if (!the_file->keep_utc) - trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); - - stsd = trak->Media->information->sampleTable->SampleDescription; - //create a new entry - entry = (GF_MPEGVisualSampleEntryBox *)gf_isom_box_new_parent(&stsd->child_boxes, vpx_type); - if (!entry) return GF_OUT_OF_MEM; - - entry->vp_config = (GF_VPConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_VPCC); - if (!entry->vp_config) return GF_OUT_OF_MEM; - entry->vp_config->config = VP_DuplicateConfig(cfg); - if (!entry->vp_config->config) return GF_OUT_OF_MEM; - strncpy(entry->compressor_name, "\012VPC Coding", sizeof(entry->compressor_name)-1); - entry->dataReferenceIndex = dataRefIndex; - *outDescriptionIndex = gf_list_count(stsd->child_boxes); - return e; -} - -GF_EXPORT -GF_Err gf_isom_av1_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AV1Config *cfg, const char *URLname, const char *URNname, u32 *outDescriptionIndex) -{ - GF_TrackBox *trak; - GF_Err e; - u32 dataRefIndex; - GF_MPEGVisualSampleEntryBox *entry; - GF_SampleDescriptionBox *stsd; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !cfg) return GF_BAD_PARAM; - - //get or create the data ref - e = Media_FindDataRef(trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - if (!dataRefIndex) { - e = Media_CreateDataRef(the_file, trak->Media->information->dataInformation->dref, (char *)URLname, (char *)URNname, &dataRefIndex); - if (e) return e; - } - if (!the_file->keep_utc) - trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); - - stsd = trak->Media->information->sampleTable->SampleDescription; - //create a new entry - entry = (GF_MPEGVisualSampleEntryBox *)gf_isom_box_new_parent(&stsd->child_boxes, GF_ISOM_BOX_TYPE_AV01); - if (!entry) return GF_OUT_OF_MEM; - entry->av1_config = (GF_AV1ConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_AV1C); - if (!entry->av1_config) return GF_OUT_OF_MEM; - entry->av1_config->config = AV1_DuplicateConfig(cfg); - if (!entry->av1_config->config) return GF_OUT_OF_MEM; - entry->dataReferenceIndex = dataRefIndex; - *outDescriptionIndex = gf_list_count(stsd->child_boxes); - return e; -} - - -typedef enum -{ - GF_ISOM_HVCC_UPDATE = 0, - GF_ISOM_HVCC_SET_INBAND, - GF_ISOM_HVCC_SET_TILE, - GF_ISOM_HVCC_SET_TILE_BASE_TRACK, - GF_ISOM_HVCC_SET_LHVC, - GF_ISOM_HVCC_SET_LHVC_WITH_BASE, - GF_ISOM_HVCC_SET_LHVC_WITH_BASE_BACKWARD, - GF_ISOM_HVCC_SET_HEVC_TILE_BASE, - GF_ISOM_LHCC_SET_INBAND -} HevcConfigUpdateType; - -static Bool hevc_cleanup_config(GF_HEVCConfig *cfg, HevcConfigUpdateType operand_type, Bool keep_xps) -{ - u32 i; - Bool array_incomplete = (operand_type==GF_ISOM_HVCC_SET_INBAND) ? 1 : 0; - if (!cfg) return 0; - - for (i=0; iparam_array); i++) { - GF_HEVCParamArray *ar = (GF_HEVCParamArray*)gf_list_get(cfg->param_array, i); - - /*we want to force hev1*/ - if (operand_type==GF_ISOM_HVCC_SET_INBAND) { - ar->array_completeness = 0; - if (keep_xps) { - array_incomplete=1; - continue; - } - - while (gf_list_count(ar->nalus)) { - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_list_get(ar->nalus, 0); - gf_list_rem(ar->nalus, 0); - if (sl->data) gf_free(sl->data); - gf_free(sl); - } - gf_list_del(ar->nalus); - gf_free(ar); - ar=NULL; - gf_list_rem(cfg->param_array, i); - i--; - continue; - } - if (ar && !ar->array_completeness) - array_incomplete = 1; - } - return array_incomplete; -} - -static -GF_Err gf_isom_hevc_config_update_ex(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_HEVCConfig *cfg, u32 operand_type, Bool keep_xps) -{ - u32 array_incomplete; - GF_TrackBox *trak; - GF_Err e; - GF_MPEGVisualSampleEntryBox *entry; - GF_SampleDescriptionBox *stsd; - - e = CanAccessMovie(the_file, GF_ISOM_OPEN_WRITE); - if (e) return e; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return GF_BAD_PARAM; - stsd = trak->Media->information->sampleTable->SampleDescription; - entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(stsd->child_boxes, DescriptionIndex-1); - if (!entry) return GF_BAD_PARAM; - switch (entry->type) { - case GF_ISOM_BOX_TYPE_HVC1: - case GF_ISOM_BOX_TYPE_HEV1: - case GF_ISOM_BOX_TYPE_HVC2: - case GF_ISOM_BOX_TYPE_HEV2: - case GF_ISOM_BOX_TYPE_LHV1: - case GF_ISOM_BOX_TYPE_LHE1: - case GF_ISOM_BOX_TYPE_HVT1: - break; - default: - return GF_BAD_PARAM; - } - - - if (operand_type == GF_ISOM_HVCC_SET_TILE_BASE_TRACK) { - if (entry->type==GF_ISOM_BOX_TYPE_HVC1) - entry->type = GF_ISOM_BOX_TYPE_HVC2; - else if (entry->type==GF_ISOM_BOX_TYPE_HEV1) - entry->type = GF_ISOM_BOX_TYPE_HEV2; - } else if (operand_type == GF_ISOM_HVCC_SET_TILE) { - if (!entry->hevc_config) entry->hevc_config = (GF_HEVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_HVCC); - if (!entry->hevc_config) return GF_OUT_OF_MEM; - if (entry->hevc_config->config) gf_odf_hevc_cfg_del(entry->hevc_config->config); - entry->hevc_config->config = NULL; - entry->type = GF_ISOM_BOX_TYPE_HVT1; - } else if (operand_type < GF_ISOM_HVCC_SET_LHVC) { - if ((operand_type != GF_ISOM_HVCC_SET_INBAND) && !entry->hevc_config) { - entry->hevc_config = (GF_HEVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_HVCC); - if (!entry->hevc_config) return GF_OUT_OF_MEM; - } - - if (cfg) { - if (entry->hevc_config->config) gf_odf_hevc_cfg_del(entry->hevc_config->config); - entry->hevc_config->config = HEVC_DuplicateConfig(cfg); - } else { - operand_type=GF_ISOM_HVCC_SET_INBAND; - } - array_incomplete = (operand_type==GF_ISOM_HVCC_SET_INBAND) ? 1 : 0; - if (entry->hevc_config && hevc_cleanup_config(entry->hevc_config->config, operand_type, keep_xps)) { - array_incomplete=1; - } - - if (entry->lhvc_config && hevc_cleanup_config(entry->lhvc_config->config, operand_type, keep_xps)) - array_incomplete=1; - - switch (entry->type) { - case GF_ISOM_BOX_TYPE_HEV1: - case GF_ISOM_BOX_TYPE_HVC1: - entry->type = array_incomplete ? GF_ISOM_BOX_TYPE_HEV1 : GF_ISOM_BOX_TYPE_HVC1; - break; - case GF_ISOM_BOX_TYPE_HEV2: - case GF_ISOM_BOX_TYPE_HVC2: - entry->type = array_incomplete ? GF_ISOM_BOX_TYPE_HEV2 : GF_ISOM_BOX_TYPE_HVC2; - break; - case GF_ISOM_BOX_TYPE_LHE1: - case GF_ISOM_BOX_TYPE_LHV1: - entry->type = array_incomplete ? GF_ISOM_BOX_TYPE_LHE1 : GF_ISOM_BOX_TYPE_LHV1; - break; - } - } else { - - /*SVCC replacement/removal with HEVC base, backward compatible signaling*/ - if ((operand_type==GF_ISOM_HVCC_SET_LHVC_WITH_BASE_BACKWARD) || (operand_type==GF_ISOM_HVCC_SET_LHVC_WITH_BASE) || (operand_type==GF_ISOM_HVCC_SET_HEVC_TILE_BASE) ) { - if (!entry->hevc_config) return GF_BAD_PARAM; - if (!cfg) { - if (entry->lhvc_config) { - gf_isom_box_del_parent(&entry->child_boxes, (GF_Box*)entry->lhvc_config); - entry->lhvc_config = NULL; - } - if (entry->type==GF_ISOM_BOX_TYPE_LHE1) entry->type = (operand_type==GF_ISOM_HVCC_SET_LHVC_WITH_BASE) ? GF_ISOM_BOX_TYPE_HEV2 : GF_ISOM_BOX_TYPE_HEV1; - else if (entry->type==GF_ISOM_BOX_TYPE_HEV1) entry->type = (operand_type==GF_ISOM_HVCC_SET_LHVC_WITH_BASE) ? GF_ISOM_BOX_TYPE_HEV2 : GF_ISOM_BOX_TYPE_HEV1; - else entry->type = (operand_type==GF_ISOM_HVCC_SET_LHVC_WITH_BASE) ? GF_ISOM_BOX_TYPE_HVC2 : GF_ISOM_BOX_TYPE_HVC1; - } else { - if (operand_type != GF_ISOM_HVCC_SET_HEVC_TILE_BASE) { - if (!entry->lhvc_config) { - entry->lhvc_config = (GF_HEVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_LHVC); - if (!entry->lhvc_config) return GF_OUT_OF_MEM; - } - if (entry->lhvc_config->config) gf_odf_hevc_cfg_del(entry->lhvc_config->config); - entry->lhvc_config->config = HEVC_DuplicateConfig(cfg); - if (!entry->lhvc_config->config) return GF_OUT_OF_MEM; - } - - if (operand_type==GF_ISOM_HVCC_SET_LHVC_WITH_BASE_BACKWARD) { - if (entry->type==GF_ISOM_BOX_TYPE_HEV2) entry->type = GF_ISOM_BOX_TYPE_HEV1; - else entry->type = GF_ISOM_BOX_TYPE_HVC1; - } else { - if (entry->type==GF_ISOM_BOX_TYPE_HEV1) entry->type = GF_ISOM_BOX_TYPE_HEV2; - else entry->type = GF_ISOM_BOX_TYPE_HVC2; - } - } - } - /*LHEVC track without base*/ - else if (operand_type==GF_ISOM_HVCC_SET_LHVC) { - if (entry->hevc_config) { - gf_isom_box_del_parent(&entry->child_boxes, (GF_Box*)entry->hevc_config); - entry->hevc_config=NULL; - } - if (!cfg) return GF_BAD_PARAM; - - if (!entry->lhvc_config) { - entry->lhvc_config = (GF_HEVCConfigurationBox*)gf_isom_box_new_parent(&entry->child_boxes, GF_ISOM_BOX_TYPE_LHVC); - if (!entry->lhvc_config) return GF_OUT_OF_MEM; - } - if (entry->lhvc_config->config) gf_odf_hevc_cfg_del(entry->lhvc_config->config); - entry->lhvc_config->config = HEVC_DuplicateConfig(cfg); - if (!entry->lhvc_config->config) return GF_OUT_OF_MEM; - - if ((entry->type==GF_ISOM_BOX_TYPE_HEV1) || (entry->type==GF_ISOM_BOX_TYPE_HEV2)) entry->type = GF_ISOM_BOX_TYPE_LHE1; - else entry->type = GF_ISOM_BOX_TYPE_LHV1; - } - /*LHEVC inband, no config change*/ - else if (operand_type==GF_ISOM_LHCC_SET_INBAND) { - entry->type = GF_ISOM_BOX_TYPE_LHE1; - } - } - - HEVC_RewriteESDescriptor(entry); - return GF_OK; -} - -GF_EXPORT -GF_Err gf_isom_hevc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_HEVCConfig *cfg) -{ - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, GF_ISOM_HVCC_UPDATE, GF_FALSE); -} - -GF_EXPORT -GF_Err gf_isom_hevc_set_inband_config(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, Bool keep_xps) -{ - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, NULL, GF_ISOM_HVCC_SET_INBAND, keep_xps); -} - -GF_EXPORT -GF_Err gf_isom_lhvc_force_inband_config(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, NULL, GF_ISOM_LHCC_SET_INBAND, GF_FALSE); -} - - -GF_EXPORT -GF_Err gf_isom_hevc_set_tile_config(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_HEVCConfig *cfg, Bool is_base_track) -{ - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, is_base_track ? GF_ISOM_HVCC_SET_TILE_BASE_TRACK : GF_ISOM_HVCC_SET_TILE, GF_FALSE); -} - -GF_EXPORT -GF_Err gf_isom_lhvc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_HEVCConfig *cfg, GF_ISOMLHEVCTrackType track_type) -{ - if (cfg) cfg->is_lhvc = GF_TRUE; - switch (track_type) { - case GF_ISOM_LEHVC_ONLY: - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, GF_ISOM_HVCC_SET_LHVC, GF_FALSE); - case GF_ISOM_LEHVC_WITH_BASE: - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, GF_ISOM_HVCC_SET_LHVC_WITH_BASE, GF_FALSE); - case GF_ISOM_LEHVC_WITH_BASE_BACKWARD: - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, GF_ISOM_HVCC_SET_LHVC_WITH_BASE_BACKWARD, GF_FALSE); - case GF_ISOM_HEVC_TILE_BASE: - return gf_isom_hevc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, GF_ISOM_HVCC_SET_HEVC_TILE_BASE, GF_FALSE); - default: - return GF_BAD_PARAM; - } -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_EXPORT -GF_Box *gf_isom_clone_config_box(GF_Box *box) -{ - u8 *data=NULL; - u32 size=0; - GF_Err e; - GF_Box *clone=NULL; - GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - e = gf_isom_box_size(box); - if (!e) - e = gf_isom_box_write(box, bs); - - gf_bs_get_content(bs, &data, &size); - gf_bs_del(bs); - if (!e) { - bs = gf_bs_new(data, size, GF_BITSTREAM_READ); - e = gf_isom_box_parse(&clone, bs); - gf_bs_del(bs); - } - if (data) - gf_free(data); - if (e) { - if (clone) - gf_isom_box_del(clone); - clone = NULL; - } - return clone; -} - -GF_EXPORT -GF_AVCConfig *gf_isom_avc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - if (gf_isom_get_avc_svc_type(the_file, trackNumber, DescriptionIndex)==GF_ISOM_AVCTYPE_NONE) - return NULL; - - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return NULL; - - if (!entry->avc_config) return NULL; - return AVC_DuplicateConfig(entry->avc_config->config); -} - -GF_EXPORT -GF_HEVCConfig *gf_isom_hevc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - if (gf_isom_get_reference_count(the_file, trackNumber, GF_ISOM_REF_TBAS)) { - u32 ref_track; - GF_Err e = gf_isom_get_reference(the_file, trackNumber, GF_ISOM_REF_TBAS, 1, &ref_track); - if (e == GF_OK) { - trackNumber = ref_track; - } - } - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - if (gf_isom_get_hevc_lhvc_type(the_file, trackNumber, DescriptionIndex)==GF_ISOM_HEVCTYPE_NONE) - return NULL; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return NULL; - if (!entry->hevc_config) return NULL; - return HEVC_DuplicateConfig(entry->hevc_config->config); -} - -GF_EXPORT -GF_AVCConfig *gf_isom_svc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - if (gf_isom_get_avc_svc_type(the_file, trackNumber, DescriptionIndex)==GF_ISOM_AVCTYPE_NONE) - return NULL; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return NULL; - if (!entry->svc_config) return NULL; - return AVC_DuplicateConfig(entry->svc_config->config); -} - - -GF_EXPORT -GF_AVCConfig *gf_isom_mvc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - if (gf_isom_get_avc_svc_type(the_file, trackNumber, DescriptionIndex)==GF_ISOM_AVCTYPE_NONE) - return NULL; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return NULL; - if (!entry->mvc_config) return NULL; - return AVC_DuplicateConfig(entry->mvc_config->config); -} - -GF_EXPORT -GF_AV1Config *gf_isom_av1_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - if (gf_isom_get_reference_count(the_file, trackNumber, GF_ISOM_REF_TBAS)) { - u32 ref_track; - GF_Err e = gf_isom_get_reference(the_file, trackNumber, GF_ISOM_REF_TBAS, 1, &ref_track); - if (e == GF_OK) { - trackNumber = ref_track; - } - } - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex - 1); - if (!entry || !entry->av1_config) return NULL; - return AV1_DuplicateConfig(entry->av1_config->config); -} - -GF_EXPORT -GF_VPConfig *gf_isom_vp_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex - 1); - if (!entry || !entry->vp_config) return NULL; - return VP_DuplicateConfig(entry->vp_config->config); -} - -GF_EXPORT -GF_DOVIDecoderConfigurationRecord *gf_isom_dovi_config_get(GF_ISOFile* the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_TrackBox* trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex - 1); - if (!entry || !entry->dovi_config) return NULL; - return DOVI_DuplicateConfig(&entry->dovi_config->DOVIConfig); -} - -GF_EXPORT -GF_ISOMAVCType gf_isom_get_avc_svc_type(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - u32 type; - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return GF_ISOM_AVCTYPE_NONE; - if (!gf_isom_is_video_handler_type(trak->Media->handler->handlerType)) - return GF_ISOM_AVCTYPE_NONE; - - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return GF_ISOM_AVCTYPE_NONE; - - type = entry->type; - - if (type == GF_ISOM_BOX_TYPE_ENCV) { - GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(entry->child_boxes, GF_ISOM_BOX_TYPE_SINF); - if (sinf && sinf->original_format) type = sinf->original_format->data_format; - } - else if (type == GF_ISOM_BOX_TYPE_RESV) { - if (entry->rinf && entry->rinf->original_format) type = entry->rinf->original_format->data_format; - } - - switch (type) { - case GF_ISOM_BOX_TYPE_AVC1: - case GF_ISOM_BOX_TYPE_AVC2: - case GF_ISOM_BOX_TYPE_AVC3: - case GF_ISOM_BOX_TYPE_AVC4: - case GF_ISOM_BOX_TYPE_SVC1: - case GF_ISOM_BOX_TYPE_MVC1: - break; - default: - return GF_ISOM_AVCTYPE_NONE; - } - if (entry->avc_config && !entry->svc_config && !entry->mvc_config) return GF_ISOM_AVCTYPE_AVC_ONLY; - if (entry->avc_config && entry->svc_config) return GF_ISOM_AVCTYPE_AVC_SVC; - if (entry->avc_config && entry->mvc_config) return GF_ISOM_AVCTYPE_AVC_MVC; - if (!entry->avc_config && entry->svc_config) return GF_ISOM_AVCTYPE_SVC_ONLY; - if (!entry->avc_config && entry->mvc_config) return GF_ISOM_AVCTYPE_MVC_ONLY; - return GF_ISOM_AVCTYPE_NONE; -} - -GF_EXPORT -GF_ISOMHEVCType gf_isom_get_hevc_lhvc_type(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - u32 type; - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return GF_ISOM_HEVCTYPE_NONE; - if (!gf_isom_is_video_handler_type(trak->Media->handler->handlerType)) - return GF_ISOM_HEVCTYPE_NONE; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return GF_ISOM_HEVCTYPE_NONE; - type = entry->type; - - if (type == GF_ISOM_BOX_TYPE_ENCV) { - GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(entry->child_boxes, GF_ISOM_BOX_TYPE_SINF); - if (sinf && sinf->original_format) type = sinf->original_format->data_format; - } - else if (type == GF_ISOM_BOX_TYPE_RESV) { - if (entry->rinf && entry->rinf->original_format) type = entry->rinf->original_format->data_format; - } - - if (type == GF_ISOM_BOX_TYPE_DVHE) { - type = GF_ISOM_BOX_TYPE_HEV1; - } - - switch (type) { - case GF_ISOM_BOX_TYPE_HVC1: - case GF_ISOM_BOX_TYPE_HEV1: - case GF_ISOM_BOX_TYPE_HVC2: - case GF_ISOM_BOX_TYPE_HEV2: - case GF_ISOM_BOX_TYPE_LHV1: - case GF_ISOM_BOX_TYPE_LHE1: - case GF_ISOM_BOX_TYPE_HVT1: - break; - default: - return GF_ISOM_HEVCTYPE_NONE; - } - if (entry->hevc_config && !entry->lhvc_config) return GF_ISOM_HEVCTYPE_HEVC_ONLY; - if (entry->hevc_config && entry->lhvc_config) return GF_ISOM_HEVCTYPE_HEVC_LHVC; - if (!entry->hevc_config && entry->lhvc_config) return GF_ISOM_HEVCTYPE_LHVC_ONLY; - return GF_ISOM_HEVCTYPE_NONE; -} - -GF_EXPORT -GF_HEVCConfig *gf_isom_lhvc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) -{ - GF_HEVCConfig *lhvc; - GF_OperatingPointsInformation *oinf=NULL; - GF_TrackBox *trak; - GF_MPEGVisualSampleEntryBox *entry; - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !trak->Media || !DescriptionIndex) return NULL; - if (gf_isom_get_hevc_lhvc_type(the_file, trackNumber, DescriptionIndex)==GF_ISOM_HEVCTYPE_NONE) - return NULL; - entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex-1); - if (!entry) return NULL; - if (!entry->lhvc_config) return NULL; - lhvc = HEVC_DuplicateConfig(entry->lhvc_config->config); - if (!lhvc) return NULL; - - gf_isom_get_oinf_info(the_file, trackNumber, &oinf); - if (oinf) { - LHEVC_ProfileTierLevel *ptl = (LHEVC_ProfileTierLevel *)gf_list_last(oinf->profile_tier_levels); - if (ptl) { - lhvc->profile_space = ptl->general_profile_space; - lhvc->tier_flag = ptl->general_tier_flag; - lhvc->profile_idc = ptl->general_profile_idc; - lhvc->general_profile_compatibility_flags = ptl->general_profile_compatibility_flags; - lhvc->constraint_indicator_flags = ptl->general_constraint_indicator_flags; - } - } - return lhvc; -} - - -void btrt_box_del(GF_Box *s) -{ - GF_BitRateBox *ptr = (GF_BitRateBox *)s; - if (ptr) gf_free(ptr); -} -GF_Err btrt_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_BitRateBox *ptr = (GF_BitRateBox *)s; - ISOM_DECREASE_SIZE(ptr, 12) - ptr->bufferSizeDB = gf_bs_read_u32(bs); - ptr->maxBitrate = gf_bs_read_u32(bs); - ptr->avgBitrate = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *btrt_box_new() -{ - GF_BitRateBox *tmp = (GF_BitRateBox *) gf_malloc(sizeof(GF_BitRateBox)); - if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_BitRateBox)); - tmp->type = GF_ISOM_BOX_TYPE_BTRT; - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err btrt_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_BitRateBox *ptr = (GF_BitRateBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->bufferSizeDB); - gf_bs_write_u32(bs, ptr->maxBitrate); - gf_bs_write_u32(bs, ptr->avgBitrate); - return GF_OK; -} -GF_Err btrt_box_size(GF_Box *s) -{ - GF_BitRateBox *ptr = (GF_BitRateBox *)s; - ptr->size += 12; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void m4ds_box_del(GF_Box *s) -{ - GF_MPEG4ExtensionDescriptorsBox *ptr = (GF_MPEG4ExtensionDescriptorsBox *)s; - gf_odf_desc_list_del(ptr->descriptors); - gf_list_del(ptr->descriptors); - gf_free(ptr); -} -GF_Err m4ds_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - char *enc_od; - GF_MPEG4ExtensionDescriptorsBox *ptr = (GF_MPEG4ExtensionDescriptorsBox *)s; - u32 od_size = (u32) ptr->size; - if (!od_size) return GF_OK; - enc_od = (char *)gf_malloc(sizeof(char) * od_size); - gf_bs_read_data(bs, enc_od, od_size); - e = gf_odf_desc_list_read((char *)enc_od, od_size, ptr->descriptors); - gf_free(enc_od); - return e; -} -GF_Box *m4ds_box_new() -{ - GF_MPEG4ExtensionDescriptorsBox *tmp = (GF_MPEG4ExtensionDescriptorsBox *) gf_malloc(sizeof(GF_MPEG4ExtensionDescriptorsBox)); - if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_MPEG4ExtensionDescriptorsBox)); - tmp->type = GF_ISOM_BOX_TYPE_M4DS; - tmp->descriptors = gf_list_new(); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err m4ds_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u8 *enc_ods; - u32 enc_od_size; - GF_MPEG4ExtensionDescriptorsBox *ptr = (GF_MPEG4ExtensionDescriptorsBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - enc_ods = NULL; - enc_od_size = 0; - e = gf_odf_desc_list_write(ptr->descriptors, &enc_ods, &enc_od_size); - if (e) return e; - if (enc_od_size) { - gf_bs_write_data(bs, enc_ods, enc_od_size); - gf_free(enc_ods); - } - return GF_OK; -} -GF_Err m4ds_box_size(GF_Box *s) -{ - GF_Err e; - u32 descSize = 0; - GF_MPEG4ExtensionDescriptorsBox *ptr = (GF_MPEG4ExtensionDescriptorsBox *)s; - e = gf_odf_desc_list_size(ptr->descriptors, &descSize); - ptr->size += descSize; - return e; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void avcc_box_del(GF_Box *s) -{ - GF_AVCConfigurationBox *ptr = (GF_AVCConfigurationBox *)s; - if (ptr->config) gf_odf_avc_cfg_del(ptr->config); - ptr->config = NULL; - gf_free(ptr); -} - -GF_Err avcc_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i, count; - GF_AVCConfigurationBox *ptr = (GF_AVCConfigurationBox *)s; - - if (ptr->config) gf_odf_avc_cfg_del(ptr->config); - ptr->config = gf_odf_avc_cfg_new(); - - ISOM_DECREASE_SIZE(ptr, 7) //7 includes the 2 counts of sps and pps - - ptr->config->configurationVersion = gf_bs_read_u8(bs); - ptr->config->AVCProfileIndication = gf_bs_read_u8(bs); - ptr->config->profile_compatibility = gf_bs_read_u8(bs); - ptr->config->AVCLevelIndication = gf_bs_read_u8(bs); - if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) { - gf_bs_read_int(bs, 6); - } else { - ptr->config->complete_representation = gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 5); - } - ptr->config->nal_unit_size = 1 + gf_bs_read_int(bs, 2); - gf_bs_read_int(bs, 3); - count = gf_bs_read_int(bs, 5); - - for (i=0; isize = gf_bs_read_u16(bs); - if (!sl->size || (gf_bs_available(bs) < sl->size) || (ptr->size < sl->size) ) { - gf_free(sl); - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("AVCC: Not enough bits to parse. Aborting.\n")); - return GF_ISOM_INVALID_FILE; - } - sl->data = (char *)gf_malloc(sizeof(char) * sl->size); - gf_bs_read_data(bs, sl->data, sl->size); - gf_list_add(ptr->config->sequenceParameterSets, sl); - ptr->size -= sl->size; - } - - count = gf_bs_read_u8(bs); - for (i=0; isize = gf_bs_read_u16(bs); - if (!sl->size || (gf_bs_available(bs) < sl->size) || (ptr->sizesize)) { - gf_free(sl); - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("AVCC: Not enough bits to parse. Aborting.\n")); - return GF_ISOM_INVALID_FILE; - } - sl->data = (char *)gf_malloc(sizeof(char) * sl->size); - gf_bs_read_data(bs, sl->data, sl->size); - gf_list_add(ptr->config->pictureParameterSets, sl); - ptr->size -= sl->size; - } - - if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) { - if (gf_avc_is_rext_profile(ptr->config->AVCProfileIndication)) { - if (!ptr->size) { -#ifndef GPAC_DISABLE_AV_PARSERS - AVCState avc; - s32 idx; - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot*)gf_list_get(ptr->config->sequenceParameterSets, 0); - idx = sl ? gf_media_avc_read_sps(sl->data+1, sl->size-1, &avc, 0, NULL) : -1; - - if (idx>=0) { - ptr->config->chroma_format = avc.sps[idx].chroma_format; - ptr->config->luma_bit_depth = 8 + avc.sps[idx].luma_bit_depth_m8; - ptr->config->chroma_bit_depth = 8 + avc.sps[idx].chroma_bit_depth_m8; - } -#else - /*set default values ...*/ - ptr->config->chroma_format = 1; - ptr->config->luma_bit_depth = 8; - ptr->config->chroma_bit_depth = 8; -#endif - return GF_OK; - } - ISOM_DECREASE_SIZE(ptr, 4) - gf_bs_read_int(bs, 6); - ptr->config->chroma_format = gf_bs_read_int(bs, 2); - gf_bs_read_int(bs, 5); - ptr->config->luma_bit_depth = 8 + gf_bs_read_int(bs, 3); - gf_bs_read_int(bs, 5); - ptr->config->chroma_bit_depth = 8 + gf_bs_read_int(bs, 3); - - count = gf_bs_read_int(bs, 8); - if (count*2 > ptr->size) { - //ffmpeg just ignores this part while allocating bytes (filled with garbage?) - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("AVCC: invalid numOfSequenceParameterSetExt value. Skipping.\n")); - return GF_OK; - } - if (count) { - ptr->config->sequenceParameterSetExtensions = gf_list_new(); - for (i=0; isize = gf_bs_read_u16(bs); - if ((gf_bs_available(bs) < sl->size) || (ptr->sizesize)) { - gf_free(sl); - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("AVCC: Not enough bits to parse. Aborting.\n")); - return GF_ISOM_INVALID_FILE; - } - sl->data = (char *)gf_malloc(sizeof(char) * sl->size); - gf_bs_read_data(bs, sl->data, sl->size); - gf_list_add(ptr->config->sequenceParameterSetExtensions, sl); - ptr->size -= sl->size; - } - } - } - } - return GF_OK; -} - -GF_Box *avcc_box_new() -{ - GF_AVCConfigurationBox *tmp = (GF_AVCConfigurationBox *) gf_malloc(sizeof(GF_AVCConfigurationBox)); - if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_AVCConfigurationBox)); - tmp->type = GF_ISOM_BOX_TYPE_AVCC; - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err avcc_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 i, count; - GF_Err e; - GF_AVCConfigurationBox *ptr = (GF_AVCConfigurationBox *) s; - if (!s) return GF_BAD_PARAM; - if (!ptr->config) return GF_OK; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u8(bs, ptr->config->configurationVersion); - gf_bs_write_u8(bs, ptr->config->AVCProfileIndication); - gf_bs_write_u8(bs, ptr->config->profile_compatibility); - gf_bs_write_u8(bs, ptr->config->AVCLevelIndication); - if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) { - gf_bs_write_int(bs, 0x3F, 6); - } else { - gf_bs_write_int(bs, ptr->config->complete_representation, 1); - gf_bs_write_int(bs, 0x1F, 5); - } - gf_bs_write_int(bs, ptr->config->nal_unit_size - 1, 2); - gf_bs_write_int(bs, 0x7, 3); - count = gf_list_count(ptr->config->sequenceParameterSets); - gf_bs_write_int(bs, count, 5); - for (i=0; iconfig->sequenceParameterSets, i); - gf_bs_write_u16(bs, sl->size); - gf_bs_write_data(bs, sl->data, sl->size); - } - - count = gf_list_count(ptr->config->pictureParameterSets); - gf_bs_write_u8(bs, count); - for (i=0; iconfig->pictureParameterSets, i); - gf_bs_write_u16(bs, sl->size); - gf_bs_write_data(bs, sl->data, sl->size); - } - - - if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) { - if (gf_avc_is_rext_profile(ptr->config->AVCProfileIndication)) { - gf_bs_write_int(bs, 0xFF, 6); - gf_bs_write_int(bs, ptr->config->chroma_format, 2); - gf_bs_write_int(bs, 0xFF, 5); - gf_bs_write_int(bs, ptr->config->luma_bit_depth - 8, 3); - gf_bs_write_int(bs, 0xFF, 5); - gf_bs_write_int(bs, ptr->config->chroma_bit_depth - 8, 3); - - count = ptr->config->sequenceParameterSetExtensions ? gf_list_count(ptr->config->sequenceParameterSetExtensions) : 0; - gf_bs_write_u8(bs, count); - for (i=0; iconfig->sequenceParameterSetExtensions, i); - gf_bs_write_u16(bs, sl->size); - gf_bs_write_data(bs, sl->data, sl->size); - } - } - } - return GF_OK; -} -GF_Err avcc_box_size(GF_Box *s) -{ - u32 i, count; - GF_AVCConfigurationBox *ptr = (GF_AVCConfigurationBox *)s; - - if (!ptr->config) { - ptr->size = 0; - return GF_OK; - } - ptr->size += 7; - count = gf_list_count(ptr->config->sequenceParameterSets); - for (i=0; isize += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->sequenceParameterSets, i))->size; - - count = gf_list_count(ptr->config->pictureParameterSets); - for (i=0; isize += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->pictureParameterSets, i))->size; - - if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) { - if (gf_avc_is_rext_profile(ptr->config->AVCProfileIndication)) { - ptr->size += 4; - count = ptr->config->sequenceParameterSetExtensions ?gf_list_count(ptr->config->sequenceParameterSetExtensions) : 0; - for (i=0; isize += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->sequenceParameterSetExtensions, i))->size; - } - } - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void hvcc_box_del(GF_Box *s) -{ - GF_HEVCConfigurationBox *ptr = (GF_HEVCConfigurationBox*)s; - if (ptr->config) gf_odf_hevc_cfg_del(ptr->config); - gf_free(ptr); -} - -GF_Err hvcc_box_read(GF_Box *s, GF_BitStream *bs) -{ - u64 consummed; - GF_HEVCConfigurationBox *ptr = (GF_HEVCConfigurationBox *)s; - - if (ptr->config) gf_odf_hevc_cfg_del(ptr->config); - - consummed = gf_bs_get_position(bs); - ptr->config = gf_odf_hevc_cfg_read_bs(bs, (s->type == GF_ISOM_BOX_TYPE_HVCC) ? GF_FALSE : GF_TRUE); - consummed = gf_bs_get_position(bs) - consummed ; - ISOM_DECREASE_SIZE(ptr, (u32)consummed) - - return ptr->config ? GF_OK : GF_ISOM_INVALID_FILE; -} - -GF_Box *hvcc_box_new() -{ - GF_HEVCConfigurationBox *tmp = (GF_HEVCConfigurationBox *) gf_malloc(sizeof(GF_HEVCConfigurationBox)); - if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_HEVCConfigurationBox)); - tmp->type = GF_ISOM_BOX_TYPE_HVCC; - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err hvcc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_HEVCConfigurationBox *ptr = (GF_HEVCConfigurationBox *) s; - if (!s) return GF_BAD_PARAM; - if (!ptr->config) return GF_OK; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - return gf_odf_hevc_cfg_write_bs(ptr->config, bs); -} - -GF_Err hvcc_box_size(GF_Box *s) -{ - u32 i, count, j, subcount; - GF_HEVCConfigurationBox *ptr = (GF_HEVCConfigurationBox *)s; - - if (!ptr->config) { - ptr->size = 0; - return GF_OK; - } - - if (!ptr->config->is_lhvc) - ptr->size += 23; - else - ptr->size += 6; - - count = gf_list_count(ptr->config->param_array); - for (i=0; iconfig->param_array, i); - ptr->size += 3; - subcount = gf_list_count(ar->nalus); - for (j=0; jsize += 2 + ((GF_AVCConfigSlot *)gf_list_get(ar->nalus, j))->size; - } - } - return GF_OK; -} - -GF_Box *av1c_box_new() { - GF_AV1ConfigurationBox *tmp = (GF_AV1ConfigurationBox *)gf_malloc(sizeof(GF_AV1ConfigurationBox)); - if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_AV1ConfigurationBox)); - tmp->type = GF_ISOM_BOX_TYPE_AV1C; - return (GF_Box *)tmp; -} - -void av1c_box_del(GF_Box *s) { - GF_AV1ConfigurationBox *ptr = (GF_AV1ConfigurationBox*)s; - if (ptr->config) gf_odf_av1_cfg_del(ptr->config); - gf_free(ptr); -} - -GF_Err av1c_box_read(GF_Box *s, GF_BitStream *bs) -{ - u64 pos, read; - GF_AV1ConfigurationBox *ptr = (GF_AV1ConfigurationBox*)s; - - if (ptr->config) gf_odf_av1_cfg_del(ptr->config); - - pos = gf_bs_get_position(bs); - - ptr->config = gf_odf_av1_cfg_read_bs_size(bs, (u32) ptr->size); - - read = gf_bs_get_position(bs) - pos; - - if (read < ptr->size) - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[ISOBMFF] AV1ConfigurationBox: read only "LLU" bytes (expected "LLU").\n", read, ptr->size)); - if (read > ptr->size) - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISOBMFF] AV1ConfigurationBox overflow read "LLU" bytes, of box size "LLU".\n", read, ptr->size)); - - return GF_OK; -} - -GF_Err av1c_box_write(GF_Box *s, GF_BitStream *bs) { - GF_Err e; - GF_AV1ConfigurationBox *ptr = (GF_AV1ConfigurationBox*)s; - if (!s) return GF_BAD_PARAM; - if (!ptr->config) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - return gf_odf_av1_cfg_write_bs(ptr->config, bs); -} - -GF_Err av1c_box_size(GF_Box *s) { - u32 i; - GF_AV1ConfigurationBox *ptr = (GF_AV1ConfigurationBox *)s; - - if (!ptr->config) { - ptr->size = 0; - return GF_BAD_PARAM; - } - - ptr->size += 4; - - for (i = 0; i < gf_list_count(ptr->config->obu_array); ++i) { - GF_AV1_OBUArrayEntry *a = gf_list_get(ptr->config->obu_array, i); - ptr->size += a->obu_length; - } - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -void vpcc_box_del(GF_Box *s) -{ - GF_VPConfigurationBox *ptr = (GF_VPConfigurationBox*)s; - if (ptr->config) gf_odf_vp_cfg_del(ptr->config); - ptr->config = NULL; - gf_free(ptr); -} - -GF_Err vpcc_box_read(GF_Box *s, GF_BitStream *bs) -{ - u64 pos; - GF_VPConfigurationBox *ptr = (GF_VPConfigurationBox *)s; - - if (ptr->config) gf_odf_vp_cfg_del(ptr->config); - ptr->config = NULL; - - pos = gf_bs_get_position(bs); - ptr->config = gf_odf_vp_cfg_read_bs(bs, ptr->version == 0); - pos = gf_bs_get_position(bs) - pos ; - - if (pos < ptr->size) - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[ISOBMFF] VPConfigurationBox: read only "LLU" bytes (expected "LLU").\n", pos, ptr->size)); - if (pos > ptr->size) - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISOBMFF] VPConfigurationBox overflow read "LLU" bytes, of box size "LLU".\n", pos, ptr->size)); - - return ptr->config ? GF_OK : GF_ISOM_INVALID_FILE; -} - -GF_Box *vpcc_box_new() -{ - GF_VPConfigurationBox *tmp = (GF_VPConfigurationBox *) gf_malloc(sizeof(GF_VPConfigurationBox)); - if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_VPConfigurationBox)); - tmp->type = GF_ISOM_BOX_TYPE_VPCC; - tmp->version = 1; - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err vpcc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_VPConfigurationBox *ptr = (GF_VPConfigurationBox *) s; - if (!s) return GF_BAD_PARAM; - if (!ptr->config) return GF_OK; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - return gf_odf_vp_cfg_write_bs(ptr->config, bs, ptr->version == 0); -} -#endif - -GF_Err vpcc_box_size(GF_Box *s) -{ - GF_VPConfigurationBox *ptr = (GF_VPConfigurationBox *)s; - - if (!ptr->config) { - ptr->size = 0; - return GF_OK; - } - - if (ptr->version == 0) { - ptr->size += 6; - } else { - if (ptr->config->codec_initdata_size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISOBMFF] VPConfigurationBox: codec_initdata_size MUST be 0, was %d\n", ptr->config->codec_initdata_size)); - return GF_ISOM_INVALID_FILE; - } - - ptr->size += 8; - } - - return GF_OK; -} - - -GF_Box *SmDm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SMPTE2086MasteringDisplayMetadataBox, GF_ISOM_BOX_TYPE_SMDM); - return (GF_Box *)tmp; -} - -void SmDm_box_del(GF_Box *a) -{ - GF_SMPTE2086MasteringDisplayMetadataBox *p = (GF_SMPTE2086MasteringDisplayMetadataBox *)a; - gf_free(p); -} - -GF_Err SmDm_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SMPTE2086MasteringDisplayMetadataBox *p = (GF_SMPTE2086MasteringDisplayMetadataBox *)s; - ISOM_DECREASE_SIZE(p, 24) - p->primaryRChromaticity_x = gf_bs_read_u16(bs); - p->primaryRChromaticity_y = gf_bs_read_u16(bs); - p->primaryGChromaticity_x = gf_bs_read_u16(bs); - p->primaryGChromaticity_y = gf_bs_read_u16(bs); - p->primaryBChromaticity_x = gf_bs_read_u16(bs); - p->primaryBChromaticity_y = gf_bs_read_u16(bs); - p->whitePointChromaticity_x = gf_bs_read_u16(bs); - p->whitePointChromaticity_y = gf_bs_read_u16(bs); - p->luminanceMax = gf_bs_read_u32(bs); - p->luminanceMin = gf_bs_read_u32(bs); - - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err SmDm_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SMPTE2086MasteringDisplayMetadataBox *p = (GF_SMPTE2086MasteringDisplayMetadataBox*)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, p->primaryRChromaticity_x); - gf_bs_write_u16(bs, p->primaryRChromaticity_y); - gf_bs_write_u16(bs, p->primaryGChromaticity_x); - gf_bs_write_u16(bs, p->primaryGChromaticity_y); - gf_bs_write_u16(bs, p->primaryBChromaticity_x); - gf_bs_write_u16(bs, p->primaryBChromaticity_y); - gf_bs_write_u16(bs, p->whitePointChromaticity_x); - gf_bs_write_u16(bs, p->whitePointChromaticity_y); - gf_bs_write_u32(bs, p->luminanceMax); - gf_bs_write_u32(bs, p->luminanceMin); - - return GF_OK; -} - -GF_Err SmDm_box_size(GF_Box *s) -{ - GF_SMPTE2086MasteringDisplayMetadataBox *p = (GF_SMPTE2086MasteringDisplayMetadataBox*)s; - p->size += 24; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *CoLL_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_VPContentLightLevelBox, GF_ISOM_BOX_TYPE_COLL); - return (GF_Box *)tmp; -} - -void CoLL_box_del(GF_Box *a) -{ - GF_VPContentLightLevelBox *p = (GF_VPContentLightLevelBox *)a; - gf_free(p); -} - -GF_Err CoLL_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_VPContentLightLevelBox *p = (GF_VPContentLightLevelBox *)s; - ISOM_DECREASE_SIZE(p, 4) - p->maxCLL = gf_bs_read_u16(bs); - p->maxFALL = gf_bs_read_u16(bs); - - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err CoLL_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_VPContentLightLevelBox *p = (GF_VPContentLightLevelBox*)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, p->maxCLL); - gf_bs_write_u16(bs, p->maxFALL); - - return GF_OK; -} - -GF_Err CoLL_box_size(GF_Box *s) -{ - GF_VPContentLightLevelBox *p = (GF_VPContentLightLevelBox*)s; - p->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_OperatingPointsInformation *gf_isom_oinf_new_entry() -{ - GF_OperatingPointsInformation* ptr; - GF_SAFEALLOC(ptr, GF_OperatingPointsInformation); - if (ptr) { - ptr->profile_tier_levels = gf_list_new(); - ptr->operating_points = gf_list_new(); - ptr->dependency_layers = gf_list_new(); - } - return ptr; - -} - -void gf_isom_oinf_del_entry(void *entry) -{ - GF_OperatingPointsInformation* ptr = (GF_OperatingPointsInformation *)entry; - if (!ptr) return; - if (ptr->profile_tier_levels) { - while (gf_list_count(ptr->profile_tier_levels)) { - LHEVC_ProfileTierLevel *ptl = (LHEVC_ProfileTierLevel *)gf_list_get(ptr->profile_tier_levels, 0); - gf_free(ptl); - gf_list_rem(ptr->profile_tier_levels, 0); - } - gf_list_del(ptr->profile_tier_levels); - } - if (ptr->operating_points) { - while (gf_list_count(ptr->operating_points)) { - LHEVC_OperatingPoint *op = (LHEVC_OperatingPoint *)gf_list_get(ptr->operating_points, 0); - gf_free(op); - gf_list_rem(ptr->operating_points, 0); - } - gf_list_del(ptr->operating_points); - } - if (ptr->dependency_layers) { - while (gf_list_count(ptr->dependency_layers)) { - LHEVC_DependentLayer *dep = (LHEVC_DependentLayer *)gf_list_get(ptr->dependency_layers, 0); - gf_free(dep); - gf_list_rem(ptr->dependency_layers, 0); - } - gf_list_del(ptr->dependency_layers); - } - gf_free(ptr); - return; -} - -GF_Err gf_isom_oinf_read_entry(void *entry, GF_BitStream *bs) -{ - GF_OperatingPointsInformation* ptr = (GF_OperatingPointsInformation *)entry; - u32 i, j, count; - - if (!ptr) return GF_BAD_PARAM; - ptr->scalability_mask = gf_bs_read_u16(bs); - gf_bs_read_int(bs, 2);//reserved - count = gf_bs_read_int(bs, 6); - for (i = 0; i < count; i++) { - LHEVC_ProfileTierLevel *ptl; - GF_SAFEALLOC(ptl, LHEVC_ProfileTierLevel); - if (!ptl) return GF_OUT_OF_MEM; - ptl->general_profile_space = gf_bs_read_int(bs, 2); - ptl->general_tier_flag= gf_bs_read_int(bs, 1); - ptl->general_profile_idc = gf_bs_read_int(bs, 5); - ptl->general_profile_compatibility_flags = gf_bs_read_u32(bs); - ptl->general_constraint_indicator_flags = gf_bs_read_long_int(bs, 48); - ptl->general_level_idc = gf_bs_read_u8(bs); - gf_list_add(ptr->profile_tier_levels, ptl); - } - count = gf_bs_read_u16(bs); - for (i = 0; i < count; i++) { - LHEVC_OperatingPoint *op; - GF_SAFEALLOC(op, LHEVC_OperatingPoint); - if (!op) return GF_OUT_OF_MEM; - op->output_layer_set_idx = gf_bs_read_u16(bs); - op->max_temporal_id = gf_bs_read_u8(bs); - op->layer_count = gf_bs_read_u8(bs); - if (op->layer_count > GF_ARRAY_LENGTH(op->layers_info)) - return GF_NON_COMPLIANT_BITSTREAM; - for (j = 0; j < op->layer_count; j++) { - op->layers_info[j].ptl_idx = gf_bs_read_u8(bs); - op->layers_info[j].layer_id = gf_bs_read_int(bs, 6); - op->layers_info[j].is_outputlayer = gf_bs_read_int(bs, 1) ? GF_TRUE : GF_FALSE; - op->layers_info[j].is_alternate_outputlayer = gf_bs_read_int(bs, 1) ? GF_TRUE : GF_FALSE; - } - op->minPicWidth = gf_bs_read_u16(bs); - op->minPicHeight = gf_bs_read_u16(bs); - op->maxPicWidth = gf_bs_read_u16(bs); - op->maxPicHeight = gf_bs_read_u16(bs); - op->maxChromaFormat = gf_bs_read_int(bs, 2); - op->maxBitDepth = gf_bs_read_int(bs, 3) + 8; - gf_bs_read_int(bs, 1);//reserved - op->frame_rate_info_flag = gf_bs_read_int(bs, 1) ? GF_TRUE : GF_FALSE; - op->bit_rate_info_flag = gf_bs_read_int(bs, 1) ? GF_TRUE : GF_FALSE; - if (op->frame_rate_info_flag) { - op->avgFrameRate = gf_bs_read_u16(bs); - gf_bs_read_int(bs, 6); //reserved - op->constantFrameRate = gf_bs_read_int(bs, 2); - } - if (op->bit_rate_info_flag) { - op->maxBitRate = gf_bs_read_u32(bs); - op->avgBitRate = gf_bs_read_u32(bs); - } - gf_list_add(ptr->operating_points, op); - } - count = gf_bs_read_u8(bs); - for (i = 0; i < count; i++) { - LHEVC_DependentLayer *dep; - GF_SAFEALLOC(dep, LHEVC_DependentLayer); - if (!dep) return GF_OUT_OF_MEM; - dep->dependent_layerID = gf_bs_read_u8(bs); - dep->num_layers_dependent_on = gf_bs_read_u8(bs); - if (dep->num_layers_dependent_on > GF_ARRAY_LENGTH(dep->dependent_on_layerID)) { - gf_free(dep); - return GF_NON_COMPLIANT_BITSTREAM; - } - for (j = 0; j < dep->num_layers_dependent_on; j++) - dep->dependent_on_layerID[j] = gf_bs_read_u8(bs); - for (j = 0; j < 16; j++) { - if (ptr->scalability_mask & (1 << j)) - dep->dimension_identifier[j] = gf_bs_read_u8(bs); - } - gf_list_add(ptr->dependency_layers, dep); - } - - return GF_OK; -} - -GF_Err gf_isom_oinf_write_entry(void *entry, GF_BitStream *bs) -{ - GF_OperatingPointsInformation* ptr = (GF_OperatingPointsInformation *)entry; - u32 i, j, count; - if (!ptr) return GF_OK; - - gf_bs_write_u16(bs, ptr->scalability_mask); - gf_bs_write_int(bs, 0xFF, 2);//reserved - count=gf_list_count(ptr->profile_tier_levels); - gf_bs_write_int(bs, count, 6); - for (i = 0; i < count; i++) { - LHEVC_ProfileTierLevel *ptl = (LHEVC_ProfileTierLevel *)gf_list_get(ptr->profile_tier_levels, i); - gf_bs_write_int(bs, ptl->general_profile_space, 2); - gf_bs_write_int(bs, ptl->general_tier_flag, 1); - gf_bs_write_int(bs, ptl->general_profile_idc, 5); - gf_bs_write_u32(bs, ptl->general_profile_compatibility_flags); - gf_bs_write_long_int(bs, ptl->general_constraint_indicator_flags, 48); - gf_bs_write_u8(bs, ptl->general_level_idc); - } - count=gf_list_count(ptr->operating_points); - gf_bs_write_u16(bs, count); - for (i = 0; i < count; i++) { - LHEVC_OperatingPoint *op = (LHEVC_OperatingPoint *)gf_list_get(ptr->operating_points, i); - gf_bs_write_u16(bs, op->output_layer_set_idx); - gf_bs_write_u8(bs, op->max_temporal_id); - gf_bs_write_u8(bs, op->layer_count); - for (j = 0; j < op->layer_count; j++) { - gf_bs_write_u8(bs, op->layers_info[j].ptl_idx); - gf_bs_write_int(bs, op->layers_info[j].layer_id, 6); - op->layers_info[j].is_outputlayer ? gf_bs_write_int(bs, 0x1, 1) : gf_bs_write_int(bs, 0x0, 1); - op->layers_info[j].is_alternate_outputlayer ? gf_bs_write_int(bs, 0x1, 1) : gf_bs_write_int(bs, 0x0, 1); - } - gf_bs_write_u16(bs, op->minPicWidth); - gf_bs_write_u16(bs, op->minPicHeight); - gf_bs_write_u16(bs, op->maxPicWidth); - gf_bs_write_u16(bs, op->maxPicHeight); - gf_bs_write_int(bs, op->maxChromaFormat, 2); - gf_bs_write_int(bs, op->maxBitDepth - 8, 3); - gf_bs_write_int(bs, 0x1, 1);//resereved - op->frame_rate_info_flag ? gf_bs_write_int(bs, 0x1, 1) : gf_bs_write_int(bs, 0x0, 1); - op->bit_rate_info_flag ? gf_bs_write_int(bs, 0x1, 1) : gf_bs_write_int(bs, 0x0, 1); - if (op->frame_rate_info_flag) { - gf_bs_write_u16(bs, op->avgFrameRate); - gf_bs_write_int(bs, 0xFF, 6); //reserved - gf_bs_write_int(bs, op->constantFrameRate, 2); - } - if (op->bit_rate_info_flag) { - gf_bs_write_u32(bs, op->maxBitRate); - gf_bs_write_u32(bs, op->avgBitRate); - } - } - count=gf_list_count(ptr->dependency_layers); - gf_bs_write_u8(bs, count); - for (i = 0; i < count; i++) { - LHEVC_DependentLayer *dep = (LHEVC_DependentLayer *)gf_list_get(ptr->dependency_layers, i); - gf_bs_write_u8(bs, dep->dependent_layerID); - gf_bs_write_u8(bs, dep->num_layers_dependent_on); - for (j = 0; j < dep->num_layers_dependent_on; j++) - gf_bs_write_u8(bs, dep->dependent_on_layerID[j]); - for (j = 0; j < 16; j++) { - if (ptr->scalability_mask & (1 << j)) - gf_bs_write_u8(bs, dep->dimension_identifier[j]); - } - } - - return GF_OK; -} - -u32 gf_isom_oinf_size_entry(void *entry) -{ - GF_OperatingPointsInformation* ptr = (GF_OperatingPointsInformation *)entry; - u32 size = 0, i ,j, count; - if (!ptr) return 0; - - size += 3; //scalability_mask + reserved + num_profile_tier_level - count=gf_list_count(ptr->profile_tier_levels); - size += count * 12; //general_profile_space + general_tier_flag + general_profile_idc + general_profile_compatibility_flags + general_constraint_indicator_flags + general_level_idc - size += 2;//num_operating_points - count=gf_list_count(ptr->operating_points); - for (i = 0; i < count; i++) { - LHEVC_OperatingPoint *op = (LHEVC_OperatingPoint *)gf_list_get(ptr->operating_points, i); - size += 2/*output_layer_set_idx*/ + 1/*max_temporal_id*/ + 1/*layer_count*/; - size += op->layer_count * 2; - size += 9; - if (op->frame_rate_info_flag) { - size += 3; - } - if (op->bit_rate_info_flag) { - size += 8; - } - } - size += 1;//max_layer_count - count=gf_list_count(ptr->dependency_layers); - for (i = 0; i < count; i++) { - LHEVC_DependentLayer *dep = (LHEVC_DependentLayer *)gf_list_get(ptr->dependency_layers, i); - size += 1/*dependent_layerID*/ + 1/*num_layers_dependent_on*/; - size += dep->num_layers_dependent_on * 1;//dependent_on_layerID - for (j = 0; j < 16; j++) { - if (ptr->scalability_mask & (1 << j)) - size += 1;//dimension_identifier - } - } - return size; -} - - -GF_LHVCLayerInformation *gf_isom_linf_new_entry() -{ - GF_LHVCLayerInformation* ptr; - GF_SAFEALLOC(ptr, GF_LHVCLayerInformation); - if (ptr) ptr->num_layers_in_track = gf_list_new(); - - return ptr; - -} - -void gf_isom_linf_del_entry(void *entry) -{ - GF_LHVCLayerInformation* ptr = (GF_LHVCLayerInformation *)entry; - if (!ptr) return; - while (gf_list_count(ptr->num_layers_in_track)) { - LHVCLayerInfoItem *li = (LHVCLayerInfoItem *)gf_list_get(ptr->num_layers_in_track, 0); - gf_free(li); - gf_list_rem(ptr->num_layers_in_track, 0); - } - gf_list_del(ptr->num_layers_in_track); - gf_free(ptr); - return; -} - -GF_Err gf_isom_linf_read_entry(void *entry, GF_BitStream *bs) -{ - GF_LHVCLayerInformation* ptr = (GF_LHVCLayerInformation *)entry; - u32 i, count; - - if (!ptr) return GF_BAD_PARAM; - gf_bs_read_int(bs, 2); - count = gf_bs_read_int(bs, 6); - for (i = 0; i < count; i++) { - LHVCLayerInfoItem *li; - GF_SAFEALLOC(li, LHVCLayerInfoItem); - if (!li) return GF_OUT_OF_MEM; - gf_bs_read_int(bs, 4); - li->layer_id = gf_bs_read_int(bs, 6); - li->min_TemporalId = gf_bs_read_int(bs, 3); - li->max_TemporalId = gf_bs_read_int(bs, 3); - gf_bs_read_int(bs, 1); - li->sub_layer_presence_flags = gf_bs_read_int(bs, 7); - gf_list_add(ptr->num_layers_in_track, li); - } - return GF_OK; -} - -GF_Err gf_isom_linf_write_entry(void *entry, GF_BitStream *bs) -{ - GF_LHVCLayerInformation* ptr = (GF_LHVCLayerInformation *)entry; - u32 i, count; - if (!ptr) return GF_OK; - - gf_bs_write_int(bs, 0, 2); - count=gf_list_count(ptr->num_layers_in_track); - gf_bs_write_int(bs, count, 6); - for (i = 0; i < count; i++) { - LHVCLayerInfoItem *li = (LHVCLayerInfoItem *)gf_list_get(ptr->num_layers_in_track, i); - gf_bs_write_int(bs, 0, 4); - gf_bs_write_int(bs, li->layer_id, 6); - gf_bs_write_int(bs, li->min_TemporalId, 3); - gf_bs_write_int(bs, li->max_TemporalId, 3); - gf_bs_write_int(bs, 0, 1); - gf_bs_write_int(bs, li->sub_layer_presence_flags, 7); - } - return GF_OK; -} - -u32 gf_isom_linf_size_entry(void *entry) -{ - GF_LHVCLayerInformation* ptr = (GF_LHVCLayerInformation *)entry; - u32 size = 0, count; - if (!ptr) return 0; - - size += 1; - count=gf_list_count(ptr->num_layers_in_track); - size += count * 3; - return size; -} - - -#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/thirdparty/gpacmp4/avilib.c b/src/thirdparty/gpacmp4/avilib.c deleted file mode 100644 index 593d12af0..000000000 --- a/src/thirdparty/gpacmp4/avilib.c +++ /dev/null @@ -1,3143 +0,0 @@ -/* - * avilib.c - * - * Copyright (C) Thomas ostreich - June 2001 - * multiple audio track support Copyright (C) 2002 Thomas ostreich - * - * Original code: - * Copyright (C) 1999 Rainer Johanni - * - * This file is part of transcode, a linux video stream processing tool - * - * transcode is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * transcode is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License aint with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include - -#ifndef GPAC_DISABLE_AVILIB - -#include - - -#define INFO_LIST - -// add a new riff chunk after XX MB -#define NEW_RIFF_THRES (1900*1024*1024) - -// Maximum number of indices per stream -#define NR_IXNN_CHUNKS 96 - - -#define DEBUG_ODML -#undef DEBUG_ODML - -/* The following variable indicates the kind of error */ - -int AVI_errno = 0; - -#define MAX_INFO_STRLEN 64 -static char id_str[MAX_INFO_STRLEN]; - -#define FRAME_RATE_SCALE 1000000 - -/******************************************************************* - * * - * Utilities for writing an AVI File * - * * - *******************************************************************/ - -static u32 avi_read(FILE *fd, char *buf, u32 len) -{ - u32 r = 0; - - while (r < len) { - s32 n = (s32) gf_fread(buf + r, len - r, fd); - if (n == 0) break; - if (n < 0) return r; - r += n; - } - - return r; -} - -static u32 avi_write (FILE *fd, char *buf, u32 len) -{ - u32 r = 0; - - while (r < len) { - s32 n = (u32) gf_fwrite (buf + r, len - r, fd); - if (n < 0) - return n; - - r += n; - } - return r; -} - -/* HEADERBYTES: The number of bytes to reserve for the header */ - -#define HEADERBYTES 2048 - -/* AVI_MAX_LEN: The maximum length of an AVI file, we stay a bit below - the 2GB limit (Remember: 2*10^9 is smaller than 2 GB) */ - -#define AVI_MAX_LEN (UINT_MAX-(1<<20)*16-HEADERBYTES) - -#define PAD_EVEN(x) ( ((x)+1) & ~1 ) - - -/* Copy n into dst as a 4 or 2 byte, little endian number. - Should also work on big endian machines */ - -static void long2str(unsigned char *dst, s32 n) -{ - dst[0] = (n )&0xff; - dst[1] = (n>> 8)&0xff; - dst[2] = (n>>16)&0xff; - dst[3] = (n>>24)&0xff; -} - -#ifdef WORDS_BIGENDIAN -static void short2str(unsigned char *dst, s32 n) -{ - dst[0] = (n )&0xff; - dst[1] = (n>> 8)&0xff; -} -#endif - -/* Convert a string of 4 or 2 bytes to a number, - also working on big endian machines */ - -static u64 str2ullong(unsigned char *str) -{ - u64 r = (str[0] | (str[1]<<8) | (str[2]<<16) | (str[3]<<24)); - u64 s = (str[4] | (str[5]<<8) | (str[6]<<16) | (str[7]<<24)); -#ifdef __GNUC__ - return ((s<<32)&0xffffffff00000000ULL)|(r&0xffffffff); -#else - return ((s<<32)&0xffffffff00000000)|(r&0xffffffff); -#endif -} - -static u32 str2ulong(unsigned char *str) -{ - return ( str[0] | (str[1]<<8) | (str[2]<<16) | (str[3]<<24) ); -} -static u32 str2ushort(unsigned char *str) -{ - return ( str[0] | (str[1]<<8) ); -} - -// bit 31 denotes a keyframe -static u32 str2ulong_len (unsigned char *str) -{ - return str2ulong(str) & 0x7fffffff; -} - - -// if bit 31 is 0, its a keyframe -static u32 str2ulong_key (unsigned char *str) -{ - u32 c = str2ulong(str); - c &= 0x80000000; - if (c == 0) return 0x10; - else return 0; -} - -/* Calculate audio sample size from number of bits and number of channels. - This may have to be adjusted for eg. 12 bits and stereo */ - -static int avi_sampsize(avi_t *AVI, int j) -{ - int s; - s = ((AVI->track[j].a_bits+7)/8)*AVI->track[j].a_chans; - // if(s==0) s=1; /* avoid possible zero divisions */ - if(s<4) s=4; /* avoid possible zero divisions */ - return s; -} - -/* Add a chunk (=tag and data) to the AVI file, - returns -1 on write error, 0 on success */ - -static int avi_add_chunk(avi_t *AVI, unsigned char *tag, unsigned char *data, u32 length) -{ - unsigned char c[8]; - char p=0; - - /* Copy tag and length int c, so that we need only 1 write system call - for these two values */ - - memcpy(c,tag,4); - long2str(c+4,length); - - /* Output tag, length and data, restore previous position - if the write fails */ - - if( avi_write(AVI->fdes,(char *)c,8) != 8 || - avi_write(AVI->fdes,(char *)data,length) != length || - avi_write(AVI->fdes,&p,length&1) != (length&1)) // if len is uneven, write a pad byte - { - gf_fseek(AVI->fdes,AVI->pos,SEEK_SET); - AVI_errno = AVI_ERR_WRITE; - return -1; - } - - /* Update file position */ - - AVI->pos += 8 + PAD_EVEN(length); - - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] pos=%lu %s\n", AVI->pos, tag)); - - return 0; -} - -#define OUTD(n) long2str((unsigned char*) (ix00+bl),(s32)n); bl+=4 -#define OUTW(n) ix00[bl] = (n)&0xff; ix00[bl+1] = (n>>8)&0xff; bl+=2 -#define OUTC(n) ix00[bl] = (n)&0xff; bl+=1 -#define OUTS(s) memcpy(ix00+bl,s,4); bl+=4 - -// this does the physical writeout of the ix## structure -static int avi_ixnn_entry(avi_t *AVI, avistdindex_chunk *ch, avisuperindex_entry *en) -{ - int bl; - u32 k; - unsigned int max = ch->nEntriesInUse * sizeof (u32) * ch->wLongsPerEntry + 24; // header - char *ix00 = (char *)gf_malloc (max); - char dfcc[5]; - memcpy (dfcc, ch->fcc, 4); - dfcc[4] = 0; - - bl = 0; - - if (en) { - en->qwOffset = AVI->pos; - en->dwSize = max; - //en->dwDuration = ch->nEntriesInUse -1; // NUMBER OF stream ticks == frames for video/samples for audio - } - -#ifdef DEBUG_ODML - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML Write %s: Entries %ld size %d \n", dfcc, ch->nEntriesInUse, max)); -#endif - - //OUTS(ch->fcc); - //OUTD(max); - OUTW(ch->wLongsPerEntry); - OUTC(ch->bIndexSubType); - OUTC(ch->bIndexType); - OUTD(ch->nEntriesInUse); - OUTS(ch->dwChunkId); - OUTD(ch->qwBaseOffset&0xffffffff); - OUTD((ch->qwBaseOffset>>32)&0xffffffff); - OUTD(ch->dwReserved3); - - for (k = 0; k < ch->nEntriesInUse; k++) { - OUTD(ch->aIndex[k].dwOffset); - OUTD(ch->aIndex[k].dwSize); - - } - avi_add_chunk (AVI, (unsigned char*)ch->fcc, (unsigned char*)ix00, max); - - gf_free(ix00); - - return 0; -} -#undef OUTS -#undef OUTW -#undef OUTD -#undef OUTC - -// inits a super index structure including its enclosed stdindex -static int avi_init_super_index(avi_t *AVI, unsigned char *idxtag, avisuperindex_chunk **si) -{ - int k; - - avisuperindex_chunk *sil = NULL; - - if ((sil = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk))) == NULL) { - AVI_errno = AVI_ERR_NO_MEM; - return -1; - } - memcpy (sil->fcc, "indx", 4); - sil->dwSize = 0; // size of this chunk - sil->wLongsPerEntry = 4; - sil->bIndexSubType = 0; - sil->bIndexType = AVI_INDEX_OF_INDEXES; - sil->nEntriesInUse = 0; // none are in use - memcpy (sil->dwChunkId, idxtag, 4); - memset (sil->dwReserved, 0, sizeof (sil->dwReserved)); - - // NR_IXNN_CHUNKS == allow 32 indices which means 32 GB files -- arbitrary - sil->aIndex = (avisuperindex_entry *) gf_malloc (sil->wLongsPerEntry * NR_IXNN_CHUNKS * sizeof (void*)); - if (!sil->aIndex) { - AVI_errno = AVI_ERR_NO_MEM; - return -1; - } - memset (sil->aIndex, 0, sil->wLongsPerEntry * NR_IXNN_CHUNKS * sizeof (u32)); - - sil->stdindex = (avistdindex_chunk **)gf_malloc (NR_IXNN_CHUNKS * sizeof (avistdindex_chunk *)); - if (!sil->stdindex) { - AVI_errno = AVI_ERR_NO_MEM; - return -1; - } - for (k = 0; k < NR_IXNN_CHUNKS; k++) { - sil->stdindex[k] = (avistdindex_chunk *) gf_malloc (sizeof (avistdindex_chunk)); - // gets rewritten later - sil->stdindex[k]->qwBaseOffset = (u64)k * AVI->new_riff_threshold; - sil->stdindex[k]->aIndex = NULL; - } - - *si = sil; - - return 0; -} - -// fills an alloc'ed stdindex structure and mallocs some entries for the actual chunks -static int avi_add_std_index(avi_t *AVI, unsigned char *idxtag, unsigned char *strtag, - avistdindex_chunk *stdil) -{ - - memcpy (stdil->fcc, idxtag, 4); - stdil->dwSize = 4096; - stdil->wLongsPerEntry = 2; //sizeof(avistdindex_entry)/sizeof(u32); - stdil->bIndexSubType = 0; - stdil->bIndexType = AVI_INDEX_OF_CHUNKS; - stdil->nEntriesInUse = 0; - - // cp 00db ChunkId - memcpy(stdil->dwChunkId, strtag, 4); - - //stdil->qwBaseOffset = AVI->video_superindex->aIndex[ cur_std_idx ]->qwOffset; - - stdil->aIndex = (avistdindex_entry *)gf_malloc(stdil->dwSize * sizeof (u32) * stdil->wLongsPerEntry); - - if (!stdil->aIndex) { - AVI_errno = AVI_ERR_NO_MEM; - return -1; - } - - - return 0; -} - -static int avi_add_odml_index_entry_core(avi_t *AVI, int flags, u64 pos, unsigned int len, avistdindex_chunk *si) -{ - u32 cur_chunk_idx; - // put new chunk into index - si->nEntriesInUse++; - cur_chunk_idx = si->nEntriesInUse-1; - - // need to fetch more memory - if (cur_chunk_idx >= si->dwSize) { - si->dwSize += 4096; - si->aIndex = (avistdindex_entry *)gf_realloc ( si->aIndex, si->dwSize * sizeof (u32) * si->wLongsPerEntry); - } - - if(len>AVI->max_len) AVI->max_len=len; - - // if bit 31 is set, it is NOT a keyframe - if (flags != 0x10) { - len |= 0x80000000; - } - - si->aIndex [ cur_chunk_idx ].dwSize = len; - si->aIndex [ cur_chunk_idx ].dwOffset = (u32) (pos - si->qwBaseOffset + 8); - - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML: POS: 0x%lX\n", si->aIndex [ cur_chunk_idx ].dwOffset)); - - return 0; -} - -static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, int flags, u64 pos, unsigned int len) -{ - char fcc[5]; - - int audio = (strchr ((char*)tag, 'w')?1:0); - int video = !audio; - - unsigned int cur_std_idx; - u32 audtr; - s64 towrite = 0; - - if (video) { - - if (!AVI->video_superindex) { - if (avi_init_super_index(AVI, (unsigned char *)"ix00", &AVI->video_superindex) < 0) return -1; - AVI->video_superindex->nEntriesInUse++; - cur_std_idx = AVI->video_superindex->nEntriesInUse-1; - - if (avi_add_std_index (AVI, (unsigned char *)"ix00", (unsigned char *)"00db", AVI->video_superindex->stdindex[ cur_std_idx ]) < 0) - return -1; - } // init - - } // video - - if (audio) { - - fcc[0] = 'i'; - fcc[1] = 'x'; - fcc[2] = tag[0]; - fcc[3] = tag[1]; - fcc[4] = '\0'; - if (!AVI->track[AVI->aptr].audio_superindex) { - -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML: fcc = %s\n", fcc)); -#endif - if (avi_init_super_index(AVI, (unsigned char *)fcc, &AVI->track[AVI->aptr].audio_superindex) < 0) return -1; - - - AVI->track[AVI->aptr].audio_superindex->nEntriesInUse++; - - sprintf(fcc, "ix%02d", AVI->aptr+1); - if (avi_add_std_index (AVI, (unsigned char *)fcc, tag, AVI->track[AVI->aptr].audio_superindex->stdindex[ - AVI->track[AVI->aptr].audio_superindex->nEntriesInUse - 1 ]) < 0 - ) return -1; - } // init - - } - - towrite = 0; - if (AVI->video_superindex) { - - cur_std_idx = AVI->video_superindex->nEntriesInUse-1; - towrite += AVI->video_superindex->stdindex[cur_std_idx]->nEntriesInUse*8 - + 4+4+2+1+1+4+4+8+4; - if (cur_std_idx == 0) { - towrite += AVI->n_idx*16 + 8; - towrite += HEADERBYTES; - } - } - - for (audtr=0; audtranum; audtr++) { - if (AVI->track[audtr].audio_superindex) { - cur_std_idx = AVI->track[audtr].audio_superindex->nEntriesInUse-1; - towrite += AVI->track[audtr].audio_superindex->stdindex[cur_std_idx]->nEntriesInUse*8 - + 4+4+2+1+1+4+4+8+4; - } - } - towrite += len + (len&1) + 8; - - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML: towrite = 0x%llX = %"LLD"\n", towrite, towrite)); - - if (AVI->video_superindex && - (s64)(AVI->pos+towrite) > (s64)((s64) AVI->new_riff_threshold*AVI->video_superindex->nEntriesInUse)) { - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] Adding a new RIFF chunk: %d\n", AVI->video_superindex->nEntriesInUse)); - - // rotate ALL indices - AVI->video_superindex->nEntriesInUse++; - cur_std_idx = AVI->video_superindex->nEntriesInUse-1; - - if (AVI->video_superindex->nEntriesInUse > NR_IXNN_CHUNKS) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Internal error in avilib - redefine NR_IXNN_CHUNKS\n")); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] cur_std_idx=%d NR_IXNN_CHUNKS=%d" - "POS=%"LLD" towrite=%"LLD"\n", - cur_std_idx,NR_IXNN_CHUNKS, AVI->pos, towrite)); - return -1; - } - - if (avi_add_std_index (AVI, (unsigned char *)"ix00", (unsigned char *)"00db", AVI->video_superindex->stdindex[ cur_std_idx ]) < 0) - return -1; - - for (audtr = 0; audtr < AVI->anum; audtr++) { - char aud[5]; - if (!AVI->track[audtr].audio_superindex) { - // not initialized -> no index - continue; - } - AVI->track[audtr].audio_superindex->nEntriesInUse++; - - sprintf(fcc, "ix%02d", audtr+1); - sprintf(aud, "0%01dwb", audtr+1); - if (avi_add_std_index (AVI, (unsigned char *)fcc, (unsigned char *)aud, AVI->track[audtr].audio_superindex->stdindex[ - AVI->track[audtr].audio_superindex->nEntriesInUse - 1 ]) < 0 - ) return -1; - } - - // write the new riff; - if (cur_std_idx > 0) { - - // dump the _previous_ == already finished index - avi_ixnn_entry (AVI, AVI->video_superindex->stdindex[cur_std_idx - 1], - &AVI->video_superindex->aIndex[cur_std_idx - 1]); - AVI->video_superindex->aIndex[cur_std_idx - 1].dwDuration = - AVI->video_superindex->stdindex[cur_std_idx - 1]->nEntriesInUse - 1; - - for (audtr = 0; audtr < AVI->anum; audtr++) { - - if (!AVI->track[audtr].audio_superindex) { - // not initialized -> no index - continue; - } - avi_ixnn_entry (AVI, AVI->track[audtr].audio_superindex->stdindex[cur_std_idx - 1], - &AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1]); - - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1].dwDuration = - AVI->track[audtr].audio_superindex->stdindex[cur_std_idx - 1]->nEntriesInUse - 1; - if (AVI->track[audtr].a_fmt == 0x1) { - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1].dwDuration *= - AVI->track[audtr].a_bits*AVI->track[audtr].a_rate*AVI->track[audtr].a_chans/800; - } - } - - // XXX: dump idx1 structure - if (cur_std_idx == 1) { - avi_add_chunk(AVI, (unsigned char *)"idx1", (unsigned char *)AVI->idx, AVI->n_idx*16); - // qwBaseOffset will contain the start of the second riff chunk - } - // Fix the Offsets later at closing time - avi_add_chunk(AVI, (unsigned char *)"RIFF", (unsigned char *)"AVIXLIST\0\0\0\0movi", 16); - - AVI->video_superindex->stdindex[ cur_std_idx ]->qwBaseOffset = AVI->pos -16 -8; -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML: RIFF No.%02d at Offset 0x%llX\n", cur_std_idx, AVI->pos -16 -8)); -#endif - - for (audtr = 0; audtr < AVI->anum; audtr++) { - if (AVI->track[audtr].audio_superindex) - AVI->track[audtr].audio_superindex->stdindex[ cur_std_idx ]->qwBaseOffset = - AVI->pos -16 -8; - - } - - // now we can be sure - AVI->is_opendml++; - } - - } - - - if (video) { - avi_add_odml_index_entry_core(AVI, flags, AVI->pos, len, - AVI->video_superindex->stdindex[ AVI->video_superindex->nEntriesInUse-1 ]); - - AVI->total_frames++; - } // video - - if (audio) { - avi_add_odml_index_entry_core(AVI, flags, AVI->pos, len, - AVI->track[AVI->aptr].audio_superindex->stdindex[ - AVI->track[AVI->aptr].audio_superindex->nEntriesInUse-1 ]); - } - - - return 0; -} - -// #undef NR_IXNN_CHUNKS - -static int avi_add_index_entry(avi_t *AVI, unsigned char *tag, int flags, u64 pos, u64 len) -{ - if(AVI->n_idx>=AVI->max_idx) { - void *ptr = gf_realloc((void *)AVI->idx,(AVI->max_idx+4096)*16); - - if(ptr == 0) { - AVI_errno = AVI_ERR_NO_MEM; - return -1; - } - AVI->max_idx += 4096; - AVI->idx = (unsigned char((*)[16]) ) ptr; - } - - /* Add index entry */ - - // GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] INDEX %s %ld %lu %lu\n", tag, flags, pos, len)); - - memcpy(AVI->idx[AVI->n_idx],tag,4); - long2str(AVI->idx[AVI->n_idx]+ 4,flags); - long2str(AVI->idx[AVI->n_idx]+ 8, (s32) pos); - long2str(AVI->idx[AVI->n_idx]+12, (s32) len); - - /* Update counter */ - - AVI->n_idx++; - - if(len>AVI->max_len) AVI->max_len=(u32) len; - - return 0; -} - -#if 0 -/* Returns 1 if more audio is in that video junk */ -int AVI_can_read_audio(avi_t *AVI) -{ - if(AVI->mode==AVI_MODE_WRITE) { - return -1; - } - if(!AVI->video_index) { - return -1; - } - if(!AVI->track[AVI->aptr].audio_index) { - return -1; - } - - // is it -1? the last ones got left out --tibit - //if (AVI->track[AVI->aptr].audio_posc>=AVI->track[AVI->aptr].audio_chunks-1) { - if (AVI->track[AVI->aptr].audio_posc>=AVI->track[AVI->aptr].audio_chunks) { - return 0; - } - - if (AVI->video_pos >= AVI->video_frames) return 1; - - if (AVI->track[AVI->aptr].audio_index[AVI->track[AVI->aptr].audio_posc].pos < AVI->video_index[AVI->video_pos].pos) return 1; - else return 0; -} -#endif - -/* - AVI_open_output_file: Open an AVI File and write a bunch - of zero bytes as space for the header. - - returns a pointer to avi_t on success, a zero pointer on error -*/ - -GF_EXPORT -avi_t* AVI_open_output_file(char * filename, u64 opendml_threshold) -{ - avi_t *AVI; - int i; - - unsigned char AVI_header[HEADERBYTES]; - - /* Allocate the avi_t struct and zero it */ - - AVI = (avi_t *) gf_malloc(sizeof(avi_t)); - if(AVI==0) - { - AVI_errno = AVI_ERR_NO_MEM; - return 0; - } - memset((void *)AVI,0,sizeof(avi_t)); - - AVI->fdes = gf_fopen(filename, "w+b"); - if (!AVI->fdes ) - { - AVI_errno = AVI_ERR_OPEN; - gf_free(AVI); - return 0; - } - - /* Write out HEADERBYTES bytes, the header will go here - when we are finished with writing */ - - for (i=0; ifdes,(char *)AVI_header,HEADERBYTES); - if (i != HEADERBYTES) - { - gf_fclose(AVI->fdes); - AVI_errno = AVI_ERR_WRITE; - gf_free(AVI); - return 0; - } - - AVI->pos = HEADERBYTES; - AVI->mode = AVI_MODE_WRITE; /* open for writing */ - if (opendml_threshold) - AVI->new_riff_threshold = opendml_threshold; - else - AVI->new_riff_threshold = (1900*1024*1024); - - //init - AVI->anum = 0; - AVI->aptr = 0; - - return AVI; -} - -GF_EXPORT -void AVI_set_video(avi_t *AVI, int width, int height, double fps, char *compressor) -{ - /* may only be called if file is open for writing */ - - if(AVI->mode==AVI_MODE_READ) return; - - AVI->width = width; - AVI->height = height; - AVI->fps = fps; - - if(strncmp(compressor, "RGB", 3)==0) { - memset(AVI->compressor, 0, 4); - } else { - memcpy(AVI->compressor,compressor,4); - } - - AVI->compressor[4] = 0; - - avi_update_header(AVI); -} - -GF_EXPORT -void AVI_set_audio(avi_t *AVI, int channels, int rate, int bits, int format, int mp3rate) -{ - /* may only be called if file is open for writing */ - - if(AVI->mode==AVI_MODE_READ) return; - - //inc audio tracks - AVI->aptr=AVI->anum; - ++AVI->anum; - - if(AVI->anum > AVI_MAX_TRACKS) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] error - only %d audio tracks supported\n", AVI_MAX_TRACKS)); - exit(1); - } - - AVI->track[AVI->aptr].a_chans = channels; - AVI->track[AVI->aptr].a_rate = rate; - AVI->track[AVI->aptr].a_bits = bits; - AVI->track[AVI->aptr].a_fmt = format; - AVI->track[AVI->aptr].mp3rate = mp3rate; - - avi_update_header(AVI); -} - -#define OUT4CC(s) \ - if(nhb<=HEADERBYTES-4) memcpy(AVI_header+nhb,s,4); nhb += 4 - -#define OUTLONG(n) \ - if(nhb<=HEADERBYTES-4) long2str(AVI_header+nhb, (s32)(n)); nhb += 4 - -#define OUTSHRT(n) \ - if(nhb<=HEADERBYTES-2) { \ - AVI_header[nhb ] = (u8) ((n )&0xff); \ - AVI_header[nhb+1] = (u8) ((n>>8)&0xff); \ - } \ - nhb += 2 - -#define OUTCHR(n) \ - if(nhb<=HEADERBYTES-1) { \ - AVI_header[nhb ] = (n )&0xff; \ - } \ - nhb += 1 - -#define OUTMEM(d, s) \ - { \ - u32 s_ = (u32) (s); \ - if(nhb + s_ <= HEADERBYTES) \ - memcpy(AVI_header+nhb, (d), s_); \ - nhb += s_; \ - } - - -//ThOe write preliminary AVI file header: 0 frames, max vid/aud size -int avi_update_header(avi_t *AVI) -{ - int njunk, ms_per_frame, frate, flag; - int movi_len, hdrl_start, strl_start; - u32 j; - unsigned char AVI_header[HEADERBYTES]; - u32 nhb; - unsigned int xd_size, xd_size_align2; - - //assume max size - movi_len = AVI_MAX_LEN - HEADERBYTES + 4; - - //assume index will be written -// int hasIndex=1; - - if(AVI->fps < 0.001) { - frate=0; - ms_per_frame=0; - } else { - frate = (int) (FRAME_RATE_SCALE*AVI->fps + 0.5); - ms_per_frame=(int) (1000000/AVI->fps + 0.5); - } - - /* Prepare the file header */ - - nhb = 0; - - /* The RIFF header */ - - OUT4CC ("RIFF"); - OUTLONG(movi_len); // assume max size - OUT4CC ("AVI "); - - /* Start the header list */ - - OUT4CC ("LIST"); - OUTLONG(0); /* Length of list in bytes, don't know yet */ - hdrl_start = nhb; /* Store start position */ - OUT4CC ("hdrl"); - - /* The main AVI header */ - - /* The Flags in AVI File header */ - -#define AVIF_HASINDEX 0x00000010 /* Index at end of file */ -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_TRUSTCKTYPE 0x00000800 /* Use CKType to find key frames */ -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 - - OUT4CC ("avih"); - OUTLONG(56); /* # of bytes to follow */ - OUTLONG(ms_per_frame); /* Microseconds per frame */ - //ThOe ->0 - // OUTLONG(10000000); /* MaxBytesPerSec, I hope this will never be used */ - OUTLONG(0); - OUTLONG(0); /* PaddingGranularity (whatever that might be) */ - /* Other sources call it 'reserved' */ - flag = AVIF_ISINTERLEAVED; - //if (hasIndex) - flag |= AVIF_HASINDEX; - if (/*hasIndex && */AVI->must_use_index) - flag |= AVIF_MUSTUSEINDEX; - OUTLONG(flag); /* Flags */ - OUTLONG(0); // no frames yet - OUTLONG(0); /* InitialFrames */ - - OUTLONG(AVI->anum+1); - - OUTLONG(0); /* SuggestedBufferSize */ - OUTLONG(AVI->width); /* Width */ - OUTLONG(AVI->height); /* Height */ - /* MS calls the following 'reserved': */ - OUTLONG(0); /* TimeScale: Unit used to measure time */ - OUTLONG(0); /* DataRate: Data rate of playback */ - OUTLONG(0); /* StartTime: Starting time of AVI data */ - OUTLONG(0); /* DataLength: Size of AVI data chunk */ - - - /* Start the video stream list ---------------------------------- */ - - OUT4CC ("LIST"); - OUTLONG(0); /* Length of list in bytes, don't know yet */ - strl_start = nhb; /* Store start position */ - OUT4CC ("strl"); - - /* The video stream header */ - - OUT4CC ("strh"); - OUTLONG(56); /* # of bytes to follow */ - OUT4CC ("vids"); /* Type */ - OUT4CC (AVI->compressor); /* Handler */ - OUTLONG(0); /* Flags */ - OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ - OUTLONG(0); /* InitialFrames */ - OUTLONG(FRAME_RATE_SCALE); /* Scale */ - OUTLONG(frate); /* Rate: Rate/Scale == samples/second */ - OUTLONG(0); /* Start */ - OUTLONG(0); // no frames yet - OUTLONG(0); /* SuggestedBufferSize */ - OUTLONG(-1); /* Quality */ - OUTLONG(0); /* SampleSize */ - OUTLONG(0); /* Frame */ - OUTLONG(0); /* Frame */ - // OUTLONG(0); /* Frame */ - //OUTLONG(0); /* Frame */ - - /* The video stream format */ - - xd_size = AVI->extradata_size; - xd_size_align2 = (AVI->extradata_size+1) & ~1; - - OUT4CC ("strf"); - OUTLONG(40 + xd_size_align2);/* # of bytes to follow */ - OUTLONG(40 + xd_size); /* Size */ - OUTLONG(AVI->width); /* Width */ - OUTLONG(AVI->height); /* Height */ - OUTSHRT(1); - OUTSHRT(24); /* Planes, Count */ - OUT4CC (AVI->compressor); /* Compression */ - // ThOe (*3) - OUTLONG(AVI->width*AVI->height*3); /* SizeImage (in bytes?) */ - OUTLONG(0); /* XPelsPerMeter */ - OUTLONG(0); /* YPelsPerMeter */ - OUTLONG(0); /* ClrUsed: Number of colors used */ - OUTLONG(0); /* ClrImportant: Number of colors important */ - - // write extradata - if (xd_size > 0 && AVI->extradata) { - OUTMEM(AVI->extradata, xd_size); - if (xd_size != xd_size_align2) { - OUTCHR(0); - } - } - - /* Finish stream list, i.e. put number of bytes in the list to proper pos */ - - long2str(AVI_header+strl_start-4,nhb-strl_start); - - - /* Start the audio stream list ---------------------------------- */ - - for(j=0; janum; ++j) { - int sampsize = avi_sampsize(AVI, j); - - OUT4CC ("LIST"); - OUTLONG(0); /* Length of list in bytes, don't know yet */ - strl_start = nhb; /* Store start position */ - OUT4CC ("strl"); - - /* The audio stream header */ - - OUT4CC ("strh"); - OUTLONG(56); /* # of bytes to follow */ - OUT4CC ("auds"); - - // ----------- - // ThOe - OUTLONG(0); /* Format (Optionally) */ - // ----------- - - OUTLONG(0); /* Flags */ - OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ - OUTLONG(0); /* InitialFrames */ - - // ThOe /4 - OUTLONG(sampsize/4); /* Scale */ - OUTLONG(1000*AVI->track[j].mp3rate/8); - OUTLONG(0); /* Start */ - OUTLONG(4*AVI->track[j].audio_bytes/sampsize); /* Length */ - OUTLONG(0); /* SuggestedBufferSize */ - OUTLONG(-1); /* Quality */ - - // ThOe /4 - OUTLONG(sampsize/4); /* SampleSize */ - - OUTLONG(0); /* Frame */ - OUTLONG(0); /* Frame */ - // OUTLONG(0); /* Frame */ - //OUTLONG(0); /* Frame */ - - /* The audio stream format */ - - OUT4CC ("strf"); - OUTLONG(16); /* # of bytes to follow */ - OUTSHRT(AVI->track[j].a_fmt); /* Format */ - OUTSHRT(AVI->track[j].a_chans); /* Number of channels */ - OUTLONG(AVI->track[j].a_rate); /* SamplesPerSec */ - // ThOe - OUTLONG(1000*AVI->track[j].mp3rate/8); - //ThOe (/4) - - OUTSHRT(sampsize/4); /* BlockAlign */ - - - OUTSHRT(AVI->track[j].a_bits); /* BitsPerSample */ - - /* Finish stream list, i.e. put number of bytes in the list to proper pos */ - - long2str(AVI_header+strl_start-4,nhb-strl_start); - } - - /* Finish header list */ - - long2str(AVI_header+hdrl_start-4,nhb-hdrl_start); - - - /* Calculate the needed amount of junk bytes, output junk */ - - njunk = HEADERBYTES - nhb - 8 - 12; - - /* Safety first: if njunk <= 0, somebody has played with - HEADERBYTES without knowing what (s)he did. - This is a fatal error */ - - if(njunk<=0) - { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] AVI_close_output_file: # of header bytes too small\n")); - exit(1); - } - - OUT4CC ("JUNK"); - OUTLONG(njunk); - memset(AVI_header+nhb,0,njunk); - - nhb += njunk; - - /* Start the movi list */ - - OUT4CC ("LIST"); - OUTLONG(movi_len); /* Length of list in bytes */ - OUT4CC ("movi"); - - /* Output the header, truncate the file to the number of bytes - actually written, report an error if someting goes wrong */ - - if ( (gf_fseek(AVI->fdes, 0, SEEK_SET) ==(u64)-1) || - avi_write(AVI->fdes,(char *)AVI_header,HEADERBYTES)!=HEADERBYTES || - (gf_fseek(AVI->fdes,AVI->pos,SEEK_SET)==(u64)-1) - ) { - AVI_errno = AVI_ERR_CLOSE; - return -1; - } - - return 0; -} - - -//SLM -#ifndef S_IRUSR -#define S_IRWXU 00700 /* read, write, execute: owner */ -#define S_IRUSR 00400 /* read permission: owner */ -#define S_IWUSR 00200 /* write permission: owner */ -#define S_IXUSR 00100 /* execute permission: owner */ -#define S_IRWXG 00070 /* read, write, execute: group */ -#define S_IRGRP 00040 /* read permission: group */ -#define S_IWGRP 00020 /* write permission: group */ -#define S_IXGRP 00010 /* execute permission: group */ -#define S_IRWXO 00007 /* read, write, execute: other */ -#define S_IROTH 00004 /* read permission: other */ -#define S_IWOTH 00002 /* write permission: other */ -#define S_IXOTH 00001 /* execute permission: other */ -#endif - -/* - Write the header of an AVI file and close it. - returns 0 on success, -1 on write error. -*/ - -static int avi_close_output_file(avi_t *AVI) -{ - int njunk, hasIndex, ms_per_frame, frate, idxerror, flag; - u64 movi_len; - int hdrl_start, strl_start; - u32 j; - unsigned char AVI_header[HEADERBYTES]; - int nhb; - unsigned int xd_size, xd_size_align2; - -#ifdef INFO_LIST - int info_len; - int id_len, real_id_len; - int info_start_pos; -// time_t calptr; -#endif - - /* Calculate length of movi list */ - - // dump the rest of the index - if (AVI->is_opendml) { - int cur_std_idx = AVI->video_superindex->nEntriesInUse-1; - u32 audtr; - -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML dump the rest indices\n")); -#endif - avi_ixnn_entry (AVI, AVI->video_superindex->stdindex[cur_std_idx], - &AVI->video_superindex->aIndex[cur_std_idx]); - - AVI->video_superindex->aIndex[cur_std_idx].dwDuration = - AVI->video_superindex->stdindex[cur_std_idx]->nEntriesInUse - 1; - - for (audtr = 0; audtr < AVI->anum; audtr++) { - if (!AVI->track[audtr].audio_superindex) { - // not initialized -> no index - continue; - } - avi_ixnn_entry (AVI, AVI->track[audtr].audio_superindex->stdindex[cur_std_idx], - &AVI->track[audtr].audio_superindex->aIndex[cur_std_idx]); - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx].dwDuration = - AVI->track[audtr].audio_superindex->stdindex[cur_std_idx]->nEntriesInUse - 1; - if (AVI->track[audtr].a_fmt == 0x1) { - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx].dwDuration *= - AVI->track[audtr].a_bits*AVI->track[audtr].a_rate*AVI->track[audtr].a_chans/800; - } - } - // The AVI->video_superindex->nEntriesInUse contains the offset - AVI->video_superindex->stdindex[ cur_std_idx+1 ]->qwBaseOffset = AVI->pos; - - // Correct! - movi_len = AVI->video_superindex->stdindex[ 1 ]->qwBaseOffset - HEADERBYTES+4 - AVI->n_idx*16 - 8; - } else { - movi_len = AVI->pos - HEADERBYTES + 4; - } - - - /* Try to ouput the index entries. This may fail e.g. if no space - is left on device. We will report this as an error, but we still - try to write the header correctly (so that the file still may be - readable in the most cases */ - - idxerror = 0; - hasIndex = 1; - if (!AVI->is_opendml) { - // GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] pos=%lu, index_len=%ld \n", AVI->pos, AVI->n_idx*16)); - int ret = avi_add_chunk(AVI, (unsigned char *)"idx1", (unsigned char *)AVI->idx, AVI->n_idx*16); - hasIndex = (ret==0); - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] pos=%lu, index_len=%d\n", AVI->pos, hasIndex)); - - if(ret) { - idxerror = 1; - AVI_errno = AVI_ERR_WRITE_INDEX; - } - } - - /* Calculate Microseconds per frame */ - - if(AVI->fps < 0.001) { - frate=0; - ms_per_frame=0; - } else { - frate = (int) (FRAME_RATE_SCALE*AVI->fps + 0.5); - ms_per_frame=(int) (1000000/AVI->fps + 0.5); - } - - /* Prepare the file header */ - - nhb = 0; - - /* The RIFF header */ - - OUT4CC ("RIFF"); - if (AVI->is_opendml) { - OUTLONG(AVI->video_superindex->stdindex[ 1 ]->qwBaseOffset - 8); /* # of bytes to follow */ - } else { - OUTLONG(AVI->pos - 8); /* # of bytes to follow */ - } - - OUT4CC ("AVI "); - - /* Start the header list */ - - OUT4CC ("LIST"); - OUTLONG(0); /* Length of list in bytes, don't know yet */ - hdrl_start = nhb; /* Store start position */ - OUT4CC ("hdrl"); - - /* The main AVI header */ - - /* The Flags in AVI File header */ - -#define AVIF_HASINDEX 0x00000010 /* Index at end of file */ -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_TRUSTCKTYPE 0x00000800 /* Use CKType to find key frames */ -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 - - OUT4CC ("avih"); - OUTLONG(56); /* # of bytes to follow */ - OUTLONG(ms_per_frame); /* Microseconds per frame */ - //ThOe ->0 - // OUTLONG(10000000); /* MaxBytesPerSec, I hope this will never be used */ - OUTLONG(0); - OUTLONG(0); /* PaddingGranularity (whatever that might be) */ - /* Other sources call it 'reserved' */ - flag = AVIF_ISINTERLEAVED; - if(hasIndex) flag |= AVIF_HASINDEX; - if(hasIndex && AVI->must_use_index) flag |= AVIF_MUSTUSEINDEX; - OUTLONG(flag); /* Flags */ - OUTLONG(AVI->video_frames); /* TotalFrames */ - OUTLONG(0); /* InitialFrames */ - - OUTLONG(AVI->anum+1); -// if (AVI->track[0].audio_bytes) -// { OUTLONG(2); } /* Streams */ -// else -// { OUTLONG(1); } /* Streams */ - - OUTLONG(0); /* SuggestedBufferSize */ - OUTLONG(AVI->width); /* Width */ - OUTLONG(AVI->height); /* Height */ - /* MS calls the following 'reserved': */ - OUTLONG(0); /* TimeScale: Unit used to measure time */ - OUTLONG(0); /* DataRate: Data rate of playback */ - OUTLONG(0); /* StartTime: Starting time of AVI data */ - OUTLONG(0); /* DataLength: Size of AVI data chunk */ - - - /* Start the video stream list ---------------------------------- */ - - OUT4CC ("LIST"); - OUTLONG(0); /* Length of list in bytes, don't know yet */ - strl_start = nhb; /* Store start position */ - OUT4CC ("strl"); - - /* The video stream header */ - - OUT4CC ("strh"); - OUTLONG(56); /* # of bytes to follow */ - OUT4CC ("vids"); /* Type */ - OUT4CC (AVI->compressor); /* Handler */ - OUTLONG(0); /* Flags */ - OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ - OUTLONG(0); /* InitialFrames */ - OUTLONG(FRAME_RATE_SCALE); /* Scale */ - OUTLONG(frate); /* Rate: Rate/Scale == samples/second */ - OUTLONG(0); /* Start */ - OUTLONG(AVI->video_frames); /* Length */ - OUTLONG(AVI->max_len); /* SuggestedBufferSize */ - OUTLONG(0); /* Quality */ - OUTLONG(0); /* SampleSize */ - OUTLONG(0); /* Frame */ - OUTLONG(0); /* Frame */ - //OUTLONG(0); /* Frame */ - //OUTLONG(0); /* Frame */ - - /* The video stream format */ - - xd_size = AVI->extradata_size; - xd_size_align2 = (AVI->extradata_size+1) & ~1; - - OUT4CC ("strf"); - OUTLONG(40 + xd_size_align2);/* # of bytes to follow */ - OUTLONG(40 + xd_size); /* Size */ - OUTLONG(AVI->width); /* Width */ - OUTLONG(AVI->height); /* Height */ - OUTSHRT(1); - OUTSHRT(24); /* Planes, Count */ - OUT4CC (AVI->compressor); /* Compression */ - // ThOe (*3) - OUTLONG(AVI->width*AVI->height*3); /* SizeImage (in bytes?) */ - OUTLONG(0); /* XPelsPerMeter */ - OUTLONG(0); /* YPelsPerMeter */ - OUTLONG(0); /* ClrUsed: Number of colors used */ - OUTLONG(0); /* ClrImportant: Number of colors important */ - - // write extradata if present - if (xd_size > 0 && AVI->extradata) { - OUTMEM(AVI->extradata, xd_size); - if (xd_size != xd_size_align2) { - OUTCHR(0); - } - } - - // dump index of indices for audio - if (AVI->is_opendml) { - u32 k; - - OUT4CC(AVI->video_superindex->fcc); - OUTLONG(2+1+1+4+4+3*4 + AVI->video_superindex->nEntriesInUse * (8+4+4)); - OUTSHRT(AVI->video_superindex->wLongsPerEntry); - OUTCHR(AVI->video_superindex->bIndexSubType); - OUTCHR(AVI->video_superindex->bIndexType); - OUTLONG(AVI->video_superindex->nEntriesInUse); - OUT4CC(AVI->video_superindex->dwChunkId); - OUTLONG(0); - OUTLONG(0); - OUTLONG(0); - - - for (k = 0; k < AVI->video_superindex->nEntriesInUse; k++) { - u32 r = (u32) ((AVI->video_superindex->aIndex[k].qwOffset >> 32) & 0xffffffff); - u32 s = (u32) ((AVI->video_superindex->aIndex[k].qwOffset) & 0xffffffff); - - OUTLONG(s); - OUTLONG(r); - OUTLONG(AVI->video_superindex->aIndex[k].dwSize); - OUTLONG(AVI->video_superindex->aIndex[k].dwDuration); - } - - } - - /* Finish stream list, i.e. put number of bytes in the list to proper pos */ - - long2str(AVI_header+strl_start-4,nhb-strl_start); - - /* Start the audio stream list ---------------------------------- */ - - for(j=0; janum; ++j) { - - //if (AVI->track[j].a_chans && AVI->track[j].audio_bytes) - { - unsigned int nBlockAlign = 0; - unsigned int avgbsec = 0; - unsigned int scalerate = 0; - - int sampsize = avi_sampsize(AVI, j); - sampsize = AVI->track[j].a_fmt==0x1?sampsize*4:sampsize; - - nBlockAlign = (AVI->track[j].a_rate<32000)?576:1152; - /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] XXX sampsize (%d) block (%ld) rate (%ld) audio_bytes (%ld) mp3rate(%ld,%ld)\n", - sampsize, nBlockAlign, AVI->track[j].a_rate, - (int int)AVI->track[j].audio_bytes, - 1000*AVI->track[j].mp3rate/8, AVI->track[j].mp3rate)); - */ - - if (AVI->track[j].a_fmt==0x1) { - sampsize = (AVI->track[j].a_chans<2)?sampsize/2:sampsize; - avgbsec = AVI->track[j].a_rate*sampsize/4; - scalerate = AVI->track[j].a_rate*sampsize/4; - } else { - avgbsec = 1000*AVI->track[j].mp3rate/8; - scalerate = 1000*AVI->track[j].mp3rate/8; - } - - OUT4CC ("LIST"); - OUTLONG(0); /* Length of list in bytes, don't know yet */ - strl_start = nhb; /* Store start position */ - OUT4CC ("strl"); - - /* The audio stream header */ - - OUT4CC ("strh"); - OUTLONG(56); /* # of bytes to follow */ - OUT4CC ("auds"); - - // ----------- - // ThOe - OUTLONG(0); /* Format (Optionally) */ - // ----------- - - OUTLONG(0); /* Flags */ - OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ - OUTLONG(0); /* InitialFrames */ - - // VBR - if (AVI->track[j].a_fmt == 0x55 && AVI->track[j].a_vbr) { - OUTLONG(nBlockAlign); /* Scale */ - OUTLONG(AVI->track[j].a_rate); /* Rate */ - OUTLONG(0); /* Start */ - OUTLONG(AVI->track[j].audio_chunks); /* Length */ - OUTLONG(0); /* SuggestedBufferSize */ - OUTLONG(0); /* Quality */ - OUTLONG(0); /* SampleSize */ - OUTLONG(0); /* Frame */ - OUTLONG(0); /* Frame */ - } else { - OUTLONG(sampsize/4); /* Scale */ - OUTLONG(scalerate); /* Rate */ - OUTLONG(0); /* Start */ - OUTLONG(4*AVI->track[j].audio_bytes/sampsize); /* Length */ - OUTLONG(0); /* SuggestedBufferSize */ - OUTLONG(0xffffffff); /* Quality */ - OUTLONG(sampsize/4); /* SampleSize */ - OUTLONG(0); /* Frame */ - OUTLONG(0); /* Frame */ - } - - /* The audio stream format */ - - OUT4CC ("strf"); - - if (AVI->track[j].a_fmt == 0x55 && AVI->track[j].a_vbr) { - - OUTLONG(30); /* # of bytes to follow */ // mplayer writes 28 - OUTSHRT(AVI->track[j].a_fmt); /* Format */ // 2 - OUTSHRT(AVI->track[j].a_chans); /* Number of channels */ // 2 - OUTLONG(AVI->track[j].a_rate); /* SamplesPerSec */ // 4 - //ThOe/tibit - OUTLONG(1000*AVI->track[j].mp3rate/8); /* maybe we should write an avg. */ // 4 - OUTSHRT(nBlockAlign); /* BlockAlign */ // 2 - OUTSHRT(AVI->track[j].a_bits); /* BitsPerSample */ // 2 - - OUTSHRT(12); /* cbSize */ // 2 - OUTSHRT(1); /* wID */ // 2 - OUTLONG(2); /* fdwFlags */ // 4 - OUTSHRT(nBlockAlign); /* nBlockSize */ // 2 - OUTSHRT(1); /* nFramesPerBlock */ // 2 - OUTSHRT(0); /* nCodecDelay */ // 2 - - } else if (AVI->track[j].a_fmt == 0x55 && !AVI->track[j].a_vbr) { - - OUTLONG(30); /* # of bytes to follow */ - OUTSHRT(AVI->track[j].a_fmt); /* Format */ - OUTSHRT(AVI->track[j].a_chans); /* Number of channels */ - OUTLONG(AVI->track[j].a_rate); /* SamplesPerSec */ - //ThOe/tibit - OUTLONG(1000*AVI->track[j].mp3rate/8); - OUTSHRT(sampsize/4); /* BlockAlign */ - OUTSHRT(AVI->track[j].a_bits); /* BitsPerSample */ - - OUTSHRT(12); /* cbSize */ - OUTSHRT(1); /* wID */ - OUTLONG(2); /* fdwFlags */ - OUTSHRT(nBlockAlign); /* nBlockSize */ - OUTSHRT(1); /* nFramesPerBlock */ - OUTSHRT(0); /* nCodecDelay */ - - } else { - - OUTLONG(18); /* # of bytes to follow */ - OUTSHRT(AVI->track[j].a_fmt); /* Format */ - OUTSHRT(AVI->track[j].a_chans); /* Number of channels */ - OUTLONG(AVI->track[j].a_rate); /* SamplesPerSec */ - //ThOe/tibit - OUTLONG(avgbsec); /* Avg bytes/sec */ - OUTSHRT(sampsize/4); /* BlockAlign */ - OUTSHRT(AVI->track[j].a_bits); /* BitsPerSample */ - OUTSHRT(0); /* cbSize */ - - } - } - if (AVI->is_opendml) { - u32 k; - - if (!AVI->track[j].audio_superindex) { - // not initialized -> no index - continue; - } - - OUT4CC(AVI->track[j].audio_superindex->fcc); /* "indx" */ - OUTLONG(2+1+1+4+4+3*4 + AVI->track[j].audio_superindex->nEntriesInUse * (8+4+4)); - OUTSHRT(AVI->track[j].audio_superindex->wLongsPerEntry); - OUTCHR(AVI->track[j].audio_superindex->bIndexSubType); - OUTCHR(AVI->track[j].audio_superindex->bIndexType); - OUTLONG(AVI->track[j].audio_superindex->nEntriesInUse); - OUT4CC(AVI->track[j].audio_superindex->dwChunkId); - OUTLONG(0); - OUTLONG(0); - OUTLONG(0); - - for (k = 0; k < AVI->track[j].audio_superindex->nEntriesInUse; k++) { - u32 r = (u32) ((AVI->track[j].audio_superindex->aIndex[k].qwOffset >> 32) & 0xffffffff); - u32 s = (u32) ((AVI->track[j].audio_superindex->aIndex[k].qwOffset) & 0xffffffff); - - /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] AUD[%d] NrEntries %d/%ld (%c%c%c%c) |0x%llX|%ld|%ld| \n", j, k, - AVI->track[j].audio_superindex->nEntriesInUse, - AVI->track[j].audio_superindex->dwChunkId[0], AVI->track[j].audio_superindex->dwChunkId[1], - AVI->track[j].audio_superindex->dwChunkId[2], AVI->track[j].audio_superindex->dwChunkId[3], - AVI->track[j].audio_superindex->aIndex[k].qwOffset, - AVI->track[j].audio_superindex->aIndex[k].dwSize, - AVI->track[j].audio_superindex->aIndex[k].dwDuration - )); - */ - - OUTLONG(s); - OUTLONG(r); - OUTLONG(AVI->track[j].audio_superindex->aIndex[k].dwSize); - OUTLONG(AVI->track[j].audio_superindex->aIndex[k].dwDuration); - } - } - /* Finish stream list, i.e. put number of bytes in the list to proper pos */ - long2str(AVI_header+strl_start-4,nhb-strl_start); - } - - if (AVI->is_opendml) { - OUT4CC("LIST"); - OUTLONG(16); - OUT4CC("odml"); - OUT4CC("dmlh"); - OUTLONG(4); - OUTLONG(AVI->total_frames); - } - - /* Finish header list */ - - long2str(AVI_header+hdrl_start-4,nhb-hdrl_start); - - - // add INFO list --- (0.6.0pre4) - -#ifdef INFO_LIST - OUT4CC ("LIST"); - - info_start_pos = nhb; - info_len = MAX_INFO_STRLEN + 12; - OUTLONG(info_len); // rewritten later - OUT4CC ("INFO"); - - OUT4CC ("ISFT"); - //OUTLONG(MAX_INFO_STRLEN); - memset(id_str, 0, MAX_INFO_STRLEN); - if (gf_sys_is_test_mode()) { - snprintf(id_str, MAX_INFO_STRLEN, "GPAC/avilib"); - } else { - snprintf(id_str, MAX_INFO_STRLEN, "GPAC/avilib-%s", gf_gpac_version()); - } - real_id_len = id_len = (u32) strlen(id_str)+1; - if (id_len&1) id_len++; - - OUTLONG(real_id_len); - - memset(AVI_header+nhb, 0, id_len); - memcpy(AVI_header+nhb, id_str, id_len); - nhb += id_len; - - info_len = 0; - - // write correct len - long2str(AVI_header+info_start_pos, info_len + id_len + 4+4+4); - - nhb += info_len; - -// OUT4CC ("ICMT"); -// OUTLONG(MAX_INFO_STRLEN); - -// calptr=time(NULL); -// sprintf(id_str, "\t%s %s", ctime(&calptr), ""); -// memset(AVI_header+nhb, 0, MAX_INFO_STRLEN); -// memcpy(AVI_header+nhb, id_str, 25); -// nhb += MAX_INFO_STRLEN; -#endif - - // ---------------------------- - - /* Calculate the needed amount of junk bytes, output junk */ - - njunk = HEADERBYTES - nhb - 8 - 12; - - /* Safety first: if njunk <= 0, somebody has played with - HEADERBYTES without knowing what (s)he did. - This is a fatal error */ - - if(njunk<=0) - { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] AVI_close_output_file: # of header bytes too small\n")); - exit(1); - } - - OUT4CC ("JUNK"); - OUTLONG(njunk); - memset(AVI_header+nhb,0,njunk); - - nhb += njunk; - - /* Start the movi list */ - - OUT4CC ("LIST"); - OUTLONG(movi_len); /* Length of list in bytes */ - OUT4CC ("movi"); - - /* Output the header, truncate the file to the number of bytes - actually written, report an error if someting goes wrong */ - - if ( (gf_fseek(AVI->fdes,0,SEEK_SET)==(u64)-1) || - avi_write(AVI->fdes,(char *)AVI_header,HEADERBYTES)!=HEADERBYTES -// || ftruncate(AVI->fdes,AVI->pos)<0 - ) - { - AVI_errno = AVI_ERR_CLOSE; - return -1; - } - - - // Fix up the empty additional RIFF and LIST chunks - if (AVI->is_opendml) { - u32 k; - char f[4]; - u32 len; - - for (k=1; kvideo_superindex->nEntriesInUse; k++) { - // the len of the RIFF Chunk - gf_fseek(AVI->fdes, AVI->video_superindex->stdindex[k]->qwBaseOffset+4, SEEK_SET); - len = (u32) (AVI->video_superindex->stdindex[k+1]->qwBaseOffset - AVI->video_superindex->stdindex[k]->qwBaseOffset - 8); - long2str((unsigned char *)f, len); - avi_write(AVI->fdes, f, 4); - - // len of the LIST/movi chunk - gf_fseek(AVI->fdes, 8, SEEK_CUR); - len -= 12; - long2str((unsigned char *)f, len); - avi_write(AVI->fdes, f, 4); - } - } - - - if(idxerror) return -1; - - return 0; -} - -/* - AVI_write_data: - Add video or audio data to the file; - - Return values: - 0 No error; - -1 Error, AVI_errno is set appropriatly; - -*/ - -static int avi_write_data(avi_t *AVI, char *data, unsigned int length, int audio, int keyframe) -{ - int n = 0; - - unsigned char astr[5]; - - // transcode core itself checks for the size -- unneeded and - // does harm to xvid 2pass encodes where the first pass can get - // _very_ large -- tibit. - -#if 0 - /* Check for maximum file length */ - - if ( (AVI->pos + 8 + length + 8 + (AVI->n_idx+1)*16) > AVI_MAX_LEN ) { - AVI_errno = AVI_ERR_SIZELIM; - return -1; - } -#endif - - /* Add index entry */ - - //set tag for current audio track - sprintf((char *)astr, "0%1dwb", (int)(AVI->aptr+1)); - - if(audio) { - if (!AVI->is_opendml) n = avi_add_index_entry(AVI,astr,0x10,AVI->pos,length); - n += avi_add_odml_index_entry(AVI,astr,0x10,AVI->pos,length); - } else { - if (!AVI->is_opendml) n = avi_add_index_entry(AVI,(unsigned char *)"00db",((keyframe)?0x10:0x0),AVI->pos,length); - n += avi_add_odml_index_entry(AVI,(unsigned char *)"00db",((keyframe)?0x10:0x0),AVI->pos,length); - } - - if(n) return -1; - - /* Output tag and data */ - - if(audio) - n = avi_add_chunk(AVI,(unsigned char *)astr, (unsigned char *)data, length); - else - n = avi_add_chunk(AVI,(unsigned char *)"00db", (unsigned char *)data, length); - - if (n) return -1; - - return 0; -} - -GF_EXPORT -int AVI_write_frame(avi_t *AVI, u8 *data, int bytes, int keyframe) -{ - s64 pos; - - if(AVI->mode==AVI_MODE_READ) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - - pos = AVI->pos; - - if(avi_write_data(AVI,data,bytes,0,keyframe)) return -1; - - AVI->last_pos = pos; - AVI->last_len = bytes; - AVI->video_frames++; - return 0; -} - -#if 0 //unused -int AVI_dup_frame(avi_t *AVI) -{ - if(AVI->mode==AVI_MODE_READ) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - - if(AVI->last_pos==0) return 0; /* No previous real frame */ - if(avi_add_index_entry(AVI,(unsigned char *)"00db",0x10,AVI->last_pos,AVI->last_len)) return -1; - AVI->video_frames++; - AVI->must_use_index = 1; - return 0; -} -#endif - -GF_EXPORT -int AVI_write_audio(avi_t *AVI, u8 *data, int bytes) -{ - if(AVI->mode==AVI_MODE_READ) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - - if( avi_write_data(AVI,data,bytes,1,0) ) return -1; - AVI->track[AVI->aptr].audio_bytes += bytes; - AVI->track[AVI->aptr].audio_chunks++; - return 0; -} - -#if 0 //unused - -int AVI_append_audio(avi_t *AVI, u8 *data, int bytes) -{ - - // won't work for >2gb - int i, length, pos; - unsigned char c[4]; - - if(AVI->mode==AVI_MODE_READ) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - - // update last index entry: - - --AVI->n_idx; - length = str2ulong(AVI->idx[AVI->n_idx]+12); - pos = str2ulong(AVI->idx[AVI->n_idx]+8); - - //update; - long2str(AVI->idx[AVI->n_idx]+12,length+bytes); - - ++AVI->n_idx; - - AVI->track[AVI->aptr].audio_bytes += bytes; - - //update chunk header - gf_fseek(AVI->fdes, pos+4, SEEK_SET); - long2str(c, length+bytes); - avi_write(AVI->fdes, (char *)c, 4); - - gf_fseek(AVI->fdes, pos+8+length, SEEK_SET); - - i=PAD_EVEN(length + bytes); - - bytes = i - length; - avi_write(AVI->fdes, data, bytes); - AVI->pos = pos + 8 + i; - - return 0; -} - -u64 AVI_bytes_remain(avi_t *AVI) -{ - if(AVI->mode==AVI_MODE_READ) return 0; - - return ( AVI_MAX_LEN - (AVI->pos + 8 + 16*AVI->n_idx)); -} - -u64 AVI_bytes_written(avi_t *AVI) -{ - if(AVI->mode==AVI_MODE_READ) return 0; - - return (AVI->pos + 8 + 16*AVI->n_idx); -} -#endif - -int AVI_set_audio_track(avi_t *AVI, u32 track) -{ - - if (track + 1 > AVI->anum) return(-1); - - //this info is not written to file anyway - AVI->aptr=track; - return 0; -} - -int AVI_get_audio_track(avi_t *AVI) -{ - return(AVI->aptr); -} - -#if 0 //unused -void AVI_set_audio_vbr(avi_t *AVI, int is_vbr) -{ - AVI->track[AVI->aptr].a_vbr = is_vbr; -} - -int AVI_get_audio_vbr(avi_t *AVI) -{ - return(AVI->track[AVI->aptr].a_vbr); -} -#endif - - -/******************************************************************* - * * - * Utilities for reading video and audio from an AVI File * - * * - *******************************************************************/ - -GF_EXPORT -int AVI_close(avi_t *AVI) -{ - int ret; - u32 j; - - /* If the file was open for writing, the header and index still have - to be written */ - - if(AVI->mode == AVI_MODE_WRITE) - ret = avi_close_output_file(AVI); - else - ret = 0; - - /* Even if there happened an error, we first clean up */ - - gf_fclose(AVI->fdes); - if(AVI->idx) gf_free(AVI->idx); - if(AVI->video_index) gf_free(AVI->video_index); - if(AVI->video_superindex) { - if(AVI->video_superindex->aIndex) gf_free(AVI->video_superindex->aIndex); - if (AVI->video_superindex->stdindex) { - for (j=0; j < NR_IXNN_CHUNKS; j++) { - if (AVI->video_superindex->stdindex[j]->aIndex) - gf_free(AVI->video_superindex->stdindex[j]->aIndex); - gf_free(AVI->video_superindex->stdindex[j]); - } - gf_free(AVI->video_superindex->stdindex); - } - gf_free(AVI->video_superindex); - } - - for (j=0; janum; j++) - { - if(AVI->track[j].audio_index) gf_free(AVI->track[j].audio_index); - if(AVI->track[j].audio_superindex) { - avisuperindex_chunk *asi = AVI->track[j].audio_superindex; - if (asi->aIndex) gf_free(asi->aIndex); - - if (asi->stdindex) { - for (j=0; j < NR_IXNN_CHUNKS; j++) { - if (asi->stdindex[j]->aIndex) - gf_free(asi->stdindex[j]->aIndex); - gf_free(asi->stdindex[j]); - } - gf_free(asi->stdindex); - } - gf_free(asi); - } - } - - if (AVI->bitmap_info_header) - gf_free(AVI->bitmap_info_header); - for (j = 0; j < AVI->anum; j++) - if (AVI->wave_format_ex[j]) - gf_free(AVI->wave_format_ex[j]); - if (AVI->extradata) - gf_free(AVI->extradata); - - gf_free(AVI); - return ret; -} - - -#define ERR_EXIT(x) \ -{ \ - AVI_close(AVI); \ - AVI_errno = x; \ - return 0; \ -} - - -avi_t *AVI_open_input_file(char *filename, int getIndex) -{ - avi_t *AVI; - - /* Create avi_t structure */ - - AVI = (avi_t *) gf_malloc(sizeof(avi_t)); - if(AVI==NULL) - { - AVI_errno = AVI_ERR_NO_MEM; - return 0; - } - memset((void *)AVI,0,sizeof(avi_t)); - - AVI->mode = AVI_MODE_READ; /* open for reading */ - - /* Open the file */ - - AVI->fdes = gf_fopen(filename,"rb"); - if(!AVI->fdes ) - { - AVI_errno = AVI_ERR_OPEN; - gf_free(AVI); - return 0; - } - - AVI_errno = 0; - avi_parse_input_file(AVI, getIndex); - - if (AVI != NULL && !AVI_errno) { - AVI->aptr=0; //reset - } - - if (AVI_errno) return NULL; - - return AVI; -} - -#if 0 -avi_t *AVI_open_fd(FILE *fd, int getIndex) -{ - avi_t *AVI=NULL; - - /* Create avi_t structure */ - - AVI = (avi_t *) gf_malloc(sizeof(avi_t)); - if(AVI==NULL) - { - AVI_errno = AVI_ERR_NO_MEM; - return 0; - } - memset((void *)AVI,0,sizeof(avi_t)); - - AVI->mode = AVI_MODE_READ; /* open for reading */ - - // file alread open - AVI->fdes = fd; - - AVI_errno = 0; - avi_parse_input_file(AVI, getIndex); - - if (AVI != NULL && !AVI_errno) { - AVI->aptr=0; //reset - } - - if (AVI_errno) - return AVI=NULL; - else - return AVI; -} -#endif - -int avi_parse_input_file(avi_t *AVI, int getIndex) -{ - int i, rate, scale, idx_type; - s64 n; - unsigned char *hdrl_data; - u64 header_offset=0; - int hdrl_len=0; - int nvi, nai[AVI_MAX_TRACKS], ioff; - u64 tot[AVI_MAX_TRACKS]; - u32 j; - int lasttag = 0; - int vids_strh_seen = 0; - int vids_strf_seen = 0; - int auds_strh_seen = 0; - // int auds_strf_seen = 0; - int num_stream = 0; - char data[256]; - s64 oldpos=-1, newpos=-1; - - int aud_chunks = 0; - if (!AVI) { - AVI_errno = AVI_ERR_OPEN; - return 0; - } - - /* Read first 12 bytes and check that this is an AVI file */ - if (avi_read(AVI->fdes,data,12) != 12 ) - ERR_EXIT(AVI_ERR_READ) - - if (strnicmp(data ,"RIFF",4) !=0 || strnicmp(data+8,"AVI ",4) !=0 ) - ERR_EXIT(AVI_ERR_NO_AVI) - - /* Go through the AVI file and extract the header list, - the start position of the 'movi' list and an optionally - present idx1 tag */ - - hdrl_data = 0; - - while(1) - { - if( avi_read(AVI->fdes,data,8) != 8 ) break; /* We assume it's EOF */ - newpos = gf_ftell(AVI->fdes); - if(oldpos==newpos) { - /* This is a broken AVI stream... */ - return -1; - } - oldpos=newpos; - - n = str2ulong((unsigned char *)data+4); - n = PAD_EVEN(n); - - if(strnicmp(data,"LIST",4) == 0) - { - if( avi_read(AVI->fdes,data,4) != 4 ) ERR_EXIT(AVI_ERR_READ) - n -= 4; - if(strnicmp(data,"hdrl",4) == 0) - { - hdrl_len = (u32) n; - hdrl_data = (unsigned char *) gf_malloc((u32)n); - if(hdrl_data==0) ERR_EXIT(AVI_ERR_NO_MEM); - - // offset of header - - header_offset = gf_ftell(AVI->fdes); - - if( avi_read(AVI->fdes,(char *)hdrl_data, (u32) n) != n ) ERR_EXIT(AVI_ERR_READ) - } - else if(strnicmp(data,"movi",4) == 0) - { - AVI->movi_start = gf_ftell(AVI->fdes); - if (gf_fseek(AVI->fdes,n,SEEK_CUR)==(u64)-1) break; - } - else if (gf_fseek(AVI->fdes,n,SEEK_CUR)==(u64)-1) break; - } - else if(strnicmp(data,"idx1",4) == 0) - { - /* n must be a multiple of 16, but the reading does not - break if this is not the case */ - - AVI->n_idx = AVI->max_idx = (u32) (n/16); - AVI->idx = (unsigned char((*)[16]) ) gf_malloc((u32)n); - if(AVI->idx==0) ERR_EXIT(AVI_ERR_NO_MEM) - if(avi_read(AVI->fdes, (char *) AVI->idx, (u32) n) != n ) { - gf_free( AVI->idx); - AVI->idx=NULL; - AVI->n_idx = 0; - } - } - else - gf_fseek(AVI->fdes,n,SEEK_CUR); - } - - if(!hdrl_data ) ERR_EXIT(AVI_ERR_NO_HDRL) - if(!AVI->movi_start) ERR_EXIT(AVI_ERR_NO_MOVI) - - /* Interpret the header list */ - - for(i=0; icompressor,hdrl_data+i+4,4); - AVI->compressor[4] = 0; - - // ThOe - AVI->v_codech_off = header_offset + i+4; - - scale = str2ulong(hdrl_data+i+20); - rate = str2ulong(hdrl_data+i+24); - if(scale!=0) AVI->fps = (double)rate/(double)scale; - AVI->video_frames = str2ulong(hdrl_data+i+32); - AVI->video_strn = num_stream; - AVI->max_len = 0; - vids_strh_seen = 1; - lasttag = 1; /* vids */ - memcpy(&AVI->video_stream_header, hdrl_data + i, - sizeof(alAVISTREAMHEADER)); - } - else if (strnicmp ((char *)hdrl_data+i,"auds",4) ==0 && ! auds_strh_seen) - { - - //inc audio tracks - AVI->aptr=AVI->anum; - ++AVI->anum; - - if(AVI->anum > AVI_MAX_TRACKS) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] error - only %d audio tracks supported\n", AVI_MAX_TRACKS)); - return(-1); - } - - AVI->track[AVI->aptr].audio_bytes = str2ulong(hdrl_data+i+32)*avi_sampsize(AVI, 0); - AVI->track[AVI->aptr].audio_strn = num_stream; - - // if samplesize==0 -> vbr - AVI->track[AVI->aptr].a_vbr = !str2ulong(hdrl_data+i+44); - - AVI->track[AVI->aptr].padrate = str2ulong(hdrl_data+i+24); - memcpy(&AVI->stream_headers[AVI->aptr], hdrl_data + i, - sizeof(alAVISTREAMHEADER)); - - // auds_strh_seen = 1; - lasttag = 2; /* auds */ - - // ThOe - AVI->track[AVI->aptr].a_codech_off = header_offset + i; - - } - else if (strnicmp ((char*)hdrl_data+i,"iavs",4) ==0 && ! auds_strh_seen) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] AVILIB: error - DV AVI Type 1 no supported\n")); - return (-1); - } - else - lasttag = 0; - num_stream++; - } - else if(strnicmp((char*)hdrl_data+i,"dmlh",4) == 0) { - AVI->total_frames = str2ulong(hdrl_data+i+8); -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] real number of frames %d\n", AVI->total_frames)); -#endif - i += 8; - } - else if(strnicmp((char *)hdrl_data+i,"strf",4)==0) - { - i += 8; - if(lasttag == 1) - { - alBITMAPINFOHEADER bih; - - memcpy(&bih, hdrl_data + i, sizeof(alBITMAPINFOHEADER)); - AVI->bitmap_info_header = (alBITMAPINFOHEADER *) - gf_malloc(str2ulong((unsigned char *)&bih.bi_size)); - if (AVI->bitmap_info_header != NULL) - memcpy(AVI->bitmap_info_header, hdrl_data + i, - str2ulong((unsigned char *)&bih.bi_size)); - - AVI->width = str2ulong(hdrl_data+i+4); - AVI->height = str2ulong(hdrl_data+i+8); - vids_strf_seen = 1; - //ThOe - AVI->v_codecf_off = header_offset + i+16; - - memcpy(AVI->compressor2, hdrl_data+i+16, 4); - AVI->compressor2[4] = 0; - - if (n>40) { - AVI->extradata_size = (u32) (n - 40); - AVI->extradata = gf_malloc(sizeof(u8)* AVI->extradata_size); - memcpy(AVI->extradata, hdrl_data + i + 40, AVI->extradata_size); - } - - } - else if(lasttag == 2) - { - alWAVEFORMATEX *wfe; - char *nwfe; - int wfes; - - if ((u32) (hdrl_len - i) < sizeof(alWAVEFORMATEX)) - wfes = hdrl_len - i; - else - wfes = sizeof(alWAVEFORMATEX); - wfe = (alWAVEFORMATEX *)gf_malloc(sizeof(alWAVEFORMATEX)); - if (wfe != NULL) { - memset(wfe, 0, sizeof(alWAVEFORMATEX)); - memcpy(wfe, hdrl_data + i, wfes); - if (str2ushort((unsigned char *)&wfe->cb_size) != 0) { - nwfe = (char *) - gf_realloc(wfe, sizeof(alWAVEFORMATEX) + - str2ushort((unsigned char *)&wfe->cb_size)); - if (nwfe != 0) { - s64 lpos = gf_ftell(AVI->fdes); - gf_fseek(AVI->fdes, header_offset + i + sizeof(alWAVEFORMATEX), - SEEK_SET); - wfe = (alWAVEFORMATEX *)nwfe; - nwfe = &nwfe[sizeof(alWAVEFORMATEX)]; - avi_read(AVI->fdes, nwfe, - str2ushort((unsigned char *)&wfe->cb_size)); - gf_fseek(AVI->fdes, lpos, SEEK_SET); - } - } - AVI->wave_format_ex[AVI->aptr] = wfe; - } - - AVI->track[AVI->aptr].a_fmt = str2ushort(hdrl_data+i ); - - //ThOe - AVI->track[AVI->aptr].a_codecf_off = header_offset + i; - - AVI->track[AVI->aptr].a_chans = str2ushort(hdrl_data+i+2); - AVI->track[AVI->aptr].a_rate = str2ulong (hdrl_data+i+4); - //ThOe: read mp3bitrate - AVI->track[AVI->aptr].mp3rate = 8*str2ulong(hdrl_data+i+8)/1000; - //:ThOe - AVI->track[AVI->aptr].a_bits = str2ushort(hdrl_data+i+14); - // auds_strf_seen = 1; - } - } - else if(strnicmp((char*)hdrl_data+i,"indx",4) == 0) { - char *a; - - if(lasttag == 1) // V I D E O - { - - a = (char*)hdrl_data+i; - - AVI->video_superindex = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk)); - memset(AVI->video_superindex, 0, sizeof (avisuperindex_chunk)); - memcpy (AVI->video_superindex->fcc, a, 4); - a += 4; - AVI->video_superindex->dwSize = str2ulong((unsigned char *)a); - a += 4; - AVI->video_superindex->wLongsPerEntry = str2ushort((unsigned char *)a); - a += 2; - AVI->video_superindex->bIndexSubType = *a; - a += 1; - AVI->video_superindex->bIndexType = *a; - a += 1; - AVI->video_superindex->nEntriesInUse = str2ulong((unsigned char *)a); - a += 4; - memcpy (AVI->video_superindex->dwChunkId, a, 4); - a += 4; - - // 3 * reserved - a += 4; - a += 4; - a += 4; - - if (AVI->video_superindex->bIndexSubType != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n")); - } - - AVI->video_superindex->aIndex = (avisuperindex_entry*) - gf_malloc (AVI->video_superindex->wLongsPerEntry * AVI->video_superindex->nEntriesInUse * sizeof (u32)); - - // position of ix## chunks - for (j=0; jvideo_superindex->nEntriesInUse; ++j) { - AVI->video_superindex->aIndex[j].qwOffset = str2ullong ((unsigned char*)a); - a += 8; - AVI->video_superindex->aIndex[j].dwSize = str2ulong ((unsigned char*)a); - a += 4; - AVI->video_superindex->aIndex[j].dwDuration = str2ulong ((unsigned char*)a); - a += 4; - -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] 0x%llx 0x%lx %lu\n", j, - (unsigned int long)AVI->video_superindex->aIndex[j].qwOffset, - (unsigned long)AVI->video_superindex->aIndex[j].dwSize, - (unsigned long)AVI->video_superindex->aIndex[j].dwDuration)); -#endif - } - - -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] FOURCC \"%c%c%c%c\"\n", AVI->video_superindex->fcc[0], AVI->video_superindex->fcc[1], - AVI->video_superindex->fcc[2], AVI->video_superindex->fcc[3])); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] LEN \"%ld\"\n", (long)AVI->video_superindex->dwSize)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] wLongsPerEntry \"%d\"\n", AVI->video_superindex->wLongsPerEntry)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] bIndexSubType \"%d\"\n", AVI->video_superindex->bIndexSubType)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] bIndexType \"%d\"\n", AVI->video_superindex->bIndexType)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] nEntriesInUse \"%ld\"\n", (long)AVI->video_superindex->nEntriesInUse)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] dwChunkId \"%c%c%c%c\"\n", AVI->video_superindex->dwChunkId[0], AVI->video_superindex->dwChunkId[1], - AVI->video_superindex->dwChunkId[2], AVI->video_superindex->dwChunkId[3])); -#endif - - AVI->is_opendml = 1; - - } - else if(lasttag == 2) // A U D I O - { - - a = (char*) hdrl_data+i; - - AVI->track[AVI->aptr].audio_superindex = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk)); - memcpy (AVI->track[AVI->aptr].audio_superindex->fcc, a, 4); - a += 4; - AVI->track[AVI->aptr].audio_superindex->dwSize = str2ulong((unsigned char*)a); - a += 4; - AVI->track[AVI->aptr].audio_superindex->wLongsPerEntry = str2ushort((unsigned char*)a); - a += 2; - AVI->track[AVI->aptr].audio_superindex->bIndexSubType = *a; - a += 1; - AVI->track[AVI->aptr].audio_superindex->bIndexType = *a; - a += 1; - AVI->track[AVI->aptr].audio_superindex->nEntriesInUse = str2ulong((unsigned char*)a); - a += 4; - memcpy (AVI->track[AVI->aptr].audio_superindex->dwChunkId, a, 4); - a += 4; - - // 3 * reserved - a += 4; - a += 4; - a += 4; - - if (AVI->track[AVI->aptr].audio_superindex->bIndexSubType != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n")); - } - - AVI->track[AVI->aptr].audio_superindex->aIndex = (avisuperindex_entry*) - gf_malloc (AVI->track[AVI->aptr].audio_superindex->wLongsPerEntry * - AVI->track[AVI->aptr].audio_superindex->nEntriesInUse * sizeof (u32)); - - // position of ix## chunks - for (j=0; jtrack[AVI->aptr].audio_superindex->nEntriesInUse; ++j) { - AVI->track[AVI->aptr].audio_superindex->aIndex[j].qwOffset = str2ullong ((unsigned char*)a); - a += 8; - AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwSize = str2ulong ((unsigned char*)a); - a += 4; - AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwDuration = str2ulong ((unsigned char*)a); - a += 4; - -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] 0x%llx 0x%lx %lu\n", j, - (unsigned int long)AVI->track[AVI->aptr].audio_superindex->aIndex[j].qwOffset, - (unsigned long)AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwSize, - (unsigned long)AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwDuration)); -#endif - } - - AVI->track[AVI->aptr].audio_superindex->stdindex = NULL; - -#ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] FOURCC \"%.4s\"\n", AVI->track[AVI->aptr].audio_superindex->fcc)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] LEN \"%ld\"\n", (long)AVI->track[AVI->aptr].audio_superindex->dwSize)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] wLongsPerEntry \"%d\"\n", AVI->track[AVI->aptr].audio_superindex->wLongsPerEntry)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] bIndexSubType \"%d\"\n", AVI->track[AVI->aptr].audio_superindex->bIndexSubType)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] bIndexType \"%d\"\n", AVI->track[AVI->aptr].audio_superindex->bIndexType)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] nEntriesInUse \"%ld\"\n", (long)AVI->track[AVI->aptr].audio_superindex->nEntriesInUse)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] dwChunkId \"%.4s\"\n", AVI->track[AVI->aptr].audio_superindex->dwChunkId[0])); -#endif - - } - i += 8; - } - else if((strnicmp((char*)hdrl_data+i,"JUNK",4) == 0) || - (strnicmp((char*)hdrl_data+i,"strn",4) == 0) || - (strnicmp((char*)hdrl_data+i,"vprp",4) == 0)) { - i += 8; - // do not reset lasttag - } else - { - i += 8; - lasttag = 0; - } - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] adding %ld bytes\n", (int int)n)); - - i += (u32) n; - } - - gf_free(hdrl_data); - - if(!vids_strh_seen || !vids_strf_seen) ERR_EXIT(AVI_ERR_NO_VIDS) - - AVI->video_tag[0] = AVI->video_strn/10 + '0'; - AVI->video_tag[1] = AVI->video_strn%10 + '0'; - AVI->video_tag[2] = 'd'; - AVI->video_tag[3] = 'b'; - - /* Audio tag is set to "99wb" if no audio present */ - if(!AVI->track[0].a_chans) AVI->track[0].audio_strn = 99; - - { - int tk=0; - for(j=0; janum+1; ++j) { - if (j == AVI->video_strn) continue; - AVI->track[tk].audio_tag[0] = j/10 + '0'; - AVI->track[tk].audio_tag[1] = j%10 + '0'; - AVI->track[tk].audio_tag[2] = 'w'; - AVI->track[tk].audio_tag[3] = 'b'; - ++tk; - } - } - - gf_fseek(AVI->fdes,AVI->movi_start,SEEK_SET); - - if(!getIndex) return(0); - - /* if the file has an idx1, check if this is relative - to the start of the file or to the start of the movi list */ - - idx_type = 0; - - if(AVI->idx) - { - s64 pos, len; - - /* Search the first videoframe in the idx1 and look where - it is in the file */ - - for(i=0; in_idx; i++) - if( strnicmp((char *)AVI->idx[i],(char *)AVI->video_tag,3)==0 ) break; - if(i>=AVI->n_idx) ERR_EXIT(AVI_ERR_NO_VIDS) - - pos = str2ulong(AVI->idx[i]+ 8); - len = str2ulong(AVI->idx[i]+12); - - gf_fseek(AVI->fdes,pos,SEEK_SET); - if(avi_read(AVI->fdes,data,8)!=8) ERR_EXIT(AVI_ERR_READ) - if( strnicmp(data,(char *)AVI->idx[i],4)==0 && str2ulong((unsigned char *)data+4)==len ) - { - idx_type = 1; /* Index from start of file */ - } - else - { - gf_fseek(AVI->fdes,pos+AVI->movi_start-4,SEEK_SET); - if(avi_read(AVI->fdes,data,8)!=8) ERR_EXIT(AVI_ERR_READ) - if( strnicmp(data,(char *)AVI->idx[i],4)==0 && str2ulong((unsigned char *)data+4)==len ) - { - idx_type = 2; /* Index from start of movi list */ - } - } - /* idx_type remains 0 if neither of the two tests above succeeds */ - } - - - if(idx_type == 0 && !AVI->is_opendml && !AVI->total_frames) - { - /* we must search through the file to get the index */ - - gf_fseek(AVI->fdes, AVI->movi_start, SEEK_SET); - - AVI->n_idx = 0; - - while(1) - { - if( avi_read(AVI->fdes,data,8) != 8 ) break; - n = str2ulong((unsigned char *)data+4); - - /* The movi list may contain sub-lists, ignore them */ - - if(strnicmp(data,"LIST",4)==0) - { - gf_fseek(AVI->fdes,4,SEEK_CUR); - continue; - } - - /* Check if we got a tag ##db, ##dc or ##wb */ - - if( ( (data[2]=='d' || data[2]=='D') && - (data[3]=='b' || data[3]=='B' || data[3]=='c' || data[3]=='C') ) - || ( (data[2]=='w' || data[2]=='W') && - (data[3]=='b' || data[3]=='B') ) ) - { - u64 __pos = gf_ftell(AVI->fdes) - 8; - avi_add_index_entry(AVI,(unsigned char *)data,0,__pos,n); - } - - gf_fseek(AVI->fdes,PAD_EVEN(n),SEEK_CUR); - } - idx_type = 1; - } - - // ************************ - // OPENDML - // ************************ - - // read extended index chunks - if (AVI->is_opendml) { - u64 offset = 0; - hdrl_len = 4+4+2+1+1+4+4+8+4; - char *en, *chunk_start; - int k = 0; - u32 audtr = 0; - u32 nrEntries = 0; - - AVI->video_index = NULL; - - nvi = 0; - for(audtr=0; audtranum; ++audtr) { - nai[audtr] = 0; - tot[audtr] = 0; - } - - // ************************ - // VIDEO - // ************************ - - for (j=0; jvideo_superindex->nEntriesInUse; j++) { - - // read from file - chunk_start = en = (char*) gf_malloc ((u32) (AVI->video_superindex->aIndex[j].dwSize+hdrl_len) ); - - if (gf_fseek(AVI->fdes, AVI->video_superindex->aIndex[j].qwOffset, SEEK_SET) == (u64)-1) { - gf_free(chunk_start); - continue; - } - - if (avi_read(AVI->fdes, en, (u32) (AVI->video_superindex->aIndex[j].dwSize+hdrl_len) ) <= 0) { - gf_free(chunk_start); - continue; - } - - nrEntries = str2ulong((unsigned char*)en + 12); -#ifdef DEBUG_ODML - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d:0] Video nrEntries %ld\n", j, nrEntries)); -#endif - offset = str2ullong((unsigned char*)en + 20); - - // skip header - en += hdrl_len; - nvi += nrEntries; - AVI->video_index = (video_index_entry *) gf_realloc (AVI->video_index, nvi * sizeof (video_index_entry)); - if (!AVI->video_index) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] out of mem (size = %ld)\n", nvi * sizeof (video_index_entry))); - exit(1); - } - - while (k < nvi) { - - AVI->video_index[k].pos = offset + str2ulong((unsigned char*)en); - en += 4; - AVI->video_index[k].len = str2ulong_len((unsigned char*)en); - AVI->video_index[k].key = str2ulong_key((unsigned char*)en); - en += 4; - - // completely empty chunk - if (AVI->video_index[k].pos-offset == 0 && AVI->video_index[k].len == 0) { - k--; - nvi--; - } - -#ifdef DEBUG_ODML - /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] POS 0x%llX len=%d key=%s offset (%llx) (%ld)\n", k, - AVI->video_index[k].pos, - (int)AVI->video_index[k].len, - AVI->video_index[k].key?"yes":"no ", offset, - AVI->video_superindex->aIndex[j].dwSize)); - */ -#endif - - k++; - } - - gf_free(chunk_start); - } - - AVI->video_frames = nvi; - // this should deal with broken 'rec ' odml files. - if (AVI->video_frames == 0) { - AVI->is_opendml=0; - goto multiple_riff; - } - - // ************************ - // AUDIO - // ************************ - - for(audtr=0; audtranum; ++audtr) { - - k = 0; - if (!AVI->track[audtr].audio_superindex) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] (%s) cannot read audio index for track %d\n", __FILE__, audtr)); - continue; - } - for (j=0; jtrack[audtr].audio_superindex->nEntriesInUse; j++) { - - // read from file - chunk_start = en = (char*)gf_malloc ((u32) (AVI->track[audtr].audio_superindex->aIndex[j].dwSize+hdrl_len)); - - if (gf_fseek(AVI->fdes, AVI->track[audtr].audio_superindex->aIndex[j].qwOffset, SEEK_SET) == (u64)-1) { - gf_free(chunk_start); - continue; - } - - if (avi_read(AVI->fdes, en, (u32) (AVI->track[audtr].audio_superindex->aIndex[j].dwSize+hdrl_len)) <= 0) { - gf_free(chunk_start); - continue; - } - - nrEntries = str2ulong((unsigned char*)en + 12); - //if (nrEntries > 50) nrEntries = 2; // XXX -#ifdef DEBUG_ODML - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d:%d] Audio nrEntries %ld\n", j, audtr, nrEntries)); -#endif - offset = str2ullong((unsigned char*)en + 20); - - // skip header - en += hdrl_len; - nai[audtr] += nrEntries; - AVI->track[audtr].audio_index = (audio_index_entry *) gf_realloc (AVI->track[audtr].audio_index, nai[audtr] * sizeof (audio_index_entry)); - - while (k < nai[audtr]) { - - AVI->track[audtr].audio_index[k].pos = offset + str2ulong((unsigned char*)en); - en += 4; - AVI->track[audtr].audio_index[k].len = str2ulong_len((unsigned char*)en); - en += 4; - AVI->track[audtr].audio_index[k].tot = tot[audtr]; - tot[audtr] += AVI->track[audtr].audio_index[k].len; - -#ifdef DEBUG_ODML - /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d:%d] POS 0x%llX len=%d offset (%llx) (%ld)\n", k, audtr, - AVI->track[audtr].audio_index[k].pos, - (int)AVI->track[audtr].audio_index[k].len, - offset, AVI->track[audtr].audio_superindex->aIndex[j].dwSize)); - */ -#endif - - ++k; - } - - gf_free(chunk_start); - } - - AVI->track[audtr].audio_chunks = nai[audtr]; - AVI->track[audtr].audio_bytes = tot[audtr]; - } - } // is opendml - - else if (AVI->total_frames && !AVI->is_opendml && idx_type==0) { - - // ********************* - // MULTIPLE RIFF CHUNKS (and no index) - // ********************* - -multiple_riff: - - gf_fseek(AVI->fdes, AVI->movi_start, SEEK_SET); - - AVI->n_idx = 0; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] Reconstructing index...")); - - // Number of frames; only one audio track supported - nvi = AVI->video_frames = AVI->total_frames; - nai[0] = AVI->track[0].audio_chunks = AVI->total_frames; - for(j=1; janum; ++j) AVI->track[j].audio_chunks = 0; - - AVI->video_index = (video_index_entry *) gf_malloc(nvi*sizeof(video_index_entry)); - - if(AVI->video_index==0) ERR_EXIT(AVI_ERR_NO_MEM); - - for(j=0; janum; ++j) { - if(AVI->track[j].audio_chunks) { - AVI->track[j].audio_index = (audio_index_entry *) gf_malloc((nai[j]+1)*sizeof(audio_index_entry)); - memset(AVI->track[j].audio_index, 0, (nai[j]+1)*(sizeof(audio_index_entry))); - if(AVI->track[j].audio_index==0) ERR_EXIT(AVI_ERR_NO_MEM); - } - } - - nvi = 0; - for(j=0; janum; ++j) { - nai[j] = 0; - tot[j] = 0; - } - - aud_chunks = AVI->total_frames; - - while(1) - { - if (nvi >= AVI->total_frames) break; - - if( avi_read(AVI->fdes,data,8) != 8 ) break; - n = str2ulong((unsigned char *)data+4); - - - j=0; - - if (aud_chunks - nai[j] -1 <= 0) { - aud_chunks += AVI->total_frames; - AVI->track[j].audio_index = (audio_index_entry *) - gf_realloc( AVI->track[j].audio_index, (aud_chunks+1)*sizeof(audio_index_entry)); - if (!AVI->track[j].audio_index) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Internal error in avilib -- no mem\n")); - AVI_errno = AVI_ERR_NO_MEM; - return -1; - } - } - - /* Check if we got a tag ##db, ##dc or ##wb */ - - // VIDEO - if( - (data[0]=='0' || data[1]=='0') && - (data[2]=='d' || data[2]=='D') && - (data[3]=='b' || data[3]=='B' || data[3]=='c' || data[3]=='C') ) { - - AVI->video_index[nvi].key = 0x0; - AVI->video_index[nvi].pos = gf_ftell(AVI->fdes); - AVI->video_index[nvi].len = (u32) n; - - /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] Frame %ld pos %"LLD" len %"LLD" key %ld\n", - nvi, AVI->video_index[nvi].pos, AVI->video_index[nvi].len, (long)AVI->video_index[nvi].key)); - */ - nvi++; - gf_fseek(AVI->fdes,PAD_EVEN(n),SEEK_CUR); - } - - //AUDIO - else if( - (data[0]=='0' || data[1]=='1') && - (data[2]=='w' || data[2]=='W') && - (data[3]=='b' || data[3]=='B') ) { - - - AVI->track[j].audio_index[nai[j]].pos = gf_ftell(AVI->fdes); - AVI->track[j].audio_index[nai[j]].len = (u32) n; - AVI->track[j].audio_index[nai[j]].tot = tot[j]; - tot[j] += AVI->track[j].audio_index[nai[j]].len; - nai[j]++; - - gf_fseek(AVI->fdes,PAD_EVEN(n),SEEK_CUR); - } - else { - gf_fseek(AVI->fdes,-4,SEEK_CUR); - } - - } - if (nvi < AVI->total_frames) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[avilib] Uh? Some frames seems missing (%ld/%d)\n", - nvi, AVI->total_frames)); - } - - - AVI->video_frames = nvi; - AVI->track[0].audio_chunks = nai[0]; - - for(j=0; janum; ++j) AVI->track[j].audio_bytes = tot[j]; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] done. nvi=%ld nai=%ld tot=%ld\n", nvi, nai[0], tot[0])); - - } // total_frames but no indx chunk (xawtv does this) - - else - - { - // ****************** - // NO OPENDML - // ****************** - - /* Now generate the video index and audio index arrays */ - - nvi = 0; - for(j=0; janum; ++j) nai[j] = 0; - - for(i=0; in_idx; i++) { - - if(strnicmp((char *)AVI->idx[i],AVI->video_tag,3) == 0) nvi++; - - for(j=0; janum; ++j) if(strnicmp((char *)AVI->idx[i], AVI->track[j].audio_tag,4) == 0) nai[j]++; - } - - AVI->video_frames = nvi; - for(j=0; janum; ++j) AVI->track[j].audio_chunks = nai[j]; - - - if(AVI->video_frames==0) ERR_EXIT(AVI_ERR_NO_VIDS); - AVI->video_index = (video_index_entry *) gf_malloc(nvi*sizeof(video_index_entry)); - if(AVI->video_index==0) ERR_EXIT(AVI_ERR_NO_MEM); - - for(j=0; janum; ++j) { - if(AVI->track[j].audio_chunks) { - AVI->track[j].audio_index = (audio_index_entry *) gf_malloc((nai[j]+1)*sizeof(audio_index_entry)); - memset(AVI->track[j].audio_index, 0, (nai[j]+1)*(sizeof(audio_index_entry))); - if(AVI->track[j].audio_index==0) ERR_EXIT(AVI_ERR_NO_MEM); - } - } - - nvi = 0; - for(j=0; janum; ++j) { - nai[j] = 0; - tot[j] = 0; - } - - ioff = idx_type == 1 ? 8 : (u32)AVI->movi_start+4; - - for(i=0; in_idx; i++) { - - //video - if(strnicmp((char *)AVI->idx[i],AVI->video_tag,3) == 0) { - AVI->video_index[nvi].key = str2ulong(AVI->idx[i]+ 4); - AVI->video_index[nvi].pos = str2ulong(AVI->idx[i]+ 8)+ioff; - AVI->video_index[nvi].len = str2ulong(AVI->idx[i]+12); - nvi++; - } - - //audio - for(j=0; janum; ++j) { - - if(strnicmp((char *)AVI->idx[i],AVI->track[j].audio_tag,4) == 0) { - AVI->track[j].audio_index[nai[j]].pos = str2ulong(AVI->idx[i]+ 8)+ioff; - AVI->track[j].audio_index[nai[j]].len = str2ulong(AVI->idx[i]+12); - AVI->track[j].audio_index[nai[j]].tot = tot[j]; - tot[j] += AVI->track[j].audio_index[nai[j]].len; - nai[j]++; - } - } - } - - - for(j=0; janum; ++j) AVI->track[j].audio_bytes = tot[j]; - - } // is no opendml - - /* Reposition the file */ - - gf_fseek(AVI->fdes,AVI->movi_start,SEEK_SET); - AVI->video_pos = 0; - - return(0); -} - -int AVI_video_frames(avi_t *AVI) -{ - return AVI->video_frames; -} -int AVI_video_width(avi_t *AVI) -{ - return AVI->width; -} -int AVI_video_height(avi_t *AVI) -{ - return AVI->height; -} -double AVI_frame_rate(avi_t *AVI) -{ - return AVI->fps; -} -char* AVI_video_compressor(avi_t *AVI) -{ - return AVI->compressor2; -} - -#if 0 -int AVI_max_video_chunk(avi_t *AVI) -{ - return AVI->max_len; -} -#endif - -int AVI_audio_tracks(avi_t *AVI) -{ - return(AVI->anum); -} - -int AVI_audio_channels(avi_t *AVI) -{ - return AVI->track[AVI->aptr].a_chans; -} - -int AVI_audio_mp3rate(avi_t *AVI) -{ - return AVI->track[AVI->aptr].mp3rate; -} - -#if 0 //unused -int AVI_audio_padrate(avi_t *AVI) -{ - return AVI->track[AVI->aptr].padrate; -} -#endif - -int AVI_audio_bits(avi_t *AVI) -{ - return AVI->track[AVI->aptr].a_bits; -} - -int AVI_audio_format(avi_t *AVI) -{ - return AVI->track[AVI->aptr].a_fmt; -} - -int AVI_audio_rate(avi_t *AVI) -{ - return AVI->track[AVI->aptr].a_rate; -} - - -int AVI_frame_size(avi_t *AVI, int frame) -{ - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->video_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - if(frame < 0 || frame >= AVI->video_frames) return 0; - return (u32) (AVI->video_index[frame].len); -} - -int AVI_audio_size(avi_t *AVI, int frame) -{ - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->track[AVI->aptr].audio_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - if(frame < 0 || frame >= AVI->track[AVI->aptr].audio_chunks) return -1; - return (u32) (AVI->track[AVI->aptr].audio_index[frame].len); -} - -u64 AVI_get_video_position(avi_t *AVI, int frame) -{ - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return (u64) -1; - } - if(!AVI->video_index) { - AVI_errno = AVI_ERR_NO_IDX; - return (u64) -1; - } - - if(frame < 0 || frame >= AVI->video_frames) return 0; - return(AVI->video_index[frame].pos); -} - - -int AVI_seek_start(avi_t *AVI) -{ - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - - gf_fseek(AVI->fdes,AVI->movi_start,SEEK_SET); - AVI->video_pos = 0; - return 0; -} - -int AVI_set_video_position(avi_t *AVI, int frame) -{ - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->video_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - if (frame < 0 ) frame = 0; - AVI->video_pos = frame; - return 0; -} - -#if 0 //unused -int AVI_set_audio_bitrate(avi_t *AVI, int bitrate) -{ - if(AVI->mode==AVI_MODE_READ) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - - AVI->track[AVI->aptr].mp3rate = bitrate; - return 0; -} -#endif - -int AVI_read_frame(avi_t *AVI, u8 *vidbuf, int *keyframe) -{ - int n; - - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->video_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - if(AVI->video_pos < 0 || AVI->video_pos >= AVI->video_frames) return -1; - n = (u32) AVI->video_index[AVI->video_pos].len; - - *keyframe = (AVI->video_index[AVI->video_pos].key==0x10) ? 1:0; - - if (vidbuf == NULL) { - AVI->video_pos++; - return n; - } - - gf_fseek(AVI->fdes, AVI->video_index[AVI->video_pos].pos, SEEK_SET); - - if (avi_read(AVI->fdes,vidbuf,n) != (u32) n) - { - AVI_errno = AVI_ERR_READ; - return -1; - } - - AVI->video_pos++; - - return n; -} - -#if 0 //unused -int AVI_get_audio_position_index(avi_t *AVI) -{ - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->track[AVI->aptr].audio_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - return (AVI->track[AVI->aptr].audio_posc); -} - -int AVI_set_audio_position_index(avi_t *AVI, int indexpos) -{ - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->track[AVI->aptr].audio_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - if(indexpos > AVI->track[AVI->aptr].audio_chunks) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - AVI->track[AVI->aptr].audio_posc = indexpos; - AVI->track[AVI->aptr].audio_posb = 0; - - return 0; -} -#endif - - -int AVI_set_audio_position(avi_t *AVI, int byte) -{ - int n0, n1; - - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->track[AVI->aptr].audio_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - if(byte < 0) byte = 0; - - /* Binary search in the audio chunks */ - - n0 = 0; - n1 = AVI->track[AVI->aptr].audio_chunks; - - while(n0track[AVI->aptr].audio_index[n].tot>(u32) byte) - n1 = n; - else - n0 = n; - } - - AVI->track[AVI->aptr].audio_posc = n0; - AVI->track[AVI->aptr].audio_posb = (u32) (byte - AVI->track[AVI->aptr].audio_index[n0].tot); - - return 0; -} - - -int AVI_read_audio(avi_t *AVI, u8 *audbuf, int bytes, int *continuous) -{ - int nr, todo; - s64 pos; - - if(AVI->mode==AVI_MODE_WRITE) { - AVI_errno = AVI_ERR_NOT_PERM; - return -1; - } - if(!AVI->track[AVI->aptr].audio_index) { - AVI_errno = AVI_ERR_NO_IDX; - return -1; - } - - nr = 0; /* total number of bytes read */ - - if (bytes==0) { - AVI->track[AVI->aptr].audio_posc++; - AVI->track[AVI->aptr].audio_posb = 0; - } - - *continuous = 1; - while(bytes>0) - { - s64 ret; - int left = (int) (AVI->track[AVI->aptr].audio_index[AVI->track[AVI->aptr].audio_posc].len - AVI->track[AVI->aptr].audio_posb); - if(left==0) - { - if(AVI->track[AVI->aptr].audio_posc>=AVI->track[AVI->aptr].audio_chunks-1) return nr; - AVI->track[AVI->aptr].audio_posc++; - AVI->track[AVI->aptr].audio_posb = 0; - *continuous = 0; - continue; - } - if(bytestrack[AVI->aptr].audio_index[AVI->track[AVI->aptr].audio_posc].pos + AVI->track[AVI->aptr].audio_posb; - gf_fseek(AVI->fdes, pos, SEEK_SET); - if ( (ret = avi_read(AVI->fdes,audbuf+nr,todo)) != todo) - { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] XXX pos = %"LLD", ret = %"LLD", todo = %ld\n", pos, ret, todo)); - AVI_errno = AVI_ERR_READ; - return -1; - } - bytes -= todo; - nr += todo; - AVI->track[AVI->aptr].audio_posb += todo; - } - - return nr; -} - - -#if 0 //unused -/* AVI_read_data: Special routine for reading the next audio or video chunk - without having an index of the file. */ - -int AVI_read_data(avi_t *AVI, char *vidbuf, int max_vidbuf, - char *audbuf, int max_audbuf, - int *len) -{ - - /* - * Return codes: - * - * 1 = video data read - * 2 = audio data read - * 0 = reached EOF - * -1 = video buffer too small - * -2 = audio buffer too small - */ - - s64 n; - char data[8]; - - if(AVI->mode==AVI_MODE_WRITE) return 0; - - while(1) - { - /* Read tag and length */ - - if( avi_read(AVI->fdes,data,8) != 8 ) return 0; - - /* if we got a list tag, ignore it */ - - if(strnicmp(data,"LIST",4) == 0) - { - gf_fseek(AVI->fdes,4,SEEK_CUR); - continue; - } - - n = PAD_EVEN(str2ulong((unsigned char *)data+4)); - - if(strnicmp(data,AVI->video_tag,3) == 0) - { - *len = (u32) n; - AVI->video_pos++; - if(n>max_vidbuf) - { - gf_fseek(AVI->fdes,n,SEEK_CUR); - return -1; - } - if(avi_read(AVI->fdes,vidbuf, (u32) n) != n ) return 0; - return 1; - } - else if(strnicmp(data,AVI->track[AVI->aptr].audio_tag,4) == 0) - { - *len = (u32) n; - if(n>max_audbuf) - { - gf_fseek(AVI->fdes,n,SEEK_CUR); - return -2; - } - if(avi_read(AVI->fdes,audbuf, (u32) n) != n ) return 0; - return 2; - break; - } - else if(gf_fseek(AVI->fdes,n,SEEK_CUR) == (u64) -1) return 0; - } -} - -u64 AVI_max_size(void) -{ - return((u64) AVI_MAX_LEN); -} -#endif - - -#endif /*GPAC_DISABLE_AVILIB*/ diff --git a/src/thirdparty/gpacmp4/base_encoding.c b/src/thirdparty/gpacmp4/base_encoding.c deleted file mode 100644 index 5fab8bbce..000000000 --- a/src/thirdparty/gpacmp4/base_encoding.c +++ /dev/null @@ -1,451 +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 / common tools sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include - -#ifndef GPAC_DISABLE_CORE_TOOLS - -static const char base_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -GF_EXPORT -u32 gf_base64_encode(const u8 *_in, u32 inSize, u8 *_out, u32 outSize) -{ - s32 padding; - u32 i = 0, j = 0; - unsigned char *in = (unsigned char *)_in; - unsigned char *out = (unsigned char *)_out; - - if (outSize < (inSize * 4 / 3)) return 0; - - while (i < inSize) { - padding = 3 - (inSize - i); - if (padding == 2) { - out[j] = base_64[in[i]>>2]; - out[j+1] = base_64[(in[i] & 0x03) << 4]; - out[j+2] = '='; - out[j+3] = '='; - } else if (padding == 1) { - out[j] = base_64[in[i]>>2]; - out[j+1] = base_64[((in[i] & 0x03) << 4) | ((in[i+1] & 0xf0) >> 4)]; - out[j+2] = base_64[(in[i+1] & 0x0f) << 2]; - out[j+3] = '='; - } else { - out[j] = base_64[in[i]>>2]; - out[j+1] = base_64[((in[i] & 0x03) << 4) | ((in[i+1] & 0xf0) >> 4)]; - out[j+2] = base_64[((in[i+1] & 0x0f) << 2) | ((in[i+2] & 0xc0) >> 6)]; - out[j+3] = base_64[in[i+2] & 0x3f]; - } - i += 3; - j += 4; - } - return j; -} - -static const unsigned char index_64[128] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff -}; - -#define char64(c) ((c > 127) ? (char) 0xff : index_64[(c)]) - -/*denoise input*/ -u32 load_block(char *in, u32 size, u32 pos, char *out) -{ - u32 i, len; - u8 c; - len = i = 0; - while ((len<4) && ((pos+i)='A') && (c<='Z')) - || ((c>='a') && (c<='z')) - || ((c>='0') && (c<='9')) - || (c=='=') || (c=='+') || (c=='/') - ) { - out[len] = c; - len++; - } - i++; - } - while (len<4) { - out[len] = (char) 0xFF; - len++; - } - return pos+i; -} - -GF_EXPORT -u32 gf_base64_decode(u8 *in_buf, u32 inSize, u8 *out, u32 outSize) -{ - u32 i = 0, j = 0, padding; - unsigned char c[4], in[4]; - - if (outSize < (inSize * 3 / 4)) return 0; - - while ((i + 3) < inSize) { - padding = 0; - i = load_block(in_buf, inSize, i, (char*)in); - c[0] = char64(in[0]); - padding += (c[0] == 0xff); - c[1] = char64(in[1]); - padding += (c[1] == 0xff); - c[2] = char64(in[2]); - padding += (c[2] == 0xff); - c[3] = char64(in[3]); - padding += (c[3] == 0xff); - if (padding == 2) { - out[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4); - out[j] = (c[1] & 0x0f) << 4; - } else if (padding == 1) { - out[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4); - out[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2); - out[j] = (c[2] & 0x03) << 6; - } else { - out[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4); - out[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2); - out[j++] = ((c[2] & 0x03) << 6) | (c[3] & 0x3f); - } - //i += 4; - } - return j; -} - -static const char base_16[] = "0123456789abcdef"; - -GF_EXPORT -u32 gf_base16_encode(u8 *_in, u32 inSize, u8 *_out, u32 outSize) -{ - u32 i = 0; - unsigned char *in = (unsigned char *)_in; - unsigned char *out = (unsigned char *)_out; - - if (outSize < (inSize * 2)+1) return 0; - - for (i=0; i> 4)]; - out[2*i+1] = base_16[(in[i] & 0x0f)]; - } - out[(inSize * 2)] = 0; - - return inSize * 2; -} - -#define char16(nb) (((nb) < 97) ? ((nb)-48) : ((nb)-87)) - -GF_EXPORT -u32 gf_base16_decode(u8 *in, u32 inSize, u8 *out, u32 outSize) -{ - u32 j=0; - u32 c[2] = {0,0}; - - if (outSize < (inSize / 2)) return 0; - if ((inSize % 2) != 0) return 0; - - for (j=0; j - -#define ZLIB_COMPRESS_SAFE 4 - -GF_EXPORT -GF_Err gf_gz_compress_payload_ex(u8 **data, u32 data_len, u32 *max_size, u8 data_offset, Bool skip_if_larger, u8 **out_comp_data) -{ - z_stream stream; - int err; - char *dest = (char *)gf_malloc(sizeof(char)*data_len*ZLIB_COMPRESS_SAFE); - stream.next_in = (Bytef*)(*data) + data_offset; - stream.avail_in = (uInt)data_len - data_offset; - stream.next_out = ( Bytef*)dest; - stream.avail_out = (uInt)data_len*ZLIB_COMPRESS_SAFE; - stream.zalloc = (alloc_func)NULL; - stream.zfree = (free_func)NULL; - stream.opaque = (voidpf)NULL; - - err = deflateInit2(&stream, 9, Z_DEFLATED, 16+MAX_WBITS, 8, Z_DEFAULT_STRATEGY); - - if (err != Z_OK) { - gf_free(dest); - return GF_IO_ERR; - } - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - gf_free(dest); - return GF_IO_ERR; - } - if (data_len-data_offset < stream.total_out) { - if (skip_if_larger) { - gf_free(dest); - deflateEnd(&stream); - *max_size = (u32) stream.total_out; - return GF_OK; - } - GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[GZ] compressed data (%d) larger than input (%d)\n", (u32) stream.total_out, (u32) data_len )); - } - - if (out_comp_data) { - data = out_comp_data; - } - - if (*max_size < stream.total_out) { - *max_size = data_len*ZLIB_COMPRESS_SAFE; - *data = (char*)gf_realloc(*data, *max_size * sizeof(char)); - } - - memcpy((*data) , dest, sizeof(char)*stream.total_out); - *max_size = (u32) stream.total_out; - gf_free(dest); - - deflateEnd(&stream); - return GF_OK; -} - -GF_EXPORT -GF_Err gf_gz_compress_payload(u8 **data, u32 data_len, u32 *max_size) -{ - return gf_gz_compress_payload_ex(data, data_len, max_size, 0, GF_FALSE, NULL); -} - -GF_EXPORT -GF_Err gf_gz_decompress_payload(u8 *data, u32 data_len, u8 **uncompressed_data, u32 *out_size) -{ - z_stream d_stream; - GF_Err e = GF_OK; - int err; - Bool owns_buffer=GF_TRUE; - u32 size = 4096; - - if (! *uncompressed_data) { - *uncompressed_data = (char*)gf_malloc(sizeof(char)*4096); - if (!*uncompressed_data) return GF_OUT_OF_MEM; - } else { - owns_buffer = GF_FALSE; - size = *out_size; - } - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - d_stream.next_in = (Bytef*)data; - d_stream.avail_in = data_len; - d_stream.next_out = (Bytef*) *uncompressed_data; - d_stream.avail_out = size; - - err = inflateInit2(&d_stream, 16+MAX_WBITS); - - if (err == Z_OK) { - while (d_stream.total_in < data_len) { - err = inflate(&d_stream, Z_NO_FLUSH); - if (err < Z_OK) { - e = GF_NON_COMPLIANT_BITSTREAM; - break; - } - if (err==Z_STREAM_END) break; - - size *= 2; - *uncompressed_data = (char*)gf_realloc(*uncompressed_data, sizeof(char)*size); - if (!*uncompressed_data) return GF_OUT_OF_MEM; - d_stream.avail_out = (u32) (size - d_stream.total_out); - d_stream.next_out = (Bytef*) ( *uncompressed_data + d_stream.total_out); - } - *out_size = (u32) d_stream.total_out; - inflateEnd(&d_stream); - return e; - } - if (e!=GF_OK) { - if (owns_buffer) { - gf_free(*uncompressed_data); - *uncompressed_data = NULL; - } - } - return e; -} -#else -GF_EXPORT -GF_Err gf_gz_decompress_payload(u8 *data, u32 data_len, u8 **uncompressed_data, u32 *out_size) -{ - *out_size = 0; - return GF_NOT_SUPPORTED; -} -GF_EXPORT -GF_Err gf_gz_compress_payload(u8 **data, u32 data_len, u32 *max_size) -{ - *max_size = 0; - return GF_NOT_SUPPORTED; -} -GF_Err gf_gz_compress_payload_ex(u8 **data, u32 data_len, u32 *max_size, u8 data_offset, Bool skip_if_larger, u8 **out_comp_data) -{ - *max_size = 0; - return GF_NOT_SUPPORTED; -} -#endif /*GPAC_DISABLE_ZLIB*/ - - -#ifdef GPAC_HAS_LZMA - -#include - -#define LZMA_COMPRESS_SAFE 2 - -GF_EXPORT -GF_Err gf_lz_compress_payload(u8 **data, u32 data_len, u32 *max_size) -{ - u32 block_size, comp_size; - lzma_options_lzma opt_lzma2; - lzma_stream strm = LZMA_STREAM_INIT; - - lzma_lzma_preset(&opt_lzma2, LZMA_PRESET_DEFAULT); - lzma_filter filters[] = { - { .id = LZMA_FILTER_X86, .options = NULL }, - { .id = LZMA_FILTER_LZMA2, .options = &opt_lzma2 }, - { .id = LZMA_VLI_UNKNOWN, .options = NULL }, - }; - lzma_ret ret = lzma_stream_encoder(&strm, filters, LZMA_CHECK_NONE); - if (ret != LZMA_OK) return GF_IO_ERR; - - block_size = data_len*LZMA_COMPRESS_SAFE; - if (block_size < 64) block_size = 64; - char *dest = (char *)gf_malloc(sizeof(char)*block_size); - - - strm.next_in = (const uint8_t *) (*data); - strm.avail_in = data_len; - strm.next_out = (uint8_t *) dest; - strm.avail_out = block_size; - - ret = lzma_code(&strm, LZMA_FINISH); - if ((ret != LZMA_OK) && (ret != LZMA_STREAM_END)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[LZMA] compressed data failure, code %d\n", ret )); - return GF_IO_ERR; - } - comp_size = block_size - strm.avail_out; - - if (data_len < comp_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[LZMA] compressed data (%d) larger than input (%d)\n", (u32) comp_size, (u32) data_len )); - } - - if (*max_size < comp_size) { - *max_size = block_size; - *data = (char*)gf_realloc(*data, block_size * sizeof(char)); - } - - memcpy((*data) , dest, sizeof(char) * comp_size); - *max_size = (u32) comp_size; - gf_free(dest); - - lzma_end(&strm); - return GF_OK; -} - -GF_EXPORT -GF_Err gf_lz_decompress_payload(u8 *data, u32 data_len, u8 **uncompressed_data, u32 *out_size) -{ - lzma_stream strm = LZMA_STREAM_INIT; - lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, 0); - if (ret != LZMA_OK) return GF_IO_ERR; - - Bool owns_buffer=GF_TRUE; - u32 block_size = 4096; - u32 done = 0; - u32 alloc_size = 0; - u8 block[4096]; - u8 *dst_buffer = NULL; - - if (*uncompressed_data) { - owns_buffer = GF_FALSE; - dst_buffer = (u8 *) *uncompressed_data; - alloc_size = *out_size; - } else { - *out_size = 0; - } - - strm.next_in = (const uint8_t *) data; - strm.avail_in = data_len; - strm.next_out = (uint8_t *) block; - strm.avail_out = block_size; - - while (1) { - ret = lzma_code(&strm, LZMA_FINISH); - - if ((strm.avail_out == 0) || (ret == LZMA_STREAM_END)) { - u32 uncomp_size = block_size - strm.avail_out; - - if (done + uncomp_size > alloc_size) { - alloc_size = done + uncomp_size; - dst_buffer = gf_realloc(dst_buffer, alloc_size); - *out_size = alloc_size; - } - memcpy(dst_buffer + done, block, uncomp_size); - done += uncomp_size; - - strm.next_out = (uint8_t *) block; - strm.avail_out = block_size; - } - if (ret == LZMA_STREAM_END) break; - if (ret != LZMA_OK) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[LZMA] error decompressing data: %d\n", ret )); - if (owns_buffer) gf_free(dst_buffer); - return GF_IO_ERR; - } - } - - *uncompressed_data = dst_buffer; - *out_size = done; - return GF_OK; -} -#else -GF_EXPORT -GF_Err gf_lz_decompress_payload(u8 *data, u32 data_len, u8 **uncompressed_data, u32 *out_size) -{ - *out_size = 0; - return GF_NOT_SUPPORTED; -} -GF_EXPORT -GF_Err gf_lz_compress_payload(u8 **data, u32 data_len, u32 *max_size) -{ - *max_size = 0; - return GF_NOT_SUPPORTED; -} -#endif /*GPAC_HAS_LZMA*/ - -#endif /* GPAC_DISABLE_CORE_TOOLS*/ diff --git a/src/thirdparty/gpacmp4/bitstream.c b/src/thirdparty/gpacmp4/bitstream.c deleted file mode 100644 index 1b9e641e3..000000000 --- a/src/thirdparty/gpacmp4/bitstream.c +++ /dev/null @@ -1,1654 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2020 - * All rights reserved - * - * This file is part of GPAC / common tools sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include - -/*the default size for new streams allocation...*/ -#define BS_MEM_BLOCK_ALLOC_SIZE 512 - -/*private types*/ -enum -{ - GF_BITSTREAM_FILE_READ = GF_BITSTREAM_WRITE_DYN + 1, - GF_BITSTREAM_FILE_WRITE, -}; - -struct __tag_bitstream -{ - /*original stream data*/ - FILE *stream; - - /*or original data*/ - char *original; - /*the size of our buffer in bytes*/ - u64 size; - /*current position in BYTES*/ - u64 position; - /*the byte readen/written*/ - u32 current; - /*the number of bits in the current byte*/ - u32 nbBits; - /*the bitstream mode*/ - u32 bsmode; - - void (*EndOfStream)(void *par); - void *par; - - - char *cache_write; - u32 cache_write_size, buffer_written; - - Bool remove_emul_prevention_byte; - u32 nb_zeros; - - GF_Err (*on_block_out)(void *cbk, u8 *data, u32 block_size); - void *usr_data; - u64 bytes_out; - u32 prevent_dispatch; - - u64 cookie; - - u8 *cache_read; - u32 cache_read_size, cache_read_pos, cache_read_alloc; - -}; - -GF_Err gf_bs_reassign_buffer(GF_BitStream *bs, const u8 *buffer, u64 BufferSize) -{ - if (!bs) return GF_BAD_PARAM; - if (bs->bsmode == GF_BITSTREAM_READ) { - bs->original = (char*)buffer; - bs->size = BufferSize; - bs->position = 0; - bs->current = 0; - bs->nbBits = 8; - bs->current = 0; - bs->nb_zeros = 0; - return GF_OK; - } - if (bs->bsmode==GF_BITSTREAM_WRITE) { - if (!buffer || !BufferSize) return GF_BAD_PARAM; - bs->original = (char*)buffer; - bs->size = BufferSize; - bs->position = 0; - bs->current = 0; - bs->nbBits = 0; - bs->current = 0; - return GF_OK; - } - if (bs->bsmode!=GF_BITSTREAM_WRITE_DYN) return GF_BAD_PARAM; - if (bs->original) return GF_BAD_PARAM; - - bs->position = 0; - bs->current = 0; - bs->nbBits = 0; - bs->current = 0; - bs->size = BufferSize ? BufferSize : BS_MEM_BLOCK_ALLOC_SIZE; - if (buffer) { - bs->original = (char *) buffer; - } else { - bs->original = (char *) gf_malloc(sizeof(char) * ((u32) bs->size)); - if (! bs->original) { - return GF_OUT_OF_MEM; - } - } - return GF_OK; -} - -GF_EXPORT -GF_BitStream *gf_bs_new(const u8 *buffer, u64 BufferSize, u32 mode) -{ - GF_BitStream *tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream)); - if (!tmp) return NULL; - memset(tmp, 0, sizeof(GF_BitStream)); - - tmp->original = (char*)buffer; - tmp->size = BufferSize; - - tmp->bsmode = mode; - - switch (tmp->bsmode) { - case GF_BITSTREAM_READ: - tmp->nbBits = 8; - tmp->current = 0; - break; - case GF_BITSTREAM_WRITE: - case GF_BITSTREAM_WRITE_DYN: - tmp->nbBits = 0; - if (! buffer) { - /*if BufferSize is specified, use it. This is typically used when AvgSize of - some buffers is known, but some exceed it.*/ - if (BufferSize) { - tmp->size = BufferSize; - } else { - tmp->size = BS_MEM_BLOCK_ALLOC_SIZE; - } - tmp->original = (char *) gf_malloc(sizeof(char) * ((u32) tmp->size)); - if (! tmp->original) { - gf_free(tmp); - return NULL; - } - tmp->bsmode = GF_BITSTREAM_WRITE_DYN; - } else { - tmp->original = (char*)buffer; - tmp->size = BufferSize; - } - break; - default: - /*the stream constructor is not the same...*/ - gf_free(tmp); - return NULL; - } - return tmp; -} - -GF_EXPORT -GF_BitStream *gf_bs_from_file(FILE *f, u32 mode) -{ - GF_BitStream *tmp; - if (!f) return NULL; - - tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream)); - if (!tmp) return NULL; - memset(tmp, 0, sizeof(GF_BitStream)); - /*switch to internal mode*/ - mode = (mode==GF_BITSTREAM_READ) ? GF_BITSTREAM_FILE_READ : GF_BITSTREAM_FILE_WRITE; - tmp->bsmode = mode; - tmp->current = 0; - tmp->nbBits = (mode == GF_BITSTREAM_FILE_READ) ? 8 : 0; - tmp->original = NULL; - tmp->position = 0; - tmp->stream = f; - - /*get the size of this file (for read streams)*/ - tmp->position = gf_ftell(f); - tmp->size = gf_fsize(f); - gf_fseek(f, tmp->position, SEEK_SET); - - - if (mode==GF_BITSTREAM_FILE_READ) { - tmp->cache_read_alloc = gf_opts_get_int("core", "bs-cache-size"); - if (tmp->cache_read_alloc) { - tmp->cache_read_pos = tmp->cache_read_size = tmp->cache_read_alloc; - tmp->cache_read = gf_malloc(tmp->cache_read_alloc); - if (!tmp->cache_read) { - gf_free(tmp); - return NULL; - } - } - } - if (mode == GF_BITSTREAM_FILE_WRITE) { - tmp->cache_write_size = gf_opts_get_int("core", "bs-cache-size"); - if (tmp->cache_write_size) { - tmp->cache_write = (char*)gf_malloc(tmp->cache_write_size); - if (!tmp->cache_write) { - gf_free(tmp); - return NULL; - } - tmp->buffer_written = 0; - } - } - - return tmp; -} - - -GF_BitStream *gf_bs_new_cbk_buffer(GF_Err (*on_block_out)(void *cbk, u8 *data, u32 block_size), void *usr_data, u8 *buffer, u32 buffer_size) -{ - GF_BitStream *tmp; - - if (!on_block_out) return NULL; - - tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream)); - if (!tmp) return NULL; - memset(tmp, 0, sizeof(GF_BitStream)); - - if (buffer && buffer_size) { - tmp->size = buffer_size; - tmp->original = buffer; - } else { - tmp->size = buffer_size ? buffer_size : 10*BS_MEM_BLOCK_ALLOC_SIZE; - tmp->original = (char *) gf_malloc(sizeof(char) * ((u32) tmp->size)); - if (! tmp->original) { - gf_free(tmp); - return NULL; - } - } - tmp->bsmode = GF_BITSTREAM_WRITE_DYN; - tmp->on_block_out = on_block_out; - tmp->usr_data = usr_data; - - return tmp; -} - -GF_BitStream *gf_bs_new_cbk(GF_Err (*on_block_out)(void *cbk, u8 *data, u32 block_size), void *usr_data, u32 block_size) -{ - return gf_bs_new_cbk_buffer(on_block_out, usr_data, NULL, block_size); - -} -void gf_bs_prevent_dispatch(GF_BitStream *bs, Bool prevent_dispatch) -{ - if (!bs) return; - if (prevent_dispatch) { - bs->prevent_dispatch ++; - return; - } - if (!bs->prevent_dispatch) return; - bs->prevent_dispatch --; - - if (bs->on_block_out && !bs->prevent_dispatch) { - assert(bs->position >= bs->bytes_out); - if (bs->position > bs->bytes_out) { - bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out)); - bs->bytes_out = bs->position; - } - } -} - -static void bs_flush_write_cache(GF_BitStream *bs) -{ - if (bs->buffer_written) { - u32 nb_write; - nb_write = (u32) gf_fwrite(bs->cache_write, bs->buffer_written, bs->stream); - - //check we didn't rewind the bitstream - if (bs->size == bs->position) - bs->size += nb_write; - bs->position += nb_write; - bs->buffer_written = 0; - } -} - - - -GF_EXPORT -void gf_bs_del(GF_BitStream *bs) -{ - if (!bs) return; - if (bs->on_block_out && bs->position>bs->bytes_out) { - bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out) ); - } - /*if we are in dynamic mode (alloc done by the bitstream), free the buffer if still present*/ - if ((bs->bsmode == GF_BITSTREAM_WRITE_DYN) && bs->original) gf_free(bs->original); - if (bs->cache_write) { - bs_flush_write_cache(bs); - gf_free(bs->cache_write); - } - if (bs->cache_read) - gf_free(bs->cache_read); - gf_free(bs); -} - -GF_EXPORT -void gf_bs_enable_emulation_byte_removal(GF_BitStream *bs, Bool do_remove) -{ - if (bs) { - bs->remove_emul_prevention_byte = do_remove; - bs->nb_zeros = 0; - } -} - -/*returns 1 if aligned wrt current mode, 0 otherwise*/ -Bool gf_bs_is_align(GF_BitStream *bs) -{ - switch (bs->bsmode) { - case GF_BITSTREAM_READ: - case GF_BITSTREAM_FILE_READ: - return ( (8 == bs->nbBits) ? GF_TRUE : GF_FALSE); - default: - return !bs->nbBits; - } -} - -static GFINLINE u8 gf_bs_load_byte(GF_BitStream *bs, Bool *is_eos) -{ - u8 res; - if (bs->cache_read) { - if (bs->cache_read_pos == bs->cache_read_size) { - bs->cache_read_size = (u32) gf_fread(bs->cache_read, bs->cache_read_alloc, bs->stream); - bs->cache_read_pos = 0; - if (!bs->cache_read_size) { - *is_eos = GF_TRUE; - return 0; - } - } - res = bs->cache_read[bs->cache_read_pos]; - bs->cache_read_pos++; - } else { - res = gf_fgetc(bs->stream); - } - return res; -} - -/*fetch a new byte in the bitstream switch between packets*/ -static u8 BS_ReadByte(GF_BitStream *bs) -{ - Bool is_eos; - if (bs->bsmode == GF_BITSTREAM_READ) { - u8 res; - if (bs->position >= bs->size) { - if (bs->EndOfStream) bs->EndOfStream(bs->par); - return 0; - } - res = bs->original[bs->position++]; - - if (bs->remove_emul_prevention_byte) { - if ((bs->nb_zeros==2) && (res==0x03) && (bs->positionsize) && (bs->original[bs->position]<0x04)) { - bs->nb_zeros = 0; - res = bs->original[bs->position++]; - } - if (!res) bs->nb_zeros++; - else bs->nb_zeros = 0; - } - return res; - } - if (bs->cache_write) - bs_flush_write_cache(bs); - - is_eos = gf_feof(bs->stream); - - /*we are in FILE mode, test for end of file*/ - if (!is_eos || bs->cache_read) { - u8 res; - Bool loc_eos=GF_FALSE; - assert(bs->position<=bs->size); - bs->position++; - - res = gf_bs_load_byte(bs, &loc_eos); - if (loc_eos) goto bs_eof; - - if (bs->remove_emul_prevention_byte) { - if ((bs->nb_zeros==2) && (res==0x03) && (bs->positionsize)) { - u8 next = gf_bs_load_byte(bs, &loc_eos); - if (next < 0x04) { - bs->nb_zeros = 0; - res = next; - bs->position++; - } else { - gf_bs_seek(bs, bs->position); - } - } - if (!res) bs->nb_zeros++; - else bs->nb_zeros = 0; - } - return res; - } - -bs_eof: - if (bs->EndOfStream) { - bs->EndOfStream(bs->par); - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to overread bitstream\n")); - } - assert(bs->position <= 1+bs->size); - return 0; -} - -#define NO_OPTS - -#ifndef NO_OPTS -static u32 bit_mask[] = {0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1}; -static u32 bits_mask[] = {0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F}; -#endif - -GF_EXPORT -u8 gf_bs_read_bit(GF_BitStream *bs) -{ - if (bs->nbBits == 8) { - bs->current = BS_ReadByte(bs); - bs->nbBits = 0; - } -#ifdef NO_OPTS - { - s32 ret; - bs->current <<= 1; - bs->nbBits++; - ret = (bs->current & 0x100) >> 8; - return (u8) ret; - } -#else - return (u8) (bs->current & bit_mask[bs->nbBits++]) ? 1 : 0; -#endif - -} - -GF_EXPORT -u32 gf_bs_read_int(GF_BitStream *bs, u32 nBits) -{ - u32 ret; - -#ifndef NO_OPTS - if (nBits + bs->nbBits <= 8) { - bs->nbBits += nBits; - ret = (bs->current >> (8 - bs->nbBits) ) & bits_mask[nBits]; - return ret; - } -#endif - ret = 0; - while (nBits-- > 0) { - ret <<= 1; - ret |= gf_bs_read_bit(bs); - } - return ret; -} - -GF_EXPORT -u32 gf_bs_read_u8(GF_BitStream *bs) -{ - assert(bs->nbBits==8); - if (bs->cache_read && (bs->cache_read_pos+1cache_read_size) ) { - u32 ret = bs->cache_read[bs->cache_read_pos]; - bs->cache_read_pos+=1; - bs->position+=1; - return ret; - } - - return (u32) BS_ReadByte(bs); -} - -#if 0 -GF_EXPORT -u32 gf_bs_read_u8_until_delimiter(GF_BitStream *bs, u8 delimiter, u8* out, u32 max_length) { - u32 i = 0; - char token=0; - u64 cur_pos = gf_bs_get_position(bs); - - if (!max_length) out = NULL; - - while(gf_bs_available(bs) && (!max_length || i < max_length)) { - gf_bs_read_data(bs, &token, 1); - if (token == delimiter) goto found; - if (out) out[i] = token; - i++; - } - - /* Delimiter not found */ - gf_bs_seek(bs, cur_pos); - return 0; - -found: - return i; -} -#endif - -GF_EXPORT -u32 gf_bs_read_u16(GF_BitStream *bs) -{ - u32 ret; - assert(bs->nbBits==8); - if (bs->cache_read && (bs->cache_read_pos+2cache_read_size) ) { - ret = bs->cache_read[bs->cache_read_pos]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+1]; - bs->cache_read_pos+=2; - bs->position+=2; - return ret; - } - - ret = BS_ReadByte(bs); - ret<<=8; - ret |= BS_ReadByte(bs); - return ret; -} - - -GF_EXPORT -u32 gf_bs_read_u24(GF_BitStream *bs) -{ - u32 ret; - assert(bs->nbBits==8); - - if (bs->cache_read && (bs->cache_read_pos+3cache_read_size) ) { - ret = bs->cache_read[bs->cache_read_pos]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+1]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+2]; - bs->cache_read_pos+=3; - bs->position+=3; - return ret; - } - - ret = BS_ReadByte(bs); - ret<<=8; - ret |= BS_ReadByte(bs); - ret<<=8; - ret |= BS_ReadByte(bs); - return ret; -} - -GF_EXPORT -u32 gf_bs_read_u32(GF_BitStream *bs) -{ - u32 ret; - assert(bs->nbBits==8); - - if (bs->cache_read && (bs->cache_read_pos+4cache_read_size) ) { - ret = bs->cache_read[bs->cache_read_pos]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+1]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+2]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+3]; - bs->cache_read_pos+=4; - bs->position+=4; - return ret; - } - ret = BS_ReadByte(bs); - ret<<=8; - ret |= BS_ReadByte(bs); - ret<<=8; - ret |= BS_ReadByte(bs); - ret<<=8; - ret |= BS_ReadByte(bs); - return ret; -} - -GF_EXPORT -u64 gf_bs_read_u64(GF_BitStream *bs) -{ - u64 ret; - - if (bs->cache_read && (bs->cache_read_pos+8cache_read_size) ) { - ret = bs->cache_read[bs->cache_read_pos]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+1]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+2]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+3]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+4]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+5]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+6]; - ret<<=8; - ret |= bs->cache_read[bs->cache_read_pos+7]; - bs->cache_read_pos+=8; - bs->position+=8; - return ret; - } - ret = gf_bs_read_u32(bs); - ret<<=32; - ret |= gf_bs_read_u32(bs); - return ret; -} - -GF_EXPORT -u64 gf_bs_read_long_int(GF_BitStream *bs, u32 nBits) -{ - u64 ret = 0; - if (nBits>64) { - gf_bs_read_long_int(bs, nBits-64); - ret = gf_bs_read_long_int(bs, 64); - } else { - while (nBits-- > 0) { - ret <<= 1; - ret |= gf_bs_read_bit(bs); - } - } - return ret; -} - - -GF_EXPORT -Float gf_bs_read_float(GF_BitStream *bs) -{ - char buf [4] = "\0\0\0"; -#ifdef NO_OPTS - s32 i; - for (i = 0; i < 32; i++) - buf[3-i/8] |= gf_bs_read_bit(bs) << (7 - i%8); -#else - buf[3] = gf_bs_read_int(bs, 8); - buf[2] = gf_bs_read_int(bs, 8); - buf[1] = gf_bs_read_int(bs, 8); - buf[0] = gf_bs_read_int(bs, 8); -#endif - return (* (Float *) buf); -} - -GF_EXPORT -Double gf_bs_read_double(GF_BitStream *bs) -{ - char buf [8] = "\0\0\0\0\0\0\0"; - s32 i; - for (i = 0; i < 64; i++) - buf[7-i/8] |= gf_bs_read_bit(bs) << (7 - i%8); - return (* (Double *) buf); -} - -GF_EXPORT -u32 gf_bs_read_data(GF_BitStream *bs, u8 *data, u32 nbBytes) -{ - u64 orig = bs->position; - - if (bs->position+nbBytes > bs->size) return 0; - - if (gf_bs_is_align(bs) ) { - s32 bytes_read, bytes_read_cache; - switch (bs->bsmode) { - case GF_BITSTREAM_READ: - case GF_BITSTREAM_WRITE: - case GF_BITSTREAM_WRITE_DYN: - memcpy(data, bs->original + bs->position, nbBytes); - bs->position += nbBytes; - return nbBytes; - case GF_BITSTREAM_FILE_READ: - case GF_BITSTREAM_FILE_WRITE: - if (bs->cache_write) - bs_flush_write_cache(bs); - - bytes_read = bytes_read_cache = 0; - if (bs->cache_read) { - u32 csize = bs->cache_read_size-bs->cache_read_pos; - if (csize>nbBytes) csize = nbBytes; - memcpy(data, bs->cache_read + bs->cache_read_pos, csize); - bs->cache_read_pos += csize; - nbBytes -= csize; - bytes_read_cache = csize; - } - if (nbBytes) { - bytes_read = (s32) gf_fread(data + bytes_read_cache, nbBytes, bs->stream); - if (bytes_read<0) return bytes_read_cache; - } - bs->position += bytes_read + bytes_read_cache; - return bytes_read + bytes_read_cache; - default: - return 0; - } - } - - while (nbBytes-- > 0) { - *data++ = gf_bs_read_int(bs, 8); - } - return (u32) (bs->position - orig); - -} - - - -static void BS_WriteByte(GF_BitStream *bs, u8 val) -{ - /*we don't allow write on READ buffers*/ - if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_FILE_READ) ) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to write on read bitstream\n")); - return; - } - if (!bs->original && !bs->stream) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to write on unassigned bitstream\n")); - return; - } - /*we are in MEM mode*/ - if ( (bs->bsmode == GF_BITSTREAM_WRITE) || (bs->bsmode == GF_BITSTREAM_WRITE_DYN) ) { - //if callback mode and dispatch is not blocked, dispatch - if (bs->on_block_out && !bs->prevent_dispatch) { - assert(bs->position >= bs->bytes_out); - if (bs->position - bs->bytes_out == bs->size) { - bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out)); - bs->bytes_out = bs->position; - } - if (bs->original) - bs->original[bs->position - bs->bytes_out] = val; - bs->position++; - assert(bs->position >= bs->bytes_out); - return; - } - //otherwise store - if (bs->position - bs->bytes_out == bs->size) { - /*no more space...*/ - if (bs->bsmode != GF_BITSTREAM_WRITE_DYN) return; - /*gf_realloc if enough space...*/ - if (bs->size > 0xFFFFFFFF) return; - bs->size = bs->size ? (bs->size * 2) : BS_MEM_BLOCK_ALLOC_SIZE; - bs->original = (char*)gf_realloc(bs->original, (u32)bs->size); - if (!bs->original) return; - } - if (bs->original) - bs->original[bs->position - bs->bytes_out] = val; - bs->position++; - return; - } - if (bs->cache_write) { - if (bs->buffer_written == bs->cache_write_size) { - bs_flush_write_cache(bs); - } - bs->cache_write[bs->buffer_written] = val; - bs->buffer_written++; - if (bs->buffer_written == bs->cache_write_size) { - bs_flush_write_cache(bs); - } - return; - } - /*we are in FILE mode, no pb for any gf_realloc...*/ - gf_fputc(val, bs->stream); - - /*check we didn't rewind the stream*/ - if (bs->size == bs->position) bs->size++; - bs->position += 1; -} - -static void BS_WriteBit(GF_BitStream *bs, u32 bit) -{ - bs->current <<= 1; - bs->current |= bit; - if (++ bs->nbBits == 8) { - bs->nbBits = 0; - BS_WriteByte(bs, (u8) bs->current); - bs->current = 0; - } -} - -static s32 bs_handle_nbits_overflow(GF_BitStream* bs, s32 nBits, s32 max_shift) -{ - if (nBits > max_shift) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to write %d bits, when max is %d\n", nBits, max_shift)); - } - while (nBits > max_shift) { - gf_bs_write_long_int(bs, 0, max_shift); - nBits -= max_shift; - } - - return nBits; -} - -GF_EXPORT -void gf_bs_write_int(GF_BitStream *bs, s32 _value, s32 nBits) -{ - u32 value, nb_shift; - s32 max_shift = sizeof(s32) * 8; - if (!nBits) return; - nBits = bs_handle_nbits_overflow(bs, nBits, max_shift); - //move to unsigned to avoid sanitizer warnings when we pass a value not codable on the given number of bits - //we do this when setting bit fields to all 1's - value = (u32) _value; - nb_shift = max_shift - nBits; - if (nb_shift) - value <<= nb_shift; - - while (--nBits >= 0) { - //but check value as signed - BS_WriteBit (bs, ((s32)value) < 0); - value <<= 1; - } -} - -GF_EXPORT -void gf_bs_write_long_int(GF_BitStream *bs, s64 _value, s32 nBits) -{ - s32 max_shift = sizeof(s64) * 8; - if (!nBits) return; - nBits = bs_handle_nbits_overflow(bs, nBits, max_shift); - - //cf note in gf_bs_write_int - u64 value = (u64) _value; - value <<= max_shift - nBits; - while (--nBits >= 0) { - BS_WriteBit (bs, ((s64)value) < 0); - value <<= 1; - } -} - -GF_EXPORT -void gf_bs_write_u8(GF_BitStream *bs, u32 value) -{ - assert(!bs->nbBits); - - if (bs->cache_write && (bs->buffer_written+1 < bs->cache_write_size) ) { - bs->cache_write[bs->buffer_written] = (u8) value; - bs->buffer_written += 1; - } else { - BS_WriteByte(bs, (u8) value); - } -} - -GF_EXPORT -void gf_bs_write_u16(GF_BitStream *bs, u32 value) -{ - assert(!bs->nbBits); - if (bs->cache_write && (bs->buffer_written+2 < bs->cache_write_size) ) { - bs->cache_write[bs->buffer_written] = (u8) ((value>>8)&0xff); - bs->cache_write[bs->buffer_written+1] = (u8) ((value)&0xff); - bs->buffer_written += 2; - } else { - BS_WriteByte(bs, (u8) ((value>>8)&0xff)); - BS_WriteByte(bs, (u8) ((value)&0xff)); - } -} - -GF_EXPORT -void gf_bs_write_u24(GF_BitStream *bs, u32 value) -{ - assert(!bs->nbBits); - if (bs->cache_write && (bs->buffer_written+3 < bs->cache_write_size) ) { - bs->cache_write[bs->buffer_written] = (u8) ((value>>16)&0xff); - bs->cache_write[bs->buffer_written+1] = (u8) ((value>>8)&0xff); - bs->cache_write[bs->buffer_written+2] = (u8) ((value)&0xff); - bs->buffer_written += 3; - } else { - BS_WriteByte(bs, (u8) ((value>>16)&0xff)); - BS_WriteByte(bs, (u8) ((value>>8)&0xff)); - BS_WriteByte(bs, (u8) ((value)&0xff)); - } -} - -GF_EXPORT -void gf_bs_write_u32(GF_BitStream *bs, u32 value) -{ - assert(!bs->nbBits); - if (bs->cache_write && (bs->buffer_written+4 < bs->cache_write_size) ) { - bs->cache_write[bs->buffer_written] = (u8) ((value>>24)&0xff); - bs->cache_write[bs->buffer_written+1] = (u8) ((value>>16)&0xff); - bs->cache_write[bs->buffer_written+2] = (u8) ((value>>8)&0xff); - bs->cache_write[bs->buffer_written+3] = (u8) ((value)&0xff); - bs->buffer_written += 4; - } else { - BS_WriteByte(bs, (u8) ((value>>24)&0xff)); - BS_WriteByte(bs, (u8) ((value>>16)&0xff)); - BS_WriteByte(bs, (u8) ((value>>8)&0xff)); - BS_WriteByte(bs, (u8) ((value)&0xff)); - } -} - -GF_EXPORT -void gf_bs_write_u64(GF_BitStream *bs, u64 value) -{ - assert(!bs->nbBits); - gf_bs_write_u32(bs, (u32) ((value>>32)&0xffffffff)); - gf_bs_write_u32(bs, (u32) (value&0xffffffff)); -} - -GF_EXPORT -u32 gf_bs_write_byte(GF_BitStream *bs, u8 byte, u32 repeat_count) -{ - if (!gf_bs_is_align(bs) || bs->cache_write) { - u32 count = 0; - while (countbsmode) { - case GF_BITSTREAM_WRITE: - if (bs->position + repeat_count > bs->size) - return 0; - memset(bs->original + bs->position, byte, repeat_count); - bs->position += repeat_count; - return repeat_count; - case GF_BITSTREAM_WRITE_DYN: - /*need to gf_realloc ...*/ - if (bs->position+repeat_count> bs->size) { - u32 new_size = (u32) (bs->size*2); - if (!new_size) new_size = BS_MEM_BLOCK_ALLOC_SIZE; - - if (bs->size + repeat_count > 0xFFFFFFFF) - return 0; - while (new_size < (u32) ( bs->size + repeat_count)) - new_size *= 2; - bs->original = (char*)gf_realloc(bs->original, sizeof(u32)*new_size); - if (!bs->original) - return 0; - bs->size = new_size; - } - memset(bs->original + bs->position, byte, repeat_count); - bs->position += repeat_count; - return repeat_count; - case GF_BITSTREAM_FILE_READ: - case GF_BITSTREAM_FILE_WRITE: - if (gf_fwrite(&byte, repeat_count, bs->stream) != repeat_count) - return 0; - if (bs->size == bs->position) bs->size += repeat_count; - bs->position += repeat_count; - return repeat_count; - default: - return 0; - } -} - - - -GF_EXPORT -void gf_bs_write_float(GF_BitStream *bs, Float value) -{ - u32 i; - union - { float f; - char sz [4]; - } float_value; - float_value.f = value; - - for (i = 0; i < 32; i++) - BS_WriteBit(bs, (float_value.sz [3 - i / 8] & 1 << (7 - i % 8)) != 0); - -} - -GF_EXPORT -void gf_bs_write_double (GF_BitStream *bs, Double value) -{ - u32 i; - union - { Double d; - char sz [8]; - } double_value; - double_value.d = value; - for (i = 0; i < 64; i++) { - BS_WriteBit(bs, (double_value.sz [7 - i / 8] & 1 << (7 - i % 8)) != 0); - } -} - - -GF_EXPORT -u32 gf_bs_write_data(GF_BitStream *bs, const u8 *data, u32 nbBytes) -{ - /*we need some feedback for this guy...*/ - u64 begin = bs->position; - if (!nbBytes) return 0; - - if (gf_bs_is_align(bs)) { - switch (bs->bsmode) { - case GF_BITSTREAM_WRITE: - if (bs->position+nbBytes > bs->size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to overwrite bitstream by %d bytes\n", bs->position + nbBytes - bs->size)); - return 0; - } - memcpy(bs->original + bs->position, data, nbBytes); - bs->position += nbBytes; - return nbBytes; - case GF_BITSTREAM_WRITE_DYN: - //if callback mode and dispatch not disabled, dispatch bytes - if (bs->on_block_out && !bs->prevent_dispatch) { - assert(bs->position >= bs->bytes_out); - - if (bs->position - bs->bytes_out + nbBytes <= bs->size) { - memcpy(bs->original + bs->position - bs->bytes_out, data, nbBytes); - bs->position += nbBytes; - } else { - if (bs->position > bs->bytes_out) - bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out) ); - if (nbBytes) - bs->on_block_out(bs->usr_data, (char *) data, nbBytes); - - bs->position += nbBytes; - bs->bytes_out = bs->position; - } - assert(bs->position >= bs->bytes_out); - return nbBytes; - } - //otherwise store - /*need to gf_realloc ...*/ - if (bs->position + nbBytes - bs->bytes_out > bs->size) { - u32 new_size = (u32) (bs->size*2); - if (!new_size) new_size = BS_MEM_BLOCK_ALLOC_SIZE; - - if (bs->size + nbBytes > 0xFFFFFFFF) - return 0; - - while (new_size < (u32) ( bs->size + nbBytes)) - new_size *= 2; - bs->original = (char*)gf_realloc(bs->original, sizeof(u32)*new_size); - if (!bs->original) - return 0; - bs->size = new_size; - } - memcpy(bs->original + bs->position - bs->bytes_out, data, nbBytes); - bs->position += nbBytes; - return nbBytes; - case GF_BITSTREAM_FILE_READ: - case GF_BITSTREAM_FILE_WRITE: - if (bs->cache_write) { - //if block fits in our write cache, write it - if (bs->buffer_written + nbBytes < bs->cache_write_size) { - memcpy(bs->cache_write+bs->buffer_written, data, nbBytes); - bs->buffer_written+=nbBytes; - return nbBytes; - } - //otherwise flush cache and use file write - bs_flush_write_cache(bs); - } - - if (gf_fwrite(data, nbBytes, bs->stream) != nbBytes) return 0; - - if (bs->size == bs->position) bs->size += nbBytes; - bs->position += nbBytes; - return nbBytes; - default: - return 0; - } - } - - while (nbBytes) { - gf_bs_write_int(bs, (s32) *data, 8); - data++; - nbBytes--; - } - return (u32) (bs->position - begin); -} - -/*align return the num of bits read in READ mode, 0 in WRITE*/ -GF_EXPORT -u8 gf_bs_align(GF_BitStream *bs) -{ - u8 res = 8 - bs->nbBits; - if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_FILE_READ)) { - if (res > 0) { - gf_bs_read_int(bs, res); - } - return res; - } - if (bs->nbBits > 0) { - gf_bs_write_int (bs, 0, res); - return res; - } - return 0; -} - - -/*size available in the bitstream*/ -GF_EXPORT -u64 gf_bs_available(GF_BitStream *bs) -{ - s64 cur, end; - - /*in WRITE mode only, this should not be called, but return something big in case ...*/ - if ( (bs->bsmode == GF_BITSTREAM_WRITE) - || (bs->bsmode == GF_BITSTREAM_WRITE_DYN) - ) - return (u64) -1; - - /*we are in MEM mode*/ - if (bs->bsmode == GF_BITSTREAM_READ) { - if (bs->size < bs->position) - return 0; - else - return (bs->size - bs->position); - } - /*FILE READ: assume size hasn't changed, otherwise the user shall call gf_bs_get_refreshed_size*/ - if (bs->bsmode==GF_BITSTREAM_FILE_READ) { - if (bs->position>bs->size) return 0; - return (bs->size - bs->position); - } - if (bs->cache_write) - bs_flush_write_cache(bs); - - cur = gf_ftell(bs->stream); - end = gf_fsize(bs->stream); - gf_fseek(bs->stream, cur, SEEK_SET); - - return (u64) (end - cur); -} - -/*call this funct to set the buffer size to the nb of bytes written -Used only in WRITE mode, as we don't know the real size during allocation... -return -1 for bad param or gf_malloc failed -return nbBytes cut*/ -static s32 BS_CutBuffer(GF_BitStream *bs) -{ - s32 nbBytes; - if ( (bs->bsmode != GF_BITSTREAM_WRITE_DYN) && (bs->bsmode != GF_BITSTREAM_WRITE)) return (u32) -1; - /*Align our buffer or we're dead!*/ - gf_bs_align(bs); - - nbBytes = (u32) (bs->size - bs->position); - if (!nbBytes || (nbBytes == 0xFFFFFFFF) || (bs->position >= 0xFFFFFFFF)) return 0; - /* - bs->original = (char*)gf_realloc(bs->original, (u32) bs->position); - if (! bs->original) return (u32) -1; - */ - /*just in case, re-adjust..*/ - bs->size = bs->position; - return nbBytes; -} - -/*For DYN mode, this gets the content out without cutting the buffer to the number of written bytes*/ -GF_EXPORT -void gf_bs_get_content_no_truncate(GF_BitStream *bs, u8 **output, u32 *outSize, u32 *alloc_size) -{ - /*only in WRITE MEM mode*/ - if (bs->bsmode != GF_BITSTREAM_WRITE_DYN) return; - - if (bs->on_block_out && bs->position>bs->bytes_out) { - bs->on_block_out(bs->usr_data, bs->original, (u32) (bs->position - bs->bytes_out) ); - } - - if (!bs->position && !bs->nbBits) { - if (!alloc_size) { - *output = NULL; - gf_free(bs->original); - } else { - *alloc_size = (u32) bs->size; - *output = bs->original; - } - *outSize = 0; - } else { - if (alloc_size) { - /*Align our buffer or we're dead!*/ - gf_bs_align(bs); - *alloc_size = (u32) bs->size; - *outSize = (u32) bs->position; - *output = bs->original; - } else { - s32 copy = BS_CutBuffer(bs); - if (copy < 0) { - *output = NULL; - } else - *output = bs->original; - *outSize = (u32) bs->size; - } - } - bs->original = NULL; - bs->size = 0; - bs->position = 0; -} - -/*For DYN mode, this gets the content out*/ -GF_EXPORT -void gf_bs_get_content(GF_BitStream *bs, u8 **output, u32 *outSize) -{ - gf_bs_get_content_no_truncate(bs, output, outSize, NULL); -} - -/* Skip nbytes. - Align - If READ (MEM or FILE) mode, just read n times 8 bit - If WRITE (MEM or FILE) mode, write n times 0 on 8 bit -*/ -GF_EXPORT -void gf_bs_skip_bytes(GF_BitStream *bs, u64 nbBytes) -{ - if (!bs || !nbBytes) return; - - gf_bs_align(bs); - - /*special case for file skipping...*/ - if ((bs->bsmode == GF_BITSTREAM_FILE_WRITE) || (bs->bsmode == GF_BITSTREAM_FILE_READ)) { - if (bs->cache_write) - bs_flush_write_cache(bs); - - if (bs->cache_read) { - u32 csize = bs->cache_read_size - bs->cache_read_pos; - if (csize>=nbBytes) { - bs->cache_read_pos += (u32) nbBytes; - bs->position += nbBytes; - return; - } - nbBytes -= csize; - bs->position += csize; - bs->cache_read_pos = bs->cache_read_size; - } - //weird msys2 bug resulting in broken seek on some files ?!? -the big is not happening when doing absolute seek -// gf_fseek(bs->stream, nbBytes, SEEK_CUR); - bs->position += nbBytes; - gf_fseek(bs->stream, bs->position, SEEK_SET); - return; - } - - /*special case for reading*/ - if (bs->bsmode == GF_BITSTREAM_READ) { - bs->position += nbBytes; - return; - } - /*for writing we must do it this way, otherwise pb in dynamic buffers*/ - while (nbBytes) { - gf_bs_write_int(bs, 0, 8); - nbBytes--; - } -} - -#ifdef GPAC_ENABLE_BIFS_PMF - -void gf_bs_rewind_bits(GF_BitStream *bs, u64 nbBits) -{ - u64 nbBytes; - if (bs->bsmode != GF_BITSTREAM_READ) return; - - nbBits -= (bs->nbBits); - nbBytes = (nbBits+8)>>3; - nbBits = nbBytes*8 - nbBits; - gf_bs_align(bs); - assert(bs->position >= nbBytes); - bs->position -= nbBytes + 1; - gf_bs_read_int(bs, (u32)nbBits); - return; -} - -#endif - -/*seek from beginning of stream: use internally even when non aligned!*/ -static GF_Err BS_SeekIntern(GF_BitStream *bs, u64 offset) -{ - u32 i; - /*if mem, do it */ - if ((bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_WRITE) || (bs->bsmode == GF_BITSTREAM_WRITE_DYN)) { - if (offset > 0xFFFFFFFF) return GF_IO_ERR; - if (!bs->original) return GF_BAD_PARAM; - /*0 for write, read will be done automatically*/ - if (offset >= bs->size) { - if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_WRITE) ) { - if (offset > bs->size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[BS] Attempt to seek to %d after end of bitstream %d, assuming seek to end\n", offset, bs->size)); - } - bs->position = bs->size; - bs->nbBits = (bs->bsmode == GF_BITSTREAM_READ) ? 8 : 0; - return GF_OK; - } - /*in DYN, gf_realloc ...*/ - bs->original = (char*)gf_realloc(bs->original, (u32) (offset + 1)); - if (!bs->original) - return GF_OUT_OF_MEM; - for (i = 0; i < (u32) (offset + 1 - bs->size); i++) { - bs->original[bs->size + i] = 0; - } - bs->size = offset + 1; - } - bs->current = bs->original[offset]; - bs->position = offset; - bs->nbBits = (bs->bsmode == GF_BITSTREAM_READ) ? 8 : 0; - return GF_OK; - } - - if (bs->cache_write) - bs_flush_write_cache(bs); - - if (bs->cache_read) { - bs->cache_read_pos = bs->cache_read_size; - } - - gf_fseek(bs->stream, offset, SEEK_SET); - - bs->position = offset; - bs->current = 0; - /*setup NbBits so that next acccess to the buffer will trigger read/write*/ - bs->nbBits = (bs->bsmode == GF_BITSTREAM_FILE_READ) ? 8 : 0; - return GF_OK; -} - -/*seek from beginning of stream: align before anything else*/ -GF_EXPORT -GF_Err gf_bs_seek(GF_BitStream *bs, u64 offset) -{ - if (bs->on_block_out) { - GF_Err e; - if (offset < bs->bytes_out) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[BS] Attempt to seek on byte range already forwarded\n")); - return GF_BAD_PARAM; - } - /*warning: we allow offset = bs->size for WRITE buffers*/ - if (offset - bs->bytes_out > bs->size) - return GF_BAD_PARAM; - gf_bs_align(bs); - e = BS_SeekIntern(bs, offset - bs->bytes_out); - bs->position += bs->bytes_out; - return e; - } - if (bs->cache_write) - bs_flush_write_cache(bs); - - /*warning: we allow offset = bs->size for WRITE buffers*/ - if (offset > bs->size) return GF_BAD_PARAM; - - gf_bs_align(bs); - return BS_SeekIntern(bs, offset); -} - -/*peek bits (as int!!) from orig position (ON BYTE BOUNDARIES, from 0) - only for read ...*/ -GF_EXPORT -u32 gf_bs_peek_bits(GF_BitStream *bs, u32 numBits, u64 byte_offset) -{ - u64 curPos; - u32 curBits, ret, current, nb_zeros; - - if ( (bs->bsmode != GF_BITSTREAM_READ) && (bs->bsmode != GF_BITSTREAM_FILE_READ)) return 0; - if (!numBits || (bs->size < bs->position + byte_offset)) return 0; - - /*store our state*/ - curPos = bs->position; - curBits = bs->nbBits; - current = bs->current; - nb_zeros = bs->nb_zeros; - - if (byte_offset) { - if (bs->remove_emul_prevention_byte) { - while (byte_offset) { - gf_bs_read_int(bs, 8); - byte_offset--; - } - } else { - gf_bs_seek(bs, bs->position + byte_offset); - } - } - ret = gf_bs_read_int(bs, numBits); - - /*restore our cache - position*/ - gf_bs_seek(bs, curPos); - /*to avoid re-reading our bits ...*/ - bs->nbBits = curBits; - bs->current = current; - bs->nb_zeros = nb_zeros; - return ret; -} - -GF_EXPORT -u64 gf_bs_get_refreshed_size(GF_BitStream *bs) -{ - s64 offset; - - switch (bs->bsmode) { - case GF_BITSTREAM_READ: - case GF_BITSTREAM_WRITE: - return bs->size; - - default: - if (bs->cache_write) - bs_flush_write_cache(bs); - - if (bs->stream) { - offset = gf_ftell(bs->stream); - bs->size = gf_fsize(bs->stream); - gf_fseek(bs->stream, offset, SEEK_SET); - } - return bs->size; - } -} - -GF_EXPORT -u64 gf_bs_get_size(GF_BitStream *bs) -{ - if (bs->cache_write) - return bs->size + bs->buffer_written; - if (bs->on_block_out) - return bs->position; - return bs->size; -} - -GF_EXPORT -u64 gf_bs_get_position(GF_BitStream *bs) -{ - if (bs->cache_write) - return bs->position + bs->buffer_written; - return bs->position; -} - -GF_EXPORT -u8 gf_bs_bits_available(GF_BitStream *bs) -{ - if (bs->size > bs->position) return 8; - if (bs->nbBits < 8) return (8-bs->nbBits); - return 0; -} - -GF_EXPORT -void gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par) -{ - bs->EndOfStream = EndOfStream; - bs->par = par; -} - - -GF_EXPORT -u64 gf_bs_read_u64_le(GF_BitStream *bs) -{ - u64 ret, v; - ret = gf_bs_read_int(bs, 8); - v = gf_bs_read_int(bs, 8); - v<<=8; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=16; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=24; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=32; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=40; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=48; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=56; - ret |= v; - return ret; -} - -GF_EXPORT -u32 gf_bs_read_u32_le(GF_BitStream *bs) -{ - u32 ret, v; - ret = gf_bs_read_int(bs, 8); - v = gf_bs_read_int(bs, 8); - v<<=8; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=16; - ret |= v; - v = gf_bs_read_int(bs, 8); - v<<=24; - ret |= v; - return ret; -} - -GF_EXPORT -u16 gf_bs_read_u16_le(GF_BitStream *bs) -{ - u32 ret, v; - ret = gf_bs_read_int(bs, 8); - v = gf_bs_read_int(bs, 8); - v<<=8; - ret |= v; - return ret; -} - -GF_EXPORT -void gf_bs_write_u64_le(GF_BitStream *bs, u64 val) -{ - gf_bs_write_int(bs, val & 0xFF, 8); - gf_bs_write_int(bs, (val>>8) & 0xFF, 8); - gf_bs_write_int(bs, (val>>16) & 0xFF, 8); - gf_bs_write_int(bs, (val>>24) & 0xFF, 8); - gf_bs_write_int(bs, (val>>32) & 0xFF, 8); - gf_bs_write_int(bs, (val>>40) & 0xFF, 8); - gf_bs_write_int(bs, (val>>48) & 0xFF, 8); - gf_bs_write_int(bs, (val>>56) & 0xFF, 8); -} - -GF_EXPORT -void gf_bs_write_u32_le(GF_BitStream *bs, u32 val) -{ - gf_bs_write_int(bs, val & 0xFF, 8); - gf_bs_write_int(bs, val>>8, 8); - gf_bs_write_int(bs, val>>16, 8); - gf_bs_write_int(bs, val>>24, 8); -} - -GF_EXPORT -void gf_bs_write_u16_le(GF_BitStream *bs, u32 val) -{ - gf_bs_write_int(bs, val & 0xFF, 8); - gf_bs_write_int(bs, val>>8, 8); -} - -GF_EXPORT -u32 gf_bs_get_bit_offset(GF_BitStream *bs) -{ - if (bs->bsmode==GF_BITSTREAM_READ) return (u32) ( (bs->position - 1) * 8 + bs->nbBits); - return (u32) ( (bs->position ) * 8 + bs->nbBits); -} - -GF_EXPORT -u32 gf_bs_get_bit_position(GF_BitStream *bs) -{ - return bs->nbBits; -} - -GF_EXPORT -u32 gf_bs_read_vluimsbf5(GF_BitStream *bs) -{ - u32 nb_words = 0; - while (gf_bs_read_int(bs, 1)) nb_words++; - nb_words++; - return gf_bs_read_int(bs, 4*nb_words); -} - -GF_EXPORT -void gf_bs_truncate(GF_BitStream *bs) -{ - bs->size = bs->position; -} - - -GF_EXPORT -GF_Err gf_bs_transfer(GF_BitStream *dst, GF_BitStream *src, Bool keep_src) -{ - u8 *data; - u32 data_len, written; - - data = NULL; - data_len = 0; - gf_bs_get_content(src, &data, &data_len); - if (!data || !data_len) - { - if (data) { - if (keep_src) { - src->original = data; - src->size = data_len; - } else { - gf_free(data); - } - return GF_IO_ERR; - } - return GF_OK; - } - written = gf_bs_write_data(dst, data, data_len); - if (keep_src) { - src->original = data; - src->size = data_len; - } else { - gf_free(data); - } - if (writtenstream) return; - if (bs->bsmode != GF_BITSTREAM_FILE_WRITE) return; - - if (bs->cache_write) - bs_flush_write_cache(bs); - - gf_fflush(bs->stream); -} - -#if 0 //unused -/*! -\brief Reassigns FILE object for stream-based bitstreams - * - *Reassigns FILE object for stream-based bitstreams. Automatically sets the stream position to the bitstream position -\param bs the target bitstream -\param stream the new stream to assign - */ -void gf_bs_reassign(GF_BitStream *bs, FILE *stream) -{ - if (!bs) return; - switch (bs->bsmode) { - case GF_BITSTREAM_FILE_WRITE: - case GF_BITSTREAM_FILE_READ: - bs->stream = stream; - if (gf_ftell(stream) != bs->position) - gf_bs_seek(bs, bs->position); - break; - } -} -#endif - -u64 gf_bs_set_cookie(GF_BitStream *bs, u64 cookie) -{ - u64 res = 0; - if (bs) { - res = bs->cookie; - bs->cookie = cookie; - } - return res; -} - -u64 gf_bs_get_cookie(GF_BitStream *bs) -{ - if (!bs) return 0; - return bs->cookie; -} - -GF_EXPORT -GF_Err gf_bs_insert_data(GF_BitStream *bs, u8 *data, u32 size, u64 offset) -{ - u64 cur_r, cur_w, pos; - u32 nb_io; - - if (bs->on_block_out) return GF_BAD_PARAM; - - pos = bs->position; - nb_io = gf_bs_write_data(bs, data, size); - if (nb_io != size) goto exit; - - cur_w = bs->position; - gf_bs_seek(bs, pos); - cur_r = pos; - pos = cur_w; - while (cur_r > offset) { - u8 block[8196]; - u32 move_bytes = 8196; - if (cur_r - offset < move_bytes) - move_bytes = (u32) (cur_r - offset); - - gf_bs_seek(bs, cur_r - move_bytes); - nb_io = gf_bs_read_data(bs, block, move_bytes); - if (nb_io != move_bytes) goto exit; - gf_bs_seek(bs, cur_w - move_bytes); - nb_io = gf_bs_write_data(bs, block, move_bytes); - if (nb_io != move_bytes) goto exit; - cur_r -= move_bytes; - cur_w -= move_bytes; - } - - gf_bs_seek(bs, offset); - nb_io = gf_bs_write_data(bs, data, size); - if (nb_io != size) goto exit; - - gf_bs_seek(bs, pos); - return GF_OK; - -exit: - gf_bs_seek(bs, pos); - return GF_IO_ERR; -} - diff --git a/src/thirdparty/gpacmp4/box_code_3gpp.c b/src/thirdparty/gpacmp4/box_code_3gpp.c deleted file mode 100644 index 9faddb219..000000000 --- a/src/thirdparty/gpacmp4/box_code_3gpp.c +++ /dev/null @@ -1,1208 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2019 - * All rights reserved - * - * This file is part of GPAC / ISO Media File Format sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include - -#ifndef GPAC_DISABLE_ISOM - - - -GF_Box *gppc_box_new() -{ - //default type is amr but overwritten by box constructor - ISOM_DECL_BOX_ALLOC(GF_3GPPConfigBox, GF_ISOM_BOX_TYPE_DAMR); - return (GF_Box *)tmp; -} - -void gppc_box_del(GF_Box *s) -{ - GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err gppc_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - memset(&ptr->cfg, 0, sizeof(GF_3GPConfig)); - - ISOM_DECREASE_SIZE(s, 5) - ptr->cfg.vendor = gf_bs_read_u32(bs); - ptr->cfg.decoder_version = gf_bs_read_u8(bs); - - switch (ptr->type) { - case GF_ISOM_BOX_TYPE_D263: - ISOM_DECREASE_SIZE(s, 2) - ptr->cfg.H263_level = gf_bs_read_u8(bs); - ptr->cfg.H263_profile = gf_bs_read_u8(bs); - break; - case GF_ISOM_BOX_TYPE_DAMR: - ISOM_DECREASE_SIZE(s, 4) - ptr->cfg.AMR_mode_set = gf_bs_read_u16(bs); - ptr->cfg.AMR_mode_change_period = gf_bs_read_u8(bs); - ptr->cfg.frames_per_sample = gf_bs_read_u8(bs); - break; - case GF_ISOM_BOX_TYPE_DEVC: - case GF_ISOM_BOX_TYPE_DQCP: - case GF_ISOM_BOX_TYPE_DSMV: - ISOM_DECREASE_SIZE(s, 1) - ptr->cfg.frames_per_sample = gf_bs_read_u8(bs); - break; - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err gppc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->cfg.vendor); - gf_bs_write_u8(bs, ptr->cfg.decoder_version); - switch (ptr->cfg.type) { - case GF_ISOM_SUBTYPE_3GP_H263: - gf_bs_write_u8(bs, ptr->cfg.H263_level); - gf_bs_write_u8(bs, ptr->cfg.H263_profile); - break; - case GF_ISOM_SUBTYPE_3GP_AMR: - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - gf_bs_write_u16(bs, ptr->cfg.AMR_mode_set); - gf_bs_write_u8(bs, ptr->cfg.AMR_mode_change_period); - gf_bs_write_u8(bs, ptr->cfg.frames_per_sample); - break; - case GF_ISOM_SUBTYPE_3GP_EVRC: - case GF_ISOM_SUBTYPE_3GP_QCELP: - case GF_ISOM_SUBTYPE_3GP_SMV: - gf_bs_write_u8(bs, ptr->cfg.frames_per_sample); - break; - } - return GF_OK; -} - -GF_Err gppc_box_size(GF_Box *s) -{ - GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; - - s->size += 5; - if (!ptr->cfg.type) { - switch (ptr->type) { - case GF_ISOM_BOX_TYPE_D263: - ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_H263; - break; - case GF_ISOM_BOX_TYPE_DAMR: - ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_AMR; - break; - case GF_ISOM_BOX_TYPE_DEVC: - ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_EVRC; - break; - case GF_ISOM_BOX_TYPE_DQCP: - ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_QCELP; - break; - case GF_ISOM_BOX_TYPE_DSMV: - ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_SMV; - break; - } - } - switch (ptr->cfg.type) { - case GF_ISOM_SUBTYPE_3GP_H263: - s->size += 2; - break; - case GF_ISOM_SUBTYPE_3GP_AMR: - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - s->size += 4; - break; - case GF_ISOM_SUBTYPE_3GP_EVRC: - case GF_ISOM_SUBTYPE_3GP_QCELP: - case GF_ISOM_SUBTYPE_3GP_SMV: - s->size += 1; - break; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *ftab_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_FontTableBox, GF_ISOM_BOX_TYPE_FTAB); - return (GF_Box *) tmp; -} -void ftab_box_del(GF_Box *s) -{ - GF_FontTableBox *ptr = (GF_FontTableBox *)s; - if (ptr->fonts) { - u32 i; - for (i=0; ientry_count; i++) - if (ptr->fonts[i].fontName) gf_free(ptr->fonts[i].fontName); - gf_free(ptr->fonts); - } - gf_free(ptr); -} -GF_Err ftab_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_FontTableBox *ptr = (GF_FontTableBox *)s; - ptr->entry_count = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(ptr, 2); - - if (ptr->sizeentry_count*3) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Corrupted ftap box, skipping\n")); - ptr->entry_count = 0; - return GF_OK; - } - ptr->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord)*ptr->entry_count); - if (!ptr->fonts) return GF_OUT_OF_MEM; - - memset(ptr->fonts, 0, sizeof(GF_FontRecord)*ptr->entry_count); - for (i=0; ientry_count; i++) { - u32 len; - ISOM_DECREASE_SIZE(ptr, 3); - ptr->fonts[i].fontID = gf_bs_read_u16(bs); - len = gf_bs_read_u8(bs); - if (len) { - ISOM_DECREASE_SIZE(ptr, len); - ptr->fonts[i].fontName = (char *)gf_malloc(sizeof(char)*(len+1)); - if (!ptr->fonts[i].fontName) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->fonts[i].fontName, len); - ptr->fonts[i].fontName[len] = 0; - } - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err ftab_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_FontTableBox *ptr = (GF_FontTableBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->entry_count); - for (i=0; ientry_count; i++) { - gf_bs_write_u16(bs, ptr->fonts[i].fontID); - if (ptr->fonts[i].fontName) { - u32 len = (u32) strlen(ptr->fonts[i].fontName); - gf_bs_write_u8(bs, len); - gf_bs_write_data(bs, ptr->fonts[i].fontName, len); - } else { - gf_bs_write_u8(bs, 0); - } - } - return GF_OK; -} -GF_Err ftab_box_size(GF_Box *s) -{ - u32 i; - GF_FontTableBox *ptr = (GF_FontTableBox *)s; - - s->size += 2; - for (i=0; ientry_count; i++) { - s->size += 3; - if (ptr->fonts[i].fontName) s->size += strlen(ptr->fonts[i].fontName); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *text_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextSampleEntryBox, GF_ISOM_BOX_TYPE_TEXT); - return (GF_Box *) tmp; -} - -void text_box_del(GF_Box *s) -{ - GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - - if (ptr->textName) - gf_free(ptr->textName); - gf_free(ptr); -} - -GF_Box *tx3g_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_Tx3gSampleEntryBox, GF_ISOM_BOX_TYPE_TX3G); - return (GF_Box *) tmp; -} - -void tx3g_box_del(GF_Box *s) -{ - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - gf_free(s); -} - -u32 gpp_read_rgba(GF_BitStream *bs) -{ - u8 r, g, b, a; - u32 col; - r = gf_bs_read_u8(bs); - g = gf_bs_read_u8(bs); - b = gf_bs_read_u8(bs); - a = gf_bs_read_u8(bs); - col = a; - col<<=8; - col |= r; - col<<=8; - col |= g; - col<<=8; - col |= b; - return col; -} - -#define GPP_BOX_SIZE 8 -void gpp_read_box(GF_BitStream *bs, GF_BoxRecord *rec) -{ - rec->top = gf_bs_read_u16(bs); - rec->left = gf_bs_read_u16(bs); - rec->bottom = gf_bs_read_u16(bs); - rec->right = gf_bs_read_u16(bs); -} - -#define GPP_STYLE_SIZE 12 -void gpp_read_style(GF_BitStream *bs, GF_StyleRecord *rec) -{ - rec->startCharOffset = gf_bs_read_u16(bs); - rec->endCharOffset = gf_bs_read_u16(bs); - rec->fontID = gf_bs_read_u16(bs); - rec->style_flags = gf_bs_read_u8(bs); - rec->font_size = gf_bs_read_u8(bs); - rec->text_color = gpp_read_rgba(bs); -} - -GF_Err tx3g_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_FTAB: - if (ptr->font_table) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->font_table = (GF_FontTableBox *)a; - break; - default: - return GF_OK; - } - return GF_OK; -} - -GF_Err tx3g_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; - - ISOM_DECREASE_SIZE(ptr, (18 + GPP_BOX_SIZE + GPP_STYLE_SIZE) ); - - e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs); - if (e) return e; - - ptr->displayFlags = gf_bs_read_u32(bs); - ptr->horizontal_justification = gf_bs_read_u8(bs); - ptr->vertical_justification = gf_bs_read_u8(bs); - ptr->back_color = gpp_read_rgba(bs); - gpp_read_box(bs, &ptr->default_box); - gpp_read_style(bs, &ptr->default_style); - - - return gf_isom_box_array_read(s, bs, tx3g_on_child_box); -} - -/*this is a quicktime specific box - see apple documentation*/ -GF_Err text_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u16 pSize; - GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; - - ISOM_DECREASE_SIZE(ptr, 51); - - e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs); - if (e) return e; - - ptr->displayFlags = gf_bs_read_u32(bs); /*Display flags*/ - ptr->textJustification = gf_bs_read_u32(bs); /*Text justification*/ - gf_bs_read_data(bs, ptr->background_color, 6); /*Background color*/ - gpp_read_box(bs, &ptr->default_box); /*Default text box*/ - gf_bs_read_data(bs, ptr->reserved1, 8); /*Reserved*/ - ptr->fontNumber = gf_bs_read_u16(bs); /*Font number*/ - ptr->fontFace = gf_bs_read_u16(bs); /*Font face*/ - ptr->reserved2 = gf_bs_read_u8(bs); /*Reserved*/ - ptr->reserved3 = gf_bs_read_u16(bs); /*Reserved*/ - gf_bs_read_data(bs, ptr->foreground_color, 6); /*Foreground color*/ - - /*ffmpeg compatibility with iPod streams: no pascal string*/ - if (!ptr->size) - return GF_OK; - - ISOM_DECREASE_SIZE(ptr, 1); - pSize = gf_bs_read_u8(bs); /*a Pascal string begins with its size: get textName size*/ - - if (ptr->size < pSize) { - u32 b_size = pSize; - size_t i = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: trying to decode anyway.\n")); - ptr->textName = (char*)gf_malloc((size_t)ptr->size + 1 + 1); - if (!ptr->textName) return GF_OUT_OF_MEM; - - do { - char c = (char)b_size; - if (c == '\0') { - break; - } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { - ptr->textName[i] = c; - } else { - gf_free(ptr->textName); - ptr->textName = NULL; - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string and contains non-chars. Abort.\n")); - return GF_ISOM_INVALID_FILE; - } - i++; - if (!ptr->size) - break; - ptr->size--; - b_size = gf_bs_read_u8(bs); - } while (b_size); - - ptr->textName[i] = '\0'; /*Font name*/ - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: \"%s\" detected.\n", ptr->textName)); - return GF_OK; - } - if (pSize) { - ptr->textName = (char*) gf_malloc(pSize+1 * sizeof(char)); - if (!ptr->textName) return GF_OUT_OF_MEM; - - if (gf_bs_read_data(bs, ptr->textName, pSize) != pSize) { - gf_free(ptr->textName); - ptr->textName = NULL; - return GF_ISOM_INVALID_FILE; - } - ptr->textName[pSize] = '\0'; /*Font name*/ - } - ISOM_DECREASE_SIZE(ptr, pSize); - return gf_isom_box_array_read(s, bs, NULL); -} - -void gpp_write_rgba(GF_BitStream *bs, u32 col) -{ - gf_bs_write_u8(bs, (col>>16) & 0xFF); - gf_bs_write_u8(bs, (col>>8) & 0xFF); - gf_bs_write_u8(bs, (col) & 0xFF); - gf_bs_write_u8(bs, (col>>24) & 0xFF); -} - -void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec) -{ - gf_bs_write_u16(bs, rec->top); - gf_bs_write_u16(bs, rec->left); - gf_bs_write_u16(bs, rec->bottom); - gf_bs_write_u16(bs, rec->right); -} - -#define GPP_STYLE_SIZE 12 -void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec) -{ - gf_bs_write_u16(bs, rec->startCharOffset); - gf_bs_write_u16(bs, rec->endCharOffset); - gf_bs_write_u16(bs, rec->fontID); - gf_bs_write_u8(bs, rec->style_flags); - gf_bs_write_u8(bs, rec->font_size); - gpp_write_rgba(bs, rec->text_color); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tx3g_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - gf_bs_write_u32(bs, ptr->displayFlags); - gf_bs_write_u8(bs, ptr->horizontal_justification); - gf_bs_write_u8(bs, ptr->vertical_justification); - gpp_write_rgba(bs, ptr->back_color); - gpp_write_box(bs, &ptr->default_box); - gpp_write_style(bs, &ptr->default_style); - return GF_OK; -} - -GF_Err text_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u16 pSize; - GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - gf_bs_write_u32(bs, ptr->displayFlags); /*Display flags*/ - gf_bs_write_u32(bs, ptr->textJustification); /*Text justification*/ - gf_bs_write_data(bs, ptr->background_color, 6); /*Background color*/ - gpp_write_box(bs, &ptr->default_box); /*Default text box*/ - gf_bs_write_data(bs, ptr->reserved1, 8); /*Reserved*/ - gf_bs_write_u16(bs, ptr->fontNumber); /*Font number*/ - gf_bs_write_u16(bs, ptr->fontFace); /*Font face*/ - gf_bs_write_u8(bs, ptr->reserved2); /*Reserved*/ - gf_bs_write_u16(bs, ptr->reserved3); /*Reserved*/ - gf_bs_write_data(bs, ptr->foreground_color, 6); /*Foreground color*/ - //pSize assignment below is not a mistake - if (ptr->textName && (pSize = (u16) strlen(ptr->textName))) { - gf_bs_write_u8(bs, pSize); /*a Pascal string begins with its size*/ - gf_bs_write_data(bs, ptr->textName, pSize); /*Font name*/ - } else { - gf_bs_write_u8(bs, 0); - } - return GF_OK; -} - -GF_Err tx3g_box_size(GF_Box *s) -{ - /*base + this + box + style*/ - s->size += 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE; - return GF_OK; -} - -GF_Err text_box_size(GF_Box *s) -{ - GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; - - /*base + this + string length*/ - s->size += 51 + 1; - if (ptr->textName) - s->size += strlen(ptr->textName); - return GF_OK; -} - -#endif - -GF_Box *styl_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextStyleBox, GF_ISOM_BOX_TYPE_STYL); - return (GF_Box *) tmp; -} - -void styl_box_del(GF_Box *s) -{ - GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; - if (ptr->styles) gf_free(ptr->styles); - gf_free(ptr); -} - -GF_Err styl_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; - ISOM_DECREASE_SIZE(ptr, 2); - ptr->entry_count = gf_bs_read_u16(bs); - - if (ptr->sizeentry_count * GPP_STYLE_SIZE) - return GF_ISOM_INVALID_FILE; - - if (ptr->entry_count) { - ptr->styles = (GF_StyleRecord*)gf_malloc(sizeof(GF_StyleRecord)*ptr->entry_count); - if (!ptr->styles) return GF_OUT_OF_MEM; - for (i=0; ientry_count; i++) { - ISOM_DECREASE_SIZE(ptr, GPP_STYLE_SIZE); - gpp_read_style(bs, &ptr->styles[i]); - } - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err styl_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, ptr->entry_count); - for (i=0; ientry_count; i++) gpp_write_style(bs, &ptr->styles[i]); - return GF_OK; -} - -GF_Err styl_box_size(GF_Box *s) -{ - GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; - - s->size += 2 + ptr->entry_count * GPP_STYLE_SIZE; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *hlit_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextHighlightBox, GF_ISOM_BOX_TYPE_HLIT); - return (GF_Box *) tmp; -} - -void hlit_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err hlit_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->startcharoffset = gf_bs_read_u16(bs); - ptr->endcharoffset = gf_bs_read_u16(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err hlit_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->startcharoffset); - gf_bs_write_u16(bs, ptr->endcharoffset); - return GF_OK; -} - -GF_Err hlit_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *hclr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextHighlightColorBox, GF_ISOM_BOX_TYPE_HCLR); - return (GF_Box *) tmp; -} - -void hclr_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err hclr_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->hil_color = gpp_read_rgba(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err hclr_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gpp_write_rgba(bs, ptr->hil_color); - return GF_OK; -} - -GF_Err hclr_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *krok_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextKaraokeBox, GF_ISOM_BOX_TYPE_KROK); - return (GF_Box *) tmp; -} - -void krok_box_del(GF_Box *s) -{ - GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; - if (ptr->records) gf_free(ptr->records); - gf_free(ptr); -} - -GF_Err krok_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; - - ISOM_DECREASE_SIZE(ptr, 6) - ptr->highlight_starttime = gf_bs_read_u32(bs); - ptr->nb_entries = gf_bs_read_u16(bs); - if (ptr->size < ptr->nb_entries * 8) - return GF_ISOM_INVALID_FILE; - - if (ptr->nb_entries) { - u32 i; - ptr->records = (KaraokeRecord*)gf_malloc(sizeof(KaraokeRecord)*ptr->nb_entries); - if (!ptr->records) return GF_OUT_OF_MEM; - for (i=0; inb_entries; i++) { - ISOM_DECREASE_SIZE(ptr, 8) - ptr->records[i].highlight_endtime = gf_bs_read_u32(bs); - ptr->records[i].start_charoffset = gf_bs_read_u16(bs); - ptr->records[i].end_charoffset = gf_bs_read_u16(bs); - } - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err krok_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->highlight_starttime); - gf_bs_write_u16(bs, ptr->nb_entries); - for (i=0; inb_entries; i++) { - gf_bs_write_u32(bs, ptr->records[i].highlight_endtime); - gf_bs_write_u16(bs, ptr->records[i].start_charoffset); - gf_bs_write_u16(bs, ptr->records[i].end_charoffset); - } - return GF_OK; -} - -GF_Err krok_box_size(GF_Box *s) -{ - GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; - s->size += 6 + 8*ptr->nb_entries; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *dlay_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextScrollDelayBox, GF_ISOM_BOX_TYPE_DLAY); - return (GF_Box *) tmp; -} - -void dlay_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err dlay_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->scroll_delay = gf_bs_read_u32(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err dlay_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->scroll_delay); - return GF_OK; -} - -GF_Err dlay_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *href_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextHyperTextBox, GF_ISOM_BOX_TYPE_HREF); - return (GF_Box *) tmp; -} - -void href_box_del(GF_Box *s) -{ - GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; - if (ptr->URL) gf_free(ptr->URL); - if (ptr->URL_hint) gf_free(ptr->URL_hint); - gf_free(ptr); -} - -GF_Err href_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 len; - GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; - ISOM_DECREASE_SIZE(ptr, 6) //including 2 length fields - ptr->startcharoffset = gf_bs_read_u16(bs); - ptr->endcharoffset = gf_bs_read_u16(bs); - len = gf_bs_read_u8(bs); - if (len) { - ISOM_DECREASE_SIZE(ptr, len) - ptr->URL = (char *) gf_malloc(sizeof(char) * (len+1)); - if (!ptr->URL) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->URL, len); - ptr->URL[len] = 0; - } - len = gf_bs_read_u8(bs); - if (len) { - ISOM_DECREASE_SIZE(ptr, len) - ptr->URL_hint = (char *) gf_malloc(sizeof(char) * (len+1)); - if (!ptr->URL_hint) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->URL_hint, len); - ptr->URL_hint[len]= 0; - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err href_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 len; - GF_Err e; - GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, ptr->startcharoffset); - gf_bs_write_u16(bs, ptr->endcharoffset); - if (ptr->URL) { - len = (u32) strlen(ptr->URL); - gf_bs_write_u8(bs, len); - gf_bs_write_data(bs, ptr->URL, len); - } else { - gf_bs_write_u8(bs, 0); - } - if (ptr->URL_hint) { - len = (u32) strlen(ptr->URL_hint); - gf_bs_write_u8(bs, len); - gf_bs_write_data(bs, ptr->URL_hint, len); - } else { - gf_bs_write_u8(bs, 0); - } - return GF_OK; -} - -GF_Err href_box_size(GF_Box *s) -{ - GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; - s->size += 6; - if (ptr->URL) s->size += strlen(ptr->URL); - if (ptr->URL_hint) s->size += strlen(ptr->URL_hint); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *tbox_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextBoxBox, GF_ISOM_BOX_TYPE_TBOX); - return (GF_Box *) tmp; -} - -void tbox_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err tbox_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextBoxBox*ptr = (GF_TextBoxBox*)s; - ISOM_DECREASE_SIZE(ptr, GPP_BOX_SIZE) - gpp_read_box(bs, &ptr->box); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err tbox_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TextBoxBox*ptr = (GF_TextBoxBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gpp_write_box(bs, &ptr->box); - return GF_OK; -} - -GF_Err tbox_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *blnk_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextBlinkBox, GF_ISOM_BOX_TYPE_BLNK); - return (GF_Box *) tmp; -} - -void blnk_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err blnk_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->startcharoffset = gf_bs_read_u16(bs); - ptr->endcharoffset = gf_bs_read_u16(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err blnk_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->startcharoffset); - gf_bs_write_u16(bs, ptr->endcharoffset); - return GF_OK; -} - -GF_Err blnk_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *twrp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextWrapBox, GF_ISOM_BOX_TYPE_TWRP); - return (GF_Box *) tmp; -} - -void twrp_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err twrp_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextWrapBox*ptr = (GF_TextWrapBox*)s; - ISOM_DECREASE_SIZE(ptr, 1) - ptr->wrap_flag = gf_bs_read_u8(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err twrp_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TextWrapBox*ptr = (GF_TextWrapBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->wrap_flag); - return GF_OK; -} -GF_Err twrp_box_size(GF_Box *s) -{ - s->size += 1; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void tsel_box_del(GF_Box *s) -{ - GF_TrackSelectionBox *ptr; - ptr = (GF_TrackSelectionBox *) s; - if (ptr == NULL) return; - if (ptr->attributeList) gf_free(ptr->attributeList); - gf_free(ptr); -} - -GF_Err tsel_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->switchGroup = gf_bs_read_u32(bs); - - if (ptr->size % 4) return GF_ISOM_INVALID_FILE; - ptr->attributeListCount = (u32)ptr->size/4; - ptr->attributeList = gf_malloc(ptr->attributeListCount*sizeof(u32)); - if (ptr->attributeList == NULL) return GF_OUT_OF_MEM; - - for (i=0; i< ptr->attributeListCount; i++) { - ptr->attributeList[i] = gf_bs_read_u32(bs); - } - return GF_OK; -} - -GF_Box *tsel_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackSelectionBox, GF_ISOM_BOX_TYPE_TSEL); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tsel_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs,ptr->switchGroup); - - for (i = 0; i < ptr->attributeListCount; i++ ) { - gf_bs_write_u32(bs, ptr->attributeList[i]); - } - - return GF_OK; -} - -GF_Err tsel_box_size(GF_Box *s) -{ - GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s; - ptr->size += 4 + (4*ptr->attributeListCount); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *dimC_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DIMSSceneConfigBox, GF_ISOM_BOX_TYPE_DIMC); - return (GF_Box *)tmp; -} -void dimC_box_del(GF_Box *s) -{ - GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; - if (p->contentEncoding) gf_free(p->contentEncoding); - if (p->textEncoding) gf_free(p->textEncoding); - gf_free(p); -} - -GF_Err dimC_box_read(GF_Box *s, GF_BitStream *bs) -{ - char str[1024]; - u32 i; - GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; - - ISOM_DECREASE_SIZE(p, 3); - p->profile = gf_bs_read_u8(bs); - p->level = gf_bs_read_u8(bs); - p->pathComponents = gf_bs_read_int(bs, 4); - p->fullRequestHost = gf_bs_read_int(bs, 1); - p->streamType = gf_bs_read_int(bs, 1); - p->containsRedundant = gf_bs_read_int(bs, 2); - - i=0; - str[0]=0; - while (i < GF_ARRAY_LENGTH(str)) { - str[i] = gf_bs_read_u8(bs); - if (!str[i]) break; - i++; - } - ISOM_DECREASE_SIZE(p, i); - - p->textEncoding = gf_strdup(str); - - i=0; - str[0]=0; - while (i < GF_ARRAY_LENGTH(str)) { - str[i] = gf_bs_read_u8(bs); - if (!str[i]) break; - i++; - } - ISOM_DECREASE_SIZE(p, i); - - p->contentEncoding = gf_strdup(str); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err dimC_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, p->profile); - gf_bs_write_u8(bs, p->level); - gf_bs_write_int(bs, p->pathComponents, 4); - gf_bs_write_int(bs, p->fullRequestHost, 1); - gf_bs_write_int(bs, p->streamType, 1); - gf_bs_write_int(bs, p->containsRedundant, 2); - if (p->textEncoding) - gf_bs_write_data(bs, p->textEncoding, (u32) strlen(p->textEncoding)); - gf_bs_write_u8(bs, 0); - if (p->contentEncoding) - gf_bs_write_data(bs, p->contentEncoding, (u32) strlen(p->contentEncoding)); - gf_bs_write_u8(bs, 0); - return GF_OK; -} -GF_Err dimC_box_size(GF_Box *s) -{ - GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; - s->size += 3 + 2; - if (p->textEncoding) s->size += strlen(p->textEncoding); - if (p->contentEncoding) s->size += strlen(p->contentEncoding); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *diST_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DIMSScriptTypesBox, GF_ISOM_BOX_TYPE_DIST); - return (GF_Box *)tmp; -} -void diST_box_del(GF_Box *s) -{ - GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; - if (p->content_script_types) gf_free(p->content_script_types); - gf_free(p); -} - -GF_Err diST_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - char str[1024]; - GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; - - i=0; - str[0]=0; - while (1) { - str[i] = gf_bs_read_u8(bs); - if (!str[i]) break; - i++; - } - ISOM_DECREASE_SIZE(p, i); - - p->content_script_types = gf_strdup(str); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err diST_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - if (p->content_script_types) - gf_bs_write_data(bs, p->content_script_types, (u32) strlen(p->content_script_types)+1); - else - gf_bs_write_u8(bs, 0); - return GF_OK; -} -GF_Err diST_box_size(GF_Box *s) -{ - GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; - s->size += p->content_script_types ? (strlen(p->content_script_types)+1) : 1; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *dims_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DIMSSampleEntryBox, GF_ISOM_BOX_TYPE_DIMS); - return (GF_Box*)tmp; -} -void dims_box_del(GF_Box *s) -{ - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - gf_free(s); -} - -static GF_Err dims_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_DIMSSampleEntryBox *ptr = (GF_DIMSSampleEntryBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_DIMC: - if (ptr->config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->config = (GF_DIMSSceneConfigBox*)a; - break; - case GF_ISOM_BOX_TYPE_DIST: - if (ptr->scripts) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->scripts = (GF_DIMSScriptTypesBox*)a; - break; - } - return GF_OK; -} -GF_Err dims_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s; - - e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)p, bs); - if (e) return e; - - ISOM_DECREASE_SIZE(p, 8); - return gf_isom_box_array_read(s, bs, dims_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err dims_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_data(bs, p->reserved, 6); - gf_bs_write_u16(bs, p->dataReferenceIndex); - return GF_OK; -} - -GF_Err dims_box_size(GF_Box *s) -{ - u32 pos = 0; - GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s; - s->size += 8; - gf_isom_check_position(s, (GF_Box *) p->config, &pos); - gf_isom_check_position(s, (GF_Box *) p->scripts, &pos); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/thirdparty/gpacmp4/box_code_adobe.c b/src/thirdparty/gpacmp4/box_code_adobe.c deleted file mode 100644 index ab5115f25..000000000 --- a/src/thirdparty/gpacmp4/box_code_adobe.c +++ /dev/null @@ -1,735 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Author: Romain Bouqueau, Jean Le Feuvre - * Copyright (c) Romain Bouqueau 2012- Telecom Paris 2019- - * All rights reserved - * - * Note: this development was kindly sponsorized by Vizion'R (http://vizionr.com) - * - * This file is part of GPAC / ISO Media File Format sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include - -#ifndef GPAC_DISABLE_ISOM_ADOBE - -#ifndef GPAC_DISABLE_ISOM - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void abst_box_del(GF_Box *s) -{ - GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s; - if (ptr == NULL) return; - - if (ptr->movie_identifier) - gf_free(ptr->movie_identifier); - if (ptr->drm_data) - gf_free(ptr->drm_data); - if (ptr->meta_data) - gf_free(ptr->meta_data); - - while (gf_list_count(ptr->server_entry_table)) { - gf_free(gf_list_get(ptr->server_entry_table, 0)); - gf_list_rem(ptr->server_entry_table, 0); - } - gf_list_del(ptr->server_entry_table); - - while (gf_list_count(ptr->quality_entry_table)) { - gf_free(gf_list_get(ptr->quality_entry_table, 0)); - gf_list_rem(ptr->quality_entry_table, 0); - } - gf_list_del(ptr->quality_entry_table); - - - while (gf_list_count(ptr->segment_run_table_entries)) { - gf_isom_box_del((GF_Box *)gf_list_get(ptr->segment_run_table_entries, 0)); - gf_list_rem(ptr->segment_run_table_entries, 0); - } - gf_list_del(ptr->segment_run_table_entries); - - while (gf_list_count(ptr->fragment_run_table_entries)) { - gf_isom_box_del((GF_Box *)gf_list_get(ptr->fragment_run_table_entries, 0)); - gf_list_rem(ptr->fragment_run_table_entries, 0); - } - gf_list_del(ptr->fragment_run_table_entries); - - gf_free(ptr); -} - -GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s; - int i; - u32 tmp_strsize; - char *tmp_str; - GF_Err e; - - ISOM_DECREASE_SIZE(ptr, 25) - ptr->bootstrapinfo_version = gf_bs_read_u32(bs); - ptr->profile = gf_bs_read_int(bs, 2); - ptr->live = gf_bs_read_int(bs, 1); - ptr->update = gf_bs_read_int(bs, 1); - ptr->reserved = gf_bs_read_int(bs, 4); - ptr->time_scale = gf_bs_read_u32(bs); - ptr->current_media_time = gf_bs_read_u64(bs); - ptr->smpte_time_code_offset = gf_bs_read_u64(bs); - - i=0; - if (ptr->size<8) return GF_ISOM_INVALID_FILE; - tmp_strsize =(u32)ptr->size; - tmp_str = gf_malloc(sizeof(char)*tmp_strsize); - if (!tmp_str) return GF_OUT_OF_MEM; - memset(tmp_str, 0, sizeof(char)*tmp_strsize); - - while (tmp_strsize) { - ISOM_DECREASE_SIZE(ptr, 1) - tmp_str[i] = gf_bs_read_u8(bs); - tmp_strsize--; - if (!tmp_str[i]) - break; - i++; - } - if (i) { - ptr->movie_identifier = gf_strdup(tmp_str); - } - - ISOM_DECREASE_SIZE(ptr, 1) - ptr->server_entry_count = gf_bs_read_u8(bs); - for (i=0; iserver_entry_count; i++) { - int j=0; - tmp_strsize=(u32)ptr->size; - while (tmp_strsize) { - ISOM_DECREASE_SIZE(ptr, 1) - tmp_str[j] = gf_bs_read_u8(bs); - tmp_strsize--; - if (!tmp_str[j]) - break; - j++; - } - if (j) { - gf_list_insert(ptr->server_entry_table, gf_strdup(tmp_str), i); - } - } - - ISOM_DECREASE_SIZE(ptr, 1) - ptr->quality_entry_count = gf_bs_read_u8(bs); - for (i=0; iquality_entry_count; i++) { - int j=0; - tmp_strsize=(u32)ptr->size; - while (tmp_strsize) { - ISOM_DECREASE_SIZE(ptr, 1) - tmp_str[j] = gf_bs_read_u8(bs); - tmp_strsize--; - if (!tmp_str[j]) - break; - j++; - } - - if (j) { - gf_list_insert(ptr->quality_entry_table, gf_strdup(tmp_str), i); - } - } - - i=0; - tmp_strsize=(u32)ptr->size; - while (tmp_strsize) { - ISOM_DECREASE_SIZE(ptr, 1) - tmp_str[i] = gf_bs_read_u8(bs); - tmp_strsize--; - if (!tmp_str[i]) - break; - i++; - } - if (i) { - ptr->drm_data = gf_strdup(tmp_str); - } - - i=0; - tmp_strsize=(u32)ptr->size; - while (tmp_strsize) { - ISOM_DECREASE_SIZE(ptr, 1) - tmp_str[i] = gf_bs_read_u8(bs); - tmp_strsize--; - if (!tmp_str[i]) - break; - i++; - } - if (i) { - ptr->meta_data = gf_strdup(tmp_str); - } - - ISOM_DECREASE_SIZE(ptr, 1) - ptr->segment_run_table_count = gf_bs_read_u8(bs); - for (i=0; isegment_run_table_count; i++) { - GF_AdobeSegmentRunTableBox *asrt = NULL; - e = gf_isom_box_parse((GF_Box **)&asrt, bs); - if (e) { - if (asrt) gf_isom_box_del((GF_Box*)asrt); - gf_free(tmp_str); - return e; - } - gf_list_add(ptr->segment_run_table_entries, asrt); - } - - ISOM_DECREASE_SIZE(ptr, 1) - ptr->fragment_run_table_count = gf_bs_read_u8(bs); - for (i=0; ifragment_run_table_count; i++) { - GF_AdobeFragmentRunTableBox *afrt = NULL; - e = gf_isom_box_parse((GF_Box **)&afrt, bs); - if (e) { - if (afrt) gf_isom_box_del((GF_Box*)afrt); - gf_free(tmp_str); - return e; - } - gf_list_add(ptr->fragment_run_table_entries, afrt); - } - - gf_free(tmp_str); - - return GF_OK; -} - -GF_Box *abst_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeBootstrapInfoBox, GF_ISOM_BOX_TYPE_ABST); - tmp->server_entry_table = gf_list_new(); - tmp->quality_entry_table = gf_list_new(); - tmp->segment_run_table_entries = gf_list_new(); - tmp->fragment_run_table_entries = gf_list_new(); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err abst_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - unsigned int i; - GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->bootstrapinfo_version); - gf_bs_write_int(bs, ptr->profile, 2); - gf_bs_write_int(bs, ptr->live, 1); - gf_bs_write_int(bs, ptr->update, 1); - gf_bs_write_int(bs, ptr->reserved, 4); - gf_bs_write_u32(bs, ptr->time_scale); - gf_bs_write_u64(bs, ptr->current_media_time); - gf_bs_write_u64(bs, ptr->smpte_time_code_offset); - if (ptr->movie_identifier) - gf_bs_write_data(bs, ptr->movie_identifier, (u32)strlen(ptr->movie_identifier) + 1); - else - gf_bs_write_u8(bs, 0); - - gf_bs_write_u8(bs, ptr->server_entry_count); - for (i=0; iserver_entry_count; i++) { - char *str = (char*)gf_list_get(ptr->server_entry_table, i); - gf_bs_write_data(bs, str, (u32)strlen(str) + 1); - } - - gf_bs_write_u8(bs, ptr->quality_entry_count); - for (i=0; iquality_entry_count; i++) { - char *str = (char*)gf_list_get(ptr->quality_entry_table, i); - gf_bs_write_data(bs, str, (u32)strlen(str) + 1); - } - - if (ptr->drm_data) - gf_bs_write_data(bs, ptr->drm_data, (u32)strlen(ptr->drm_data) + 1); - else - gf_bs_write_u8(bs, 0); - - if (ptr->meta_data) - gf_bs_write_data(bs, ptr->meta_data, (u32)strlen(ptr->meta_data) + 1); - else - gf_bs_write_u8(bs, 0); - - gf_bs_write_u8(bs, ptr->segment_run_table_count); - for (i=0; isegment_run_table_count; i++) { - e = gf_isom_box_write((GF_Box *)gf_list_get(ptr->segment_run_table_entries, i), bs); - if (e) return e; - } - - gf_bs_write_u8(bs, ptr->fragment_run_table_count); - for (i=0; ifragment_run_table_count; i++) { - e = gf_isom_box_write((GF_Box *)gf_list_get(ptr->fragment_run_table_entries, i), bs); - if (e) return e; - } - - return GF_OK; -} - -GF_Err abst_box_size(GF_Box *s) -{ - GF_Err e; - u32 i; - GF_AdobeBootstrapInfoBox *ptr = (GF_AdobeBootstrapInfoBox *)s; - - s->size += 25 - + (ptr->movie_identifier ? (strlen(ptr->movie_identifier) + 1) : 1) - + 1; - - for (i=0; iserver_entry_count; i++) - s->size += strlen(gf_list_get(ptr->server_entry_table, i)) + 1; - - s->size += 1; - - for (i=0; iquality_entry_count; i++) - s->size += strlen(gf_list_get(ptr->quality_entry_table, i)) + 1; - - s->size += (ptr->drm_data ? (strlen(ptr->drm_data) + 1) : 1) - + (ptr->meta_data ? (strlen(ptr->meta_data) + 1) : 1) - + 1; - - for (i=0; isegment_run_table_count; i++) { - GF_Box *box = (GF_Box *)gf_list_get(ptr->segment_run_table_entries, i); - e = gf_isom_box_size(box); - if (e) return e; - s->size += box->size; - } - - s->size += 1; - for (i=0; ifragment_run_table_count; i++) { - GF_Box *box = (GF_Box *)gf_list_get(ptr->fragment_run_table_entries, i); - e = gf_isom_box_size(box); - if (e) return e; - s->size += box->size; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void afra_box_del(GF_Box *s) -{ - GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s; - if (ptr == NULL) return; - - while (gf_list_count(ptr->local_access_entries)) { - gf_free(gf_list_get(ptr->local_access_entries, 0)); - gf_list_rem(ptr->local_access_entries, 0); - } - gf_list_del(ptr->local_access_entries); - - while (gf_list_count(ptr->global_access_entries)) { - gf_free(gf_list_get(ptr->global_access_entries, 0)); - gf_list_rem(ptr->global_access_entries, 0); - } - gf_list_del(ptr->global_access_entries); - - gf_free(ptr); -} - -GF_Err afra_box_read(GF_Box *s, GF_BitStream *bs) -{ - unsigned int i; - GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s; - - ISOM_DECREASE_SIZE(ptr, 9) - ptr->long_ids = gf_bs_read_int(bs, 1); - ptr->long_offsets = gf_bs_read_int(bs, 1); - ptr->global_entries = gf_bs_read_int(bs, 1); - ptr->reserved = gf_bs_read_int(bs, 5); - ptr->time_scale = gf_bs_read_u32(bs); - - ptr->entry_count = gf_bs_read_u32(bs); - if (ptr->size < ptr->entry_count * (ptr->long_offsets ? 16 : 12)) - return GF_ISOM_INVALID_FILE; - - for (i=0; ientry_count; i++) { - GF_AfraEntry *ae = gf_malloc(sizeof(GF_AfraEntry)); - if (!ae) return GF_OUT_OF_MEM; - - ISOM_DECREASE_SIZE(ptr, 8) - ae->time = gf_bs_read_u64(bs); - if (ptr->long_offsets) { - ISOM_DECREASE_SIZE(ptr, 8) - ae->offset = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 4) - ae->offset = gf_bs_read_u32(bs); - } - - gf_list_insert(ptr->local_access_entries, ae, i); - } - - if (ptr->global_entries) { - ISOM_DECREASE_SIZE(ptr, 4) - ptr->global_entry_count = gf_bs_read_u32(bs); - for (i=0; iglobal_entry_count; i++) { - GF_GlobalAfraEntry *ae = gf_malloc(sizeof(GF_GlobalAfraEntry)); - if (!ae) return GF_OUT_OF_MEM; - ISOM_DECREASE_SIZE(ptr, 8) - ae->time = gf_bs_read_u64(bs); - if (ptr->long_ids) { - ISOM_DECREASE_SIZE(ptr, 8) - ae->segment = gf_bs_read_u32(bs); - ae->fragment = gf_bs_read_u32(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 4) - ae->segment = gf_bs_read_u16(bs); - ae->fragment = gf_bs_read_u16(bs); - } - if (ptr->long_offsets) { - ISOM_DECREASE_SIZE(ptr, 16) - ae->afra_offset = gf_bs_read_u64(bs); - ae->offset_from_afra = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 8) - ae->afra_offset = gf_bs_read_u32(bs); - ae->offset_from_afra = gf_bs_read_u32(bs); - } - - gf_list_insert(ptr->global_access_entries, ae, i); - } - } - - return GF_OK; -} - -GF_Box *afra_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeFragRandomAccessBox, GF_ISOM_BOX_TYPE_AFRA); - tmp->local_access_entries = gf_list_new(); - tmp->global_access_entries = gf_list_new(); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err afra_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - unsigned int i; - GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_int(bs, ptr->long_ids, 1); - gf_bs_write_int(bs, ptr->long_offsets, 1); - gf_bs_write_int(bs, ptr->global_entries, 1); - gf_bs_write_int(bs, 0, 5); - gf_bs_write_u32(bs, ptr->time_scale); - - gf_bs_write_u32(bs, ptr->entry_count); - for (i=0; ientry_count; i++) { - GF_AfraEntry *ae = (GF_AfraEntry *)gf_list_get(ptr->local_access_entries, i); - gf_bs_write_u64(bs, ae->time); - if (ptr->long_offsets) - gf_bs_write_u64(bs, ae->offset); - else - gf_bs_write_u32(bs, (u32)ae->offset); - } - - if (ptr->global_entries) { - gf_bs_write_u32(bs, ptr->global_entry_count); - for (i=0; iglobal_entry_count; i++) { - GF_GlobalAfraEntry *gae = (GF_GlobalAfraEntry *)gf_list_get(ptr->global_access_entries, i); - gf_bs_write_u64(bs, gae->time); - if (ptr->long_ids) { - gf_bs_write_u32(bs, gae->segment); - gf_bs_write_u32(bs, gae->fragment); - } else { - gf_bs_write_u16(bs, (u16)gae->segment); - gf_bs_write_u16(bs, (u16)gae->fragment); - } - if (ptr->long_offsets) { - gf_bs_write_u64(bs, gae->afra_offset); - gf_bs_write_u64(bs, gae->offset_from_afra); - } else { - gf_bs_write_u32(bs, (u32)gae->afra_offset); - gf_bs_write_u32(bs, (u32)gae->offset_from_afra); - } - } - } - - return GF_OK; -} - - -GF_Err afra_box_size(GF_Box *s) -{ - GF_AdobeFragRandomAccessBox *ptr = (GF_AdobeFragRandomAccessBox *)s; - - s->size += 9 - + ptr->entry_count * (ptr->long_offsets ? 16 : 12) - + (ptr->global_entries ? 4 + ptr->global_entry_count * (4 + (ptr->long_offsets ? 16 : 8) + (ptr->long_ids ? 8 : 4)) : 0); - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void asrt_box_del(GF_Box *s) -{ - GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s; - if (ptr == NULL) return; - - while (gf_list_count(ptr->quality_segment_url_modifiers)) { - gf_free(gf_list_get(ptr->quality_segment_url_modifiers, 0)); - gf_list_rem(ptr->quality_segment_url_modifiers, 0); - } - gf_list_del(ptr->quality_segment_url_modifiers); - - while (gf_list_count(ptr->segment_run_entry_table)) { - gf_free(gf_list_get(ptr->segment_run_entry_table, 0)); - gf_list_rem(ptr->segment_run_entry_table, 0); - } - gf_list_del(ptr->segment_run_entry_table); - - gf_free(ptr); -} - -GF_Err asrt_box_read(GF_Box *s, GF_BitStream *bs) -{ - unsigned int i; - GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s; - - ISOM_DECREASE_SIZE(ptr, 1) - ptr->quality_entry_count = gf_bs_read_u8(bs); - if (ptr->size < ptr->quality_entry_count) - return GF_ISOM_INVALID_FILE; - - for (i=0; iquality_entry_count; i++) { - int j=0; - u32 tmp_strsize=(u32)ptr->size; - char *tmp_str = (char*) gf_malloc(tmp_strsize); - if (!tmp_str) return GF_OUT_OF_MEM; - while (tmp_strsize) { - tmp_str[j] = gf_bs_read_u8(bs); - tmp_strsize--; - if (!tmp_str[j]) - break; - j++; - } - ISOM_DECREASE_SIZE(ptr, j) - gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i); - } - - ISOM_DECREASE_SIZE(ptr, 4) - ptr->segment_run_entry_count = gf_bs_read_u32(bs); - if (ptr->size < ptr->segment_run_entry_count*8) - return GF_ISOM_INVALID_FILE; - - for (i=0; isegment_run_entry_count; i++) { - GF_AdobeSegmentRunEntry *sre = gf_malloc(sizeof(GF_AdobeSegmentRunEntry)); - if (!sre) return GF_OUT_OF_MEM; - ISOM_DECREASE_SIZE(ptr, 8) - sre->first_segment = gf_bs_read_u32(bs); - sre->fragment_per_segment = gf_bs_read_u32(bs); - gf_list_insert(ptr->segment_run_entry_table, sre, i); - } - - return GF_OK; -} - -GF_Box *asrt_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeSegmentRunTableBox, GF_ISOM_BOX_TYPE_ASRT); - tmp->quality_segment_url_modifiers = gf_list_new(); - tmp->segment_run_entry_table = gf_list_new(); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err asrt_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - unsigned int i; - GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u8(bs, ptr->quality_entry_count); - for (i=0; iquality_entry_count; i++) { - char *str = (char*)gf_list_get(ptr->quality_segment_url_modifiers, i); - gf_bs_write_data(bs, str, (u32)strlen(str) + 1); - } - - gf_bs_write_u32(bs, ptr->segment_run_entry_count); - for (i=0; isegment_run_entry_count; i++) { - GF_AdobeSegmentRunEntry *sre = (GF_AdobeSegmentRunEntry *)gf_list_get(ptr->segment_run_entry_table, i); - gf_bs_write_u32(bs, sre->first_segment); - gf_bs_write_u32(bs, sre->fragment_per_segment); - } - - return GF_OK; -} - - -GF_Err asrt_box_size(GF_Box *s) -{ - int i; - GF_AdobeSegmentRunTableBox *ptr = (GF_AdobeSegmentRunTableBox *)s; - - s->size += 5; - - for (i=0; iquality_entry_count; i++) - s->size += strlen(gf_list_get(ptr->quality_segment_url_modifiers, i)) + 1; - - s->size += ptr->segment_run_entry_count * sizeof(GF_AdobeSegmentRunEntry); - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void afrt_box_del(GF_Box *s) -{ - GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s; - if (ptr == NULL) return; - - while (gf_list_count(ptr->quality_segment_url_modifiers)) { - gf_free(gf_list_get(ptr->quality_segment_url_modifiers, 0)); - gf_list_rem(ptr->quality_segment_url_modifiers, 0); - } - gf_list_del(ptr->quality_segment_url_modifiers); - - while (gf_list_count(ptr->fragment_run_entry_table)) { - gf_free(gf_list_get(ptr->fragment_run_entry_table, 0)); - gf_list_rem(ptr->fragment_run_entry_table, 0); - } - gf_list_del(ptr->fragment_run_entry_table); - - gf_free(ptr); -} - -GF_Err afrt_box_read(GF_Box *s, GF_BitStream *bs) -{ - unsigned int i; - GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s; - - ISOM_DECREASE_SIZE(ptr, 5) - ptr->timescale = gf_bs_read_u32(bs); - - ptr->quality_entry_count = gf_bs_read_u8(bs); - if (ptr->size < ptr->quality_entry_count) - return GF_ISOM_INVALID_FILE; - - for (i=0; iquality_entry_count; i++) { - int j=0; - u32 tmp_strsize=(u32)ptr->size-8; - char *tmp_str = (char*) gf_malloc(tmp_strsize); - if (!tmp_str) return GF_OUT_OF_MEM; - while (tmp_strsize) { - tmp_str[j] = gf_bs_read_u8(bs); - tmp_strsize--; - if (!tmp_str[j]) - break; - j++; - } - ISOM_DECREASE_SIZE(ptr, j) - gf_list_insert(ptr->quality_segment_url_modifiers, tmp_str, i); - } - - ptr->fragment_run_entry_count = gf_bs_read_u32(bs); - if (ptr->size < ptr->fragment_run_entry_count*16) - return GF_ISOM_INVALID_FILE; - for (i=0; ifragment_run_entry_count; i++) { - GF_AdobeFragmentRunEntry *fre = gf_malloc(sizeof(GF_AdobeFragmentRunEntry)); - if (!fre) return GF_ISOM_INVALID_FILE; - ISOM_DECREASE_SIZE(ptr, 16) - fre->first_fragment = gf_bs_read_u32(bs); - fre->first_fragment_timestamp = gf_bs_read_u64(bs); - fre->fragment_duration = gf_bs_read_u32(bs); - if (!fre->fragment_duration) { - ISOM_DECREASE_SIZE(ptr, 1) - fre->discontinuity_indicator = gf_bs_read_u8(bs); - } - gf_list_insert(ptr->fragment_run_entry_table, fre, i); - } - - return GF_OK; -} - -GF_Box *afrt_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeFragmentRunTableBox, GF_ISOM_BOX_TYPE_AFRT); - tmp->quality_segment_url_modifiers = gf_list_new(); - tmp->fragment_run_entry_table = gf_list_new(); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err afrt_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - unsigned int i; - GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->timescale); - gf_bs_write_u8(bs, ptr->quality_entry_count); - for (i=0; iquality_entry_count; i++) { - char *str = (char*)gf_list_get(ptr->quality_segment_url_modifiers, i); - gf_bs_write_data(bs, str, (u32)strlen(str) + 1); - } - - gf_bs_write_u32(bs, ptr->fragment_run_entry_count); - for (i=0; ifragment_run_entry_count; i++) { - GF_AdobeFragmentRunEntry *fre = (GF_AdobeFragmentRunEntry *)gf_list_get(ptr->fragment_run_entry_table, i); - gf_bs_write_u32(bs, fre->first_fragment); - gf_bs_write_u64(bs, fre->first_fragment_timestamp); - gf_bs_write_u32(bs, fre->fragment_duration); - if (!fre->fragment_duration) - gf_bs_write_u8(bs, fre->discontinuity_indicator); - } - - return GF_OK; -} - - -GF_Err afrt_box_size(GF_Box *s) -{ - u32 i; - GF_AdobeFragmentRunTableBox *ptr = (GF_AdobeFragmentRunTableBox *)s; - - s->size += 5; - - for (i=0; iquality_entry_count; i++) - s->size += strlen(gf_list_get(ptr->quality_segment_url_modifiers, i)) + 1; - - s->size += 4; - - for (i=0; ifragment_run_entry_count; i++) { - GF_AdobeFragmentRunEntry *fre = (GF_AdobeFragmentRunEntry *)gf_list_get(ptr->fragment_run_entry_table, i); - if (fre->fragment_duration) - s->size += 16; - else - s->size += 17; - } - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - -#endif /*GPAC_DISABLE_ISOM*/ - -#endif /*GPAC_DISABLE_ISOM_ADOBE*/ diff --git a/src/thirdparty/gpacmp4/box_code_apple.c b/src/thirdparty/gpacmp4/box_code_apple.c deleted file mode 100644 index 51fd65895..000000000 --- a/src/thirdparty/gpacmp4/box_code_apple.c +++ /dev/null @@ -1,978 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2006-2019 - * All rights reserved - * - * This file is part of GPAC / ISO Media File Format sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include - -#ifndef GPAC_DISABLE_ISOM - -void ilst_box_del(GF_Box *s) -{ - GF_ItemListBox *ptr = (GF_ItemListBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err ilst_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 sub_type; - GF_Box *a; - GF_ItemListBox *ptr = (GF_ItemListBox *)s; - while (ptr->size) { - /*if no ilst type coded, break*/ - sub_type = gf_bs_peek_bits(bs, 32, 0); - if (sub_type) { - e = gf_isom_box_parse_ex(&a, bs, s->type, GF_FALSE); - - /* the macro will return in this case before we can free */ - if (!e && ptr->size < a->size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isom] not enough bytes in box %s: %d left, reading %d (file %s, line %d)\n", gf_4cc_to_str(ptr->type), ptr->size, a->size, __FILE__, __LINE__ )); \ - e = GF_ISOM_INVALID_FILE; - } - if (e) { - if (a) gf_isom_box_del(a); - return e; - } - - ISOM_DECREASE_SIZE(ptr, a->size); - gf_list_add(ptr->child_boxes, a); - } else { - gf_bs_read_u32(bs); - ISOM_DECREASE_SIZE(ptr, 4); - } - } - return GF_OK; -} - -GF_Box *ilst_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ItemListBox, GF_ISOM_BOX_TYPE_ILST); - tmp->child_boxes = gf_list_new(); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ilst_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; -// GF_ItemListBox *ptr = (GF_ItemListBox *)s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - return GF_OK; -} - - -GF_Err ilst_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void ilst_item_box_del(GF_Box *s) -{ - GF_ListItemBox *ptr = (GF_ListItemBox *) s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err ilst_item_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_Err e; - u32 sub_type; - GF_Box *a = NULL; - GF_ListItemBox *ptr = (GF_ListItemBox *)s; - /*iTunes way: there's a data atom containing the data*/ - sub_type = gf_bs_peek_bits(bs, 32, 4); - if (sub_type == GF_ISOM_BOX_TYPE_DATA ) { - e = gf_isom_box_parse(&a, bs); - - if (!e && a && (ptr->size < a->size)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isom] not enough bytes in box %s: %d left, reading %d (file %s, line %d)\n", gf_4cc_to_str(ptr->type), ptr->size, a->size, __FILE__, __LINE__ )); \ - e = GF_ISOM_INVALID_FILE; - } - if (!a) e = GF_ISOM_INVALID_FILE; - - if (e) { - if (a) gf_isom_box_del(a); - return e; - } - if (!a) return GF_NON_COMPLIANT_BITSTREAM; - - ISOM_DECREASE_SIZE(ptr, a->size); - - if (ptr->data) gf_isom_box_del_parent(&ptr->child_boxes, (GF_Box *) ptr->data); - - /* otherwise a->data will always overflow */ - if (a->size > 4 && (a->type != GF_ISOM_BOX_TYPE_VOID)) { - ptr->data = (GF_DataBox *)a; - if (!ptr->child_boxes) ptr->child_boxes = gf_list_new(); - gf_list_add(ptr->child_boxes, ptr->data); - } else { - ptr->data = NULL; - gf_isom_box_del(a); - } - } - /*QT way*/ - else { - u64 pos = gf_bs_get_position(bs); - u64 prev_size = s->size; - /*try parsing as generic box list*/ - e = gf_isom_box_array_read(s, bs, NULL); - if (e==GF_OK) return GF_OK; - //reset content and retry - this deletes ptr->data !! - gf_isom_box_array_del(s->child_boxes); - s->child_boxes=NULL; - gf_bs_seek(bs, pos); - s->size = prev_size; - - ptr->data = (GF_DataBox *)gf_isom_box_new_parent(&ptr->child_boxes, GF_ISOM_BOX_TYPE_DATA); - //nope, check qt-style - ptr->data->qt_style = GF_TRUE; - ISOM_DECREASE_SIZE(ptr, 2); - ptr->data->dataSize = gf_bs_read_u16(bs); - gf_bs_read_u16(bs); - - ptr->data->data = (char *) gf_malloc(sizeof(char)*(ptr->data->dataSize + 1)); - if (!ptr->data->data) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, ptr->data->data, ptr->data->dataSize); - ptr->data->data[ptr->data->dataSize] = 0; - ISOM_DECREASE_SIZE(ptr, ptr->data->dataSize); - } - return GF_OK; -} - -GF_Box *ilst_item_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ListItemBox, GF_ISOM_BOX_TYPE_CPIL); //type will be overwrite - tmp->data = (GF_DataBox *)gf_isom_box_new_parent(&tmp->child_boxes, GF_ISOM_BOX_TYPE_DATA); - if (tmp->data == NULL) { - if (tmp->child_boxes) gf_list_del(tmp->child_boxes); - gf_free(tmp); - return NULL; - } - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ilst_item_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ListItemBox *ptr = (GF_ListItemBox *) s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - /*generic box list*/ - if (ptr->child_boxes && !ptr->data) { - } - //empty ilst - else if (!ptr->data) { - } - /*iTune way: data-box-encapsulated box list*/ - else if (!ptr->data->qt_style) { - } - /*QT way: raw data*/ - else { - gf_bs_write_u16(bs, ptr->data->dataSize); - gf_bs_write_u16(bs, 0); - gf_bs_write_data(bs, ptr->data->data, ptr->data->dataSize); - ptr->size = 0; //abort - } - return GF_OK; -} - -GF_Err ilst_item_box_size(GF_Box *s) -{ - GF_ListItemBox *ptr = (GF_ListItemBox *)s; - - /*generic box list*/ - if (ptr->child_boxes && !ptr->data) { - } - /*iTune way: data-box-encapsulated box list*/ - else if (ptr->data && !ptr->data->qt_style) { - u32 pos=0; - gf_isom_check_position(s, (GF_Box* ) ptr->data, &pos); - } - /*QT way: raw data*/ - else if (ptr->data) { - ptr->size += ptr->data->dataSize + 4; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void databox_box_del(GF_Box *s) -{ - GF_DataBox *ptr = (GF_DataBox *) s; - if (ptr == NULL) return; - if (ptr->data) - gf_free(ptr->data); - gf_free(ptr); - -} - -GF_Err databox_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_DataBox *ptr = (GF_DataBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->reserved = gf_bs_read_u32(bs); - - if (ptr->size) { - ptr->dataSize = (u32) ptr->size; - ptr->data = (char*)gf_malloc(ptr->dataSize * sizeof(ptr->data[0]) + 1); - if (!ptr->data) return GF_OUT_OF_MEM; - ptr->data[ptr->dataSize] = 0; - gf_bs_read_data(bs, ptr->data, ptr->dataSize); - } - - return GF_OK; -} - -GF_Box *databox_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DataBox, GF_ISOM_BOX_TYPE_DATA); - - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err databox_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DataBox *ptr = (GF_DataBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_int(bs, ptr->reserved, 32); - if(ptr->data != NULL && ptr->dataSize > 0) { - gf_bs_write_data(bs, ptr->data, ptr->dataSize); - } - return GF_OK; -} - -GF_Err databox_box_size(GF_Box *s) -{ - GF_DataBox *ptr = (GF_DataBox *)s; - - ptr->size += 4; - if(ptr->data != NULL && ptr->dataSize > 0) { - ptr->size += ptr->dataSize; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void alis_box_del(GF_Box *s) -{ - GF_DataEntryAliasBox *ptr = (GF_DataEntryAliasBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err alis_box_read(GF_Box *s, GF_BitStream *bs) -{ -// GF_DataEntryAliasBox *ptr = (GF_DataEntryAliasBox *)s; - return GF_OK; -} - -GF_Box *alis_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DataEntryAliasBox, GF_QT_BOX_TYPE_ALIS); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err alis_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; -// GF_DataEntryAliasBox *ptr = (GF_DataEntryAliasBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - return GF_OK; -} - -GF_Err alis_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void wide_box_del(GF_Box *s) -{ - if (s == NULL) return; - gf_free(s); -} - - -GF_Err wide_box_read(GF_Box *s, GF_BitStream *bs) -{ - gf_bs_skip_bytes(bs, s->size); - s->size = 0; - return GF_OK; -} - -GF_Box *wide_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_WideBox, GF_QT_BOX_TYPE_WIDE); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err wide_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - return GF_OK; -} - -GF_Err wide_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_MetaBox *gf_isom_apple_get_meta_extensions(GF_ISOFile *mov) -{ - u32 i; - GF_UserDataMap *map; - - if (!mov || !mov->moov) return NULL; - - if (!mov->moov->udta) return NULL; - map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_META, NULL); - if (!map) return NULL; - - for(i = 0; i < gf_list_count(map->boxes); i++) { - GF_MetaBox *meta = (GF_MetaBox*)gf_list_get(map->boxes, i); - - if(meta != NULL && meta->handler != NULL && meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR) return meta; - } - - return NULL; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov) -{ - GF_Err e; - u32 i; - GF_MetaBox *meta; - GF_UserDataMap *map; - - if (!mov || !mov->moov) return NULL; - - if (!mov->moov->udta) { - e = moov_on_child_box((GF_Box*)mov->moov, gf_isom_box_new_parent(&mov->moov->child_boxes, GF_ISOM_BOX_TYPE_UDTA)); - if (e) return NULL; - } - - map = udta_getEntry(mov->moov->udta, GF_ISOM_BOX_TYPE_META, NULL); - if (map) { - for(i = 0; i < gf_list_count(map->boxes); i++) { - meta = (GF_MetaBox*)gf_list_get(map->boxes, i); - - if(meta != NULL && meta->handler != NULL && meta->handler->handlerType == GF_ISOM_HANDLER_TYPE_MDIR) return meta; - } - } - - //udta handles children boxes through maps - meta = (GF_MetaBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_META); - - if(meta != NULL) { - meta->handler = (GF_HandlerBox *)gf_isom_box_new_parent(&meta->child_boxes, GF_ISOM_BOX_TYPE_HDLR); - if(meta->handler == NULL) { - gf_isom_box_del((GF_Box *)meta); - return NULL; - } - meta->handler->handlerType = GF_ISOM_HANDLER_TYPE_MDIR; - gf_isom_box_new_parent(&meta->child_boxes, GF_ISOM_BOX_TYPE_ILST); - udta_on_child_box((GF_Box *)mov->moov->udta, (GF_Box *)meta); - } - - return meta; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void gmin_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err gmin_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_GenericMediaHeaderInfoBox *ptr = (GF_GenericMediaHeaderInfoBox *)s; - ISOM_DECREASE_SIZE(ptr, 12); - ptr->graphics_mode = gf_bs_read_u16(bs); - ptr->op_color_red = gf_bs_read_u16(bs); - ptr->op_color_green = gf_bs_read_u16(bs); - ptr->op_color_blue = gf_bs_read_u16(bs); - ptr->balance = gf_bs_read_u16(bs); - ptr->reserved = gf_bs_read_u16(bs); - return GF_OK; -} - -GF_Box *gmin_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_GenericMediaHeaderInfoBox, GF_QT_BOX_TYPE_GMIN); - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err gmin_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_GenericMediaHeaderInfoBox *ptr = (GF_GenericMediaHeaderInfoBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, ptr->graphics_mode); - gf_bs_write_u16(bs, ptr->op_color_red); - gf_bs_write_u16(bs, ptr->op_color_green); - gf_bs_write_u16(bs, ptr->op_color_blue); - gf_bs_write_u16(bs, ptr->balance); - gf_bs_write_u16(bs, ptr->reserved); - return GF_OK; -} - -GF_Err gmin_box_size(GF_Box *s) -{ - GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s; - ptr->size += 12; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -void clef_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err clef_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ApertureBox *ptr = (GF_ApertureBox *)s; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->width = gf_bs_read_u32(bs); - ptr->height = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *clef_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ApertureBox, GF_QT_BOX_TYPE_CLEF); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err clef_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ApertureBox *ptr = (GF_ApertureBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->width); - gf_bs_write_u32(bs, ptr->height); - return GF_OK; -} - -GF_Err clef_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void tmcd_box_del(GF_Box *s) -{ - if (s == NULL) return; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - gf_free(s); -} - - -GF_Err tmcd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TimeCodeSampleEntryBox *ptr = (GF_TimeCodeSampleEntryBox *)s; - GF_Err e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs); - if (e) return e; - - ISOM_DECREASE_SIZE(s, 26); - gf_bs_read_u32(bs); //reserved - ptr->flags = gf_bs_read_u32(bs); - ptr->timescale = gf_bs_read_u32(bs); - ptr->frame_duration = gf_bs_read_u32(bs); - ptr->frames_per_counter_tick = gf_bs_read_u8(bs); - gf_bs_read_u8(bs); //reserved - - return gf_isom_box_array_read(s, bs, NULL); -} - -GF_Box *tmcd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TimeCodeSampleEntryBox, GF_QT_BOX_TYPE_TMCD); - gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tmcd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TimeCodeSampleEntryBox *ptr = (GF_TimeCodeSampleEntryBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - - gf_bs_write_u32(bs, 0); //reserved - gf_bs_write_u32(bs, ptr->flags); - gf_bs_write_u32(bs, ptr->timescale); - gf_bs_write_u32(bs, ptr->frame_duration); - gf_bs_write_u8(bs, ptr->frames_per_counter_tick); - gf_bs_write_u8(bs, 0); //reserved - - return GF_OK; -} - -GF_Err tmcd_box_size(GF_Box *s) -{ - GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s; - ptr->size += 8 + 18; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void tcmi_box_del(GF_Box *s) -{ - GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s; - if (ptr->font) gf_free(ptr->font); - gf_free(s); -} - - -GF_Err tcmi_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 len; - GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s; - - //don't remove font name len field, some writers just skip it if no font ... - ISOM_DECREASE_SIZE(s, 20); - - ptr->text_font = gf_bs_read_u16(bs); - ptr->text_face = gf_bs_read_u16(bs); - ptr->text_size = gf_bs_read_u16(bs); - gf_bs_read_u16(bs); - ptr->text_color_red = gf_bs_read_u16(bs); - ptr->text_color_green = gf_bs_read_u16(bs); - ptr->text_color_blue = gf_bs_read_u16(bs); - ptr->back_color_red = gf_bs_read_u16(bs); - ptr->back_color_green = gf_bs_read_u16(bs); - ptr->back_color_blue = gf_bs_read_u16(bs); - if (!ptr->size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] broken tmci box, missing font name length field\n" )); - return GF_OK; - } - ISOM_DECREASE_SIZE(s, 1); - - len = gf_bs_read_u8(bs); - if (len > ptr->size) - len = (u32) ptr->size; - if (len) { - ptr->font = gf_malloc(len+1); - if (!ptr->font) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->font, len); - ptr->size -= len; - ptr->font[len]=0; - } - return GF_OK; -} - -GF_Box *tcmi_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TimeCodeMediaInformationBox, GF_QT_BOX_TYPE_TCMI); - tmp->text_size = 12; - tmp->text_color_red = 0xFFFF; - tmp->text_color_green = 0xFFFF; - tmp->text_color_blue = 0xFFFF; - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tcmi_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 len; - GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->text_font); - gf_bs_write_u16(bs, ptr->text_face); - gf_bs_write_u16(bs, ptr->text_size); - gf_bs_write_u16(bs, 0); - gf_bs_write_u16(bs, ptr->text_color_red); - gf_bs_write_u16(bs, ptr->text_color_green); - gf_bs_write_u16(bs, ptr->text_color_blue); - gf_bs_write_u16(bs, ptr->back_color_red); - gf_bs_write_u16(bs, ptr->back_color_green); - gf_bs_write_u16(bs, ptr->back_color_blue); - len = ptr->font ? (u32) strlen(ptr->font) : 0; - gf_bs_write_u8(bs, len); - if (ptr->font) - gf_bs_write_data(bs, ptr->font, len); - - return GF_OK; -} - -GF_Err tcmi_box_size(GF_Box *s) -{ - GF_TimeCodeMediaInformationBox *ptr = (GF_TimeCodeMediaInformationBox *)s; - ptr->size += 21; - if (ptr->font) - ptr->size += strlen(ptr->font); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void fiel_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err fiel_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_FieldInfoBox *ptr = (GF_FieldInfoBox *)s; - - ISOM_DECREASE_SIZE(s, 2); - - ptr->field_count = gf_bs_read_u8(bs); - ptr->field_order = gf_bs_read_u8(bs); - return GF_OK; -} - -GF_Box *fiel_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_FieldInfoBox, GF_QT_BOX_TYPE_FIEL); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err fiel_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_FieldInfoBox *ptr = (GF_FieldInfoBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->field_count); - gf_bs_write_u8(bs, ptr->field_order); - return GF_OK; -} - -GF_Err fiel_box_size(GF_Box *s) -{ - s->size += 2; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void gama_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err gama_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_GamaInfoBox *ptr = (GF_GamaInfoBox *)s; - - ISOM_DECREASE_SIZE(s, 4); - - ptr->gama = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *gama_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_GamaInfoBox, GF_QT_BOX_TYPE_GAMA); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err gama_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_GamaInfoBox *ptr = (GF_GamaInfoBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->gama); - return GF_OK; -} - -GF_Err gama_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void chrm_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err chrm_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ChromaInfoBox *ptr = (GF_ChromaInfoBox *)s; - - ISOM_DECREASE_SIZE(s, 2); - - ptr->chroma = gf_bs_read_u16(bs); - return GF_OK; -} - -GF_Box *chrm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ChromaInfoBox, GF_QT_BOX_TYPE_CHRM); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err chrm_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_ChromaInfoBox *ptr = (GF_ChromaInfoBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->chroma); - return GF_OK; -} - -GF_Err chrm_box_size(GF_Box *s) -{ - s->size += 2; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void chan_box_del(GF_Box *s) -{ - GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s; - if (ptr->audio_descs) gf_free(ptr->audio_descs); - if (ptr->ext_data) gf_free(ptr->ext_data); - gf_free(s); -} - - -GF_Err chan_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s; - - ISOM_DECREASE_SIZE(s, 12); - ptr->layout_tag = gf_bs_read_u32(bs); - ptr->bitmap = gf_bs_read_u32(bs); - ptr->num_audio_description = gf_bs_read_u32(bs); - - if (ptr->size < ptr->num_audio_description*20) - return GF_ISOM_INVALID_FILE; - - ptr->audio_descs = gf_malloc(sizeof(GF_AudioChannelDescription) * ptr->num_audio_description); - if (!ptr->audio_descs) return GF_OUT_OF_MEM; - - for (i=0; inum_audio_description; i++) { - GF_AudioChannelDescription *adesc = &ptr->audio_descs[i]; - ISOM_DECREASE_SIZE(s, 20); - adesc->label = gf_bs_read_u32(bs); - adesc->flags = gf_bs_read_u32(bs); - adesc->coordinates[0] = gf_bs_read_float(bs); - adesc->coordinates[1] = gf_bs_read_float(bs); - adesc->coordinates[2] = gf_bs_read_float(bs); - } - //avoids warning on most files - if (ptr->size==20) { - ptr->size=0; - gf_bs_skip_bytes(bs, 20); - } - if (ptr->size<10000) { - ptr->ext_data_size = (u32) ptr->size; - ptr->ext_data = gf_malloc(sizeof(u8) * ptr->ext_data_size); - if (!ptr->ext_data) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, (char *)ptr->ext_data, (u32) ptr->size); - ptr->size = 0; - } - return GF_OK; -} - -GF_Box *chan_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ChannelLayoutInfoBox, GF_QT_BOX_TYPE_CHAN); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err chan_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - - gf_bs_write_u32(bs, ptr->layout_tag); - gf_bs_write_u32(bs, ptr->bitmap); - gf_bs_write_u32(bs, ptr->num_audio_description); - for (i=0; inum_audio_description; i++) { - GF_AudioChannelDescription *adesc = &ptr->audio_descs[i]; - gf_bs_write_u32(bs, adesc->label); - gf_bs_write_u32(bs, adesc->flags); - gf_bs_write_float(bs, adesc->coordinates[0]); - gf_bs_write_float(bs, adesc->coordinates[1]); - gf_bs_write_float(bs, adesc->coordinates[2]); - } - if (ptr->ext_data) { - gf_bs_write_data(bs, ptr->ext_data, ptr->ext_data_size); - } - return GF_OK; -} - -GF_Err chan_box_size(GF_Box *s) -{ - GF_ChannelLayoutInfoBox *ptr = (GF_ChannelLayoutInfoBox *)s; - s->size += 12 + 20 * ptr->num_audio_description; - if (ptr->ext_data) { - s->size += ptr->ext_data_size; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void load_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err load_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackLoadBox *ptr = (GF_TrackLoadBox *)s; - ISOM_DECREASE_SIZE(s, 16); - ptr->preload_start_time = gf_bs_read_u32(bs); - ptr->preload_duration = gf_bs_read_u32(bs); - ptr->preload_flags = gf_bs_read_u32(bs); - ptr->default_hints = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *load_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackLoadBox, GF_QT_BOX_TYPE_LOAD); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err load_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackLoadBox *ptr = (GF_TrackLoadBox *)s; - - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->preload_start_time); - gf_bs_write_u32(bs, ptr->preload_duration); - gf_bs_write_u32(bs, ptr->preload_flags); - gf_bs_write_u32(bs, ptr->default_hints); - return GF_OK; -} - -GF_Err load_box_size(GF_Box *s) -{ - s->size += 16; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/thirdparty/gpacmp4/box_code_base.c b/src/thirdparty/gpacmp4/box_code_base.c deleted file mode 100644 index 809106bb9..000000000 --- a/src/thirdparty/gpacmp4/box_code_base.c +++ /dev/null @@ -1,11956 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2019 - * All rights reserved - * - * This file is part of GPAC / ISO Media File Format sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include - - - -#ifndef GPAC_DISABLE_ISOM - -void co64_box_del(GF_Box *s) -{ - GF_ChunkLargeOffsetBox *ptr; - ptr = (GF_ChunkLargeOffsetBox *) s; - if (ptr == NULL) return; - if (ptr->offsets) gf_free(ptr->offsets); - gf_free(ptr); -} - -GF_Err co64_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 entries; - GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s; - ptr->nb_entries = gf_bs_read_u32(bs); - - ISOM_DECREASE_SIZE(ptr, 4) - - if (ptr->nb_entries > ptr->size / 8) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in co64\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - - ptr->offsets = (u64 *) gf_malloc(ptr->nb_entries * sizeof(u64) ); - if (ptr->offsets == NULL) return GF_OUT_OF_MEM; - ptr->alloc_size = ptr->nb_entries; - for (entries = 0; entries < ptr->nb_entries; entries++) { - ptr->offsets[entries] = gf_bs_read_u64(bs); - } - return GF_OK; -} - -GF_Box *co64_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ChunkLargeOffsetBox, GF_ISOM_BOX_TYPE_CO64); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err co64_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nb_entries); - for (i = 0; i < ptr->nb_entries; i++ ) { - gf_bs_write_u64(bs, ptr->offsets[i]); - } - return GF_OK; -} - -GF_Err co64_box_size(GF_Box *s) -{ - GF_ChunkLargeOffsetBox *ptr = (GF_ChunkLargeOffsetBox *) s; - - ptr->size += 4 + (8 * ptr->nb_entries); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void cprt_box_del(GF_Box *s) -{ - GF_CopyrightBox *ptr = (GF_CopyrightBox *) s; - if (ptr == NULL) return; - if (ptr->notice) - gf_free(ptr->notice); - gf_free(ptr); -} - - -GF_Box *chpl_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ChapterListBox, GF_ISOM_BOX_TYPE_CHPL); - tmp->list = gf_list_new(); - tmp->version = 1; - return (GF_Box *)tmp; -} - -void chpl_box_del(GF_Box *s) -{ - GF_ChapterListBox *ptr = (GF_ChapterListBox *) s; - if (ptr == NULL) return; - while (gf_list_count(ptr->list)) { - GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0); - if (ce->name) gf_free(ce->name); - gf_free(ce); - gf_list_rem(ptr->list, 0); - } - gf_list_del(ptr->list); - gf_free(ptr); -} - -/*this is using chpl format according to some NeroRecode samples*/ -GF_Err chpl_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_ChapterEntry *ce; - u32 nb_chaps, len, i, count; - GF_ChapterListBox *ptr = (GF_ChapterListBox *)s; - - ISOM_DECREASE_SIZE(ptr, 5) - /*reserved or ???*/ - gf_bs_read_u32(bs); - nb_chaps = gf_bs_read_u8(bs); - - count = 0; - while (nb_chaps) { - GF_SAFEALLOC(ce, GF_ChapterEntry); - if (!ce) return GF_OUT_OF_MEM; - ISOM_DECREASE_SIZE(ptr, 9) - ce->start_time = gf_bs_read_u64(bs); - len = gf_bs_read_u8(bs); - if (ptr->sizename = (char *)gf_malloc(sizeof(char)*(len+1)); - if (!ce->name) return GF_OUT_OF_MEM; - ISOM_DECREASE_SIZE(ptr, len) - gf_bs_read_data(bs, ce->name, len); - ce->name[len] = 0; - } else { - ce->name = gf_strdup(""); - } - - for (i=0; ilist, i); - if (ace->start_time >= ce->start_time) { - gf_list_insert(ptr->list, ce, i); - ce = NULL; - break; - } - } - if (ce) gf_list_add(ptr->list, ce); - count++; - nb_chaps--; - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err chpl_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 count, i; - GF_ChapterListBox *ptr = (GF_ChapterListBox *) s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - count = gf_list_count(ptr->list); - gf_bs_write_u32(bs, 0); - gf_bs_write_u8(bs, count); - for (i=0; ilist, i); - gf_bs_write_u64(bs, ce->start_time); - if (ce->name) { - len = (u32) strlen(ce->name); - if (len>255) len = 255; - gf_bs_write_u8(bs, len); - gf_bs_write_data(bs, ce->name, len); - } else { - gf_bs_write_u8(bs, 0); - } - } - return GF_OK; -} - -GF_Err chpl_box_size(GF_Box *s) -{ - u32 count, i; - GF_ChapterListBox *ptr = (GF_ChapterListBox *)s; - - ptr->size += 5; - - count = gf_list_count(ptr->list); - for (i=0; ilist, i); - ptr->size += 9; /*64bit time stamp + 8bit str len*/ - if (ce->name) ptr->size += strlen(ce->name); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Err cprt_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_CopyrightBox *ptr = (GF_CopyrightBox *)s; - - ISOM_DECREASE_SIZE(ptr, 2); - gf_bs_read_int(bs, 1); - //the spec is unclear here, just says "the value 0 is interpreted as undetermined" - ptr->packedLanguageCode[0] = gf_bs_read_int(bs, 5); - ptr->packedLanguageCode[1] = gf_bs_read_int(bs, 5); - ptr->packedLanguageCode[2] = gf_bs_read_int(bs, 5); - - //but before or after compaction ?? We assume before - if (ptr->packedLanguageCode[0] || ptr->packedLanguageCode[1] || ptr->packedLanguageCode[2]) { - ptr->packedLanguageCode[0] += 0x60; - ptr->packedLanguageCode[1] += 0x60; - ptr->packedLanguageCode[2] += 0x60; - } else { - ptr->packedLanguageCode[0] = 'u'; - ptr->packedLanguageCode[1] = 'n'; - ptr->packedLanguageCode[2] = 'd'; - } - if (ptr->size) { - u32 bytesToRead = (u32) ptr->size; - ptr->notice = (char*)gf_malloc(bytesToRead * sizeof(char)); - if (ptr->notice == NULL) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->notice, bytesToRead); - } - return GF_OK; -} - -GF_Box *cprt_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_CopyrightBox, GF_ISOM_BOX_TYPE_CPRT); - tmp->packedLanguageCode[0] = 'u'; - tmp->packedLanguageCode[1] = 'n'; - tmp->packedLanguageCode[2] = 'd'; - - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err cprt_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_CopyrightBox *ptr = (GF_CopyrightBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_int(bs, 0, 1); - if (ptr->packedLanguageCode[0]) { - gf_bs_write_int(bs, ptr->packedLanguageCode[0] - 0x60, 5); - gf_bs_write_int(bs, ptr->packedLanguageCode[1] - 0x60, 5); - gf_bs_write_int(bs, ptr->packedLanguageCode[2] - 0x60, 5); - } else { - gf_bs_write_int(bs, 0, 15); - } - if (ptr->notice) { - gf_bs_write_data(bs, ptr->notice, (u32) (strlen(ptr->notice) + 1) ); - } - return GF_OK; -} - -GF_Err cprt_box_size(GF_Box *s) -{ - GF_CopyrightBox *ptr = (GF_CopyrightBox *)s; - - ptr->size += 2; - if (ptr->notice) - ptr->size += strlen(ptr->notice) + 1; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void kind_box_del(GF_Box *s) -{ - GF_KindBox *ptr = (GF_KindBox *) s; - if (ptr == NULL) return; - if (ptr->schemeURI) gf_free(ptr->schemeURI); - if (ptr->value) gf_free(ptr->value); - gf_free(ptr); -} - -GF_Err kind_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_KindBox *ptr = (GF_KindBox *)s; - - if (ptr->size) { - u32 bytesToRead = (u32) ptr->size; - char *data; - u32 schemeURIlen; - data = (char*)gf_malloc(bytesToRead * sizeof(char)); - if (!data) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, data, bytesToRead); - /*safety check in case the string is not null-terminated*/ - if (data[bytesToRead-1]) { - data = (char*)gf_realloc(data, sizeof(char)*(bytesToRead + 1)); - if (!data) return GF_OUT_OF_MEM; - data[bytesToRead] = 0; - bytesToRead++; - } - ptr->schemeURI = gf_strdup(data); - if (!ptr->schemeURI) return GF_OUT_OF_MEM; - schemeURIlen = (u32) strlen(data); - if (bytesToRead > schemeURIlen+1) { - /* read the value */ - char *data_value = data + schemeURIlen +1; - ptr->value = gf_strdup(data_value); - if (!ptr->value) return GF_OUT_OF_MEM; - } - gf_free(data); - } - return GF_OK; -} - -GF_Box *kind_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_KindBox, GF_ISOM_BOX_TYPE_KIND); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err kind_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_KindBox *ptr = (GF_KindBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->schemeURI) - gf_bs_write_data(bs, ptr->schemeURI, (u32) (strlen(ptr->schemeURI) + 1 )); - else - gf_bs_write_u8(bs, 0); - - if (ptr->value) { - gf_bs_write_data(bs, ptr->value, (u32) (strlen(ptr->value) + 1) ); - } - return GF_OK; -} - -GF_Err kind_box_size(GF_Box *s) -{ - GF_KindBox *ptr = (GF_KindBox *)s; - - ptr->size += (ptr->schemeURI ? strlen(ptr->schemeURI) : 0) + 1; - if (ptr->value) { - ptr->size += strlen(ptr->value) + 1; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void ctts_box_del(GF_Box *s) -{ - GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s; - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - - - -GF_Err ctts_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - u32 sampleCount; - GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nb_entries = gf_bs_read_u32(bs); - - if (ptr->nb_entries > ptr->size / 8) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - - ptr->alloc_size = ptr->nb_entries; - ptr->entries = (GF_DttsEntry *)gf_malloc(sizeof(GF_DttsEntry)*ptr->alloc_size); - if (!ptr->entries) return GF_OUT_OF_MEM; - sampleCount = 0; - for (i=0; inb_entries; i++) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->entries[i].sampleCount = gf_bs_read_u32(bs); - if (ptr->version) - ptr->entries[i].decodingOffset = gf_bs_read_int(bs, 32); - else - ptr->entries[i].decodingOffset = (s32) gf_bs_read_u32(bs); - sampleCount += ptr->entries[i].sampleCount; - - if (ptr->max_ts_delta < ABS(ptr->entries[i].decodingOffset)) - ptr->max_ts_delta = ABS(ptr->entries[i].decodingOffset); - } -#ifndef GPAC_DISABLE_ISOM_WRITE - ptr->w_LastSampleNumber = sampleCount; -#endif - return GF_OK; -} - -GF_Box *ctts_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_CompositionOffsetBox, GF_ISOM_BOX_TYPE_CTTS); - return (GF_Box *) tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ctts_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nb_entries); - for (i=0; inb_entries; i++ ) { - gf_bs_write_u32(bs, ptr->entries[i].sampleCount); - if (ptr->version) { - gf_bs_write_int(bs, ptr->entries[i].decodingOffset, 32); - } else { - gf_bs_write_u32(bs, (u32) ptr->entries[i].decodingOffset); - } - } - return GF_OK; -} - -GF_Err ctts_box_size(GF_Box *s) -{ - GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *) s; - - ptr->size += 4 + (8 * ptr->nb_entries); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void cslg_box_del(GF_Box *s) -{ - GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s; - if (ptr == NULL) return; - gf_free(ptr); - return; -} - -GF_Err cslg_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s; - - ISOM_DECREASE_SIZE(ptr, 20); - ptr->compositionToDTSShift = gf_bs_read_int(bs, 32); - ptr->leastDecodeToDisplayDelta = gf_bs_read_int(bs, 32); - ptr->greatestDecodeToDisplayDelta = gf_bs_read_int(bs, 32); - ptr->compositionStartTime = gf_bs_read_int(bs, 32); - ptr->compositionEndTime = gf_bs_read_int(bs, 32); - return GF_OK; -} - -GF_Box *cslg_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_CompositionToDecodeBox, GF_ISOM_BOX_TYPE_CSLG); - return (GF_Box *) tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err cslg_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_int(bs, ptr->compositionToDTSShift, 32); - gf_bs_write_int(bs, ptr->leastDecodeToDisplayDelta, 32); - gf_bs_write_int(bs, ptr->greatestDecodeToDisplayDelta, 32); - gf_bs_write_int(bs, ptr->compositionStartTime, 32); - gf_bs_write_int(bs, ptr->compositionEndTime, 32); - return GF_OK; -} - -GF_Err cslg_box_size(GF_Box *s) -{ - GF_CompositionToDecodeBox *ptr = (GF_CompositionToDecodeBox *)s; - - ptr->size += 20; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void ccst_box_del(GF_Box *s) -{ - GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s; - if (ptr) gf_free(ptr); - return; -} - -GF_Err ccst_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->all_ref_pics_intra = gf_bs_read_int(bs, 1); - ptr->intra_pred_used = gf_bs_read_int(bs, 1); - ptr->max_ref_per_pic = gf_bs_read_int(bs, 4); - ptr->reserved = gf_bs_read_int(bs, 26); - return GF_OK; -} - -GF_Box *ccst_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_CodingConstraintsBox, GF_ISOM_BOX_TYPE_CCST); - return (GF_Box *) tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ccst_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_int(bs, ptr->all_ref_pics_intra, 1); - gf_bs_write_int(bs, ptr->intra_pred_used, 1); - gf_bs_write_int(bs, ptr->max_ref_per_pic, 4); - gf_bs_write_int(bs, 0, 26); - return GF_OK; -} - -GF_Err ccst_box_size(GF_Box *s) -{ - GF_CodingConstraintsBox *ptr = (GF_CodingConstraintsBox *)s; - ptr->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void url_box_del(GF_Box *s) -{ - GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s; - if (ptr == NULL) return; - if (ptr->location) gf_free(ptr->location); - gf_free(ptr); - return; -} - - -GF_Err url_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s; - - if (ptr->size) { - ptr->location = (char*)gf_malloc((u32) ptr->size); - if (! ptr->location) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->location, (u32)ptr->size); - if (ptr->location[ptr->size-1]) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] url box location is not 0-terminated\n" )); - return GF_ISOM_INVALID_FILE; - } - } - return GF_OK; -} - -GF_Box *url_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DataEntryURLBox, GF_ISOM_BOX_TYPE_URL); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err url_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - //the flag set indicates we have a string (WE HAVE TO for URLs) - if ( !(ptr->flags & 1)) { - if (ptr->location) { - gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1); - } - } - return GF_OK; -} - -GF_Err url_box_size(GF_Box *s) -{ - GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s; - - if ( !(ptr->flags & 1)) { - if (ptr->location) ptr->size += 1 + strlen(ptr->location); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void urn_box_del(GF_Box *s) -{ - GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s; - if (ptr == NULL) return; - if (ptr->location) gf_free(ptr->location); - if (ptr->nameURN) gf_free(ptr->nameURN); - gf_free(ptr); -} - - -GF_Err urn_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i, to_read; - char *tmpName; - GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s; - if (! ptr->size ) return GF_OK; - - //here we have to handle that in a clever way - to_read = (u32) ptr->size; - tmpName = (char*)gf_malloc(sizeof(char) * to_read); - if (!tmpName) return GF_OUT_OF_MEM; - //get the data - gf_bs_read_data(bs, tmpName, to_read); - - //then get the break - i = 0; - while ( (i < to_read) && (tmpName[i] != 0) ) { - i++; - } - //check the data is consistent - if (i == to_read) { - gf_free(tmpName); - return GF_ISOM_INVALID_FILE; - } - //no NULL char, URL is not specified - if (i == to_read - 1) { - ptr->nameURN = tmpName; - ptr->location = NULL; - return GF_OK; - } - //OK, this has both URN and URL - ptr->nameURN = (char*)gf_malloc(sizeof(char) * (i+1)); - if (!ptr->nameURN) { - gf_free(tmpName); - return GF_OUT_OF_MEM; - } - memcpy(ptr->nameURN, tmpName, i + 1); - - if (tmpName[to_read - 1] != 0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] urn box contains invalid location field\n" )); - } - else { - ptr->location = (char*)gf_malloc(sizeof(char) * (to_read - i - 1)); - if (!ptr->location) { - gf_free(tmpName); - gf_free(ptr->nameURN); - ptr->nameURN = NULL; - return GF_OUT_OF_MEM; - } - memcpy(ptr->location, tmpName + i + 1, (to_read - i - 1)); - } - - gf_free(tmpName); - return GF_OK; -} - -GF_Box *urn_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DataEntryURNBox, GF_ISOM_BOX_TYPE_URN); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err urn_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - //the flag set indicates we have a string (WE HAVE TO for URLs) - if ( !(ptr->flags & 1)) { - //to check, the spec says: First name, then location - if (ptr->nameURN) { - gf_bs_write_data(bs, ptr->nameURN, (u32)strlen(ptr->nameURN) + 1); - } - if (ptr->location) { - gf_bs_write_data(bs, ptr->location, (u32)strlen(ptr->location) + 1); - } - } - return GF_OK; -} - -GF_Err urn_box_size(GF_Box *s) -{ - GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s; - - if ( !(ptr->flags & 1)) { - if (ptr->nameURN) ptr->size += 1 + strlen(ptr->nameURN); - if (ptr->location) ptr->size += 1 + strlen(ptr->location); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void unkn_box_del(GF_Box *s) -{ - GF_UnknownBox *ptr = (GF_UnknownBox *) s; - if (!s) return; - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - - -GF_Err unkn_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 bytesToRead, sub_size, sub_a; - GF_BitStream *sub_bs; - GF_UnknownBox *ptr = (GF_UnknownBox *)s; - if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE; - bytesToRead = (u32) (ptr->size); - - if (!bytesToRead) return GF_OK; - if (bytesToRead>1000000) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unknown box %s (0x%08X) with payload larger than 1 MBytes, ignoring\n", gf_4cc_to_str(ptr->type), ptr->type )); - gf_bs_skip_bytes(bs, ptr->dataSize); - return GF_OK; - } - - ptr->data = (char*)gf_malloc(bytesToRead); - if (ptr->data == NULL ) return GF_OUT_OF_MEM; - ptr->dataSize = bytesToRead; - gf_bs_read_data(bs, ptr->data, ptr->dataSize); - - //try to parse container boxes, check if next 8 bytes match a subbox - sub_bs = gf_bs_new(ptr->data, ptr->dataSize, GF_BITSTREAM_READ); - sub_size = gf_bs_read_u32(sub_bs); - sub_a = gf_bs_read_u8(sub_bs); - e = (sub_size && (sub_size <= ptr->dataSize)) ? GF_OK : GF_NOT_SUPPORTED; - if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED; - sub_a = gf_bs_read_u8(sub_bs); - if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED; - sub_a = gf_bs_read_u8(sub_bs); - if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED; - sub_a = gf_bs_read_u8(sub_bs); - if (! isalnum(sub_a)) e = GF_NOT_SUPPORTED; - - if (e == GF_OK) { - gf_bs_seek(sub_bs, 0); - gf_bs_set_cookie(sub_bs, GF_ISOM_BS_COOKIE_NO_LOGS); - e = gf_isom_box_array_read(s, sub_bs, NULL); - } - gf_bs_del(sub_bs); - if (e==GF_OK) { - gf_free(ptr->data); - ptr->data = NULL; - ptr->dataSize = 0; - } else if (s->child_boxes) { - gf_isom_box_array_del(s->child_boxes); - s->child_boxes=NULL; - } - - return GF_OK; -} - -GF_Box *unkn_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_UnknownBox, GF_ISOM_BOX_TYPE_UNKNOWN); - return (GF_Box *) tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err unkn_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 type; - GF_UnknownBox *ptr = (GF_UnknownBox *)s; - if (!s) return GF_BAD_PARAM; - type = s->type; - ptr->type = ptr->original_4cc; - e = gf_isom_box_write_header(s, bs); - ptr->type = type; - if (e) return e; - - if (ptr->dataSize && ptr->data) { - gf_bs_write_data(bs, ptr->data, ptr->dataSize); - } - return GF_OK; -} - -GF_Err unkn_box_size(GF_Box *s) -{ - GF_UnknownBox *ptr = (GF_UnknownBox *)s; - - if (ptr->dataSize && ptr->data) { - ptr->size += ptr->dataSize; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void def_parent_box_del(GF_Box *s) -{ - if (s) gf_free(s); -} - - -GF_Err def_parent_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, NULL); -} - -GF_Box *def_parent_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_Box, 0); - return (GF_Box *) tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITEHintSa - -GF_Err def_parent_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err def_parent_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void def_parent_full_box_del(GF_Box *s) -{ - if (s) gf_free(s); -} - - -GF_Err def_parent_full_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, NULL); -} - -GF_Box *def_parent_full_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_Box, 0); - return (GF_Box *) tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITEHintSa - -GF_Err def_parent_full_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err def_parent_full_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void uuid_box_del(GF_Box *s) -{ - GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *) s; - if (!s) return; - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - - -GF_Err uuid_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 bytesToRead; - GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *)s; - if (ptr->size > 0xFFFFFFFF) return GF_ISOM_INVALID_FILE; - bytesToRead = (u32) (ptr->size); - - if (bytesToRead) { - ptr->data = (char*)gf_malloc(bytesToRead); - if (ptr->data == NULL ) return GF_OUT_OF_MEM; - ptr->dataSize = bytesToRead; - gf_bs_read_data(bs, ptr->data, ptr->dataSize); - } - return GF_OK; -} - -GF_Box *uuid_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_UnknownUUIDBox, GF_ISOM_BOX_TYPE_UUID); - return (GF_Box *) tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err uuid_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox*)s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - if (ptr->data) { - gf_bs_write_data(bs, ptr->data, ptr->dataSize); - } - return GF_OK; -} - -GF_Err uuid_box_size(GF_Box *s) -{ - GF_UnknownUUIDBox*ptr = (GF_UnknownUUIDBox*)s; - ptr->size += ptr->dataSize; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void dinf_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err dinf_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_DataInformationBox *ptr = (GF_DataInformationBox *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_DREF: - if (ptr->dref) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->dref = (GF_DataReferenceBox *)a; - return GF_OK; - } - return GF_OK; -} - -GF_Err dinf_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_DataInformationBox *dinf; - GF_Err e = gf_isom_box_array_read(s, bs, dinf_on_child_box); - if (e) { - return e; - } - dinf = (GF_DataInformationBox *)s; - if (!dinf->dref) { - if (! (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_NO_LOGS) ) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing dref box in dinf\n")); - } - dinf->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&dinf->child_boxes, GF_ISOM_BOX_TYPE_DREF); - } - return GF_OK; -} - -GF_Box *dinf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DataInformationBox, GF_ISOM_BOX_TYPE_DINF); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err dinf_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err dinf_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void dref_box_del(GF_Box *s) -{ - GF_DataReferenceBox *ptr = (GF_DataReferenceBox *) s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err dref_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - gf_bs_read_u32(bs); - return gf_isom_box_array_read(s, bs, NULL); -} - -GF_Box *dref_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DataReferenceBox, GF_ISOM_BOX_TYPE_DREF); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err dref_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 count; - GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - count = ptr->child_boxes ? gf_list_count(ptr->child_boxes) : 0; - gf_bs_write_u32(bs, count); - return GF_OK; -} - -GF_Err dref_box_size(GF_Box *s) -{ - GF_DataReferenceBox *ptr = (GF_DataReferenceBox *)s; - if (!s) return GF_BAD_PARAM; - - ptr->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void edts_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err edts_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_EditBox *ptr = (GF_EditBox *)s; - if (a->type == GF_ISOM_BOX_TYPE_ELST) { - if (ptr->editList) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->editList = (GF_EditListBox *)a; - return GF_OK; - } else { - return GF_OK; - } - return GF_OK; -} - - -GF_Err edts_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, edts_on_child_box); -} - -GF_Box *edts_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_EditBox, GF_ISOM_BOX_TYPE_EDTS); - return (GF_Box *) tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err edts_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_EditBox *ptr = (GF_EditBox *)s; - - //here we have a trick: if editList is empty, skip the box - if (ptr->editList && gf_list_count(ptr->editList->entryList)) { - return gf_isom_box_write_header(s, bs); - } else { - s->size = 0; - } - return GF_OK; -} - -GF_Err edts_box_size(GF_Box *s) -{ - GF_EditBox *ptr = (GF_EditBox *)s; - - //here we have a trick: if editList is empty, skip the box - if (!ptr->editList || ! gf_list_count(ptr->editList->entryList)) { - ptr->size = 0; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void elst_box_del(GF_Box *s) -{ - GF_EditListBox *ptr; - u32 nb_entries; - u32 i; - - ptr = (GF_EditListBox *)s; - if (ptr == NULL) return; - nb_entries = gf_list_count(ptr->entryList); - for (i = 0; i < nb_entries; i++) { - GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i); - if (p) gf_free(p); - } - gf_list_del(ptr->entryList); - gf_free(ptr); -} - -GF_Err elst_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 entries; - s32 tr; - u32 nb_entries; - GF_EditListBox *ptr = (GF_EditListBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - nb_entries = gf_bs_read_u32(bs); - - if (ptr->version == 1) { - if (nb_entries > ptr->size / 20) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries)); - return GF_ISOM_INVALID_FILE; - } - } else { - if (nb_entries > ptr->size / 12) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in ctts\n", nb_entries)); - return GF_ISOM_INVALID_FILE; - } - } - - - for (entries = 0; entries < nb_entries; entries++) { - GF_EdtsEntry *p = (GF_EdtsEntry *) gf_malloc(sizeof(GF_EdtsEntry)); - if (!p) return GF_OUT_OF_MEM; - if (ptr->version == 1) { - ISOM_DECREASE_SIZE(ptr, 16); - p->segmentDuration = gf_bs_read_u64(bs); - p->mediaTime = (s64) gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 8); - p->segmentDuration = gf_bs_read_u32(bs); - tr = gf_bs_read_u32(bs); - p->mediaTime = (s64) tr; - } - ISOM_DECREASE_SIZE(ptr, 4); - p->mediaRate = gf_bs_read_u16(bs); - gf_bs_read_u16(bs); - gf_list_add(ptr->entryList, p); - } - return GF_OK; -} - -GF_Box *elst_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_EditListBox, GF_ISOM_BOX_TYPE_ELST); - tmp->entryList = gf_list_new(); - if (!tmp->entryList) { - gf_free(tmp); - return NULL; - } - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err elst_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - u32 nb_entries; - GF_EditListBox *ptr = (GF_EditListBox *)s; - if (!ptr) return GF_BAD_PARAM; - - nb_entries = gf_list_count(ptr->entryList); - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, nb_entries); - for (i = 0; i < nb_entries; i++ ) { - GF_EdtsEntry *p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i); - if (ptr->version == 1) { - gf_bs_write_u64(bs, p->segmentDuration); - gf_bs_write_u64(bs, p->mediaTime); - } else { - gf_bs_write_u32(bs, (u32) p->segmentDuration); - gf_bs_write_u32(bs, (s32) p->mediaTime); - } - gf_bs_write_u16(bs, p->mediaRate); - gf_bs_write_u16(bs, 0); - } - return GF_OK; -} - -GF_Err elst_box_size(GF_Box *s) -{ - u32 durtimebytes; - u32 i, nb_entries; - GF_EditListBox *ptr = (GF_EditListBox *)s; - - //entry count - ptr->size += 4; - nb_entries = gf_list_count(ptr->entryList); - ptr->version = 0; - for (i=0; ientryList, i); - if ((p->segmentDuration>0xFFFFFFFF) || (p->mediaTime>0xFFFFFFFF)) { - ptr->version = 1; - break; - } - } - durtimebytes = (ptr->version == 1 ? 16 : 8) + 4; - ptr->size += (nb_entries * durtimebytes); - return GF_OK; -} - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void esds_box_del(GF_Box *s) -{ - GF_ESDBox *ptr = (GF_ESDBox *)s; - if (ptr == NULL) return; - if (ptr->desc) gf_odf_desc_del((GF_Descriptor *)ptr->desc); - gf_free(ptr); -} - - -GF_Err esds_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e=GF_OK; - u32 descSize; - GF_ESDBox *ptr = (GF_ESDBox *)s; - - descSize = (u32) (ptr->size); - - if (descSize) { - char *enc_desc = (char*)gf_malloc(sizeof(char) * descSize); - if (!enc_desc) return GF_OUT_OF_MEM; - //get the payload - gf_bs_read_data(bs, enc_desc, descSize); - //send it to the OD Codec - e = gf_odf_desc_read(enc_desc, descSize, (GF_Descriptor **) &ptr->desc); - //OK, free our desc - gf_free(enc_desc); - - if (ptr->desc && (ptr->desc->tag!=GF_ODF_ESD_TAG) ) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid descriptor tag 0x%x in esds\n", ptr->desc->tag)); - gf_odf_desc_del((GF_Descriptor*)ptr->desc); - ptr->desc=NULL; - return GF_ISOM_INVALID_FILE; - } - - if (e) { - ptr->desc = NULL; - } else { - /*fix broken files*/ - if (ptr->desc && !ptr->desc->URLString) { - if (!ptr->desc->slConfig) { - ptr->desc->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); - ptr->desc->slConfig->predefined = SLPredef_MP4; - } else if (ptr->desc->slConfig->predefined != SLPredef_MP4) { - ptr->desc->slConfig->predefined = SLPredef_MP4; - gf_odf_slc_set_pref(ptr->desc->slConfig); - } - } - } - } - return e; -} - -GF_Box *esds_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ESDBox, GF_ISOM_BOX_TYPE_ESDS); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err esds_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u8 *enc_desc; - u32 descSize = 0; - GF_ESDBox *ptr = (GF_ESDBox *)s; - //make sure we write with no ESID and no OCRESID - if (ptr->desc) { - ptr->desc->ESID = 0; - ptr->desc->OCRESID = 0; - } - e = gf_isom_full_box_write(s, bs); - if (e) return e; - e = gf_odf_desc_write((GF_Descriptor *)ptr->desc, &enc_desc, &descSize); - if (e) return e; - gf_bs_write_data(bs, enc_desc, descSize); - //free our buffer - gf_free(enc_desc); - return GF_OK; -} - -GF_Err esds_box_size(GF_Box *s) -{ - u32 descSize = 0; - GF_ESDBox *ptr = (GF_ESDBox *)s; - descSize = gf_odf_desc_size((GF_Descriptor *)ptr->desc); - ptr->size += descSize; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void free_box_del(GF_Box *s) -{ - GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s; - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - - -GF_Err free_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 bytesToRead; - GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s; - - if (ptr->size > 0xFFFFFFFF) return GF_IO_ERR; - - bytesToRead = (u32) (ptr->size); - - if (bytesToRead) { - ptr->data = (char*)gf_malloc(bytesToRead * sizeof(char)); - if (!ptr->data) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->data, bytesToRead); - ptr->dataSize = bytesToRead; - } - return GF_OK; -} - -GF_Box *free_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_FreeSpaceBox, GF_ISOM_BOX_TYPE_FREE); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err free_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s; - if (ptr->original_4cc) { - u32 t = s->type; - s->type=ptr->original_4cc; - e = gf_isom_box_write_header(s, bs); - s->type=t; - } else { - e = gf_isom_box_write_header(s, bs); - } - if (e) return e; - if (ptr->dataSize) { - if (ptr->data) { - gf_bs_write_data(bs, ptr->data, ptr->dataSize); - } else { - u32 i = 0; - while (idataSize) { - gf_bs_write_u8(bs, 0); - i++; - } - } - } - return GF_OK; -} - -GF_Err free_box_size(GF_Box *s) -{ - GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s; - ptr->size += ptr->dataSize; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void ftyp_box_del(GF_Box *s) -{ - GF_FileTypeBox *ptr = (GF_FileTypeBox *) s; - if (ptr->altBrand) gf_free(ptr->altBrand); - gf_free(ptr); -} - -GF_Box *ftyp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_FileTypeBox, GF_ISOM_BOX_TYPE_FTYP); - return (GF_Box *)tmp; -} - -GF_Err ftyp_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_FileTypeBox *ptr = (GF_FileTypeBox *)s; - - ISOM_DECREASE_SIZE(ptr, 8); - ptr->majorBrand = gf_bs_read_u32(bs); - ptr->minorVersion = gf_bs_read_u32(bs); - - if (ptr->size % 4) return GF_ISOM_INVALID_FILE; - ptr->altCount = ( (u32) (ptr->size)) / 4; - if (!ptr->altCount) return GF_OK; - - ptr->altBrand = (u32*)gf_malloc(sizeof(u32)*ptr->altCount); - if (!ptr->altBrand) return GF_OUT_OF_MEM; - - for (i = 0; ialtCount; i++) { - ptr->altBrand[i] = gf_bs_read_u32(bs); - } - return GF_OK; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ftyp_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_FileTypeBox *ptr = (GF_FileTypeBox *) s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->majorBrand); - gf_bs_write_u32(bs, ptr->minorVersion); - for (i=0; ialtCount; i++) { - gf_bs_write_u32(bs, ptr->altBrand[i]); - } - return GF_OK; -} - -GF_Err ftyp_box_size(GF_Box *s) -{ - GF_FileTypeBox *ptr = (GF_FileTypeBox *)s; - - ptr->size += 8 + ptr->altCount * 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void gnrm_box_del(GF_Box *s) -{ - GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr); - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - -GF_Box *gnrm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_GenericSampleEntryBox, GF_ISOM_BOX_TYPE_GNRM); - - gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp); - return (GF_Box *)tmp; -} - -//dummy -GF_Err gnrm_box_read(GF_Box *s, GF_BitStream *bs) -{ - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err gnrm_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s; - - //carefull we are not writing the box type but the entry type so switch for write - ptr->type = ptr->EntryType; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - ptr->type = GF_ISOM_BOX_TYPE_GNRM; - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - gf_bs_write_data(bs, ptr->data, ptr->data_size); - return GF_OK; -} - -GF_Err gnrm_box_size(GF_Box *s) -{ - GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s; - s->type = GF_ISOM_BOX_TYPE_GNRM; - ptr->size += 8+ptr->data_size; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void gnrv_box_del(GF_Box *s) -{ - GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr); - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - -GF_Box *gnrv_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_GenericVisualSampleEntryBox, GF_ISOM_BOX_TYPE_GNRV); - gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox*) tmp); - return (GF_Box *)tmp; -} -//dummy -GF_Err gnrv_box_read(GF_Box *s, GF_BitStream *bs) -{ - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err gnrv_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s; - - //carefull we are not writing the box type but the entry type so switch for write - ptr->type = ptr->EntryType; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - ptr->type = GF_ISOM_BOX_TYPE_GNRV; - - gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)ptr, bs); - gf_bs_write_data(bs, ptr->data, ptr->data_size); - return GF_OK; -} - -GF_Err gnrv_box_size(GF_Box *s) -{ - GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s; - s->type = GF_ISOM_BOX_TYPE_GNRV; - gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s); - ptr->size += ptr->data_size; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void gnra_box_del(GF_Box *s) -{ - GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr); - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - -GF_Box *gnra_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_GenericAudioSampleEntryBox, GF_ISOM_BOX_TYPE_GNRA); - gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*) tmp); - return (GF_Box *)tmp; -} -//dummy -GF_Err gnra_box_read(GF_Box *s, GF_BitStream *bs) -{ - return GF_OK; -} -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err gnra_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s; - - //carefull we are not writing the box type but the entry type so switch for write - ptr->type = ptr->EntryType; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - ptr->type = GF_ISOM_BOX_TYPE_GNRA; - - gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox *)ptr, bs); - if (ptr->data) { - gf_bs_write_data(bs, ptr->data, ptr->data_size); - } - return GF_OK; -} - -GF_Err gnra_box_size(GF_Box *s) -{ - GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s; - s->type = GF_ISOM_BOX_TYPE_GNRA; - gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox *)s); - ptr->size += ptr->data_size; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void hdlr_box_del(GF_Box *s) -{ - GF_HandlerBox *ptr = (GF_HandlerBox *)s; - if (ptr == NULL) return; - if (ptr->nameUTF8) gf_free(ptr->nameUTF8); - gf_free(ptr); -} - - -GF_Err hdlr_box_read(GF_Box *s, GF_BitStream *bs) -{ - u64 cookie; - GF_HandlerBox *ptr = (GF_HandlerBox *)s; - - ISOM_DECREASE_SIZE(ptr, 20); - ptr->reserved1 = gf_bs_read_u32(bs); - ptr->handlerType = gf_bs_read_u32(bs); - gf_bs_read_data(bs, (char*)ptr->reserved2, 12); - - cookie = gf_bs_get_cookie(bs); - if (ptr->handlerType==GF_ISOM_MEDIA_VISUAL) - cookie |= GF_ISOM_BS_COOKIE_VISUAL_TRACK; - else - cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK; - gf_bs_set_cookie(bs, cookie); - - if (ptr->size) { - ptr->nameUTF8 = (char*)gf_malloc((u32) ptr->size); - if (!ptr->nameUTF8) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->nameUTF8, (u32) ptr->size); - - //patch for old QT files - we cannot rely on checking if str[0]==len(str+1) since we may have - //cases where the first character of the string decimal value is indeed the same as the string length!! - //we had this issue with encryption_import test - //we therefore only check if last char is null, and if not so assume old QT style - if (ptr->nameUTF8[ptr->size-1]) { - memmove(ptr->nameUTF8, ptr->nameUTF8+1, sizeof(char) * (u32) (ptr->size-1) ); - ptr->nameUTF8[ptr->size-1] = 0; - ptr->store_counted_string = GF_TRUE; - } - } - return GF_OK; -} - -GF_Box *hdlr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_HandlerBox, GF_ISOM_BOX_TYPE_HDLR); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err hdlr_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_HandlerBox *ptr = (GF_HandlerBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->reserved1); - gf_bs_write_u32(bs, ptr->handlerType); - gf_bs_write_data(bs, (char*)ptr->reserved2, 12); - - if (ptr->nameUTF8) { - u32 len = (u32)strlen(ptr->nameUTF8); - if (ptr->store_counted_string) { - gf_bs_write_u8(bs, len); - gf_bs_write_data(bs, ptr->nameUTF8, len); - } else { - gf_bs_write_data(bs, ptr->nameUTF8, len); - gf_bs_write_u8(bs, 0); - } - } else { - gf_bs_write_u8(bs, 0); - } - return GF_OK; -} - -GF_Err hdlr_box_size(GF_Box *s) -{ - GF_HandlerBox *ptr = (GF_HandlerBox *)s; - ptr->size += 20 + 1; //null term or counted string - if (ptr->nameUTF8) { - ptr->size += strlen(ptr->nameUTF8); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void hinf_box_del(GF_Box *s) -{ - GF_HintInfoBox *hinf = (GF_HintInfoBox *)s; - gf_free(hinf); -} - -GF_Box *hinf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_HintInfoBox, GF_ISOM_BOX_TYPE_HINF); - - tmp->child_boxes = gf_list_new(); - return (GF_Box *)tmp; -} - -GF_Err hinf_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MAXRBox *maxR; - GF_HintInfoBox *hinf = (GF_HintInfoBox *)s; - u32 i; - switch (a->type) { - case GF_ISOM_BOX_TYPE_MAXR: - i=0; - while ((maxR = (GF_MAXRBox *)gf_list_enum(hinf->child_boxes, &i))) { - if ((maxR->type==GF_ISOM_BOX_TYPE_MAXR) && (maxR->granularity == ((GF_MAXRBox *)a)->granularity)) - ERROR_ON_DUPLICATED_BOX(a, s) - } - break; - } - return GF_OK; -} - - -GF_Err hinf_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, hinf_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err hinf_box_write(GF_Box *s, GF_BitStream *bs) -{ -// GF_HintInfoBox *ptr = (GF_HintInfoBox *)s; - if (!s) return GF_BAD_PARAM; - return gf_isom_box_write_header(s, bs); -} - -GF_Err hinf_box_size(GF_Box *s) -{ - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void hmhd_box_del(GF_Box *s) -{ - GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err hmhd_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s; - - ISOM_DECREASE_SIZE(ptr, 16); - ptr->maxPDUSize = gf_bs_read_u16(bs); - ptr->avgPDUSize = gf_bs_read_u16(bs); - ptr->maxBitrate = gf_bs_read_u32(bs); - ptr->avgBitrate = gf_bs_read_u32(bs); - ptr->slidingAverageBitrate = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *hmhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_HintMediaHeaderBox, GF_ISOM_BOX_TYPE_HMHD); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err hmhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->maxPDUSize); - gf_bs_write_u16(bs, ptr->avgPDUSize); - gf_bs_write_u32(bs, ptr->maxBitrate); - gf_bs_write_u32(bs, ptr->avgBitrate); - gf_bs_write_u32(bs, ptr->slidingAverageBitrate); - return GF_OK; -} - -GF_Err hmhd_box_size(GF_Box *s) -{ - GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s; - ptr->size += 16; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *hnti_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_HintTrackInfoBox, GF_ISOM_BOX_TYPE_HNTI); - return (GF_Box *)tmp; -} - -void hnti_box_del(GF_Box *a) -{ - gf_free(a); -} - -GF_Err hnti_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_HintTrackInfoBox *hnti = (GF_HintTrackInfoBox *)s; - if (!hnti || !a) return GF_BAD_PARAM; - - switch (a->type) { - //this is the value for GF_RTPBox - same as HintSampleEntry for RTP !!! - case GF_ISOM_BOX_TYPE_RTP: - case GF_ISOM_BOX_TYPE_SDP: - if (hnti->SDP) ERROR_ON_DUPLICATED_BOX(a, s) - hnti->SDP = a; - break; - default: - break; - } - return GF_OK; -} - -GF_Err hnti_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read_ex(s, bs, hnti_on_child_box, s->type); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err hnti_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - - -GF_Err hnti_box_size(GF_Box *s) -{ - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/********************************************************** - GF_SDPBox -**********************************************************/ - -void sdp_box_del(GF_Box *s) -{ - GF_SDPBox *ptr = (GF_SDPBox *)s; - if (ptr->sdpText) gf_free(ptr->sdpText); - gf_free(ptr); - -} -GF_Err sdp_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 length; - GF_SDPBox *ptr = (GF_SDPBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - length = (u32) (ptr->size); - //sdp text has no delimiter !!! - ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1)); - if (!ptr->sdpText) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, ptr->sdpText, length); - ptr->sdpText[length] = 0; - return GF_OK; -} -GF_Box *sdp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SDPBox, GF_ISOM_BOX_TYPE_SDP); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err sdp_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SDPBox *ptr = (GF_SDPBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - //don't write the NULL char!!! - if (ptr->sdpText) - gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText)); - return GF_OK; -} -GF_Err sdp_box_size(GF_Box *s) -{ - GF_SDPBox *ptr = (GF_SDPBox *)s; - //don't count the NULL char!!! - if (ptr->sdpText) - ptr->size += strlen(ptr->sdpText); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -void rtp_hnti_box_del(GF_Box *s) -{ - GF_RTPBox *ptr = (GF_RTPBox *)s; - if (ptr->sdpText) gf_free(ptr->sdpText); - gf_free(ptr); - -} -GF_Err rtp_hnti_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 length; - GF_RTPBox *ptr = (GF_RTPBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - ISOM_DECREASE_SIZE(ptr, 4) - ptr->subType = gf_bs_read_u32(bs); - - length = (u32) (ptr->size); - //sdp text has no delimiter !!! - ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1)); - if (!ptr->sdpText) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, ptr->sdpText, length); - ptr->sdpText[length] = 0; - return GF_OK; -} - -GF_Box *rtp_hnti_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_RTPBox, GF_ISOM_BOX_TYPE_RTP); - tmp->subType = GF_ISOM_BOX_TYPE_SDP; - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err rtp_hnti_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_RTPBox *ptr = (GF_RTPBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->subType); - //don't write the NULL char!!! - gf_bs_write_data(bs, ptr->sdpText, (u32) strlen(ptr->sdpText)); - return GF_OK; -} - -GF_Err rtp_hnti_box_size(GF_Box *s) -{ - GF_RTPBox *ptr = (GF_RTPBox *)s; - ptr->size += 4 + strlen(ptr->sdpText); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - TRPY GF_Box -**********************************************************/ - -void trpy_box_del(GF_Box *s) -{ - gf_free((GF_TRPYBox *)s); -} -GF_Err trpy_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TRPYBox *ptr = (GF_TRPYBox *)s; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->nbBytes = gf_bs_read_u64(bs); - return GF_OK; -} -GF_Box *trpy_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TRPYBox, GF_ISOM_BOX_TYPE_TRPY); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err trpy_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TRPYBox *ptr = (GF_TRPYBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u64(bs, ptr->nbBytes); - return GF_OK; -} -GF_Err trpy_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/********************************************************** - TOTL GF_Box -**********************************************************/ - -void totl_box_del(GF_Box *s) -{ - gf_free((GF_TRPYBox *)s); -} -GF_Err totl_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TOTLBox *ptr = (GF_TOTLBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nbBytes = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *totl_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TOTLBox, GF_ISOM_BOX_TYPE_TOTL); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err totl_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TOTLBox *ptr = (GF_TOTLBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nbBytes); - return GF_OK; -} -GF_Err totl_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - NUMP GF_Box -**********************************************************/ - -void nump_box_del(GF_Box *s) -{ - gf_free((GF_NUMPBox *)s); -} -GF_Err nump_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_NUMPBox *ptr = (GF_NUMPBox *)s; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->nbPackets = gf_bs_read_u64(bs); - return GF_OK; -} -GF_Box *nump_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_NUMPBox, GF_ISOM_BOX_TYPE_NUMP); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err nump_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_NUMPBox *ptr = (GF_NUMPBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u64(bs, ptr->nbPackets); - return GF_OK; -} -GF_Err nump_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - NPCK GF_Box -**********************************************************/ - -void npck_box_del(GF_Box *s) -{ - gf_free((GF_NPCKBox *)s); -} -GF_Err npck_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_NPCKBox *ptr = (GF_NPCKBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nbPackets = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *npck_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_NPCKBox, GF_ISOM_BOX_TYPE_NPCK); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err npck_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_NPCKBox *ptr = (GF_NPCKBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nbPackets); - return GF_OK; -} -GF_Err npck_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - TPYL GF_Box -**********************************************************/ - -void tpyl_box_del(GF_Box *s) -{ - gf_free((GF_NTYLBox *)s); -} -GF_Err tpyl_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_NTYLBox *ptr = (GF_NTYLBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->nbBytes = gf_bs_read_u64(bs); - return GF_OK; -} -GF_Box *tpyl_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_NTYLBox, GF_ISOM_BOX_TYPE_TPYL); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err tpyl_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_NTYLBox *ptr = (GF_NTYLBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u64(bs, ptr->nbBytes); - return GF_OK; -} -GF_Err tpyl_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/********************************************************** - TPAY GF_Box -**********************************************************/ - -void tpay_box_del(GF_Box *s) -{ - gf_free((GF_TPAYBox *)s); -} -GF_Err tpay_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TPAYBox *ptr = (GF_TPAYBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nbBytes = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *tpay_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TPAYBox, GF_ISOM_BOX_TYPE_TPAY); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err tpay_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TPAYBox *ptr = (GF_TPAYBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nbBytes); - return GF_OK; -} -GF_Err tpay_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - MAXR GF_Box -**********************************************************/ - -void maxr_box_del(GF_Box *s) -{ - gf_free((GF_MAXRBox *)s); -} -GF_Err maxr_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MAXRBox *ptr = (GF_MAXRBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->granularity = gf_bs_read_u32(bs); - ptr->maxDataRate = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *maxr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MAXRBox, GF_ISOM_BOX_TYPE_MAXR); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err maxr_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MAXRBox *ptr = (GF_MAXRBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->granularity); - gf_bs_write_u32(bs, ptr->maxDataRate); - return GF_OK; -} -GF_Err maxr_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - DMED GF_Box -**********************************************************/ - -void dmed_box_del(GF_Box *s) -{ - gf_free((GF_DMEDBox *)s); -} -GF_Err dmed_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_DMEDBox *ptr = (GF_DMEDBox *)s; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->nbBytes = gf_bs_read_u64(bs); - return GF_OK; -} -GF_Box *dmed_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DMEDBox, GF_ISOM_BOX_TYPE_DMED); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err dmed_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DMEDBox *ptr = (GF_DMEDBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u64(bs, ptr->nbBytes); - return GF_OK; -} -GF_Err dmed_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/********************************************************** - DIMM GF_Box -**********************************************************/ - -void dimm_box_del(GF_Box *s) -{ - gf_free((GF_DIMMBox *)s); -} -GF_Err dimm_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_DIMMBox *ptr = (GF_DIMMBox *)s; - ISOM_DECREASE_SIZE(ptr, 8) - ptr->nbBytes = gf_bs_read_u64(bs); - return GF_OK; -} -GF_Box *dimm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DIMMBox, GF_ISOM_BOX_TYPE_DIMM); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err dimm_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DIMMBox *ptr = (GF_DIMMBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u64(bs, ptr->nbBytes); - return GF_OK; -} -GF_Err dimm_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/********************************************************** - DREP GF_Box -**********************************************************/ - -void drep_box_del(GF_Box *s) -{ - gf_free((GF_DREPBox *)s); -} -GF_Err drep_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_DREPBox *ptr = (GF_DREPBox *)s; - ISOM_DECREASE_SIZE(ptr, 8) - ptr->nbBytes = gf_bs_read_u64(bs); - return GF_OK; -} -GF_Box *drep_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DREPBox, GF_ISOM_BOX_TYPE_DREP); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err drep_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DREPBox *ptr = (GF_DREPBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u64(bs, ptr->nbBytes); - return GF_OK; -} -GF_Err drep_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -/********************************************************** - TMIN GF_Box -**********************************************************/ - -void tmin_box_del(GF_Box *s) -{ - gf_free((GF_TMINBox *)s); -} -GF_Err tmin_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TMINBox *ptr = (GF_TMINBox *)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->minTime = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *tmin_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TMINBox, GF_ISOM_BOX_TYPE_TMIN); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err tmin_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TMINBox *ptr = (GF_TMINBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->minTime); - return GF_OK; -} -GF_Err tmin_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - TMAX GF_Box -**********************************************************/ - -void tmax_box_del(GF_Box *s) -{ - gf_free((GF_TMAXBox *)s); -} -GF_Err tmax_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TMAXBox *ptr = (GF_TMAXBox *)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->maxTime = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *tmax_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TMAXBox, GF_ISOM_BOX_TYPE_TMAX); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err tmax_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TMAXBox *ptr = (GF_TMAXBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->maxTime); - return GF_OK; -} -GF_Err tmax_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - PMAX GF_Box -**********************************************************/ - -void pmax_box_del(GF_Box *s) -{ - gf_free((GF_PMAXBox *)s); -} -GF_Err pmax_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_PMAXBox *ptr = (GF_PMAXBox *)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->maxSize = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *pmax_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PMAXBox, GF_ISOM_BOX_TYPE_PMAX); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err pmax_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_PMAXBox *ptr = (GF_PMAXBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->maxSize); - return GF_OK; -} -GF_Err pmax_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - DMAX GF_Box -**********************************************************/ - -void dmax_box_del(GF_Box *s) -{ - gf_free((GF_DMAXBox *)s); -} -GF_Err dmax_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_DMAXBox *ptr = (GF_DMAXBox *)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->maxDur = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *dmax_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DMAXBox, GF_ISOM_BOX_TYPE_DMAX); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err dmax_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DMAXBox *ptr = (GF_DMAXBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->maxDur); - return GF_OK; -} -GF_Err dmax_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - PAYT GF_Box -**********************************************************/ - -void payt_box_del(GF_Box *s) -{ - GF_PAYTBox *payt = (GF_PAYTBox *)s; - if (payt->payloadString) gf_free(payt->payloadString); - gf_free(payt); -} -GF_Err payt_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 length; - GF_PAYTBox *ptr = (GF_PAYTBox *)s; - - ISOM_DECREASE_SIZE(ptr, 5 ); - ptr->payloadCode = gf_bs_read_u32(bs); - length = gf_bs_read_u8(bs); - ISOM_DECREASE_SIZE(ptr, length); - ptr->payloadString = (char*)gf_malloc(sizeof(char) * (length+1) ); - if (! ptr->payloadString) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->payloadString, length); - ptr->payloadString[length] = 0; - - return GF_OK; -} -GF_Box *payt_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PAYTBox, GF_ISOM_BOX_TYPE_PAYT); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err payt_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 len; - GF_Err e; - GF_PAYTBox *ptr = (GF_PAYTBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->payloadCode); - len = ptr->payloadString ? (u32) strlen(ptr->payloadString) : 0; - gf_bs_write_u8(bs, len); - if (len) gf_bs_write_data(bs, ptr->payloadString, len); - return GF_OK; -} -GF_Err payt_box_size(GF_Box *s) -{ - GF_PAYTBox *ptr = (GF_PAYTBox *)s; - s->size += 4 + 1; - if (ptr->payloadString) ptr->size += strlen(ptr->payloadString); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/********************************************************** - PAYT GF_Box -**********************************************************/ - -void name_box_del(GF_Box *s) -{ - GF_NameBox *name = (GF_NameBox *)s; - if (name->string) gf_free(name->string); - gf_free(name); -} -GF_Err name_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 length; - GF_NameBox *ptr = (GF_NameBox *)s; - - length = (u32) (ptr->size); - ptr->string = (char*)gf_malloc(sizeof(char) * (length+1)); - if (! ptr->string) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, ptr->string, length); - ptr->string[length] = 0; - return GF_OK; -} -GF_Box *name_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_NameBox, GF_ISOM_BOX_TYPE_NAME); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err name_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_NameBox *ptr = (GF_NameBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - if (ptr->string) { - gf_bs_write_data(bs, ptr->string, (u32) strlen(ptr->string) + 1); - } - return GF_OK; -} -GF_Err name_box_size(GF_Box *s) -{ - GF_NameBox *ptr = (GF_NameBox *)s; - if (ptr->string) ptr->size += strlen(ptr->string) + 1; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void tssy_box_del(GF_Box *s) -{ - gf_free(s); -} -GF_Err tssy_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s; - ISOM_DECREASE_SIZE(ptr, 1) - gf_bs_read_int(bs, 6); - ptr->timestamp_sync = gf_bs_read_int(bs, 2); - return GF_OK; -} -GF_Box *tssy_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TimeStampSynchronyBox, GF_ISOM_BOX_TYPE_TSSY); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err tssy_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TimeStampSynchronyBox *ptr = (GF_TimeStampSynchronyBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_int(bs, 0, 6); - gf_bs_write_int(bs, ptr->timestamp_sync, 2); - return GF_OK; -} -GF_Err tssy_box_size(GF_Box *s) -{ - s->size += 1; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void srpp_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err srpp_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_SCHI: - if (ptr->info) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->info = (GF_SchemeInformationBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_SCHM: - if (ptr->scheme_type) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->scheme_type = (GF_SchemeTypeBox *)a; - return GF_OK; - } - return GF_OK; -} - -GF_Err srpp_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s; - - ISOM_DECREASE_SIZE(s, 16) - ptr->encryption_algorithm_rtp = gf_bs_read_u32(bs); - ptr->encryption_algorithm_rtcp = gf_bs_read_u32(bs); - ptr->integrity_algorithm_rtp = gf_bs_read_u32(bs); - ptr->integrity_algorithm_rtcp = gf_bs_read_u32(bs); - return gf_isom_box_array_read(s, bs, srpp_on_child_box); -} -GF_Box *srpp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SRTPProcessBox, GF_ISOM_BOX_TYPE_SRPP); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err srpp_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->encryption_algorithm_rtp); - gf_bs_write_u32(bs, ptr->encryption_algorithm_rtcp); - gf_bs_write_u32(bs, ptr->integrity_algorithm_rtp); - gf_bs_write_u32(bs, ptr->integrity_algorithm_rtcp); - - return GF_OK; -} -GF_Err srpp_box_size(GF_Box *s) -{ - u32 pos = 0; - GF_SRTPProcessBox *ptr = (GF_SRTPProcessBox *)s; - s->size += 16; - gf_isom_check_position(s, (GF_Box*)ptr->info, &pos); - gf_isom_check_position(s, (GF_Box*)ptr->scheme_type, &pos); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void rssr_box_del(GF_Box *s) -{ - gf_free(s); -} -GF_Err rssr_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s; - ISOM_DECREASE_SIZE(ptr, 4) - ptr->ssrc = gf_bs_read_u32(bs); - return GF_OK; -} -GF_Box *rssr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ReceivedSsrcBox, GF_ISOM_BOX_TYPE_RSSR); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err rssr_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ReceivedSsrcBox *ptr = (GF_ReceivedSsrcBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->ssrc); - return GF_OK; -} -GF_Err rssr_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -void iods_box_del(GF_Box *s) -{ - GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s; - if (ptr == NULL) return; - if (ptr->descriptor) gf_odf_desc_del(ptr->descriptor); - gf_free(ptr); -} - - -GF_Err iods_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 descSize; - char *desc; - GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s; - - //use the OD codec... - descSize = (u32) (ptr->size); - desc = (char*)gf_malloc(sizeof(char) * descSize); - if (!desc) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, desc, descSize); - e = gf_odf_desc_read(desc, descSize, &ptr->descriptor); - //OK, free our desc - gf_free(desc); - return e; -} - -GF_Box *iods_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ObjectDescriptorBox, GF_ISOM_BOX_TYPE_IODS); - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err iods_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 descSize; - u8 *desc; - GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - //call our OD codec - e = gf_odf_desc_write(ptr->descriptor, &desc, &descSize); - if (e) return e; - gf_bs_write_data(bs, desc, descSize); - //and free our stuff maybe!! - gf_free(desc); - return GF_OK; -} - -GF_Err iods_box_size(GF_Box *s) -{ - GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s; - - ptr->size += gf_odf_desc_size(ptr->descriptor); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void mdat_box_del(GF_Box *s) -{ - GF_MediaDataBox *ptr = (GF_MediaDataBox *)s; - if (!s) return; - - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - - -GF_Err mdat_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MediaDataBox *ptr = (GF_MediaDataBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - ptr->dataSize = s->size; - ptr->bsOffset = gf_bs_get_position(bs); - - //then skip these bytes - gf_bs_skip_bytes(bs, ptr->dataSize); - return GF_OK; -} - -GF_Box *mdat_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MediaDataBox, GF_ISOM_BOX_TYPE_MDAT); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mdat_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MediaDataBox *ptr = (GF_MediaDataBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - //make sure we have some data ... - //if not, we handle that independently (edit files) - if (ptr->data) { - gf_bs_write_data(bs, ptr->data, (u32) ptr->dataSize); - } - return GF_OK; -} - -GF_Err mdat_box_size(GF_Box *s) -{ - GF_MediaDataBox *ptr = (GF_MediaDataBox *)s; - ptr->size += ptr->dataSize; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void mdhd_box_del(GF_Box *s) -{ - GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err mdhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s; - - if (ptr->version == 1) { - ISOM_DECREASE_SIZE(ptr, 28) - ptr->creationTime = gf_bs_read_u64(bs); - ptr->modificationTime = gf_bs_read_u64(bs); - ptr->timeScale = gf_bs_read_u32(bs); - ptr->duration = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 16) - ptr->creationTime = gf_bs_read_u32(bs); - ptr->modificationTime = gf_bs_read_u32(bs); - ptr->timeScale = gf_bs_read_u32(bs); - ptr->duration = gf_bs_read_u32(bs); - } - if (!ptr->timeScale) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Media header timescale is 0 - defaulting to 90000\n" )); - ptr->timeScale = 90000; - } - - ptr->original_duration = ptr->duration; - - ISOM_DECREASE_SIZE(ptr, 4) - //our padding bit - gf_bs_read_int(bs, 1); - //the spec is unclear here, just says "the value 0 is interpreted as undetermined" - ptr->packedLanguage[0] = gf_bs_read_int(bs, 5); - ptr->packedLanguage[1] = gf_bs_read_int(bs, 5); - ptr->packedLanguage[2] = gf_bs_read_int(bs, 5); - //but before or after compaction ?? We assume before - if (ptr->packedLanguage[0] || ptr->packedLanguage[1] || ptr->packedLanguage[2]) { - ptr->packedLanguage[0] += 0x60; - ptr->packedLanguage[1] += 0x60; - ptr->packedLanguage[2] += 0x60; - } else { - ptr->packedLanguage[0] = 'u'; - ptr->packedLanguage[1] = 'n'; - ptr->packedLanguage[2] = 'd'; - } - ptr->reserved = gf_bs_read_u16(bs); - return GF_OK; -} - -GF_Box *mdhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MediaHeaderBox, GF_ISOM_BOX_TYPE_MDHD); - - tmp->packedLanguage[0] = 'u'; - tmp->packedLanguage[1] = 'n'; - tmp->packedLanguage[2] = 'd'; - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mdhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->version == 1) { - gf_bs_write_u64(bs, ptr->creationTime); - gf_bs_write_u64(bs, ptr->modificationTime); - gf_bs_write_u32(bs, ptr->timeScale); - gf_bs_write_u64(bs, ptr->duration); - } else { - gf_bs_write_u32(bs, (u32) ptr->creationTime); - gf_bs_write_u32(bs, (u32) ptr->modificationTime); - gf_bs_write_u32(bs, ptr->timeScale); - gf_bs_write_u32(bs, (u32) ptr->duration); - } - //SPECS: BIT(1) of padding - gf_bs_write_int(bs, 0, 1); - gf_bs_write_int(bs, ptr->packedLanguage[0] - 0x60, 5); - gf_bs_write_int(bs, ptr->packedLanguage[1] - 0x60, 5); - gf_bs_write_int(bs, ptr->packedLanguage[2] - 0x60, 5); - gf_bs_write_u16(bs, ptr->reserved); - return GF_OK; -} - -GF_Err mdhd_box_size(GF_Box *s) -{ - GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s; - ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0; - - ptr->size += 4; - ptr->size += (ptr->version == 1) ? 28 : 16; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void mdia_box_del(GF_Box *s) -{ - GF_MediaBox *ptr = (GF_MediaBox *)s; - if (ptr == NULL) return; - if (ptr->nalu_parser) gf_bs_del(ptr->nalu_parser); - if (ptr->nalu_out_bs) gf_bs_del(ptr->nalu_out_bs); - if (ptr->nalu_ps_bs) gf_bs_del(ptr->nalu_ps_bs); - if (ptr->extracted_bs) gf_bs_del(ptr->extracted_bs); - if (ptr->extracted_samp) gf_isom_sample_del(&ptr->extracted_samp); - if (ptr->in_sample_buffer) gf_free(ptr->in_sample_buffer); - if (ptr->tmp_nal_copy_buffer) gf_free(ptr->tmp_nal_copy_buffer); - gf_free(ptr); -} - - -GF_Err mdia_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MediaBox *ptr = (GF_MediaBox *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_MDHD: - if (ptr->mediaHeader) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->mediaHeader = (GF_MediaHeaderBox *)a; - return GF_OK; - - case GF_ISOM_BOX_TYPE_HDLR: - if (ptr->handler) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->handler = (GF_HandlerBox *)a; - return GF_OK; - - case GF_ISOM_BOX_TYPE_MINF: - if (ptr->information) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->information = (GF_MediaInformationBox *)a; - return GF_OK; - } - return GF_OK; -} - - -GF_Err mdia_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u64 cookie = gf_bs_get_cookie(bs); - cookie &= ~GF_ISOM_BS_COOKIE_VISUAL_TRACK; - gf_bs_set_cookie(bs, cookie); - e = gf_isom_box_array_read(s, bs, mdia_on_child_box); - gf_bs_set_cookie(bs, cookie); - - if (e) return e; - if (!((GF_MediaBox *)s)->information) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaInformationBox\n")); - return GF_ISOM_INVALID_FILE; - } - if (!((GF_MediaBox *)s)->handler) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing HandlerBox\n")); - return GF_ISOM_INVALID_FILE; - } - if (!((GF_MediaBox *)s)->mediaHeader) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaHeaderBox\n")); - return GF_ISOM_INVALID_FILE; - } - return GF_OK; -} - -GF_Box *mdia_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_MDIA); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mdia_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err mdia_box_size(GF_Box *s) -{ - u32 pos = 0; - GF_MediaBox *ptr = (GF_MediaBox *)s; - //Header first - gf_isom_check_position(s, (GF_Box*)ptr->mediaHeader, &pos); - //then handler - gf_isom_check_position(s, (GF_Box*)ptr->handler, &pos); - //then info - gf_isom_check_position(s, (GF_Box*)ptr->information, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void mfra_box_del(GF_Box *s) -{ - GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s; - if (ptr == NULL) return; - gf_list_del(ptr->tfra_list); - gf_free(ptr); -} - -GF_Box *mfra_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_MFRA); - tmp->tfra_list = gf_list_new(); - return (GF_Box *)tmp; -} - -GF_Err mfra_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_TFRA: - return gf_list_add(ptr->tfra_list, a); - case GF_ISOM_BOX_TYPE_MFRO: - if (ptr->mfro) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->mfro = (GF_MovieFragmentRandomAccessOffsetBox *)a; - return GF_OK; - } - return GF_OK; -} - -GF_Err mfra_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, mfra_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mfra_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err mfra_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MovieFragmentRandomAccessBox *ptr = (GF_MovieFragmentRandomAccessBox *)s; - gf_isom_check_position_list(s, ptr->tfra_list, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->mfro, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void tfra_box_del(GF_Box *s) -{ - GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s; - if (ptr == NULL) return; - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - -GF_Box *tfra_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRandomAccessBox, GF_ISOM_BOX_TYPE_TFRA); - return (GF_Box *)tmp; -} - -GF_Err tfra_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_RandomAccessEntry *p = 0; - GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s; - - ISOM_DECREASE_SIZE(ptr, 12); - - ptr->track_id = gf_bs_read_u32(bs); - if (gf_bs_read_int(bs, 26) != 0) - return GF_ISOM_INVALID_FILE; - - ptr->traf_bits = (gf_bs_read_int(bs, 2) + 1) * 8; - ptr->trun_bits = (gf_bs_read_int(bs, 2) + 1) * 8; - ptr->sample_bits = (gf_bs_read_int(bs, 2) + 1) * 8; - - ptr->nb_entries = gf_bs_read_u32(bs); - - if (ptr->version == 1) { - if (ptr->nb_entries > ptr->size / (16+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - } else { - if (ptr->nb_entries > ptr->size / (8+(ptr->traf_bits+ptr->trun_bits+ptr->sample_bits)/8)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in traf\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - } - - if (ptr->nb_entries) { - p = (GF_RandomAccessEntry *) gf_malloc(sizeof(GF_RandomAccessEntry) * ptr->nb_entries); - if (!p) return GF_OUT_OF_MEM; - } - - ptr->entries = p; - - for (i=0; inb_entries; i++) { - memset(p, 0, sizeof(GF_RandomAccessEntry)); - - if (ptr->version == 1) { - p->time = gf_bs_read_u64(bs); - p->moof_offset = gf_bs_read_u64(bs); - } else { - p->time = gf_bs_read_u32(bs); - p->moof_offset = gf_bs_read_u32(bs); - } - p->traf_number = gf_bs_read_int(bs, ptr->traf_bits); - p->trun_number = gf_bs_read_int(bs, ptr->trun_bits); - p->sample_number = gf_bs_read_int(bs, ptr->sample_bits); - - ++p; - } - - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tfra_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i, sap_nb_entries; - GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->track_id); - gf_bs_write_int(bs, 0, 26); - - gf_bs_write_int(bs, ptr->traf_bits/8 - 1, 2); - gf_bs_write_int(bs, ptr->trun_bits/8 - 1, 2); - gf_bs_write_int(bs, ptr->sample_bits/8 - 1, 2); - - sap_nb_entries = 0; - for (i=0; inb_entries; i++) { - GF_RandomAccessEntry *p = &ptr->entries[i]; - //no sap found, do not store - if (p->trun_number) sap_nb_entries++; - } - - gf_bs_write_u32(bs, sap_nb_entries); - - for (i=0; inb_entries; i++) { - GF_RandomAccessEntry *p = &ptr->entries[i]; - //no sap found, do not store - if (!p->trun_number) continue; - if (ptr->version==1) { - gf_bs_write_u64(bs, p->time); - gf_bs_write_u64(bs, p->moof_offset); - } else { - gf_bs_write_u32(bs, (u32) p->time); - gf_bs_write_u32(bs, (u32) p->moof_offset); - } - gf_bs_write_int(bs, p->traf_number, ptr->traf_bits); - gf_bs_write_int(bs, p->trun_number, ptr->trun_bits); - gf_bs_write_int(bs, p->sample_number, ptr->sample_bits); - } - return GF_OK; -} - -GF_Err tfra_box_size(GF_Box *s) -{ - u32 i; - GF_TrackFragmentRandomAccessBox *ptr = (GF_TrackFragmentRandomAccessBox *)s; - ptr->size += 12; - - for (i=0; inb_entries; i++) { - GF_RandomAccessEntry *p = &ptr->entries[i]; - //no sap found, do not store - if (!p->trun_number) continue; - ptr->size += ((ptr->version==1) ? 16 : 8 ) + ptr->traf_bits/8 + ptr->trun_bits/8 + ptr->sample_bits/8; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void mfro_box_del(GF_Box *s) -{ - GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Box *mfro_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieFragmentRandomAccessOffsetBox, GF_ISOM_BOX_TYPE_MFRO); - return (GF_Box *)tmp; -} - -GF_Err mfro_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->container_size = gf_bs_read_u32(bs); - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mfro_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MovieFragmentRandomAccessOffsetBox *ptr = (GF_MovieFragmentRandomAccessOffsetBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->container_size); - return GF_OK; -} - -GF_Err mfro_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void elng_box_del(GF_Box *s) -{ - GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s; - if (ptr == NULL) return; - if (ptr->extended_language) gf_free(ptr->extended_language); - gf_free(ptr); -} - -GF_Err elng_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s; - - if (ptr->size) { - ptr->extended_language = (char*)gf_malloc((u32) ptr->size); - if (ptr->extended_language == NULL) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->extended_language, (u32) ptr->size); - /*safety check in case the string is not null-terminated*/ - if (ptr->extended_language[ptr->size-1]) { - char *str = (char*)gf_malloc((u32) ptr->size + 1); - if (!str) return GF_OUT_OF_MEM; - memcpy(str, ptr->extended_language, (u32) ptr->size); - str[ptr->size] = 0; - gf_free(ptr->extended_language); - ptr->extended_language = str; - } - } - return GF_OK; -} - -GF_Box *elng_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MediaBox, GF_ISOM_BOX_TYPE_ELNG); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err elng_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->extended_language) { - gf_bs_write_data(bs, ptr->extended_language, (u32)(strlen(ptr->extended_language)+1)); - } - return GF_OK; -} - -GF_Err elng_box_size(GF_Box *s) -{ - GF_ExtendedLanguageBox *ptr = (GF_ExtendedLanguageBox *)s; - - if (ptr->extended_language) { - ptr->size += strlen(ptr->extended_language)+1; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void mfhd_box_del(GF_Box *s) -{ - GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err mfhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->sequence_number = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *mfhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieFragmentHeaderBox, GF_ISOM_BOX_TYPE_MFHD); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err mfhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->sequence_number); - return GF_OK; -} - -GF_Err mfhd_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - - -void minf_box_del(GF_Box *s) -{ - GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s; - if (ptr == NULL) return; - - //if we have a Handler not self-contained, delete it (the self-contained belongs to the movie) - if (ptr->dataHandler) { - gf_isom_datamap_close(ptr); - } - gf_free(ptr); -} - -GF_Err minf_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_NMHD: - case GF_ISOM_BOX_TYPE_STHD: - case GF_ISOM_BOX_TYPE_VMHD: - case GF_ISOM_BOX_TYPE_SMHD: - case GF_ISOM_BOX_TYPE_HMHD: - case GF_ISOM_BOX_TYPE_GMHD: - if (ptr->InfoHeader) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->InfoHeader = a; - return GF_OK; - - case GF_ISOM_BOX_TYPE_DINF: - if (ptr->dataInformation) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->dataInformation = (GF_DataInformationBox *)a; - return GF_OK; - - case GF_ISOM_BOX_TYPE_STBL: - if (ptr->sampleTable ) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->sampleTable = (GF_SampleTableBox *)a; - return GF_OK; - } - return GF_OK; -} - - -GF_Err minf_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s; - GF_Err e; - - e = gf_isom_box_array_read(s, bs, minf_on_child_box); - - if (!e && ! ptr->dataInformation) { - GF_Box *url; - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing DataInformationBox\n")); - //commented on purpose, we are still able to handle the file, we only throw an error but keep processing -// e = GF_ISOM_INVALID_FILE; - - //add a dinf box to avoid any access to a null dinf - ptr->dataInformation = (GF_DataInformationBox *) gf_isom_box_new_parent(&ptr->child_boxes, GF_ISOM_BOX_TYPE_DINF); - if (!ptr->dataInformation) return GF_OUT_OF_MEM; - - ptr->dataInformation->dref = (GF_DataReferenceBox *) gf_isom_box_new_parent(&ptr->dataInformation->child_boxes, GF_ISOM_BOX_TYPE_DREF); - if (!ptr->dataInformation->dref) return GF_OUT_OF_MEM; - - url = gf_isom_box_new_parent(&ptr->dataInformation->dref->child_boxes, GF_ISOM_BOX_TYPE_URL); - if (!url) return GF_OUT_OF_MEM; - ((GF_FullBox*)url)->flags = 1; - } - return e; -} - -GF_Box *minf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MediaInformationBox, GF_ISOM_BOX_TYPE_MINF); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err minf_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err minf_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MediaInformationBox *ptr = (GF_MediaInformationBox *)s; - //Header first - gf_isom_check_position(s, (GF_Box *)ptr->InfoHeader, &pos); - //then dataInfo - gf_isom_check_position(s, (GF_Box *)ptr->dataInformation, &pos); - gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_MVCI), &pos); - //then sampleTable - gf_isom_check_position(s, (GF_Box *)ptr->sampleTable, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void moof_box_del(GF_Box *s) -{ - GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s; - if (ptr == NULL) return; - - gf_list_del(ptr->TrackList); - if (ptr->PSSHs) gf_list_del(ptr->PSSHs); - if (ptr->mdat) gf_free(ptr->mdat); - gf_free(ptr); -} - -GF_Err moof_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_MFHD: - if (ptr->mfhd) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->mfhd = (GF_MovieFragmentHeaderBox *) a; - return GF_OK; - case GF_ISOM_BOX_TYPE_TRAF: - return gf_list_add(ptr->TrackList, a); - case GF_ISOM_BOX_TYPE_PSSH: - if (!ptr->PSSHs) ptr->PSSHs = gf_list_new(); - return gf_list_add(ptr->PSSHs, a); - } - return GF_OK; -} - -GF_Err moof_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, moof_on_child_box); -} - -GF_Box *moof_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieFragmentBox, GF_ISOM_BOX_TYPE_MOOF); - tmp->TrackList = gf_list_new(); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err moof_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err moof_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MovieFragmentBox *ptr = (GF_MovieFragmentBox *) s; - if (!s) return GF_BAD_PARAM; - //Header First - gf_isom_check_position(s, (GF_Box *)ptr->mfhd, &pos); - //then PSSH - gf_isom_check_position_list(s, ptr->PSSHs, &pos); - //then the track list - gf_isom_check_position_list(s, ptr->TrackList, &pos); - return GF_OK; -} - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - -void moov_box_del(GF_Box *s) -{ - GF_MovieBox *ptr = (GF_MovieBox *)s; - if (ptr == NULL) return; - gf_list_del(ptr->trackList); - gf_free(ptr); -} - -GF_Err moov_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MovieBox *ptr = (GF_MovieBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_IODS: - if (ptr->iods) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->iods = (GF_ObjectDescriptorBox *)a; - //if no IOD, delete the box - if (!ptr->iods->descriptor) { - ptr->iods = NULL; - gf_isom_box_del_parent(&s->child_boxes, a); - } - return GF_OK; - - case GF_ISOM_BOX_TYPE_MVHD: - if (ptr->mvhd) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->mvhd = (GF_MovieHeaderBox *)a; - return GF_OK; - - case GF_ISOM_BOX_TYPE_UDTA: - if (ptr->udta) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->udta = (GF_UserDataBox *)a; - return GF_OK; - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - case GF_ISOM_BOX_TYPE_MVEX: - if (ptr->mvex) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->mvex = (GF_MovieExtendsBox *)a; - ptr->mvex->mov = ptr->mov; - return GF_OK; -#endif - - case GF_ISOM_BOX_TYPE_META: - if (ptr->meta) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->meta = (GF_MetaBox *)a; - return GF_OK; - - case GF_ISOM_BOX_TYPE_TRAK: - //set our pointer to this obj - ((GF_TrackBox *)a)->moov = ptr; - return gf_list_add(ptr->trackList, a); - } - return GF_OK; -} - - -GF_Err moov_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, moov_on_child_box); -} - -GF_Box *moov_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieBox, GF_ISOM_BOX_TYPE_MOOV); - tmp->trackList = gf_list_new(); - if (!tmp->trackList) { - gf_free(tmp); - return NULL; - } - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err moov_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err moov_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MovieBox *ptr = (GF_MovieBox *)s; - - gf_isom_check_position(s, (GF_Box *) ptr->mvhd, &pos); - gf_isom_check_position(s, (GF_Box *) ptr->iods, &pos); - gf_isom_check_position(s, (GF_Box *) ptr->meta, &pos); -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - if (ptr->mvex && !ptr->mvex_after_traks) { - gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos); - } -#endif - gf_isom_check_position_list(s, ptr->trackList, &pos); - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - if (ptr->mvex && ptr->mvex_after_traks) { - gf_isom_check_position(s, (GF_Box *) ptr->mvex, &pos); - } -#endif - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void audio_sample_entry_box_del(GF_Box *s) -{ - GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s; - if (ptr == NULL) return; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc); - gf_free(ptr); -} - -GF_Err audio_sample_entry_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_UnknownBox *wave = NULL; - Bool drop_wave=GF_FALSE; - GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s; - - switch (a->type) { - case GF_ISOM_BOX_TYPE_ESDS: - if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->esd = (GF_ESDBox *)a; - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - break; - - case GF_ISOM_BOX_TYPE_DAMR: - case GF_ISOM_BOX_TYPE_DEVC: - case GF_ISOM_BOX_TYPE_DQCP: - case GF_ISOM_BOX_TYPE_DSMV: - if (ptr->cfg_3gpp) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->cfg_3gpp = (GF_3GPPConfigBox *) a; - /*for 3GP config, remember sample entry type in config*/ - ptr->cfg_3gpp->cfg.type = ptr->type; - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - break; - - case GF_ISOM_BOX_TYPE_DOPS: - if (ptr->cfg_opus) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->cfg_opus = (GF_OpusSpecificBox *)a; - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - break; - case GF_ISOM_BOX_TYPE_DAC3: - if (ptr->cfg_ac3) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->cfg_ac3 = (GF_AC3ConfigBox *) a; - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - break; - case GF_ISOM_BOX_TYPE_DEC3: - if (ptr->cfg_ac3) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->cfg_ac3 = (GF_AC3ConfigBox *) a; - break; - case GF_ISOM_BOX_TYPE_MHAC: - if (ptr->cfg_mha) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->cfg_mha = (GF_MHAConfigBox *) a; - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - break; - case GF_ISOM_BOX_TYPE_DFLA: - if (ptr->cfg_flac) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->cfg_flac = (GF_FLACConfigBox *) a; - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - break; - - case GF_ISOM_BOX_TYPE_UNKNOWN: - wave = (GF_UnknownBox *)a; - /*HACK for QT files: get the esds box from the track*/ - if (s->type == GF_ISOM_BOX_TYPE_MP4A) { - if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr) - - //wave subboxes may have been properly parsed - if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) { - u32 i; - for (i =0; ichild_boxes); i++) { - GF_Box *inner_box = (GF_Box *)gf_list_get(wave->child_boxes, i); - if (inner_box->type == GF_ISOM_BOX_TYPE_ESDS) { - ptr->esd = (GF_ESDBox *)inner_box; - if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) { - gf_list_rem(a->child_boxes, i); - drop_wave=GF_TRUE; - ptr->compression_id = 0; - gf_list_add(ptr->child_boxes, inner_box); - } - } - } - if (drop_wave) { - gf_isom_box_del_parent(&ptr->child_boxes, a); - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - ptr->version = 0; - return GF_OK; - } - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID; - return GF_OK; - } - gf_isom_box_del_parent(&ptr->child_boxes, a); - return GF_ISOM_INVALID_MEDIA; - - } - ptr->qtff_mode &= ~GF_ISOM_AUDIO_QTFF_CONVERT_FLAG; - - if ((wave->original_4cc == GF_QT_BOX_TYPE_WAVE) && gf_list_count(wave->child_boxes)) { - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT; - } - return GF_OK; - case GF_QT_BOX_TYPE_WAVE: - { - u32 subtype = 0; - GF_Box **cfg_ptr = NULL; - if (s->type == GF_ISOM_BOX_TYPE_MP4A) { - cfg_ptr = (GF_Box **) &ptr->esd; - subtype = GF_ISOM_BOX_TYPE_ESDS; - } - else if (s->type == GF_ISOM_BOX_TYPE_AC3) { - cfg_ptr = (GF_Box **) &ptr->cfg_ac3; - subtype = GF_ISOM_BOX_TYPE_DAC3; - } - else if (s->type == GF_ISOM_BOX_TYPE_EC3) { - cfg_ptr = (GF_Box **) &ptr->cfg_ac3; - subtype = GF_ISOM_BOX_TYPE_DEC3; - } - else if (s->type == GF_ISOM_BOX_TYPE_OPUS) { - cfg_ptr = (GF_Box **) &ptr->cfg_opus; - subtype = GF_ISOM_BOX_TYPE_DOPS; - } - else if ((s->type == GF_ISOM_BOX_TYPE_MHA1) - || (s->type == GF_ISOM_BOX_TYPE_MHA2) - || (s->type == GF_ISOM_BOX_TYPE_MHM1) - || (s->type == GF_ISOM_BOX_TYPE_MHM2) - ) { - cfg_ptr = (GF_Box **) &ptr->cfg_mha; - subtype = GF_ISOM_BOX_TYPE_MHAC; - } - - if (cfg_ptr) { - if (*cfg_ptr) ERROR_ON_DUPLICATED_BOX(a, ptr) - - //wave subboxes may have been properly parsed - if (gf_list_count(a->child_boxes)) { - u32 i; - for (i =0; ichild_boxes); i++) { - GF_Box *inner_box = (GF_Box *)gf_list_get(a->child_boxes, i); - if (inner_box->type == subtype) { - *cfg_ptr = inner_box; - if (ptr->qtff_mode & GF_ISOM_AUDIO_QTFF_CONVERT_FLAG) { - gf_list_rem(a->child_boxes, i); - drop_wave=GF_TRUE; - gf_list_add(ptr->child_boxes, inner_box); - } - break; - } - } - if (drop_wave) { - gf_isom_box_del_parent(&ptr->child_boxes, a); - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - ptr->compression_id = 0; - ptr->version = 0; - return GF_OK; - } - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID; - return GF_OK; - } - } - } - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_EXT_VALID; - return GF_OK; - } - return GF_OK; -} -GF_Err audio_sample_entry_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MPEGAudioSampleEntryBox *ptr; - char *data; - u8 a, b, c, d; - u32 i, size, v, nb_alnum; - GF_Err e; - u64 pos, start; - - ptr = (GF_MPEGAudioSampleEntryBox *)s; - - start = gf_bs_get_position(bs); - gf_bs_seek(bs, start + 8); - v = gf_bs_read_u16(bs); - if (v) - ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_ON_NOEXT; - - //try to disambiguate QTFF v1 and MP4 v1 audio sample entries ... - if (v==1) { - //go to end of ISOM audio sample entry, skip 4 byte (box size field), read 4 bytes (box type) and check if this looks like a box - gf_bs_seek(bs, start + 8 + 20 + 4); - a = gf_bs_read_u8(bs); - b = gf_bs_read_u8(bs); - c = gf_bs_read_u8(bs); - d = gf_bs_read_u8(bs); - nb_alnum = 0; - if (isalnum(a)) nb_alnum++; - if (isalnum(b)) nb_alnum++; - if (isalnum(c)) nb_alnum++; - if (isalnum(d)) nb_alnum++; - if (nb_alnum>2) ptr->qtff_mode = GF_ISOM_AUDIO_QTFF_NONE; - } - - gf_bs_seek(bs, start); - e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs); - if (e) return e; - pos = gf_bs_get_position(bs); - size = (u32) s->size; - - //when cookie is set on bs, always convert qtff-style mp4a to isobmff-style - //since the conversion is done in addBox and we don't have the bitstream there (arg...), flag the box - if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_QT_CONV) { - ptr->qtff_mode |= GF_ISOM_AUDIO_QTFF_CONVERT_FLAG; - } - - e = gf_isom_box_array_read(s, bs, audio_sample_entry_on_child_box); - if (!e) { - if (s->type==GF_ISOM_BOX_TYPE_ENCA) { - GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF); - - if (sinf && sinf->original_format) { - u32 type = sinf->original_format->data_format; - switch (type) { - case GF_ISOM_SUBTYPE_3GP_AMR: - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - case GF_ISOM_SUBTYPE_3GP_EVRC: - case GF_ISOM_SUBTYPE_3GP_QCELP: - case GF_ISOM_SUBTYPE_3GP_SMV: - if (ptr->cfg_3gpp) ptr->cfg_3gpp->cfg.type = type; - break; - } - } - } - return GF_OK; - } - if (size<8) return GF_ISOM_INVALID_FILE; - - - /*hack for some weird files (possibly recorded with live.com tools, needs further investigations)*/ - gf_bs_seek(bs, pos); - data = (char*)gf_malloc(sizeof(char) * size); - if (!data) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, data, size); - for (i=0; iesd) gf_isom_box_del_parent(&ptr->child_boxes, (GF_Box *)ptr->esd); - ptr->esd = NULL; - e = gf_isom_box_parse((GF_Box **)&ptr->esd, mybs); - gf_bs_del(mybs); - if (e==GF_OK) { - if (!ptr->child_boxes) ptr->child_boxes = gf_list_new(); - gf_list_add(ptr->child_boxes, ptr->esd); - } else if (ptr->esd) { - gf_isom_box_del((GF_Box *)ptr->esd); - ptr->esd = NULL; - } - break; - } - } - gf_free(data); - return e; -} - -GF_Box *audio_sample_entry_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_MP4A); - gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp); - return (GF_Box *)tmp; -} - -GF_Box *enca_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MPEGAudioSampleEntryBox, GF_ISOM_BOX_TYPE_ENCA); - gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err audio_sample_entry_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs); - return GF_OK; -} - -GF_Err audio_sample_entry_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MPEGAudioSampleEntryBox *ptr = (GF_MPEGAudioSampleEntryBox *)s; - gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s); - if (ptr->qtff_mode) - return GF_OK; - - gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->cfg_opus, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->cfg_ac3, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->cfg_flac, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void gen_sample_entry_box_del(GF_Box *s) -{ - GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s; - if (ptr == NULL) return; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - gf_free(ptr); -} - - -GF_Err gen_sample_entry_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)s, bs); - if (e) return e; - ISOM_DECREASE_SIZE(s, 8); - return gf_isom_box_array_read(s, bs, NULL); -} - -GF_Box *gen_sample_entry_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleEntryBox, GF_QT_SUBTYPE_C608);//type will be overriten - gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err gen_sample_entry_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - return GF_OK; -} - -GF_Err gen_sample_entry_box_size(GF_Box *s) -{ - GF_SampleEntryBox *ptr = (GF_SampleEntryBox *)s; - ptr->size += 8; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void mp4s_box_del(GF_Box *s) -{ - GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s; - if (ptr == NULL) return; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc); - gf_free(ptr); -} - -GF_Err mp4s_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_ESDS: - if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->esd = (GF_ESDBox *)a; - break; - } - return GF_OK; -} - -GF_Err mp4s_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s; - - e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs); - if (e) return e; - - ISOM_DECREASE_SIZE(ptr, 8); - return gf_isom_box_array_read(s, bs, mp4s_on_child_box); -} - -GF_Box *mp4s_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_MP4S); - gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp); - tmp->internal_type = GF_ISOM_SAMPLE_ENTRY_MP4S; - return (GF_Box *)tmp; -} - -GF_Box *encs_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MPEGSampleEntryBox, GF_ISOM_BOX_TYPE_ENCS); - gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp); - tmp->internal_type = GF_ISOM_SAMPLE_ENTRY_MP4S; - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mp4s_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - return GF_OK; -} - -GF_Err mp4s_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MPEGSampleEntryBox *ptr = (GF_MPEGSampleEntryBox *)s; - s->size += 8; - gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void video_sample_entry_box_del(GF_Box *s) -{ - GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s; - if (ptr == NULL) return; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - - if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc); - /*for publishing*/ - if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd); - gf_free(ptr); -} - -GF_Err video_sample_entry_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_ESDS: - if (ptr->esd) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->esd = (GF_ESDBox *)a; - break; - case GF_ISOM_BOX_TYPE_RINF: - if (ptr->rinf) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->rinf = (GF_RestrictedSchemeInfoBox *) a; - break; - case GF_ISOM_BOX_TYPE_AVCC: - if (ptr->avc_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->avc_config = (GF_AVCConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_HVCC: - if (ptr->hevc_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->hevc_config = (GF_HEVCConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_SVCC: - if (ptr->svc_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->svc_config = (GF_AVCConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_MVCC: - if (ptr->mvc_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->mvc_config = (GF_AVCConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_LHVC: - if (ptr->lhvc_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->lhvc_config = (GF_HEVCConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_AV1C: - if (ptr->av1_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->av1_config = (GF_AV1ConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_VPCC: - if (ptr->vp_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->vp_config = (GF_VPConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_DVCC: - if (ptr->dovi_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->dovi_config = (GF_DOVIConfigurationBox*)a; - break; - case GF_ISOM_BOX_TYPE_UUID: - if (! memcmp(((GF_UnknownUUIDBox*)a)->uuid, GF_ISOM_IPOD_EXT, 16)) { - if (ptr->ipod_ext) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->ipod_ext = (GF_UnknownUUIDBox *)a; - } else { - return GF_OK; - } - break; - case GF_ISOM_BOX_TYPE_D263: - if (ptr->cfg_3gpp) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->cfg_3gpp = (GF_3GPPConfigBox *)a; - /*for 3GP config, remember sample entry type in config*/ - ptr->cfg_3gpp->cfg.type = ptr->type; - break; - - case GF_ISOM_BOX_TYPE_JP2H: - if (ptr->jp2h) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->jp2h = (GF_J2KHeaderBox *)a; - return GF_OK; - - case GF_ISOM_BOX_TYPE_PASP: - case GF_ISOM_BOX_TYPE_CLAP: - case GF_ISOM_BOX_TYPE_COLR: - case GF_ISOM_BOX_TYPE_MDCV: - case GF_ISOM_BOX_TYPE_CLLI: - case GF_ISOM_BOX_TYPE_CCST: - case GF_ISOM_BOX_TYPE_AUXI: - case GF_ISOM_BOX_TYPE_RVCC: - case GF_ISOM_BOX_TYPE_M4DS: - if (!gf_isom_box_check_unique(s->child_boxes, a)) { - ERROR_ON_DUPLICATED_BOX(a, ptr) - } - return GF_OK; - } - return GF_OK; -} - -GF_Err video_sample_entry_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MPEGVisualSampleEntryBox *mp4v = (GF_MPEGVisualSampleEntryBox*)s; - GF_Err e; - e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)s, bs); - if (e) return e; - e = gf_isom_box_array_read(s, bs, video_sample_entry_on_child_box); - if (e) return e; - /*this is an AVC sample desc*/ - if (mp4v->avc_config || mp4v->svc_config || mp4v->mvc_config) - AVC_RewriteESDescriptor(mp4v); - /*this is an HEVC sample desc*/ - if (mp4v->hevc_config || mp4v->lhvc_config || (mp4v->type==GF_ISOM_BOX_TYPE_HVT1)) - HEVC_RewriteESDescriptor(mp4v); - /*this is an AV1 sample desc*/ - if (mp4v->av1_config) - AV1_RewriteESDescriptor(mp4v); - /*this is a VP8-9 sample desc*/ - if (mp4v->vp_config) - VP9_RewriteESDescriptor(mp4v); - - if (s->type==GF_ISOM_BOX_TYPE_ENCV) { - GF_ProtectionSchemeInfoBox *sinf = (GF_ProtectionSchemeInfoBox *) gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_SINF); - - if (sinf && sinf->original_format) { - u32 type = sinf->original_format->data_format; - switch (type) { - case GF_ISOM_SUBTYPE_3GP_H263: - if (mp4v->cfg_3gpp) mp4v->cfg_3gpp->cfg.type = type; - break; - } - } - } - return GF_OK; -} - -GF_Box *video_sample_entry_box_new() -{ - GF_MPEGVisualSampleEntryBox *tmp; - GF_SAFEALLOC(tmp, GF_MPEGVisualSampleEntryBox); - if (tmp == NULL) return NULL; - - gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err video_sample_entry_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs); - return GF_OK; -} - -GF_Err video_sample_entry_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MPEGVisualSampleEntryBox *ptr = (GF_MPEGVisualSampleEntryBox *)s; - gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s); - - /*make sure we write the config box first, we don't care about the rest*/ - - /*mp4v*/ - gf_isom_check_position(s, (GF_Box *)ptr->esd, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->cfg_3gpp, &pos); - /*avc / SVC + MVC*/ - gf_isom_check_position(s, (GF_Box *)ptr->avc_config, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->svc_config, &pos); - if (ptr->mvc_config) { - gf_isom_check_position(s, gf_isom_box_find_child(s->child_boxes, GF_ISOM_BOX_TYPE_VWID), &pos); - gf_isom_check_position(s, (GF_Box *)ptr->mvc_config, &pos); - } - - /*HEVC*/ - gf_isom_check_position(s, (GF_Box *)ptr->hevc_config, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->lhvc_config, &pos); - - /*AV1*/ - gf_isom_check_position(s, (GF_Box *)ptr->av1_config, &pos); - - /*VPx*/ - gf_isom_check_position(s, (GF_Box *)ptr->vp_config, &pos); - - /*JP2H*/ - gf_isom_check_position(s, (GF_Box *)ptr->jp2h, &pos); - - /*DolbyVision*/ - gf_isom_check_position(s, (GF_Box *)ptr->dovi_config, &pos); - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void mvex_box_del(GF_Box *s) -{ - GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s; - if (ptr == NULL) return; - gf_list_del(ptr->TrackExList); - gf_list_del(ptr->TrackExPropList); - gf_free(ptr); -} - - -GF_Err mvex_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *)s; - - switch (a->type) { - case GF_ISOM_BOX_TYPE_TREX: - return gf_list_add(ptr->TrackExList, a); - case GF_ISOM_BOX_TYPE_TREP: - return gf_list_add(ptr->TrackExPropList, a); - case GF_ISOM_BOX_TYPE_MEHD: - if (ptr->mehd) ERROR_ON_DUPLICATED_BOX(a, s) - ptr->mehd = (GF_MovieExtendsHeaderBox*)a; - return GF_OK; - } - return GF_OK; -} - - - -GF_Err mvex_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, mvex_on_child_box); -} - -GF_Box *mvex_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieExtendsBox, GF_ISOM_BOX_TYPE_MVEX); - tmp->TrackExList = gf_list_new(); - if (!tmp->TrackExList) { - gf_free(tmp); - return NULL; - } - tmp->TrackExPropList = gf_list_new(); - if (!tmp->TrackExPropList) { - gf_list_del(tmp->TrackExList); - gf_free(tmp); - return NULL; - } - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err mvex_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err mvex_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MovieExtendsBox *ptr = (GF_MovieExtendsBox *) s; - gf_isom_check_position(s, (GF_Box *)ptr->mehd, &pos); - gf_isom_check_position_list(s, ptr->TrackExList, &pos); - gf_isom_check_position_list(s, ptr->TrackExPropList, &pos); - return GF_OK; -} - - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *mehd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieExtendsHeaderBox, GF_ISOM_BOX_TYPE_MEHD); - return (GF_Box *)tmp; -} -void mehd_box_del(GF_Box *s) -{ - gf_free(s); -} -GF_Err mehd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s; - - if (ptr->version==1) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->fragment_duration = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->fragment_duration = (u64) gf_bs_read_u32(bs); - } - return GF_OK; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err mehd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s; - GF_Err e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->version == 1) { - gf_bs_write_u64(bs, ptr->fragment_duration); - } else { - gf_bs_write_u32(bs, (u32) ptr->fragment_duration); - } - return GF_OK; -} -GF_Err mehd_box_size(GF_Box *s) -{ - GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s; - ptr->version = (ptr->fragment_duration>0xFFFFFFFF) ? 1 : 0; - s->size += (ptr->version == 1) ? 8 : 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - - -void mvhd_box_del(GF_Box *s) -{ - GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err mvhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - if (ptr->version == 1) { - ISOM_DECREASE_SIZE(ptr, 28); - ptr->creationTime = gf_bs_read_u64(bs); - ptr->modificationTime = gf_bs_read_u64(bs); - ptr->timeScale = gf_bs_read_u32(bs); - ptr->duration = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 16); - ptr->creationTime = gf_bs_read_u32(bs); - ptr->modificationTime = gf_bs_read_u32(bs); - ptr->timeScale = gf_bs_read_u32(bs); - ptr->duration = gf_bs_read_u32(bs); - } - if (!ptr->timeScale) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Movie header timescale is invalid (0) - defaulting to 600\n" )); - ptr->timeScale = 600; - } - ISOM_DECREASE_SIZE(ptr, 80); - ptr->preferredRate = gf_bs_read_u32(bs); - ptr->preferredVolume = gf_bs_read_u16(bs); - gf_bs_read_data(bs, ptr->reserved, 10); - ptr->matrixA = gf_bs_read_u32(bs); - ptr->matrixB = gf_bs_read_u32(bs); - ptr->matrixU = gf_bs_read_u32(bs); - ptr->matrixC = gf_bs_read_u32(bs); - ptr->matrixD = gf_bs_read_u32(bs); - ptr->matrixV = gf_bs_read_u32(bs); - ptr->matrixX = gf_bs_read_u32(bs); - ptr->matrixY = gf_bs_read_u32(bs); - ptr->matrixW = gf_bs_read_u32(bs); - ptr->previewTime = gf_bs_read_u32(bs); - ptr->previewDuration = gf_bs_read_u32(bs); - ptr->posterTime = gf_bs_read_u32(bs); - ptr->selectionTime = gf_bs_read_u32(bs); - ptr->selectionDuration = gf_bs_read_u32(bs); - ptr->currentTime = gf_bs_read_u32(bs); - ptr->nextTrackID = gf_bs_read_u32(bs); - ptr->original_duration = ptr->duration; - return GF_OK; -} - -GF_Box *mvhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MovieHeaderBox, GF_ISOM_BOX_TYPE_MVHD); - - tmp->preferredRate = (1<<16); - tmp->preferredVolume = (1<<8); - - tmp->matrixA = (1<<16); - tmp->matrixD = (1<<16); - tmp->matrixW = (1<<30); - - tmp->nextTrackID = 1; - - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mvhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->version == 1) { - gf_bs_write_u64(bs, ptr->creationTime); - gf_bs_write_u64(bs, ptr->modificationTime); - gf_bs_write_u32(bs, ptr->timeScale); - gf_bs_write_u64(bs, ptr->duration); - } else { - gf_bs_write_u32(bs, (u32) ptr->creationTime); - gf_bs_write_u32(bs, (u32) ptr->modificationTime); - gf_bs_write_u32(bs, ptr->timeScale); - gf_bs_write_u32(bs, (u32) ptr->duration); - } - gf_bs_write_u32(bs, ptr->preferredRate); - gf_bs_write_u16(bs, ptr->preferredVolume); - gf_bs_write_data(bs, ptr->reserved, 10); - gf_bs_write_u32(bs, ptr->matrixA); - gf_bs_write_u32(bs, ptr->matrixB); - gf_bs_write_u32(bs, ptr->matrixU); - gf_bs_write_u32(bs, ptr->matrixC); - gf_bs_write_u32(bs, ptr->matrixD); - gf_bs_write_u32(bs, ptr->matrixV); - gf_bs_write_u32(bs, ptr->matrixX); - gf_bs_write_u32(bs, ptr->matrixY); - gf_bs_write_u32(bs, ptr->matrixW); - gf_bs_write_u32(bs, ptr->previewTime); - gf_bs_write_u32(bs, ptr->previewDuration); - gf_bs_write_u32(bs, ptr->posterTime); - gf_bs_write_u32(bs, ptr->selectionTime); - gf_bs_write_u32(bs, ptr->selectionDuration); - gf_bs_write_u32(bs, ptr->currentTime); - gf_bs_write_u32(bs, ptr->nextTrackID); - return GF_OK; -} - -GF_Err mvhd_box_size(GF_Box *s) -{ - GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s; - if (ptr->duration==(u64) -1) ptr->version = 0; - else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0; - - ptr->size += (ptr->version == 1) ? 28 : 16; - ptr->size += 80; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void nmhd_box_del(GF_Box *s) -{ - GF_MPEGMediaHeaderBox *ptr = (GF_MPEGMediaHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - - -GF_Err nmhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - return GF_OK; -} - -GF_Box *nmhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MPEGMediaHeaderBox, GF_ISOM_BOX_TYPE_NMHD); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err nmhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err nmhd_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void padb_box_del(GF_Box *s) -{ - GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s; - if (ptr == NULL) return; - if (ptr->padbits) gf_free(ptr->padbits); - gf_free(ptr); -} - - -GF_Err padb_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->SampleCount = gf_bs_read_u32(bs); - if (ptr->size < ptr->SampleCount/2) //half byte per sample - return GF_ISOM_INVALID_FILE; - - ptr->padbits = (u8 *)gf_malloc(sizeof(u8)*ptr->SampleCount); - if (!ptr->padbits) return GF_OUT_OF_MEM; - - for (i=0; iSampleCount; i += 2) { - gf_bs_read_int(bs, 1); - if (i+1 < ptr->SampleCount) { - ptr->padbits[i+1] = gf_bs_read_int(bs, 3); - } else { - gf_bs_read_int(bs, 3); - } - gf_bs_read_int(bs, 1); - ptr->padbits[i] = gf_bs_read_int(bs, 3); - } - return GF_OK; -} - -GF_Box *padb_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PaddingBitsBox, GF_ISOM_BOX_TYPE_PADB); - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err padb_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_Err e; - GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_int(bs, ptr->SampleCount, 32); - - for (i=0 ; iSampleCount; i += 2) { - gf_bs_write_int(bs, 0, 1); - if (i+1 < ptr->SampleCount) { - gf_bs_write_int(bs, ptr->padbits[i+1], 3); - } else { - gf_bs_write_int(bs, 0, 3); - } - gf_bs_write_int(bs, 0, 1); - gf_bs_write_int(bs, ptr->padbits[i], 3); - } - return GF_OK; -} - -GF_Err padb_box_size(GF_Box *s) -{ - GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *)s; - ptr->size += 4; - if (ptr->SampleCount) ptr->size += (ptr->SampleCount + 1) / 2; - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void rely_box_del(GF_Box *s) -{ - GF_RelyHintBox *rely = (GF_RelyHintBox *)s; - gf_free(rely); -} - -GF_Err rely_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_RelyHintBox *ptr = (GF_RelyHintBox *)s; - ISOM_DECREASE_SIZE(ptr, 1); - ptr->reserved = gf_bs_read_int(bs, 6); - ptr->preferred = gf_bs_read_int(bs, 1); - ptr->required = gf_bs_read_int(bs, 1); - return GF_OK; -} - -GF_Box *rely_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_RelyHintBox, GF_ISOM_BOX_TYPE_RELY); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err rely_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_RelyHintBox *ptr = (GF_RelyHintBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_int(bs, ptr->reserved, 6); - gf_bs_write_int(bs, ptr->preferred, 1); - gf_bs_write_int(bs, ptr->required, 1); - return GF_OK; -} - -GF_Err rely_box_size(GF_Box *s) -{ - s->size += 1; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void rtpo_box_del(GF_Box *s) -{ - GF_RTPOBox *rtpo = (GF_RTPOBox *)s; - gf_free(rtpo); -} - -GF_Err rtpo_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_RTPOBox *ptr = (GF_RTPOBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->timeOffset = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *rtpo_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_RTPOBox, GF_ISOM_BOX_TYPE_RTPO); - return (GF_Box *)tmp; -} -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err rtpo_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_RTPOBox *ptr = (GF_RTPOBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - //here we have no pb, just remembed that some entries will have to - //be 4-bytes aligned ... - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->timeOffset); - return GF_OK; -} - -GF_Err rtpo_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void smhd_box_del(GF_Box *s) -{ - GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s; - if (ptr == NULL ) return; - gf_free(ptr); -} - - -GF_Err smhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->balance = gf_bs_read_u16(bs); - ptr->reserved = gf_bs_read_u16(bs); - return GF_OK; -} - -GF_Box *smhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SoundMediaHeaderBox, GF_ISOM_BOX_TYPE_SMHD); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err smhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->balance); - gf_bs_write_u16(bs, ptr->reserved); - return GF_OK; -} - -GF_Err smhd_box_size(GF_Box *s) -{ - GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s; - - ptr->reserved = 0; - ptr->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void snro_box_del(GF_Box *s) -{ - GF_SeqOffHintEntryBox *snro = (GF_SeqOffHintEntryBox *)s; - gf_free(snro); -} - -GF_Err snro_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->SeqOffset = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *snro_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SeqOffHintEntryBox, GF_ISOM_BOX_TYPE_SNRO); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err snro_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SeqOffHintEntryBox *ptr = (GF_SeqOffHintEntryBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->SeqOffset); - return GF_OK; -} - -GF_Err snro_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void stbl_box_del(GF_Box *s) -{ - GF_SampleTableBox *ptr = (GF_SampleTableBox *)s; - if (ptr == NULL) return; - - if (ptr->sub_samples) gf_list_del(ptr->sub_samples); - if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups); - if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription); - if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes); - if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets); - if (ptr->traf_map) { - if (ptr->traf_map->frag_starts) { - u32 i; - for (i=0; itraf_map->nb_entries; i++) { - if (ptr->traf_map->frag_starts[i].moof_template) - gf_free(ptr->traf_map->frag_starts[i].moof_template); - } - gf_free(ptr->traf_map->frag_starts); - } - gf_free(ptr->traf_map); - } - gf_free(ptr); -} - -GF_Err stbl_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_SampleTableBox *ptr = (GF_SampleTableBox *)s; - if (!a) return GF_OK; - switch (a->type) { - case GF_ISOM_BOX_TYPE_STTS: - if (ptr->TimeToSample) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->TimeToSample = (GF_TimeToSampleBox *)a; - break; - case GF_ISOM_BOX_TYPE_CTTS: - if (ptr->CompositionOffset) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->CompositionOffset = (GF_CompositionOffsetBox *)a; - break; - case GF_ISOM_BOX_TYPE_CSLG: - if (ptr->CompositionToDecode) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->CompositionToDecode = (GF_CompositionToDecodeBox *)a; - break; - case GF_ISOM_BOX_TYPE_STSS: - if (ptr->SyncSample) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->SyncSample = (GF_SyncSampleBox *)a; - break; - case GF_ISOM_BOX_TYPE_STSD: - if (ptr->SampleDescription) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->SampleDescription =(GF_SampleDescriptionBox *)a; - break; - case GF_ISOM_BOX_TYPE_STZ2: - case GF_ISOM_BOX_TYPE_STSZ: - if (ptr->SampleSize) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->SampleSize = (GF_SampleSizeBox *)a; - break; - case GF_ISOM_BOX_TYPE_STSC: - if (ptr->SampleToChunk) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->SampleToChunk = (GF_SampleToChunkBox *)a; - break; - case GF_ISOM_BOX_TYPE_PADB: - if (ptr->PaddingBits) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->PaddingBits = (GF_PaddingBitsBox *) a; - break; - - //WARNING: AS THIS MAY CHANGE DYNAMICALLY DURING EDIT, - case GF_ISOM_BOX_TYPE_CO64: - case GF_ISOM_BOX_TYPE_STCO: - if (ptr->ChunkOffset) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->ChunkOffset = a; - return GF_OK; - case GF_ISOM_BOX_TYPE_STSH: - if (ptr->ShadowSync) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->ShadowSync = (GF_ShadowSyncBox *)a; - break; - case GF_ISOM_BOX_TYPE_STDP: - if (ptr->DegradationPriority) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->DegradationPriority = (GF_DegradationPriorityBox *)a; - break; - case GF_ISOM_BOX_TYPE_SDTP: - if (ptr->SampleDep) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->SampleDep = (GF_SampleDependencyTypeBox *)a; - break; - - case GF_ISOM_BOX_TYPE_SUBS: - if (!ptr->sub_samples) ptr->sub_samples = gf_list_new(); - gf_list_add(ptr->sub_samples, a); - //check subsample box - { - GF_SubSampleInformationBox *subs = (GF_SubSampleInformationBox *)a; - GF_SubSampleInfoEntry *ent = gf_list_get(subs->Samples, 0); - if (!ent) { - gf_list_rem(subs->Samples, 0); - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable is invalid\n")); - } - else if (ent->sample_delta==0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] first entry in SubSample in track SampleTable has sample_delta of 0, should be one. Fixing\n")); - ent->sample_delta = 1; - } - } - break; - - case GF_ISOM_BOX_TYPE_SBGP: - if (!ptr->sampleGroups) ptr->sampleGroups = gf_list_new(); - gf_list_add(ptr->sampleGroups, a); - break; - case GF_ISOM_BOX_TYPE_SGPD: - if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new(); - gf_list_add(ptr->sampleGroupsDescription, a); - break; - - case GF_ISOM_BOX_TYPE_SAIZ: - if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new(); - gf_list_add(ptr->sai_sizes, a); - break; - case GF_ISOM_BOX_TYPE_SAIO: - if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new(); - gf_list_add(ptr->sai_offsets, a); - break; - } - return GF_OK; -} - - - - -GF_Err stbl_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - //we need to parse DegPrior in a special way - GF_SampleTableBox *ptr = (GF_SampleTableBox *)s; - - e = gf_isom_box_array_read(s, bs, stbl_on_child_box); - if (e) return e; - - if (!ptr->SyncSample) - ptr->no_sync_found = 1; - - ptr->nb_sgpd_in_stbl = gf_list_count(ptr->sampleGroupsDescription); - ptr->nb_stbl_boxes = gf_list_count(ptr->child_boxes); - - if (gf_bs_get_cookie(bs) & GF_ISOM_BS_COOKIE_CLONE_TRACK) - return GF_OK; -// return GF_OK; - - //these boxes are mandatory ! - if (!ptr->SampleToChunk || !ptr->SampleSize || !ptr->ChunkOffset || !ptr->TimeToSample) - return GF_ISOM_INVALID_FILE; - //sanity check - if (ptr->SampleSize->sampleCount) { - if (!ptr->TimeToSample->nb_entries || !ptr->SampleToChunk->nb_entries) - return GF_ISOM_INVALID_FILE; - } - return GF_OK; -} - -GF_Box *stbl_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleTableBox, GF_ISOM_BOX_TYPE_STBL); - //maxSamplePer chunk is 10 by default - tmp->MaxSamplePerChunk = 10; - tmp->groupID = 1; - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stbl_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err stbl_box_size(GF_Box *s) -{ - u32 pos=0; - GF_SampleTableBox *ptr = (GF_SampleTableBox *)s; - - gf_isom_check_position(s, (GF_Box *)ptr->SampleDescription, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->TimeToSample, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->CompositionOffset, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->CompositionToDecode, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->SyncSample, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->ShadowSync, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->SampleToChunk, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->SampleSize, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->ChunkOffset, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->DegradationPriority, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->SampleDep, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->PaddingBits, &pos); - - if (ptr->sub_samples) { - gf_isom_check_position_list(s, ptr->sub_samples, &pos); - } - if (ptr->sampleGroupsDescription) { - gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos); - } - if (ptr->sampleGroups) { - gf_isom_check_position_list(s, ptr->sampleGroups, &pos); - } - if (ptr->sai_sizes) { - gf_isom_check_position_list(s, ptr->sai_sizes, &pos); - } - if (ptr->sai_offsets) { - gf_isom_check_position_list(s, ptr->sai_offsets, &pos); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void stco_box_del(GF_Box *s) -{ - GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s; - if (ptr == NULL) return; - if (ptr->offsets) gf_free(ptr->offsets); - gf_free(ptr); -} - - -GF_Err stco_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 entries; - GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nb_entries = gf_bs_read_u32(bs); - if (ptr->nb_entries > ptr->size / 4) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stco\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - - if (ptr->nb_entries) { - ptr->offsets = (u32 *) gf_malloc(ptr->nb_entries * sizeof(u32) ); - if (ptr->offsets == NULL) return GF_OUT_OF_MEM; - ptr->alloc_size = ptr->nb_entries; - - for (entries = 0; entries < ptr->nb_entries; entries++) { - ptr->offsets[entries] = gf_bs_read_u32(bs); - } - } - return GF_OK; -} - -GF_Box *stco_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ChunkOffsetBox, GF_ISOM_BOX_TYPE_STCO); - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stco_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nb_entries); - for (i = 0; i < ptr->nb_entries; i++) { - gf_bs_write_u32(bs, ptr->offsets[i]); - } - return GF_OK; -} - - -GF_Err stco_box_size(GF_Box *s) -{ - GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s; - - ptr->size += 4 + (4 * ptr->nb_entries); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void stdp_box_del(GF_Box *s) -{ - GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s; - if (ptr == NULL ) return; - if (ptr->priorities) gf_free(ptr->priorities); - gf_free(ptr); -} - -//this is called through stbl_read... -GF_Err stdp_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 entry; - GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s; - - /*out-of-order stdp, assume no padding at the end and take the entire remaining data for entries*/ - if (!ptr->nb_entries) ptr->nb_entries = (u32) ptr->size / 2; - else if (ptr->nb_entries > ptr->size / 2) return GF_ISOM_INVALID_FILE; - - ptr->priorities = (u16 *) gf_malloc(ptr->nb_entries * sizeof(u16)); - if (ptr->priorities == NULL) return GF_OUT_OF_MEM; - for (entry = 0; entry < ptr->nb_entries; entry++) { - ptr->priorities[entry] = gf_bs_read_u16(bs); - } - ISOM_DECREASE_SIZE(ptr, (2*ptr->nb_entries) ); - return GF_OK; -} - -GF_Box *stdp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_DegradationPriorityBox, GF_ISOM_BOX_TYPE_STDP); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stdp_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - for (i = 0; i < ptr->nb_entries; i++) { - gf_bs_write_u16(bs, ptr->priorities[i]); - } - return GF_OK; -} - -GF_Err stdp_box_size(GF_Box *s) -{ - GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s; - - ptr->size += (2 * ptr->nb_entries); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void stsc_box_del(GF_Box *s) -{ - GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s; - if (ptr == NULL) return; - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - - -GF_Err stsc_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nb_entries = gf_bs_read_u32(bs); - - if (ptr->nb_entries > ptr->size / 12) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsc\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - - ptr->alloc_size = ptr->nb_entries; - ptr->entries = NULL; - if (ptr->nb_entries) { - ptr->entries = gf_malloc(sizeof(GF_StscEntry)*ptr->alloc_size); - if (!ptr->entries) return GF_OUT_OF_MEM; - } - - for (i = 0; i < ptr->nb_entries; i++) { - ptr->entries[i].firstChunk = gf_bs_read_u32(bs); - ptr->entries[i].samplesPerChunk = gf_bs_read_u32(bs); - ptr->entries[i].sampleDescriptionIndex = gf_bs_read_u32(bs); - ptr->entries[i].isEdited = 0; - ptr->entries[i].nextChunk = 0; - if (!ptr->entries[i].firstChunk) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] invalid first chunk 0 in stsc entry\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - - //update the next chunk in the previous entry - if (i) ptr->entries[i-1].nextChunk = ptr->entries[i].firstChunk; - } - ptr->currentIndex = 0; - ptr->firstSampleInCurrentChunk = 0; - ptr->currentChunk = 0; - ptr->ghostNumber = 0; - return GF_OK; -} - -GF_Box *stsc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleToChunkBox, GF_ISOM_BOX_TYPE_STSC); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stsc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nb_entries); - for (i=0; inb_entries; i++) { - gf_bs_write_u32(bs, ptr->entries[i].firstChunk); - gf_bs_write_u32(bs, ptr->entries[i].samplesPerChunk); - gf_bs_write_u32(bs, ptr->entries[i].sampleDescriptionIndex); - } - return GF_OK; -} - -GF_Err stsc_box_size(GF_Box *s) -{ - GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s; - - ptr->size += 4 + (12 * ptr->nb_entries); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void stsd_box_del(GF_Box *s) -{ - GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err stsd_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_UnknownBox *def; - if (!a) return GF_OK; - - if (gf_box_valid_in_parent(a, "stsd")) { - return GF_OK; - } - switch (a->type) { - //unknown sample description: we need a specific box to handle the data ref index - //rather than a default box ... - case GF_ISOM_BOX_TYPE_UNKNOWN: - def = (GF_UnknownBox *)a; - /*we need at least 8 bytes for unknown sample entries*/ - if (def->dataSize < 8) { - gf_isom_box_del_parent(&s->child_boxes, a); - return GF_ISOM_INVALID_MEDIA; - } - return GF_OK; - - default: - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Cannot process box of type %s\n", gf_4cc_to_str(a->type))); - return GF_ISOM_INVALID_FILE; - } -} - - -GF_Err stsd_box_read(GF_Box *s, GF_BitStream *bs) -{ - ISOM_DECREASE_SIZE(s, 4) - gf_bs_read_u32(bs); - - return gf_isom_box_array_read_ex(s, bs, stsd_on_child_box, GF_ISOM_BOX_TYPE_STSD); -} - -GF_Box *stsd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleDescriptionBox, GF_ISOM_BOX_TYPE_STSD); - tmp->child_boxes = gf_list_new(); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stsd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 nb_entries; - GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - nb_entries = gf_list_count(ptr->child_boxes); - gf_bs_write_u32(bs, nb_entries); - return GF_OK; -} - -GF_Err stsd_box_size(GF_Box *s) -{ - GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s; - ptr->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void stsh_box_del(GF_Box *s) -{ - u32 i = 0; - GF_StshEntry *ent; - GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s; - if (ptr == NULL) return; - while ( (ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i)) ) { - gf_free(ent); - } - gf_list_del(ptr->entries); - gf_free(ptr); -} - - - -GF_Err stsh_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 count, i; - GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s; - - ISOM_DECREASE_SIZE(s, 4) - count = gf_bs_read_u32(bs); - if (ptr->size < count*8) - return GF_ISOM_INVALID_FILE; - - for (i = 0; i < count; i++) { - GF_StshEntry *ent = (GF_StshEntry *) gf_malloc(sizeof(GF_StshEntry)); - if (!ent) return GF_OUT_OF_MEM; - ent->shadowedSampleNumber = gf_bs_read_u32(bs); - ent->syncSampleNumber = gf_bs_read_u32(bs); - e = gf_list_add(ptr->entries, ent); - if (e) return e; - } - return GF_OK; -} - -GF_Box *stsh_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ShadowSyncBox, GF_ISOM_BOX_TYPE_STSH); - - tmp->entries = gf_list_new(); - if (!tmp->entries) { - gf_free(tmp); - return NULL; - } - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stsh_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_StshEntry *ent; - GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, gf_list_count(ptr->entries)); - i=0; - while ((ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i))) { - gf_bs_write_u32(bs, ent->shadowedSampleNumber); - gf_bs_write_u32(bs, ent->syncSampleNumber); - } - return GF_OK; -} - -GF_Err stsh_box_size(GF_Box *s) -{ - GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s; - ptr->size += 4 + (8 * gf_list_count(ptr->entries)); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void stss_box_del(GF_Box *s) -{ - GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s; - if (ptr == NULL) return; - if (ptr->sampleNumbers) gf_free(ptr->sampleNumbers); - gf_free(ptr); -} - -GF_Err stss_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nb_entries = gf_bs_read_u32(bs); - if (ptr->size < ptr->nb_entries * 4) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stss\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - - ptr->alloc_size = ptr->nb_entries; - ptr->sampleNumbers = (u32 *) gf_malloc( ptr->alloc_size * sizeof(u32)); - if (ptr->sampleNumbers == NULL) return GF_OUT_OF_MEM; - - for (i = 0; i < ptr->nb_entries; i++) { - ptr->sampleNumbers[i] = gf_bs_read_u32(bs); - } - return GF_OK; -} - -GF_Box *stss_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SyncSampleBox, GF_ISOM_BOX_TYPE_STSS); - return (GF_Box*)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stss_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nb_entries); - for (i = 0; i < ptr->nb_entries; i++) { - gf_bs_write_u32(bs, ptr->sampleNumbers[i]); - } - return GF_OK; -} - -GF_Err stss_box_size(GF_Box *s) -{ - GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s; - ptr->size += 4 + (4 * ptr->nb_entries); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void stsz_box_del(GF_Box *s) -{ - GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s; - if (ptr == NULL) return; - if (ptr->sizes) gf_free(ptr->sizes); - gf_free(ptr); -} - - -GF_Err stsz_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i, estSize; - GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - //support for CompactSizes - if (s->type == GF_ISOM_BOX_TYPE_STSZ) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->sampleSize = gf_bs_read_u32(bs); - ptr->sampleCount = gf_bs_read_u32(bs); - } else { - //24-reserved - ISOM_DECREASE_SIZE(ptr, 8); - gf_bs_read_int(bs, 24); - i = gf_bs_read_u8(bs); - ptr->sampleCount = gf_bs_read_u32(bs); - switch (i) { - case 4: - case 8: - case 16: - ptr->sampleSize = i; - break; - default: - //try to fix the file - //no samples, no parsing pb - if (!ptr->sampleCount) { - ptr->sampleSize = 16; - return GF_OK; - } - estSize = (u32) (ptr->size) / ptr->sampleCount; - if (!estSize && ((ptr->sampleCount+1)/2 == (ptr->size)) ) { - ptr->sampleSize = 4; - break; - } else if (estSize == 1 || estSize == 2) { - ptr->sampleSize = 8 * estSize; - } else { - return GF_ISOM_INVALID_FILE; - } - } - } - if (s->type == GF_ISOM_BOX_TYPE_STSZ) { - if (! ptr->sampleSize && ptr->sampleCount) { - if (ptr->sampleCount > ptr->size / 4) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount)); - return GF_ISOM_INVALID_FILE; - } - ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32)); - if (! ptr->sizes) return GF_OUT_OF_MEM; - ptr->alloc_size = ptr->sampleCount; - for (i = 0; i < ptr->sampleCount; i++) { - ptr->sizes[i] = gf_bs_read_u32(bs); - if (ptr->max_size < ptr->sizes[i]) - ptr->max_size = ptr->sizes[i]; - ptr->total_size += ptr->sizes[i]; - ptr->total_samples++; - } - } - } else { - if (ptr->sampleSize==4) { - if (ptr->sampleCount / 2 > ptr->size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount)); - return GF_ISOM_INVALID_FILE; - } - } else { - if (ptr->sampleCount > ptr->size / (ptr->sampleSize/8)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stsz\n", ptr->sampleCount)); - return GF_ISOM_INVALID_FILE; - } - } - //note we could optimize the mem usage by keeping the table compact - //in memory. But that would complicate both caching and editing - //we therefore keep all sizes as u32 and uncompress the table - ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32)); - if (! ptr->sizes) return GF_OUT_OF_MEM; - ptr->alloc_size = ptr->sampleCount; - - for (i = 0; i < ptr->sampleCount; ) { - switch (ptr->sampleSize) { - case 4: - ptr->sizes[i] = gf_bs_read_int(bs, 4); - if (i+1 < ptr->sampleCount) { - ptr->sizes[i+1] = gf_bs_read_int(bs, 4); - } else { - //0 padding in odd sample count - gf_bs_read_int(bs, 4); - } - i += 2; - break; - default: - ptr->sizes[i] = gf_bs_read_int(bs, ptr->sampleSize); - i += 1; - break; - } - if (ptr->max_size < ptr->sizes[i]) - ptr->max_size = ptr->sizes[i]; - ptr->total_size += ptr->sizes[i]; - ptr->total_samples++; - } - } - return GF_OK; -} - -GF_Box *stsz_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleSizeBox, 0); - - //type is unknown here, can be regular or compact table - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stsz_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - //in both versions this is still valid - if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) { - gf_bs_write_u32(bs, ptr->sampleSize); - } else { - gf_bs_write_u24(bs, 0); - gf_bs_write_u8(bs, ptr->sampleSize); - } - gf_bs_write_u32(bs, ptr->sampleCount); - - if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) { - if (! ptr->sampleSize) { - for (i = 0; i < ptr->sampleCount; i++) { - gf_bs_write_u32(bs, ptr->sizes ? ptr->sizes[i] : 0); - } - } - } else { - for (i = 0; i < ptr->sampleCount; ) { - switch (ptr->sampleSize) { - case 4: - gf_bs_write_int(bs, ptr->sizes[i], 4); - if (i+1 < ptr->sampleCount) { - gf_bs_write_int(bs, ptr->sizes[i+1], 4); - } else { - //0 padding in odd sample count - gf_bs_write_int(bs, 0, 4); - } - i += 2; - break; - default: - gf_bs_write_int(bs, ptr->sizes[i], ptr->sampleSize); - i += 1; - break; - } - } - } - return GF_OK; -} - -GF_Err stsz_box_size(GF_Box *s) -{ - u32 i, fieldSize, size; - GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s; - - ptr->size += 8; - if (!ptr->sampleCount) return GF_OK; - - //regular table - if (ptr->type == GF_ISOM_BOX_TYPE_STSZ) { - if (ptr->sampleSize) return GF_OK; - ptr->size += (4 * ptr->sampleCount); - return GF_OK; - } - - fieldSize = 4; - size = ptr->sizes[0]; - - for (i=0; i < ptr->sampleCount; i++) { - if (ptr->sizes[i] <= 0xF) continue; - //switch to 8-bit table - else if (ptr->sizes[i] <= 0xFF) { - fieldSize = 8; - } - //switch to 16-bit table - else if (ptr->sizes[i] <= 0xFFFF) { - fieldSize = 16; - } - //switch to 32-bit table - else { - fieldSize = 32; - } - - //check the size - if (size != ptr->sizes[i]) size = 0; - } - //if all samples are of the same size, switch to regular (more compact) - if (size) { - ptr->type = GF_ISOM_BOX_TYPE_STSZ; - ptr->sampleSize = size; - gf_free(ptr->sizes); - ptr->sizes = NULL; - } - - if (fieldSize == 32) { - //oops, doesn't fit in a compact table - ptr->type = GF_ISOM_BOX_TYPE_STSZ; - ptr->size += (4 * ptr->sampleCount); - return GF_OK; - } - - //make sure we are a compact table (no need to change the mem representation) - ptr->type = GF_ISOM_BOX_TYPE_STZ2; - ptr->sampleSize = fieldSize; - if (fieldSize == 4) { - //do not forget the 0 padding field for odd count - ptr->size += (ptr->sampleCount + 1) / 2; - } else { - ptr->size += (ptr->sampleCount) * (fieldSize/8); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void stts_box_del(GF_Box *s) -{ - GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s; - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - - -GF_Err stts_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s; - -#ifndef GPAC_DISABLE_ISOM_WRITE - ptr->w_LastDTS = 0; -#endif - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->nb_entries = gf_bs_read_u32(bs); - if (ptr->size < ptr->nb_entries * 8) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in stts\n", ptr->nb_entries)); - return GF_ISOM_INVALID_FILE; - } - - ptr->alloc_size = ptr->nb_entries; - ptr->entries = gf_malloc(sizeof(GF_SttsEntry)*ptr->alloc_size); - if (!ptr->entries) return GF_OUT_OF_MEM; - - for (i=0; inb_entries; i++) { - ptr->entries[i].sampleCount = gf_bs_read_u32(bs); - ptr->entries[i].sampleDelta = gf_bs_read_u32(bs); -#ifndef GPAC_DISABLE_ISOM_WRITE - ptr->w_currentSampleNum += ptr->entries[i].sampleCount; - ptr->w_LastDTS += (u64)ptr->entries[i].sampleCount * ptr->entries[i].sampleDelta; -#endif - if (ptr->max_ts_deltaentries[i].sampleDelta) - ptr->max_ts_delta = ptr->entries[i].sampleDelta; - - if (!ptr->entries[i].sampleDelta) { - if ((i+1nb_entries) ) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Found stts entry with sample_delta=0 - forbidden ! Fixing to 1\n" )); - ptr->entries[i].sampleDelta = 1; - } else if (ptr->entries[i].sampleCount>1) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] more than one stts entry at the end of the track with sample_delta=0 - forbidden ! Fixing to 1\n" )); - ptr->entries[i].sampleDelta = 1; - } - } else if ((s32) ptr->entries[i].sampleDelta < 0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] stts entry %d has negative duration %d - forbidden ! Fixing to 1, sync may get lost (consider reimport raw media)\n", i, (s32) ptr->entries[i].sampleDelta )); - ptr->entries[i].sampleDelta = 1; - } - } - if (ptr->size<(ptr->nb_entries*8)) return GF_ISOM_INVALID_FILE; - ISOM_DECREASE_SIZE(ptr, ptr->nb_entries*8); - - //remove the last sample delta. -#ifndef GPAC_DISABLE_ISOM_WRITE - if (ptr->nb_entries) ptr->w_LastDTS -= ptr->entries[ptr->nb_entries-1].sampleDelta; -#endif - return GF_OK; -} - -GF_Box *stts_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TimeToSampleBox, GF_ISOM_BOX_TYPE_STTS); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stts_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->nb_entries); - for (i=0; inb_entries; i++) { - gf_bs_write_u32(bs, ptr->entries[i].sampleCount); - gf_bs_write_u32(bs, ptr->entries[i].sampleDelta); - } - return GF_OK; -} - -GF_Err stts_box_size(GF_Box *s) -{ - GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s; - ptr->size += 4 + (8 * ptr->nb_entries); - return GF_OK; -} - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void tfhd_box_del(GF_Box *s) -{ - GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err tfhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->trackID = gf_bs_read_u32(bs); - - //The rest depends on the flags - if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->base_data_offset = gf_bs_read_u64(bs); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->sample_desc_index = gf_bs_read_u32(bs); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->def_sample_duration = gf_bs_read_u32(bs); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->def_sample_size = gf_bs_read_u32(bs); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->def_sample_flags = gf_bs_read_u32(bs); - } - return GF_OK; -} - -GF_Box *tfhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackFragmentHeaderBox, GF_ISOM_BOX_TYPE_TFHD); - //NO FLAGS SET BY DEFAULT - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err tfhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->trackID); - - //The rest depends on the flags - if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) { - gf_bs_write_u64(bs, ptr->base_data_offset); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) { - gf_bs_write_u32(bs, ptr->sample_desc_index); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) { - gf_bs_write_u32(bs, ptr->def_sample_duration); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) { - gf_bs_write_u32(bs, ptr->def_sample_size); - } - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) { - gf_bs_write_u32(bs, ptr->def_sample_flags); - } - return GF_OK; -} - -GF_Err tfhd_box_size(GF_Box *s) -{ - GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s; - ptr->size += 4; - - //The rest depends on the flags - if (ptr->flags & GF_ISOM_TRAF_BASE_OFFSET) ptr->size += 8; - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DESC) ptr->size += 4; - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_DUR) ptr->size += 4; - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_SIZE) ptr->size += 4; - if (ptr->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) ptr->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - - -void tims_box_del(GF_Box *s) -{ - GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s; - gf_free(tims); -} - -GF_Err tims_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->timeScale = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *tims_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TSHintEntryBox, GF_ISOM_BOX_TYPE_TIMS); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tims_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TSHintEntryBox *ptr = (GF_TSHintEntryBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->timeScale); - return GF_OK; -} - -GF_Err tims_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void tkhd_box_del(GF_Box *s) -{ - GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); - return; -} - - -GF_Err tkhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s; - - if (ptr->version == 1) { - ISOM_DECREASE_SIZE(ptr, 32); - ptr->creationTime = gf_bs_read_u64(bs); - ptr->modificationTime = gf_bs_read_u64(bs); - ptr->trackID = gf_bs_read_u32(bs); - ptr->reserved1 = gf_bs_read_u32(bs); - ptr->duration = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 20); - ptr->creationTime = gf_bs_read_u32(bs); - ptr->modificationTime = gf_bs_read_u32(bs); - ptr->trackID = gf_bs_read_u32(bs); - ptr->reserved1 = gf_bs_read_u32(bs); - ptr->duration = gf_bs_read_u32(bs); - } - ptr->initial_duration = ptr->duration; - - ISOM_DECREASE_SIZE(ptr, 60); - ptr->reserved2[0] = gf_bs_read_u32(bs); - ptr->reserved2[1] = gf_bs_read_u32(bs); - ptr->layer = gf_bs_read_u16(bs); - ptr->alternate_group = gf_bs_read_u16(bs); - ptr->volume = gf_bs_read_u16(bs); - ptr->reserved3 = gf_bs_read_u16(bs); - ptr->matrix[0] = gf_bs_read_u32(bs); - ptr->matrix[1] = gf_bs_read_u32(bs); - ptr->matrix[2] = gf_bs_read_u32(bs); - ptr->matrix[3] = gf_bs_read_u32(bs); - ptr->matrix[4] = gf_bs_read_u32(bs); - ptr->matrix[5] = gf_bs_read_u32(bs); - ptr->matrix[6] = gf_bs_read_u32(bs); - ptr->matrix[7] = gf_bs_read_u32(bs); - ptr->matrix[8] = gf_bs_read_u32(bs); - ptr->width = gf_bs_read_u32(bs); - ptr->height = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *tkhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackHeaderBox, GF_ISOM_BOX_TYPE_TKHD); - tmp->matrix[0] = 0x00010000; - tmp->matrix[4] = 0x00010000; - tmp->matrix[8] = 0x40000000; - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tkhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->version == 1) { - gf_bs_write_u64(bs, ptr->creationTime); - gf_bs_write_u64(bs, ptr->modificationTime); - gf_bs_write_u32(bs, ptr->trackID); - gf_bs_write_u32(bs, ptr->reserved1); - gf_bs_write_u64(bs, ptr->duration); - } else { - gf_bs_write_u32(bs, (u32) ptr->creationTime); - gf_bs_write_u32(bs, (u32) ptr->modificationTime); - gf_bs_write_u32(bs, ptr->trackID); - gf_bs_write_u32(bs, ptr->reserved1); - gf_bs_write_u32(bs, (u32) ptr->duration); - } - gf_bs_write_u32(bs, ptr->reserved2[0]); - gf_bs_write_u32(bs, ptr->reserved2[1]); - gf_bs_write_u16(bs, ptr->layer); - gf_bs_write_u16(bs, ptr->alternate_group); - gf_bs_write_u16(bs, ptr->volume); - gf_bs_write_u16(bs, ptr->reserved3); - gf_bs_write_u32(bs, ptr->matrix[0]); - gf_bs_write_u32(bs, ptr->matrix[1]); - gf_bs_write_u32(bs, ptr->matrix[2]); - gf_bs_write_u32(bs, ptr->matrix[3]); - gf_bs_write_u32(bs, ptr->matrix[4]); - gf_bs_write_u32(bs, ptr->matrix[5]); - gf_bs_write_u32(bs, ptr->matrix[6]); - gf_bs_write_u32(bs, ptr->matrix[7]); - gf_bs_write_u32(bs, ptr->matrix[8]); - gf_bs_write_u32(bs, ptr->width); - gf_bs_write_u32(bs, ptr->height); - return GF_OK; -} - -GF_Err tkhd_box_size(GF_Box *s) -{ - GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s; - - if (ptr->duration==(u64) -1) ptr->version = 0; - else ptr->version = (ptr->duration>0xFFFFFFFF) ? 1 : 0; - ptr->size += (ptr->version == 1) ? 32 : 20; - ptr->size += 60; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void traf_box_del(GF_Box *s) -{ - GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s; - if (ptr == NULL) return; - if (ptr->sub_samples) gf_list_del(ptr->sub_samples); - gf_list_del(ptr->TrackRuns); - if (ptr->sampleGroups) gf_list_del(ptr->sampleGroups); - if (ptr->sampleGroupsDescription) gf_list_del(ptr->sampleGroupsDescription); - if (ptr->sai_sizes) gf_list_del(ptr->sai_sizes); - if (ptr->sai_offsets) gf_list_del(ptr->sai_offsets); - gf_free(ptr); -} - -GF_Err traf_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s; - - switch (a->type) { - case GF_ISOM_BOX_TYPE_TFHD: - if (ptr->tfhd) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->tfhd = (GF_TrackFragmentHeaderBox *) a; - return GF_OK; - case GF_ISOM_BOX_TYPE_TRUN: - return gf_list_add(ptr->TrackRuns, a); - case GF_ISOM_BOX_TYPE_SDTP: - if (ptr->sdtp) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->sdtp = (GF_SampleDependencyTypeBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_TFDT: - if (ptr->tfdt) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->tfdt = (GF_TFBaseMediaDecodeTimeBox*) a; - return GF_OK; - case GF_ISOM_BOX_TYPE_SUBS: - if (!ptr->sub_samples) ptr->sub_samples = gf_list_new(); - return gf_list_add(ptr->sub_samples, a); - case GF_ISOM_BOX_TYPE_SBGP: - if (!ptr->sampleGroups) ptr->sampleGroups = gf_list_new(); - gf_list_add(ptr->sampleGroups, a); - return GF_OK; - case GF_ISOM_BOX_TYPE_SGPD: - if (!ptr->sampleGroupsDescription) ptr->sampleGroupsDescription = gf_list_new(); - gf_list_add(ptr->sampleGroupsDescription, a); - return GF_OK; - case GF_ISOM_BOX_TYPE_SAIZ: - if (!ptr->sai_sizes) ptr->sai_sizes = gf_list_new(); - gf_list_add(ptr->sai_sizes, a); - return GF_OK; - case GF_ISOM_BOX_TYPE_SAIO: - if (!ptr->sai_offsets) ptr->sai_offsets = gf_list_new(); - gf_list_add(ptr->sai_offsets, a); - return GF_OK; - //we will throw an error if both PIFF_PSEC and SENC are found. Not such files seen yet - case GF_ISOM_BOX_TYPE_UUID: - if ( ((GF_UUIDBox *)a)->internal_4cc==GF_ISOM_BOX_UUID_PSEC) { - if (ptr->sample_encryption) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->sample_encryption = (GF_SampleEncryptionBox *)a; - ptr->sample_encryption->traf = ptr; - return GF_OK; - } else { - return GF_OK; - } - case GF_ISOM_BOX_TYPE_SENC: - if (ptr->sample_encryption) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->sample_encryption = (GF_SampleEncryptionBox *)a; - ptr->sample_encryption->traf = ptr; - return GF_OK; - } - return GF_OK; -} - - -GF_Err traf_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s; - GF_Err e = gf_isom_box_array_read(s, bs, traf_on_child_box); - if (e) return e; - - if (!ptr->tfhd) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackFragmentHeaderBox \n")); - return GF_ISOM_INVALID_FILE; - } - return GF_OK; -} - -GF_Box *traf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackFragmentBox, GF_ISOM_BOX_TYPE_TRAF); - tmp->TrackRuns = gf_list_new(); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Box *tfxd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MSSTimeExtBox, GF_ISOM_BOX_TYPE_UUID); - tmp->internal_4cc = GF_ISOM_BOX_UUID_TFXD; - return (GF_Box *)tmp; -} - -void tfxd_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err tfxd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->version = gf_bs_read_u8(bs); - ptr->flags = gf_bs_read_u24(bs); - - if (ptr->version == 0x01) { - ISOM_DECREASE_SIZE(ptr, 16); - ptr->absolute_time_in_track_timescale = gf_bs_read_u64(bs); - ptr->fragment_duration_in_track_timescale = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->absolute_time_in_track_timescale = gf_bs_read_u32(bs); - ptr->fragment_duration_in_track_timescale = gf_bs_read_u32(bs); - } - - return GF_OK; -} - -GF_Err tfxd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MSSTimeExtBox *uuid = (GF_MSSTimeExtBox*)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u8(bs, 1); - gf_bs_write_u24(bs, 0); - gf_bs_write_u64(bs, uuid->absolute_time_in_track_timescale); - gf_bs_write_u64(bs, uuid->fragment_duration_in_track_timescale); - - return GF_OK; -} - -GF_Err tfxd_box_size(GF_Box *s) -{ - s->size += 20; - return GF_OK; -} - -GF_Err traf_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err traf_box_size(GF_Box *s) -{ - u32 pos=0; - GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *) s; - - //Header first - gf_isom_check_position(s, (GF_Box *)ptr->tfhd, &pos); - gf_isom_check_position_list(s, ptr->sub_samples, &pos); - - gf_isom_check_position(s, (GF_Box *)ptr->tfdt, &pos); - gf_isom_check_position_list(s, ptr->sampleGroupsDescription, &pos); - gf_isom_check_position_list(s, ptr->sampleGroups, &pos); - gf_isom_check_position_list(s, ptr->sai_sizes, &pos); - gf_isom_check_position_list(s, ptr->sai_offsets, &pos); - - gf_isom_check_position(s, (GF_Box *)ptr->sample_encryption, &pos); - - gf_isom_check_position_list(s, ptr->TrackRuns, &pos); - - //when sdtp is present (smooth-like) write it after the trun box - gf_isom_check_position(s, (GF_Box *)ptr->sdtp, &pos); - - //tfxd should be last ... - if (ptr->tfxd) - gf_isom_check_position(s, (GF_Box *)ptr->tfxd, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - - -void trak_box_del(GF_Box *s) -{ -#ifndef GPAC_DISABLE_ISOM_WRITE - GF_TrackBox *ptr = (GF_TrackBox *)s; - if (ptr->chunk_cache) - gf_bs_del(ptr->chunk_cache); -#endif - gf_free(s); -} - -static void gf_isom_check_sample_desc(GF_TrackBox *trak) -{ - GF_BitStream *bs; - GF_UnknownBox *a; - u32 i; - GF_Err e; - GF_SampleTableBox *stbl; - - if (!trak->Media || !trak->Media->information) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no media box !\n" )); - return; - } - if (!trak->Media->information->sampleTable) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample table !\n" )); - trak->Media->information->sampleTable = (GF_SampleTableBox *) gf_isom_box_new_parent(&trak->Media->information->child_boxes, GF_ISOM_BOX_TYPE_STBL); - } - stbl = trak->Media->information->sampleTable; - - if (!stbl->SampleDescription) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Track with no sample description box !\n" )); - stbl->SampleDescription = (GF_SampleDescriptionBox *) gf_isom_box_new_parent(&stbl->child_boxes, GF_ISOM_BOX_TYPE_STSD); - return; - } - - i=0; - while ((a = (GF_UnknownBox*)gf_list_enum(trak->Media->information->sampleTable->SampleDescription->child_boxes, &i))) { - switch (a->type) { - case GF_ISOM_BOX_TYPE_MP4S: - case GF_ISOM_BOX_TYPE_ENCS: - case GF_ISOM_BOX_TYPE_MP4A: - case GF_ISOM_BOX_TYPE_ENCA: - case GF_ISOM_BOX_TYPE_MP4V: - case GF_ISOM_BOX_TYPE_ENCV: - case GF_ISOM_BOX_TYPE_RESV: - case GF_ISOM_SUBTYPE_3GP_AMR: - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - case GF_ISOM_SUBTYPE_3GP_EVRC: - case GF_ISOM_SUBTYPE_3GP_QCELP: - case GF_ISOM_SUBTYPE_3GP_SMV: - case GF_ISOM_SUBTYPE_3GP_H263: - case GF_ISOM_BOX_TYPE_GHNT: - case GF_ISOM_BOX_TYPE_RTP_STSD: - case GF_ISOM_BOX_TYPE_SRTP_STSD: - case GF_ISOM_BOX_TYPE_FDP_STSD: - case GF_ISOM_BOX_TYPE_RRTP_STSD: - case GF_ISOM_BOX_TYPE_RTCP_STSD: - case GF_ISOM_BOX_TYPE_METX: - case GF_ISOM_BOX_TYPE_METT: - case GF_ISOM_BOX_TYPE_STXT: - case GF_ISOM_BOX_TYPE_AVC1: - case GF_ISOM_BOX_TYPE_AVC2: - case GF_ISOM_BOX_TYPE_AVC3: - case GF_ISOM_BOX_TYPE_AVC4: - case GF_ISOM_BOX_TYPE_SVC1: - case GF_ISOM_BOX_TYPE_MVC1: - case GF_ISOM_BOX_TYPE_HVC1: - case GF_ISOM_BOX_TYPE_HEV1: - case GF_ISOM_BOX_TYPE_HVC2: - case GF_ISOM_BOX_TYPE_HEV2: - case GF_ISOM_BOX_TYPE_HVT1: - case GF_ISOM_BOX_TYPE_LHV1: - case GF_ISOM_BOX_TYPE_LHE1: - case GF_ISOM_BOX_TYPE_AV01: - case GF_ISOM_BOX_TYPE_VP08: - case GF_ISOM_BOX_TYPE_VP09: - case GF_ISOM_BOX_TYPE_AV1C: - case GF_ISOM_BOX_TYPE_TX3G: - case GF_ISOM_BOX_TYPE_TEXT: - case GF_ISOM_BOX_TYPE_ENCT: - case GF_ISOM_BOX_TYPE_DIMS: - case GF_ISOM_BOX_TYPE_OPUS: - case GF_ISOM_BOX_TYPE_AC3: - case GF_ISOM_BOX_TYPE_EC3: - case GF_ISOM_BOX_TYPE_LSR1: - case GF_ISOM_BOX_TYPE_WVTT: - case GF_ISOM_BOX_TYPE_STPP: - case GF_ISOM_BOX_TYPE_SBTT: - case GF_ISOM_BOX_TYPE_MP3: - case GF_ISOM_BOX_TYPE_JPEG: - case GF_ISOM_BOX_TYPE_PNG: - case GF_ISOM_BOX_TYPE_JP2K: - case GF_ISOM_BOX_TYPE_MHA1: - case GF_ISOM_BOX_TYPE_MHA2: - case GF_ISOM_BOX_TYPE_MHM1: - case GF_ISOM_BOX_TYPE_MHM2: - case GF_ISOM_BOX_TYPE_MJP2: - case GF_QT_SUBTYPE_RAW_AUD: - case GF_QT_SUBTYPE_TWOS: - case GF_QT_SUBTYPE_SOWT: - case GF_QT_SUBTYPE_FL32: - case GF_QT_SUBTYPE_FL64: - case GF_QT_SUBTYPE_IN24: - case GF_QT_SUBTYPE_IN32: - case GF_QT_SUBTYPE_ULAW: - case GF_QT_SUBTYPE_ALAW: - case GF_QT_SUBTYPE_ADPCM: - case GF_QT_SUBTYPE_IMA_ADPCM: - case GF_QT_SUBTYPE_DVCA: - case GF_QT_SUBTYPE_QDMC: - case GF_QT_SUBTYPE_QDMC2: - case GF_QT_SUBTYPE_QCELP: - case GF_QT_SUBTYPE_kMP3: - case GF_QT_SUBTYPE_RAW_VID: - 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: - case GF_QT_SUBTYPE_YUV422: - case GF_QT_SUBTYPE_YUV444: - case GF_QT_SUBTYPE_YUV422_10: - case GF_QT_SUBTYPE_YUV444_10: - case GF_ISOM_BOX_TYPE_IPCM: - case GF_ISOM_BOX_TYPE_FPCM: - continue; - - case GF_ISOM_BOX_TYPE_UNKNOWN: - break; - default: - if (gf_box_valid_in_parent((GF_Box *) a, "stsd")) { - continue; - } - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Unexpected box %s in stsd!\n", gf_4cc_to_str(a->type))); - continue; - } - //we are sure to have an unknown box here - assert(a->type==GF_ISOM_BOX_TYPE_UNKNOWN); - - if (!a->data || (a->dataSize<8) ) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Sample description %s does not have at least 8 bytes!\n", gf_4cc_to_str(a->original_4cc) )); - continue; - } - else if (a->dataSize > a->size) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Sample description %s has wrong data size %d!\n", gf_4cc_to_str(a->original_4cc), a->dataSize)); - continue; - } - -#define STSD_SWITCH_BOX(_box) \ - if (gf_bs_available(bs)) { \ - u64 pos = gf_bs_get_position(bs); \ - u32 count_subb = 0; \ - gf_bs_set_cookie(bs, GF_ISOM_BS_COOKIE_NO_LOGS);\ - e = gf_isom_box_array_read((GF_Box *) _box, bs, NULL); \ - count_subb = _box->child_boxes ? gf_list_count(_box->child_boxes) : 0; \ - if (!count_subb || e) { \ - gf_bs_seek(bs, pos); \ - _box->data_size = (u32) gf_bs_available(bs); \ - if (_box->data_size) { \ - _box->data = a->data; \ - a->data = NULL; \ - memmove(_box->data, _box->data + pos, _box->data_size); \ - } \ - } else { \ - _box->data_size = 0; \ - } \ - } \ - gf_bs_del(bs); \ - if (!_box->data_size && _box->data) { \ - gf_free(_box->data); \ - _box->data = NULL; \ - } \ - _box->size = 0; \ - _box->EntryType = a->original_4cc; \ - gf_list_rem(trak->Media->information->sampleTable->SampleDescription->child_boxes, i-1); \ - gf_isom_box_del((GF_Box *)a); \ - gf_list_insert(trak->Media->information->sampleTable->SampleDescription->child_boxes, _box, i-1); \ - - - /*only process visual or audio - note: no need for new_box_parent here since we always store sample descriptions in child_boxes*/ - switch (trak->Media->handler->handlerType) { - case GF_ISOM_MEDIA_VISUAL: - case GF_ISOM_MEDIA_AUXV: - case GF_ISOM_MEDIA_PICT: - { - GF_GenericVisualSampleEntryBox *genv = (GF_GenericVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRV); - bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ); - genv->size = a->size-8; - gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *) genv, bs); - - STSD_SWITCH_BOX(genv) - - } - break; - case GF_ISOM_MEDIA_AUDIO: - { - GF_GenericAudioSampleEntryBox *gena = (GF_GenericAudioSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRA); - gena->size = a->size-8; - bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ); - gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *) gena, bs); - - STSD_SWITCH_BOX(gena) - - } - break; - - default: - { - GF_GenericSampleEntryBox *genm = (GF_GenericSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_GNRM); - genm->size = a->size-8; - bs = gf_bs_new(a->data, a->dataSize, GF_BITSTREAM_READ); - - e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)genm, bs); - if (e) return; - - STSD_SWITCH_BOX(genm) - } - break; - } - - } -} - - -GF_Err trak_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_TrackBox *ptr = (GF_TrackBox *)s; - if (!a) return GF_OK; - switch(a->type) { - case GF_ISOM_BOX_TYPE_TKHD: - if (ptr->Header) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->Header = (GF_TrackHeaderBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_EDTS: - if (ptr->editBox) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->editBox = (GF_EditBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_UDTA: - if (ptr->udta) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->udta = (GF_UserDataBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_META: - if (ptr->meta) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->meta = (GF_MetaBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_TREF: - if (ptr->References) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->References = (GF_TrackReferenceBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_MDIA: - if (ptr->Media) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->Media = (GF_MediaBox *)a; - ((GF_MediaBox *)a)->mediaTrack = ptr; - return GF_OK; - case GF_ISOM_BOX_TYPE_TRGR: - if (ptr->groups) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->groups = (GF_TrackGroupBox *)a; - return GF_OK; - case GF_QT_BOX_TYPE_TAPT: - if (ptr->Aperture) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->Aperture = (GF_Box *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_SENC: - ptr->sample_encryption = (GF_SampleEncryptionBox*)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_UUID: - if (((GF_UnknownUUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC) { - ptr->sample_encryption = (GF_SampleEncryptionBox*) a; - return GF_OK; - } - } - return GF_OK; -} - - -GF_Err trak_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TrackBox *ptr = (GF_TrackBox *)s; - e = gf_isom_box_array_read(s, bs, trak_on_child_box); - if (e) return e; - gf_isom_check_sample_desc(ptr); - - if (!ptr->Header) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing TrackHeaderBox\n")); - return GF_ISOM_INVALID_FILE; - } - if (!ptr->Media) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing MediaBox\n")); - return GF_ISOM_INVALID_FILE; - } - if (!ptr->Media->information || !ptr->Media->information->sampleTable) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid MediaBox\n")); - return GF_ISOM_INVALID_FILE; - } - if (!ptr->Media->information->sampleTable->SampleSize || (ptr->Media->information->sampleTable->SampleSize->sampleCount==0)) { - if (ptr->Header->initial_duration) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Track with no samples but duration defined, ignoring duration\n")); - ptr->Header->initial_duration = 0; - } - } - - for (i=0; iMedia->information->sampleTable->child_boxes); i++) { - GF_Box *a = gf_list_get(ptr->Media->information->sampleTable->child_boxes, i); - if ((a->type ==GF_ISOM_BOX_TYPE_UUID) && (((GF_UUIDBox *)a)->internal_4cc == GF_ISOM_BOX_UUID_PSEC)) { - ptr->sample_encryption = (struct __sample_encryption_box *) a; - break; - } - else if (a->type == GF_ISOM_BOX_TYPE_SENC) { - ptr->sample_encryption = (struct __sample_encryption_box *)a; - break; - } - } - return e; -} - -GF_Box *trak_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackBox, GF_ISOM_BOX_TYPE_TRAK); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err trak_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err trak_box_size(GF_Box *s) -{ - u32 pos=0; - GF_TrackBox *ptr = (GF_TrackBox *)s; - - if (ptr->sample_encryption && ptr->sample_encryption->load_needed) { - GF_Err e = senc_Parse(ptr->moov->mov->movieFileMap->bs, ptr, NULL, ptr->sample_encryption); - if (e) return e; - } - - gf_isom_check_position(s, (GF_Box *)ptr->Header, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->Aperture, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->References, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->editBox, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->Media, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->meta, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->groups, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->udta, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void stri_box_del(GF_Box *s) -{ - GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s; - if (ptr == NULL) return; - if (ptr->attribute_list) gf_free(ptr->attribute_list); - gf_free(ptr); -} - -GF_Err stri_box_read(GF_Box *s, GF_BitStream *bs) -{ - size_t i; - GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s; - ISOM_DECREASE_SIZE(ptr, 8) - ptr->switch_group = gf_bs_read_u16(bs); - ptr->alternate_group = gf_bs_read_u16(bs); - ptr->sub_track_id = gf_bs_read_u32(bs); - ptr->attribute_count = ptr->size / 4; - GF_SAFE_ALLOC_N(ptr->attribute_list, (size_t)ptr->attribute_count, u32); - if (!ptr->attribute_list) return GF_OUT_OF_MEM; - for (i = 0; i < ptr->attribute_count; i++) { - ISOM_DECREASE_SIZE(ptr, 4) - ptr->attribute_list[i] = gf_bs_read_u32(bs); - } - return GF_OK; -} - -GF_Box *stri_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SubTrackInformationBox, GF_ISOM_BOX_TYPE_STRI); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stri_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, ptr->switch_group); - gf_bs_write_u16(bs, ptr->alternate_group); - gf_bs_write_u32(bs, ptr->sub_track_id); - for (i = 0; i < ptr->attribute_count; i++) { - gf_bs_write_u32(bs, ptr->attribute_list[i]); - } - return GF_OK; -} - -GF_Err stri_box_size(GF_Box *s) -{ - GF_SubTrackInformationBox *ptr = (GF_SubTrackInformationBox *)s; - - ptr->size += 8 + 4 * ptr->attribute_count; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void stsg_box_del(GF_Box *s) -{ - GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s; - if (ptr == NULL) return; - if (ptr->group_description_index) gf_free(ptr->group_description_index); - gf_free(ptr); -} - -GF_Err stsg_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s; - ISOM_DECREASE_SIZE(s, 6); - ptr->grouping_type = gf_bs_read_u32(bs); - ptr->nb_groups = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(s, ptr->nb_groups*4); - GF_SAFE_ALLOC_N(ptr->group_description_index, ptr->nb_groups, u32); - if (!ptr->group_description_index) return GF_OUT_OF_MEM; - for (i = 0; i < ptr->nb_groups; i++) { - ptr->group_description_index[i] = gf_bs_read_u32(bs); - } - return GF_OK; -} - -GF_Box *stsg_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SubTrackSampleGroupBox, GF_ISOM_BOX_TYPE_STSG); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stsg_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->grouping_type); - gf_bs_write_u16(bs, ptr->nb_groups); - for (i = 0; i < ptr->nb_groups; i++) { - gf_bs_write_u32(bs, ptr->group_description_index[i]); - } - return GF_OK; -} - -GF_Err stsg_box_size(GF_Box *s) -{ - GF_SubTrackSampleGroupBox *ptr = (GF_SubTrackSampleGroupBox *)s; - ptr->size += 6 + 4 * ptr->nb_groups; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void strk_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err strk_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_SubTrackBox *ptr = (GF_SubTrackBox *)s; - if (!a) return GF_OK; - switch (a->type) { - case GF_ISOM_BOX_TYPE_STRI: - if (ptr->info) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->info = (GF_SubTrackInformationBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_STRD: - if (ptr->strd) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->strd = a; - return GF_OK; - } - return GF_OK; -} - - -GF_Err strk_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SubTrackBox *ptr = (GF_SubTrackBox *)s; - e = gf_isom_box_array_read(s, bs, strk_on_child_box); - if (e) return e; - - if (!ptr->info) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Missing SubTrackInformationBox\n")); - return GF_ISOM_INVALID_FILE; - } - return GF_OK; -} - -GF_Box *strk_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SubTrackBox, GF_ISOM_BOX_TYPE_STRK); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err strk_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err strk_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void tref_box_del(GF_Box *s) -{ - GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err tref_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read_ex(s, bs, NULL, s->type); -} - -GF_Box *tref_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackReferenceBox, GF_ISOM_BOX_TYPE_TREF); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tref_box_write(GF_Box *s, GF_BitStream *bs) -{ -// GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s; - return gf_isom_box_write_header(s, bs); -} - -GF_Err tref_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void reftype_box_del(GF_Box *s) -{ - GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s; - if (!ptr) return; - if (ptr->trackIDs) gf_free(ptr->trackIDs); - gf_free(ptr); -} - - -GF_Err reftype_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 bytesToRead; - u32 i; - GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s; - - bytesToRead = (u32) (ptr->size); - if (!bytesToRead) return GF_OK; - - ptr->trackIDCount = (u32) (bytesToRead) / sizeof(u32); - ptr->trackIDs = (GF_ISOTrackID *) gf_malloc(ptr->trackIDCount * sizeof(GF_ISOTrackID)); - if (!ptr->trackIDs) return GF_OUT_OF_MEM; - - for (i = 0; i < ptr->trackIDCount; i++) { - ptr->trackIDs[i] = gf_bs_read_u32(bs); - } - return GF_OK; -} - -GF_Box *reftype_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackReferenceTypeBox, GF_ISOM_BOX_TYPE_REFT); - return (GF_Box *)tmp; -} - - -GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, GF_ISOTrackID trackID, u16 *outRefIndex) -{ - u32 i; - if (!ref || !trackID) return GF_BAD_PARAM; - - if (outRefIndex) *outRefIndex = 0; - //don't add a dep if already here !! - for (i = 0; i < ref->trackIDCount; i++) { - if (ref->trackIDs[i] == trackID) { - if (outRefIndex) *outRefIndex = i+1; - return GF_OK; - } - } - - ref->trackIDs = (GF_ISOTrackID *) gf_realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(GF_ISOTrackID) ); - if (!ref->trackIDs) return GF_OUT_OF_MEM; - ref->trackIDs[ref->trackIDCount] = trackID; - ref->trackIDCount++; - if (outRefIndex) *outRefIndex = ref->trackIDCount; - return GF_OK; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err reftype_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s; - ptr->type = ptr->reference_type; - e = gf_isom_box_write_header(s, bs); - ptr->type = GF_ISOM_BOX_TYPE_REFT; - if (e) return e; - for (i = 0; i < ptr->trackIDCount; i++) { - gf_bs_write_u32(bs, ptr->trackIDs[i]); - } - return GF_OK; -} - - -GF_Err reftype_box_size(GF_Box *s) -{ - GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s; - if (ptr->trackIDCount) - ptr->size += (ptr->trackIDCount * sizeof(u32)); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void trex_box_del(GF_Box *s) -{ - GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err trex_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s; - - ISOM_DECREASE_SIZE(ptr, 20); - ptr->trackID = gf_bs_read_u32(bs); - ptr->def_sample_desc_index = gf_bs_read_u32(bs); - ptr->def_sample_duration = gf_bs_read_u32(bs); - ptr->def_sample_size = gf_bs_read_u32(bs); - ptr->def_sample_flags = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *trex_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackExtendsBox, GF_ISOM_BOX_TYPE_TREX); - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err trex_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->trackID); - //we always write 1 in trex default sample desc as using 0 breaks chrome/opera/... - gf_bs_write_u32(bs, ptr->def_sample_desc_index ? ptr->def_sample_desc_index : 1); - gf_bs_write_u32(bs, ptr->def_sample_duration); - gf_bs_write_u32(bs, ptr->def_sample_size); - gf_bs_write_u32(bs, ptr->def_sample_flags); - return GF_OK; -} - -GF_Err trex_box_size(GF_Box *s) -{ - GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s; - ptr->size += 20; - return GF_OK; -} - - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void trep_box_del(GF_Box *s) -{ - GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err trep_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->trackID = gf_bs_read_u32(bs); - - return gf_isom_box_array_read(s, bs, NULL); -} - -GF_Box *trep_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackExtensionPropertiesBox, GF_ISOM_BOX_TYPE_TREP); - tmp->child_boxes = gf_list_new(); - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err trep_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->trackID); - return GF_OK; -} - -GF_Err trep_box_size(GF_Box *s) -{ - GF_TrackExtensionPropertiesBox *ptr = (GF_TrackExtensionPropertiesBox *)s; - ptr->size += 4; - return GF_OK; -} - - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - - - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -void trun_box_del(GF_Box *s) -{ - GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s; - if (ptr == NULL) return; - - if (ptr->samples) gf_free(ptr->samples); - if (ptr->cache) gf_bs_del(ptr->cache); - if (ptr->sample_order) gf_free(ptr->sample_order); - gf_free(ptr); -} - -#ifdef GF_ENABLE_CTRN - -static u32 ctrn_field_size(u32 field_idx) -{ - if (field_idx==3) return 4; - return field_idx; -} - -u32 gf_isom_ctrn_field_size_bits(u32 field_idx) -{ - if (field_idx==3) return 32; - return field_idx*8; -} -static u32 ctrn_read_flags(GF_BitStream *bs, u32 nbbits) -{ - u32 val = gf_bs_read_int(bs, nbbits); - if (nbbits==16) val <<= 16; - else if (nbbits==8) val <<= 24; - return val; -} - -static GF_Err ctrn_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i, count, flags, first_idx=0; - Bool inherit_dur, inherit_size, inherit_flags, inherit_ctso; - GF_TrunEntry *ent; - GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s; - flags = ptr->flags; - ptr->ctrn_flags = flags; - ptr->flags = 0; - - ptr->sample_count = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(ptr, 2); - - if (flags & GF_ISOM_TRUN_DATA_OFFSET) { - if (flags & GF_ISOM_CTRN_DATAOFFSET_16) { - ptr->data_offset = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(ptr, 2); - } else { - ptr->data_offset = gf_bs_read_u32(bs); - ISOM_DECREASE_SIZE(ptr, 4); - } - ptr->flags |= GF_ISOM_TRUN_DATA_OFFSET; - } - if (flags & GF_ISOM_CTRN_CTSO_MULTIPLIER) { - ptr->ctso_multiplier = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(ptr, 2); - } - /*no sample dur/sample_flag/size/ctso for first or following, create a pack sample */ - if (! (flags & 0x00FFFF00)) { - GF_SAFEALLOC(ent, GF_TrunEntry); - if (!ent) return GF_OUT_OF_MEM; - ent->nb_pack = ptr->sample_count; - gf_list_add(ptr->entries, ent); - return GF_OK; - } - /*allocate all entries*/ - for (i=0; isample_count; i++) { - GF_SAFEALLOC(ent, GF_TrunEntry); - if (!ent) return GF_OUT_OF_MEM; - gf_list_add(ptr->entries, ent); - } - //unpack flags - ptr->ctrn_first_dur = (flags>>22) & 0x3; - ptr->ctrn_first_size = (flags>>20) & 0x3; - ptr->ctrn_first_sample_flags = (flags>>18) & 0x3; - ptr->ctrn_first_ctts = (flags>>16) & 0x3; - ptr->ctrn_dur = (flags>>14) & 0x3; - ptr->ctrn_size = (flags>>12) & 0x3; - ptr->ctrn_sample_flags = (flags>>10) & 0x3; - ptr->ctrn_ctts = (flags>>8) & 0x3; - - inherit_dur = flags & GF_ISOM_CTRN_INHERIT_DUR; - inherit_size = flags & GF_ISOM_CTRN_INHERIT_SIZE; - inherit_flags = flags & GF_ISOM_CTRN_INHERIT_FLAGS; - inherit_ctso = flags & GF_ISOM_CTRN_INHERIT_CTSO; - - if (flags & GF_ISOM_CTRN_FIRST_SAMPLE) { - ent = gf_list_get(ptr->entries, 0); - first_idx = 1; - if (!inherit_dur && ptr->ctrn_first_dur) { - ent->Duration = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_dur) ); - ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_dur) ); - } - if (!inherit_size && ptr->ctrn_first_size) { - ent->size = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_size) ); - ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_size) ); - } - if (!inherit_flags && ptr->ctrn_first_sample_flags) { - ent->flags = ctrn_read_flags(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_sample_flags) ); - ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_sample_flags) ); - } - if (!inherit_ctso && ptr->ctrn_first_ctts) { - ent->CTS_Offset = gf_bs_read_int(bs, gf_isom_ctrn_field_size_bits(ptr->ctrn_first_ctts) ); - ISOM_DECREASE_SIZE(ptr, ctrn_field_size(ptr->ctrn_first_ctts) ); - if (ptr->ctso_multiplier) - ent->CTS_Offset *= (s32) ptr->ctso_multiplier; - } - } - count = ptr->sample_count - first_idx; - if (!inherit_dur && ptr->ctrn_dur) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_dur); - ISOM_DECREASE_SIZE(ptr, count * nbbits / 8); - for (i=first_idx; isample_count; i++) { - ent = gf_list_get(ptr->entries, i); - ent->Duration = gf_bs_read_int(bs, nbbits); - } - } - if (!inherit_size && ptr->ctrn_size) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_size); - ISOM_DECREASE_SIZE(ptr, count * nbbits / 8); - for (i=first_idx; isample_count; i++) { - ent = gf_list_get(ptr->entries, i); - ent->size = gf_bs_read_int(bs, nbbits); - } - } - if (!inherit_flags && ptr->ctrn_sample_flags) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_sample_flags); - ISOM_DECREASE_SIZE(ptr, count * nbbits / 8); - for (i=first_idx; isample_count; i++) { - ent = gf_list_get(ptr->entries, i); - ent->flags = ctrn_read_flags(bs, nbbits); - } - } - if (!inherit_ctso && ptr->ctrn_ctts) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ptr->ctrn_ctts); - ISOM_DECREASE_SIZE(ptr, count * nbbits / 8); - for (i=first_idx; isample_count; i++) { - ent = gf_list_get(ptr->entries, i); - ent->CTS_Offset = gf_bs_read_int(bs, nbbits); - if (ptr->ctso_multiplier) - ent->CTS_Offset *= (s32) ptr->ctso_multiplier; - } - } - - return GF_OK; -} -#endif - -GF_Err trun_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s; - -#ifdef GF_ENABLE_CTRN - if (ptr->type == GF_ISOM_BOX_TYPE_CTRN) { - ptr->type = GF_ISOM_BOX_TYPE_TRUN; - ptr->use_ctrn = GF_TRUE; - return ctrn_box_read(s, bs); - } -#endif - - //check this is a good file - if ((ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) && (ptr->flags & GF_ISOM_TRUN_FLAGS)) - return GF_ISOM_INVALID_FILE; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->sample_count = gf_bs_read_u32(bs); - - //The rest depends on the flags - if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->data_offset = gf_bs_read_u32(bs); - } - if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->first_sample_flags = gf_bs_read_u32(bs); - } - if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) { - ptr->samples = gf_malloc(sizeof(GF_TrunEntry)); - if (!ptr->samples) return GF_OUT_OF_MEM; - ptr->sample_alloc = ptr->nb_samples = 1; - ptr->samples[0].nb_pack = ptr->sample_count; - } else { - //if we get here, at least one flag (so at least 4 bytes) is set, check size - if (ptr->sample_count * 4 > ptr->size) { - ISOM_DECREASE_SIZE(ptr, ptr->sample_count*4); - } - ptr->samples = gf_malloc(sizeof(GF_TrunEntry) * ptr->sample_count); - if (!ptr->samples) return GF_OUT_OF_MEM; - ptr->sample_alloc = ptr->nb_samples = ptr->sample_count; - - //read each entry (even though nothing may be written) - for (i=0; isample_count; i++) { - u32 trun_size = 0; - GF_TrunEntry *p = &ptr->samples[i]; - memset(p, 0, sizeof(GF_TrunEntry)); - - if (ptr->flags & GF_ISOM_TRUN_DURATION) { - p->Duration = gf_bs_read_u32(bs); - trun_size += 4; - } - if (ptr->flags & GF_ISOM_TRUN_SIZE) { - p->size = gf_bs_read_u32(bs); - trun_size += 4; - } - //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED - if (ptr->flags & GF_ISOM_TRUN_FLAGS) { - p->flags = gf_bs_read_u32(bs); - trun_size += 4; - } - if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) { - if (ptr->version==0) { - p->CTS_Offset = (u32) gf_bs_read_u32(bs); - } else { - p->CTS_Offset = (s32) gf_bs_read_u32(bs); - } - trun_size += 4; - } - ISOM_DECREASE_SIZE(ptr, trun_size); - } - } - /*todo parse sample reorder*/ - if (ptr->size) { - gf_bs_skip_bytes(bs, ptr->size); - ptr->size = 0; - } - return GF_OK; -} - -GF_Box *trun_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackFragmentRunBox, GF_ISOM_BOX_TYPE_TRUN); - //NO FLAGS SET BY DEFAULT - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -#ifdef GF_ENABLE_CTRN -static void ctrn_write_sample_flags(GF_BitStream *bs, u32 flags, u32 field_size) -{ - if (!field_size) return; - - if (field_size==8) flags = flags>>24; - else if (field_size==16) flags = flags>>16; - gf_bs_write_int(bs, flags, field_size); -} - - -static void ctrn_write_ctso(GF_TrackFragmentRunBox *ctrn, GF_BitStream *bs, u32 ctso, u32 field_size) -{ - if (!field_size) return; - - if (ctrn->ctso_multiplier) { - gf_bs_write_int(bs, ctso / ctrn->ctso_multiplier, field_size); - } else { - gf_bs_write_int(bs, ctso, field_size); - } -} - -GF_Err ctrn_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i, count, flags; - GF_TrunEntry *ent; - GF_TrackFragmentRunBox *ctrn = (GF_TrackFragmentRunBox *) s; - if (!s) return GF_BAD_PARAM; - flags = ctrn->flags; - ctrn->flags = ctrn->ctrn_flags; - ctrn->type = GF_ISOM_BOX_TYPE_CTRN; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - ctrn->flags = flags; - ctrn->type = GF_ISOM_BOX_TYPE_TRUN; - - gf_bs_write_u16(bs, ctrn->sample_count); - if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) { - if (ctrn->ctrn_flags & GF_ISOM_CTRN_DATAOFFSET_16) { - gf_bs_write_u16(bs, ctrn->data_offset); - } else { - gf_bs_write_u32(bs, ctrn->data_offset); - } - } - if (ctrn->ctso_multiplier) { - gf_bs_write_u16(bs, ctrn->ctso_multiplier); - } - /*we always write first sample using first flags*/ - ent = gf_list_get(ctrn->entries, 0); - gf_bs_write_int(bs, ent->Duration, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_dur) ); - gf_bs_write_int(bs, ent->size, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_size) ); - ctrn_write_sample_flags(bs, ent->flags, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_sample_flags) ); - ctrn_write_ctso(ctrn,bs, ent->CTS_Offset, gf_isom_ctrn_field_size_bits(ctrn->ctrn_first_ctts) ); - - count = gf_list_count(ctrn->entries); - if (ctrn->ctrn_dur) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_dur); - for (i=1; ientries, i); - gf_bs_write_int(bs, a_ent->Duration, nbbits); - } - } - if (ctrn->ctrn_size) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_size); - for (i=1; ientries, i); - gf_bs_write_int(bs, a_ent->size, nbbits); - } - } - if (ctrn->ctrn_sample_flags) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_sample_flags); - for (i=1; ientries, i); - ctrn_write_sample_flags(bs, a_ent->flags, nbbits); - } - } - if (ctrn->ctrn_ctts) { - u32 nbbits = gf_isom_ctrn_field_size_bits(ctrn->ctrn_ctts); - for (i=1; ientries, i); - ctrn_write_ctso(ctrn, bs, a_ent->CTS_Offset, nbbits); - } - } - - return GF_OK; -} -#endif - -GF_Err trun_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *) s; - if (!s) return GF_BAD_PARAM; - -#ifdef GF_ENABLE_CTRN - if (ptr->use_ctrn) - return ctrn_box_write(s, bs); -#endif - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->sample_count); - - //The rest depends on the flags - if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) { - gf_bs_write_u32(bs, ptr->data_offset); - } - if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) { - gf_bs_write_u32(bs, ptr->first_sample_flags); - } - - if (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) { - for (i=0; inb_samples; i++) { - GF_TrunEntry *p = &ptr->samples[i]; - - if (ptr->flags & GF_ISOM_TRUN_DURATION) { - gf_bs_write_u32(bs, p->Duration); - } - if (ptr->flags & GF_ISOM_TRUN_SIZE) { - gf_bs_write_u32(bs, p->size); - } - //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED - if (ptr->flags & GF_ISOM_TRUN_FLAGS) { - gf_bs_write_u32(bs, p->flags); - } - if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) { - if (ptr->version==0) { - gf_bs_write_u32(bs, p->CTS_Offset); - } else { - gf_bs_write_u32(bs, (u32) p->CTS_Offset); - } - } - } - } - - if (ptr->sample_order) { - u32 nb_bits = 8; - if (ptr->sample_count>0xFFFFFF) nb_bits = 32; - else if (ptr->sample_count>0xFFFF) nb_bits = 24; - else if (ptr->sample_count>0xFF) nb_bits = 16; - - for (i=0; isample_count; i++) { - gf_bs_write_int(bs, ptr->sample_order[i], nb_bits); - } - } - return GF_OK; -} - -#ifdef GF_ENABLE_CTRN -static u32 ctrn_sample_flags_to_index(u32 val) -{ - if (!val) return 0; - if (val & 0x0000FFFF) - return 3; - if (val & 0x00FF0000) - return 2; - return 1; -} -static u32 ctrn_u32_to_index(u32 val) -{ - if (!val) return 0; - if (val<=255) return 1; - if (val<=65535) return 2; - return 3; -} -static u32 ctrn_s32_to_index(s32 val) -{ - if (!val) return 0; - if (ABS(val)<=127) return 1; - if (ABS(val)<=32767) return 2; - return 3; -} -static u32 ctrn_ctts_to_index(GF_TrackFragmentRunBox *ctrn, s32 ctts) -{ - if (!(ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET)) - return 0; - - if (!ctts) return 0; - - if (ctrn->version) { - if (ctrn->ctso_multiplier) return ctrn_s32_to_index(ctts / ctrn->ctso_multiplier); - return ctrn_s32_to_index(ctts); - } - assert(ctts>0); - if (ctrn->ctso_multiplier) return ctrn_u32_to_index((u32)ctts / ctrn->ctso_multiplier); - return ctrn_s32_to_index((u32)ctts); -} - -static GF_Err ctrn_box_size(GF_TrackFragmentRunBox *ctrn) -{ - Bool use_ctso_multi = GF_TRUE; - u32 i, count; - GF_TrunEntry *ent; - - ctrn->ctrn_flags = 0; - ctrn->ctrn_first_dur = ctrn->ctrn_first_size = ctrn->ctrn_first_sample_flags = ctrn->ctrn_first_ctts = 0; - ctrn->ctrn_dur = ctrn->ctrn_size = ctrn->ctrn_sample_flags = ctrn->ctrn_ctts = 0; - - ctrn->size += 2; //16 bits for sample count - if (ctrn->flags & GF_ISOM_TRUN_DATA_OFFSET) { - ctrn->ctrn_flags |= GF_ISOM_TRUN_DATA_OFFSET; - if (ABS(ctrn->data_offset) < 32767) { - ctrn->size += 2; - ctrn->ctrn_flags |= GF_ISOM_CTRN_DATAOFFSET_16; - } else - ctrn->size += 4; - } - - count = gf_list_count(ctrn->entries); - if (ctrn->ctso_multiplier && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET) && (ctrn->ctso_multiplier<=0xFFFF) ) { - for (i=0; ientries, i); - if (a_ent->CTS_Offset % ctrn->ctso_multiplier) { - use_ctso_multi = GF_FALSE; - break; - } - } - } else { - use_ctso_multi = GF_FALSE; - } - if (ctrn->use_inherit) { - use_ctso_multi = GF_FALSE; - ctrn->ctrn_flags |= 0xB0; //duration=1,size=0,flags=1,cts=1 << 4 - } - - if (use_ctso_multi) { - ctrn->size += 2; - ctrn->ctrn_flags |= GF_ISOM_CTRN_CTSO_MULTIPLIER; - } else { - ctrn->ctso_multiplier = 0; - } - - /*we always write first sample using first flags*/ - ent = gf_list_get(ctrn->entries, 0); - ctrn->ctrn_flags |= GF_ISOM_CTRN_FIRST_SAMPLE; - - if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) { - ctrn->ctrn_first_dur = ctrn_u32_to_index(ent->Duration); - if (ctrn->ctrn_first_dur) { - ctrn->size += ctrn_field_size(ctrn->ctrn_first_dur); - ctrn->ctrn_flags |= ctrn->ctrn_first_dur<<22; - } - } - - if (ctrn->flags & GF_ISOM_TRUN_SIZE) { - ctrn->ctrn_first_size = ctrn_u32_to_index(ent->size); - if (ctrn->ctrn_first_size) { - ctrn->size += ctrn_field_size(ctrn->ctrn_first_size); - ctrn->ctrn_flags |= ctrn->ctrn_first_size<<20; - } - } - - if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) { - ctrn->ctrn_first_sample_flags = ctrn_sample_flags_to_index(ent->flags); - if (ctrn->ctrn_first_sample_flags) { - ctrn->size += ctrn_field_size(ctrn->ctrn_first_sample_flags); - ctrn->ctrn_flags |= ctrn->ctrn_first_sample_flags<<18; - } - } - if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_CTS_OFFSET)) { - ctrn->ctrn_first_ctts = ctrn_ctts_to_index(ctrn, ent->CTS_Offset); - if (ctrn->ctrn_first_ctts) { - ctrn->size += ctrn_field_size(ctrn->ctrn_first_ctts); - ctrn->ctrn_flags |= ctrn->ctrn_first_ctts<<16; - } - } - - for (i=1; ientries, i); - - if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_DURATION)) { - field_idx = ctrn_u32_to_index(a_ent->Duration); - if (ctrn->ctrn_dur < field_idx) - ctrn->ctrn_dur = field_idx; - } - if (ctrn->flags & GF_ISOM_TRUN_SIZE) { - field_idx = ctrn_u32_to_index(a_ent->size); - if (ctrn->ctrn_size < field_idx) - ctrn->ctrn_size = field_idx; - } - if (!ctrn->use_inherit && (ctrn->flags & GF_ISOM_TRUN_FLAGS)) { - field_idx = ctrn_sample_flags_to_index(a_ent->flags); - if (ctrn->ctrn_sample_flags < field_idx) - ctrn->ctrn_sample_flags = field_idx; - } - if (!ctrn->use_inherit) { - field_idx = ctrn_ctts_to_index(ctrn, a_ent->CTS_Offset); - if (ctrn->ctrn_ctts < field_idx) - ctrn->ctrn_ctts = field_idx; - } - } - count-=1; - if (ctrn->ctrn_dur) { - ctrn->size += count * ctrn_field_size(ctrn->ctrn_dur); - ctrn->ctrn_flags |= ctrn->ctrn_dur<<14; - } - if (ctrn->ctrn_size) { - ctrn->size += count * ctrn_field_size(ctrn->ctrn_size); - ctrn->ctrn_flags |= ctrn->ctrn_size<<12; - } - if (ctrn->ctrn_sample_flags) { - ctrn->size += count * ctrn_field_size(ctrn->ctrn_sample_flags); - ctrn->ctrn_flags |= ctrn->ctrn_sample_flags<<10; - } - if (ctrn->ctrn_ctts) { - ctrn->size += count * ctrn_field_size(ctrn->ctrn_ctts); - ctrn->ctrn_flags |= ctrn->ctrn_ctts<<8; - } - return GF_OK; -} -#endif - -GF_Err trun_box_size(GF_Box *s) -{ - GF_TrackFragmentRunBox *ptr = (GF_TrackFragmentRunBox *)s; - -#ifdef GF_ENABLE_CTRN - if (ptr->use_ctrn) - return ctrn_box_size(ptr); -#endif - - ptr->size += 4; - //The rest depends on the flags - if (ptr->flags & GF_ISOM_TRUN_DATA_OFFSET) ptr->size += 4; - if (ptr->flags & GF_ISOM_TRUN_FIRST_FLAG) ptr->size += 4; - - if (ptr->sample_order) { - u32 nb_bytes = 1; - if (ptr->sample_count>0xFFFFFF) nb_bytes = 4; - else if (ptr->sample_count>0xFFFF) nb_bytes = 3; - else if (ptr->sample_count>0xFF) nb_bytes = 2; - ptr->size += ptr->sample_count*nb_bytes; - } - - if (! (ptr->flags & (GF_ISOM_TRUN_DURATION | GF_ISOM_TRUN_SIZE | GF_ISOM_TRUN_FLAGS | GF_ISOM_TRUN_CTS_OFFSET) ) ) { - return GF_OK; - } - - //if nothing to do, this will be skipped automatically - if (ptr->flags & GF_ISOM_TRUN_DURATION) ptr->size += 4*ptr->nb_samples; - if (ptr->flags & GF_ISOM_TRUN_SIZE) ptr->size += 4*ptr->nb_samples; - //SHOULDN'T BE USED IF GF_ISOM_TRUN_FIRST_FLAG IS DEFINED - if (ptr->flags & GF_ISOM_TRUN_FLAGS) ptr->size += 4*ptr->nb_samples; - if (ptr->flags & GF_ISOM_TRUN_CTS_OFFSET) ptr->size += 4*ptr->nb_samples; - - return GF_OK; -} - - - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - - -void tsro_box_del(GF_Box *s) -{ - GF_TimeOffHintEntryBox *tsro = (GF_TimeOffHintEntryBox *)s; - gf_free(tsro); -} - -GF_Err tsro_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->TimeOffset = gf_bs_read_u32(bs); - return GF_OK; -} - -GF_Box *tsro_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TimeOffHintEntryBox, GF_ISOM_BOX_TYPE_TSRO); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err tsro_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TimeOffHintEntryBox *ptr = (GF_TimeOffHintEntryBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->TimeOffset); - return GF_OK; -} - -GF_Err tsro_box_size(GF_Box *s) -{ - s->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void udta_box_del(GF_Box *s) -{ - u32 i; - GF_UserDataMap *map; - GF_UserDataBox *ptr = (GF_UserDataBox *)s; - if (ptr == NULL) return; - i=0; - while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) { - gf_isom_box_array_del(map->boxes); - gf_free(map); - } - gf_list_del(ptr->recordList); - gf_free(ptr); -} - -GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid) -{ - u32 i; - GF_UserDataMap *map; - if (ptr == NULL) return NULL; - i=0; - while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) { - if (map->boxType == box_type) { - if ((box_type != GF_ISOM_BOX_TYPE_UUID) || !uuid) return map; - if (!memcmp(map->uuid, *uuid, 16)) return map; - } - } - return NULL; -} - -GF_Err udta_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_Err e; - u32 box_type; - GF_UserDataMap *map; - GF_UserDataBox *ptr = (GF_UserDataBox *)s; - if (!ptr) return GF_BAD_PARAM; - if (!a) return GF_OK; - - //detach from parent list if any - gf_list_del_item(ptr->child_boxes, a); - - /* for unknown udta boxes, we reference them by their original box type */ - box_type = a->type; - if (box_type == GF_ISOM_BOX_TYPE_UNKNOWN) { - GF_UnknownBox* unkn = (GF_UnknownBox *)a; - box_type = unkn->original_4cc; - } - - map = udta_getEntry(ptr, box_type, (a->type==GF_ISOM_BOX_TYPE_UUID) ? & ((GF_UUIDBox *)a)->uuid : NULL); - if (map == NULL) { - map = (GF_UserDataMap *) gf_malloc(sizeof(GF_UserDataMap)); - if (map == NULL) return GF_OUT_OF_MEM; - memset(map, 0, sizeof(GF_UserDataMap)); - - map->boxType = box_type; - if (a->type == GF_ISOM_BOX_TYPE_UUID) - memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16); - map->boxes = gf_list_new(); - if (!map->boxes) { - gf_free(map); - return GF_OUT_OF_MEM; - } - e = gf_list_add(ptr->recordList, map); - if (e) return e; - } - return gf_list_add(map->boxes, a); -} - - -GF_Err udta_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e = gf_isom_box_array_read(s, bs, udta_on_child_box); - if (e) return e; - if (s->size==4) { - u32 val = gf_bs_read_u32(bs); - s->size = 0; - if (val) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] udta has 4 remaining bytes set to %08X but they should be 0\n", val)); - } - } - return GF_OK; -} - -GF_Box *udta_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_UserDataBox, GF_ISOM_BOX_TYPE_UDTA); - tmp->recordList = gf_list_new(); - if (!tmp->recordList) { - gf_free(tmp); - return NULL; - } - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err udta_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_UserDataMap *map; - GF_UserDataBox *ptr = (GF_UserDataBox *)s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - i=0; - while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) { - //warning: here we are not passing the actual "parent" of the list - //but the UDTA box. The parent itself is not an box, we don't care about it - e = gf_isom_box_array_write(s, map->boxes, bs); - if (e) return e; - } - return GF_OK; -} - -GF_Err udta_box_size(GF_Box *s) -{ - GF_Err e; - u32 i; - GF_UserDataMap *map; - GF_UserDataBox *ptr = (GF_UserDataBox *)s; - - i=0; - while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) { - //warning: here we are not passing the actual "parent" of the list - //but the UDTA box. The parent itself is not an box, we don't care about it - e = gf_isom_box_array_size(s, map->boxes); - if (e) return e; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void vmhd_box_del(GF_Box *s) -{ - GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err vmhd_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s; - - ISOM_DECREASE_SIZE(ptr, 8); - ptr->reserved = gf_bs_read_u64(bs); - return GF_OK; -} - -GF_Box *vmhd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_VideoMediaHeaderBox, GF_ISOM_BOX_TYPE_VMHD); - tmp->flags = 1; - return (GF_Box *)tmp; -} - - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err vmhd_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u64(bs, ptr->reserved); - return GF_OK; -} - -GF_Err vmhd_box_size(GF_Box *s) -{ - GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s; - ptr->size += 8; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void void_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err void_box_read(GF_Box *s, GF_BitStream *bs) -{ - if (s->size) return GF_ISOM_INVALID_FILE; - return GF_OK; -} - -GF_Box *void_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_Box, GF_ISOM_BOX_TYPE_VOID); - return tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err void_box_write(GF_Box *s, GF_BitStream *bs) -{ - gf_bs_write_u32(bs, 0); - return GF_OK; -} - -GF_Err void_box_size(GF_Box *s) -{ - s->size = 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *pdin_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ProgressiveDownloadBox, GF_ISOM_BOX_TYPE_PDIN); - return (GF_Box *)tmp; -} - - -void pdin_box_del(GF_Box *s) -{ - GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s; - if (ptr == NULL) return; - if (ptr->rates) gf_free(ptr->rates); - if (ptr->times) gf_free(ptr->times); - gf_free(ptr); -} - - -GF_Err pdin_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s; - - ptr->count = (u32) (ptr->size) / 8; - ptr->rates = (u32*)gf_malloc(sizeof(u32)*ptr->count); - if (!ptr->rates) return GF_OUT_OF_MEM; - ptr->times = (u32*)gf_malloc(sizeof(u32)*ptr->count); - if (!ptr->times) return GF_OUT_OF_MEM; - for (i=0; icount; i++) { - ptr->rates[i] = gf_bs_read_u32(bs); - ptr->times[i] = gf_bs_read_u32(bs); - } - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err pdin_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - for (i=0; icount; i++) { - gf_bs_write_u32(bs, ptr->rates[i]); - gf_bs_write_u32(bs, ptr->times[i]); - } - return GF_OK; -} - -GF_Err pdin_box_size(GF_Box *s) -{ - GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox *)s; - ptr->size += 8*ptr->count; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -GF_Box *sdtp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleDependencyTypeBox, GF_ISOM_BOX_TYPE_SDTP); - return (GF_Box *)tmp; -} - - -void sdtp_box_del(GF_Box *s) -{ - GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s; - if (ptr == NULL) return; - if (ptr->sample_info) gf_free(ptr->sample_info); - gf_free(ptr); -} - - -GF_Err sdtp_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s; - - /*out-of-order sdtp, assume no padding at the end*/ - if (!ptr->sampleCount) ptr->sampleCount = (u32) ptr->size; - else if (ptr->sampleCount > (u32) ptr->size) return GF_ISOM_INVALID_FILE; - - ptr->sample_info = (u8 *) gf_malloc(sizeof(u8)*ptr->sampleCount); - if (!ptr->sample_info) return GF_OUT_OF_MEM; - ptr->sample_alloc = ptr->sampleCount; - gf_bs_read_data(bs, (char*)ptr->sample_info, ptr->sampleCount); - ISOM_DECREASE_SIZE(ptr, ptr->sampleCount); - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err sdtp_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_data(bs, (char*)ptr->sample_info, ptr->sampleCount); - return GF_OK; -} - -GF_Err sdtp_box_size(GF_Box *s) -{ - GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox *)s; - ptr->size += ptr->sampleCount; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *pasp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PixelAspectRatioBox, GF_ISOM_BOX_TYPE_PASP); - return (GF_Box *)tmp; -} - - -void pasp_box_del(GF_Box *s) -{ - GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err pasp_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->hSpacing = gf_bs_read_u32(bs); - ptr->vSpacing = gf_bs_read_u32(bs); - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err pasp_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->hSpacing); - gf_bs_write_u32(bs, ptr->vSpacing); - return GF_OK; -} - -GF_Err pasp_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *clap_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_CleanApertureBox, GF_ISOM_BOX_TYPE_CLAP); - return (GF_Box *)tmp; -} - - -void clap_box_del(GF_Box *s) -{ - GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err clap_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_CleanApertureBox *ptr = (GF_CleanApertureBox*)s; - ISOM_DECREASE_SIZE(ptr, 32); - ptr->cleanApertureWidthN = gf_bs_read_u32(bs); - ptr->cleanApertureWidthD = gf_bs_read_u32(bs); - ptr->cleanApertureHeightN = gf_bs_read_u32(bs); - ptr->cleanApertureHeightD = gf_bs_read_u32(bs); - ptr->horizOffN = gf_bs_read_u32(bs); - ptr->horizOffD = gf_bs_read_u32(bs); - ptr->vertOffN = gf_bs_read_u32(bs); - ptr->vertOffD = gf_bs_read_u32(bs); - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err clap_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_CleanApertureBox *ptr = (GF_CleanApertureBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->cleanApertureWidthN); - gf_bs_write_u32(bs, ptr->cleanApertureWidthD); - gf_bs_write_u32(bs, ptr->cleanApertureHeightN); - gf_bs_write_u32(bs, ptr->cleanApertureHeightD); - gf_bs_write_u32(bs, ptr->horizOffN); - gf_bs_write_u32(bs, ptr->horizOffD); - gf_bs_write_u32(bs, ptr->vertOffN); - gf_bs_write_u32(bs, ptr->vertOffD); - return GF_OK; -} - -GF_Err clap_box_size(GF_Box *s) -{ - s->size += 32; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -GF_Box *metx_box_new() -{ - //type is overridden by the box constructor - ISOM_DECL_BOX_ALLOC(GF_MetaDataSampleEntryBox, GF_ISOM_BOX_TYPE_METX); - gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp); - return (GF_Box *)tmp; -} - - -void metx_box_del(GF_Box *s) -{ - GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s; - if (ptr == NULL) return; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - - if (ptr->content_encoding) gf_free(ptr->content_encoding); - if (ptr->xml_namespace) gf_free(ptr->xml_namespace); - if (ptr->xml_schema_loc) gf_free(ptr->xml_schema_loc); - if (ptr->mime_type) gf_free(ptr->mime_type); - gf_free(ptr); -} - - -GF_Err metx_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_SINF: - return GF_OK; - case GF_ISOM_BOX_TYPE_TXTC: - //we allow the config box on metx - if (ptr->config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->config = (GF_TextConfigBox *)a; - break; - } - return GF_OK; -} - -GF_Err metx_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 size, i; - GF_Err e; - char *str; - GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s; - - e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs); - if (e) return e; - ISOM_DECREASE_SIZE(ptr, 8); - - size = (u32) ptr->size; - str = gf_malloc(sizeof(char)*size); - if (!str) return GF_OUT_OF_MEM; - - i=0; - - while (size) { - str[i] = gf_bs_read_u8(bs); - size--; - if (!str[i]) { - i++; - break; - } - i++; - } - if (!size && i>1 && str[i-1]) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n")); - gf_free(str); - return GF_ISOM_INVALID_FILE; - } - if (i>1) { - if (ptr->type==GF_ISOM_BOX_TYPE_STPP) { - ptr->xml_namespace = gf_strdup(str); - } else { - ptr->content_encoding = gf_strdup(str); - } - } - - i=0; - while (size) { - str[i] = gf_bs_read_u8(bs); - size--; - if (!str[i]) { - i++; - break; - } - i++; - } - if (!size && i>1 && str[i-1]) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n")); - gf_free(str); - return GF_ISOM_INVALID_FILE; - } - if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) { - if (i>1) { - if (ptr->type==GF_ISOM_BOX_TYPE_STPP) { - ptr->xml_schema_loc = gf_strdup(str); - } else { - ptr->xml_namespace = gf_strdup(str); - } - } - - i=0; - while (size) { - str[i] = gf_bs_read_u8(bs); - size--; - if (!str[i]) { - i++; - break; - } - i++; - } - if (!size && i>1 && str[i-1]) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] metx read invalid string\n")); - gf_free(str); - return GF_ISOM_INVALID_FILE; - } - if (i>1) { - if (ptr->type==GF_ISOM_BOX_TYPE_STPP) { - ptr->mime_type = gf_strdup(str); - } else { - ptr->xml_schema_loc = gf_strdup(str); - } - } - } - //mett, sbtt, stxt, stpp - else { - if (i>1) ptr->mime_type = gf_strdup(str); - } - ptr->size = size; - gf_free(str); - return gf_isom_box_array_read(s, bs, metx_on_child_box); -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err metx_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - - if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) { - if (ptr->content_encoding) - gf_bs_write_data(bs, ptr->content_encoding, (u32) strlen(ptr->content_encoding)); - gf_bs_write_u8(bs, 0); - } - - if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) { - if (ptr->xml_namespace) - gf_bs_write_data(bs, ptr->xml_namespace, (u32) strlen(ptr->xml_namespace)); - - gf_bs_write_u8(bs, 0); - - if (ptr->xml_schema_loc) - gf_bs_write_data(bs, ptr->xml_schema_loc, (u32) strlen(ptr->xml_schema_loc)); - gf_bs_write_u8(bs, 0); - - if (ptr->type==GF_ISOM_BOX_TYPE_STPP) { - if (ptr->mime_type) - gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type)); - - gf_bs_write_u8(bs, 0); - } - } - //mett, sbtt, stxt - else { - if (ptr->mime_type) - gf_bs_write_data(bs, ptr->mime_type, (u32) strlen(ptr->mime_type)); - - gf_bs_write_u8(bs, 0); - } - - return GF_OK; -} - -GF_Err metx_box_size(GF_Box *s) -{ - GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox *)s; - ptr->size += 8; - - if (ptr->type!=GF_ISOM_BOX_TYPE_STPP) { - if (ptr->content_encoding) - ptr->size += strlen(ptr->content_encoding); - ptr->size++; - } - - if ((ptr->type==GF_ISOM_BOX_TYPE_METX) || (ptr->type==GF_ISOM_BOX_TYPE_STPP)) { - - if (ptr->xml_namespace) - ptr->size += strlen(ptr->xml_namespace); - ptr->size++; - - if (ptr->xml_schema_loc) - ptr->size += strlen(ptr->xml_schema_loc); - ptr->size++; - - if (ptr->type==GF_ISOM_BOX_TYPE_STPP) { - if (ptr->mime_type) - ptr->size += strlen(ptr->mime_type); - ptr->size++; - } - - } - //mett, sbtt, stxt - else { - if (ptr->mime_type) - ptr->size += strlen(ptr->mime_type); - ptr->size++; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/* SimpleTextSampleEntry */ -GF_Box *txtc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TextConfigBox, GF_ISOM_BOX_TYPE_TXTC); - return (GF_Box *)tmp; -} - - -void txtc_box_del(GF_Box *s) -{ - GF_TextConfigBox *ptr = (GF_TextConfigBox*)s; - if (ptr == NULL) return; - - if (ptr->config) gf_free(ptr->config); - gf_free(ptr); -} - -GF_Err txtc_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TextConfigBox *ptr = (GF_TextConfigBox*)s; - ptr->config = (char *)gf_malloc(sizeof(char)*((u32) ptr->size+1)); - if (!ptr->config) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->config, (u32) ptr->size); - ptr->config[ptr->size] = 0; - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err txtc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_TextConfigBox *ptr = (GF_TextConfigBox *)s; - GF_Err e = gf_isom_full_box_write(s, bs); - if (e) return e; - - if (ptr->config) - gf_bs_write_data(bs, ptr->config, (u32) strlen(ptr->config)); - gf_bs_write_u8(bs, 0); - return GF_OK; -} - -GF_Err txtc_box_size(GF_Box *s) -{ - GF_TextConfigBox *ptr = (GF_TextConfigBox *)s; - if (ptr->config) - ptr->size += strlen(ptr->config); - ptr->size++; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *dac3_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3); - return (GF_Box *)tmp; -} - -GF_Box *dec3_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AC3ConfigBox, GF_ISOM_BOX_TYPE_DAC3); - tmp->cfg.is_ec3 = 1; - return (GF_Box *)tmp; -} - -void dac3_box_del(GF_Box *s) -{ - GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s; - gf_free(ptr); -} - -GF_Err gf_isom_ac3_config_parse_bs(GF_BitStream *bs, Bool is_ec3, GF_AC3Config *cfg); - -GF_Err dac3_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - return gf_isom_ac3_config_parse_bs(bs, ptr->cfg.is_ec3, &ptr->cfg); -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err dac3_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s; - - if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DEC3; - e = gf_isom_box_write_header(s, bs); - if (ptr->cfg.is_ec3) s->type = GF_ISOM_BOX_TYPE_DAC3; - if (e) return e; - - if (ptr->cfg.is_ec3) { - u32 i; - gf_bs_write_int(bs, ptr->cfg.brcode, 13); - gf_bs_write_int(bs, ptr->cfg.nb_streams - 1, 3); - for (i=0; icfg.nb_streams; i++) { - gf_bs_write_int(bs, ptr->cfg.streams[i].fscod, 2); - gf_bs_write_int(bs, ptr->cfg.streams[i].bsid, 5); - gf_bs_write_int(bs, ptr->cfg.streams[i].bsmod, 5); - gf_bs_write_int(bs, ptr->cfg.streams[i].acmod, 3); - gf_bs_write_int(bs, ptr->cfg.streams[i].lfon, 1); - gf_bs_write_int(bs, 0, 3); - gf_bs_write_int(bs, ptr->cfg.streams[i].nb_dep_sub, 4); - if (ptr->cfg.streams[i].nb_dep_sub) { - gf_bs_write_int(bs, ptr->cfg.streams[i].chan_loc, 9); - } else { - gf_bs_write_int(bs, 0, 1); - } - } - } else { - gf_bs_write_int(bs, ptr->cfg.streams[0].fscod, 2); - gf_bs_write_int(bs, ptr->cfg.streams[0].bsid, 5); - gf_bs_write_int(bs, ptr->cfg.streams[0].bsmod, 3); - gf_bs_write_int(bs, ptr->cfg.streams[0].acmod, 3); - gf_bs_write_int(bs, ptr->cfg.streams[0].lfon, 1); - gf_bs_write_int(bs, ptr->cfg.brcode, 5); - gf_bs_write_int(bs, 0, 5); - } - return GF_OK; -} - -GF_Err dac3_box_size(GF_Box *s) -{ - GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s; - - if (ptr->cfg.is_ec3) { - u32 i; - s->size += 2; - for (i=0; icfg.nb_streams; i++) { - s->size += 3; - if (ptr->cfg.streams[i].nb_dep_sub) - s->size += 1; - } - } else { - s->size += 3; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void lsrc_box_del(GF_Box *s) -{ - GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; - if (ptr == NULL) return; - if (ptr->hdr) gf_free(ptr->hdr); - gf_free(ptr); -} - - -GF_Err lsrc_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; - ptr->hdr_size = (u32) ptr->size; - ptr->hdr = gf_malloc(sizeof(char)*ptr->hdr_size); - if (!ptr->hdr) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->hdr, ptr->hdr_size); - return GF_OK; -} - -GF_Box *lsrc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_LASERConfigurationBox, GF_ISOM_BOX_TYPE_LSRC); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err lsrc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_data(bs, ptr->hdr, ptr->hdr_size); - return GF_OK; -} - -GF_Err lsrc_box_size(GF_Box *s) -{ - GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; - ptr->size += ptr->hdr_size; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void lsr1_box_del(GF_Box *s) -{ - GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; - if (ptr == NULL) return; - gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); - if (ptr->slc) gf_odf_desc_del((GF_Descriptor *)ptr->slc); - gf_free(ptr); -} - -GF_Err lsr1_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_LSRC: - if (ptr->lsr_config) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->lsr_config = (GF_LASERConfigurationBox *)a; - break; - case GF_ISOM_BOX_TYPE_M4DS: - if (ptr->descr) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a; - break; - } - return GF_OK; -} - -GF_Err lsr1_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox*)s; - - e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs); - if (e) return e; - - ISOM_DECREASE_SIZE(ptr, 8); - - return gf_isom_box_array_read(s, bs, lsr1_on_child_box); -} - -GF_Box *lsr1_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_LASeRSampleEntryBox, GF_ISOM_BOX_TYPE_LSR1); - gf_isom_sample_entry_init((GF_SampleEntryBox*)tmp); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err lsr1_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_data(bs, ptr->reserved, 6); - gf_bs_write_u16(bs, ptr->dataReferenceIndex); - return GF_OK; -} - -GF_Err lsr1_box_size(GF_Box *s) -{ - u32 pos=0; - GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; - s->size += 8; - gf_isom_check_position(s, (GF_Box *)ptr->lsr_config, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void sidx_box_del(GF_Box *s) -{ - GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox *) s; - if (ptr == NULL) return; - if (ptr->refs) gf_free(ptr->refs); - gf_free(ptr); -} - -GF_Err sidx_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s; - - ISOM_DECREASE_SIZE(ptr, 8); - ptr->reference_ID = gf_bs_read_u32(bs); - ptr->timescale = gf_bs_read_u32(bs); - - if (ptr->version==0) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->earliest_presentation_time = gf_bs_read_u32(bs); - ptr->first_offset = gf_bs_read_u32(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 16); - ptr->earliest_presentation_time = gf_bs_read_u64(bs); - ptr->first_offset = gf_bs_read_u64(bs); - } - ISOM_DECREASE_SIZE(ptr, 4); - gf_bs_read_u16(bs); /* reserved */ - ptr->nb_refs = gf_bs_read_u16(bs); - - ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs); - if (!ptr->refs) return GF_OUT_OF_MEM; - for (i=0; inb_refs; i++) { - ptr->refs[i].reference_type = gf_bs_read_int(bs, 1); - ptr->refs[i].reference_size = gf_bs_read_int(bs, 31); - ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs); - ptr->refs[i].starts_with_SAP = gf_bs_read_int(bs, 1); - ptr->refs[i].SAP_type = gf_bs_read_int(bs, 3); - ptr->refs[i].SAP_delta_time = gf_bs_read_int(bs, 28); - - ISOM_DECREASE_SIZE(ptr, 12); - } - return GF_OK; -} - -GF_Box *sidx_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SegmentIndexBox, GF_ISOM_BOX_TYPE_SIDX); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err sidx_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->reference_ID); - gf_bs_write_u32(bs, ptr->timescale); - if (ptr->version==0) { - gf_bs_write_u32(bs, (u32) ptr->earliest_presentation_time); - gf_bs_write_u32(bs, (u32) ptr->first_offset); - } else { - gf_bs_write_u64(bs, ptr->earliest_presentation_time); - gf_bs_write_u64(bs, ptr->first_offset); - } - gf_bs_write_u16(bs, 0); - gf_bs_write_u16(bs, ptr->nb_refs); - for (i=0; inb_refs; i++ ) { - gf_bs_write_int(bs, ptr->refs[i].reference_type, 1); - gf_bs_write_int(bs, ptr->refs[i].reference_size, 31); - gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration); - gf_bs_write_int(bs, ptr->refs[i].starts_with_SAP, 1); - gf_bs_write_int(bs, ptr->refs[i].SAP_type, 3); - gf_bs_write_int(bs, ptr->refs[i].SAP_delta_time, 28); - } - return GF_OK; -} - -GF_Err sidx_box_size(GF_Box *s) -{ - GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s; - - ptr->size += 12; - if (ptr->version==0) { - ptr->size += 8; - } else { - ptr->size += 16; - } - ptr->size += ptr->nb_refs * 12; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void ssix_box_del(GF_Box *s) -{ - u32 i; - GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox *)s; - if (ptr == NULL) return; - if (ptr->subsegments) { - for (i = 0; i < ptr->subsegment_alloc; i++) { - GF_SubsegmentInfo *subsegment = &ptr->subsegments[i]; - if (subsegment->ranges) gf_free(subsegment->ranges); - } - gf_free(ptr->subsegments); - } - gf_free(ptr); -} - -GF_Err ssix_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i,j; - GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s; - - ISOM_DECREASE_SIZE(ptr, 4) - ptr->subsegment_count = gf_bs_read_u32(bs); - //each subseg has at least one range_count (4 bytes), abort if not enough bytes (broken box) - if (ptr->size < ptr->subsegment_count*4) - return GF_ISOM_INVALID_FILE; - - GF_SAFE_ALLOC_N(ptr->subsegments, ptr->subsegment_count, GF_SubsegmentInfo); - if (!ptr->subsegments) - return GF_OUT_OF_MEM; - for (i = 0; i < ptr->subsegment_count; i++) { - GF_SubsegmentInfo *subseg = &ptr->subsegments[i]; - ISOM_DECREASE_SIZE(ptr, 4) - subseg->range_count = gf_bs_read_u32(bs); - //each range is 4 bytes, abort if not enough bytes - if (ptr->size < subseg->range_count*4) - return GF_ISOM_INVALID_FILE; - subseg->ranges = (GF_SubsegmentRangeInfo*) gf_malloc(sizeof(GF_SubsegmentRangeInfo) * subseg->range_count); - if (!subseg->ranges) return GF_OUT_OF_MEM; - for (j = 0; j < subseg->range_count; j++) { - ISOM_DECREASE_SIZE(ptr, 4) - subseg->ranges[j].level = gf_bs_read_u8(bs); - subseg->ranges[j].range_size = gf_bs_read_u24(bs); - } - } - return GF_OK; -} - -GF_Box *ssix_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SubsegmentIndexBox, GF_ISOM_BOX_TYPE_SSIX); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ssix_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i, j; - GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->subsegment_count); - for (i = 0; isubsegment_count; i++) { - gf_bs_write_u32(bs, ptr->subsegments[i].range_count); - for (j = 0; j < ptr->subsegments[i].range_count; j++) { - gf_bs_write_u8(bs, ptr->subsegments[i].ranges[j].level); - gf_bs_write_u24(bs, ptr->subsegments[i].ranges[j].range_size); - } - } - return GF_OK; -} - -GF_Err ssix_box_size(GF_Box *s) -{ - u32 i; - GF_SubsegmentIndexBox *ptr = (GF_SubsegmentIndexBox*)s; - - ptr->size += 4; - for (i = 0; i < ptr->subsegment_count; i++) { - ptr->size += 4 + 4 * ptr->subsegments[i].range_count; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void leva_box_del(GF_Box *s) -{ - GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox *)s; - if (ptr == NULL) return; - if (ptr->levels) gf_free(ptr->levels); - gf_free(ptr); -} - -GF_Err leva_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s; - - ISOM_DECREASE_SIZE(ptr, 1) - ptr->level_count = gf_bs_read_u8(bs); - //each level is at least 5 bytes - if (ptr->size < ptr->level_count * 5) - return GF_ISOM_INVALID_FILE; - - GF_SAFE_ALLOC_N(ptr->levels, ptr->level_count, GF_LevelAssignment); - if (!ptr->levels) return GF_OUT_OF_MEM; - - for (i = 0; i < ptr->level_count; i++) { - GF_LevelAssignment *level = &ptr->levels[i]; - u8 tmp; - if (!level || ptr->size < 5) return GF_BAD_PARAM; - ISOM_DECREASE_SIZE(ptr, 5) - - level->track_id = gf_bs_read_u32(bs); - tmp = gf_bs_read_u8(bs); - level->padding_flag = tmp >> 7; - level->type = tmp & 0x7F; - if (level->type == 0) { - ISOM_DECREASE_SIZE(ptr, 4) - level->grouping_type = gf_bs_read_u32(bs); - } - else if (level->type == 1) { - ISOM_DECREASE_SIZE(ptr, 8) - level->grouping_type = gf_bs_read_u32(bs); - level->grouping_type_parameter = gf_bs_read_u32(bs); - } - else if (level->type == 4) { - ISOM_DECREASE_SIZE(ptr, 4) - level->sub_track_id = gf_bs_read_u32(bs); - } - } - return GF_OK; -} - -GF_Box *leva_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_LevelAssignmentBox, GF_ISOM_BOX_TYPE_LEVA); - return (GF_Box *)tmp; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err leva_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u8(bs, ptr->level_count); - for (i = 0; ilevel_count; i++) { - gf_bs_write_u32(bs, ptr->levels[i].track_id); - gf_bs_write_u8(bs, ptr->levels[i].padding_flag << 7 | (ptr->levels[i].type & 0x7F)); - if (ptr->levels[i].type == 0) { - gf_bs_write_u32(bs, ptr->levels[i].grouping_type); - } - else if (ptr->levels[i].type == 1) { - gf_bs_write_u32(bs, ptr->levels[i].grouping_type); - gf_bs_write_u32(bs, ptr->levels[i].grouping_type_parameter); - } - else if (ptr->levels[i].type == 4) { - gf_bs_write_u32(bs, ptr->levels[i].sub_track_id); - } - } - return GF_OK; -} - -GF_Err leva_box_size(GF_Box *s) -{ - u32 i; - GF_LevelAssignmentBox *ptr = (GF_LevelAssignmentBox*)s; - - ptr->size += 1; - for (i = 0; i < ptr->level_count; i++) { - ptr->size += 5; - if (ptr->levels[i].type == 0 || ptr->levels[i].type == 4) { - ptr->size += 4; - } - else if (ptr->levels[i].type == 1) { - ptr->size += 8; - } - } - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *pcrb_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PcrInfoBox, GF_ISOM_BOX_TYPE_PCRB); - return (GF_Box *)tmp; -} - -void pcrb_box_del(GF_Box *s) -{ - GF_PcrInfoBox *ptr = (GF_PcrInfoBox *) s; - if (ptr == NULL) return; - if (ptr->pcr_values) gf_free(ptr->pcr_values); - gf_free(ptr); -} - -GF_Err pcrb_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->subsegment_count = gf_bs_read_u32(bs); - - ptr->pcr_values = gf_malloc(sizeof(u64)*ptr->subsegment_count); - if (!ptr->pcr_values) return GF_OUT_OF_MEM; - for (i=0; isubsegment_count; i++) { - u64 data1 = gf_bs_read_u32(bs); - u64 data2 = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(ptr, 6); - ptr->pcr_values[i] = (data1 << 10) | (data2 >> 6); - - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err pcrb_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->subsegment_count); - - for (i=0; isubsegment_count; i++ ) { - u32 data1 = (u32) (ptr->pcr_values[i] >> 10); - u16 data2 = (u16) (ptr->pcr_values[i] << 6); - - gf_bs_write_u32(bs, data1); - gf_bs_write_u16(bs, data2); - } - return GF_OK; -} - -GF_Err pcrb_box_size(GF_Box *s) -{ - GF_PcrInfoBox *ptr = (GF_PcrInfoBox*) s; - - ptr->size += 4; - ptr->size += ptr->subsegment_count * 6; - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *subs_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SubSampleInformationBox, GF_ISOM_BOX_TYPE_SUBS); - tmp->Samples = gf_list_new(); - return (GF_Box *)tmp; -} - -void subs_box_del(GF_Box *s) -{ - GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s; - if (ptr == NULL) return; - - while (gf_list_count(ptr->Samples)) { - GF_SubSampleInfoEntry *pSamp; - pSamp = (GF_SubSampleInfoEntry*)gf_list_get(ptr->Samples, 0); - while (gf_list_count(pSamp->SubSamples)) { - GF_SubSampleEntry *pSubSamp; - pSubSamp = (GF_SubSampleEntry*) gf_list_get(pSamp->SubSamples, 0); - gf_free(pSubSamp); - gf_list_rem(pSamp->SubSamples, 0); - } - gf_list_del(pSamp->SubSamples); - gf_free(pSamp); - gf_list_rem(ptr->Samples, 0); - } - gf_list_del(ptr->Samples); - gf_free(ptr); -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err subs_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i, j, entry_count; - u16 subsample_count; - GF_SubSampleEntry *pSubSamp; - GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s; - - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - entry_count = gf_list_count(ptr->Samples); - gf_bs_write_u32(bs, entry_count); - - for (i=0; iSamples, i); - subsample_count = gf_list_count(pSamp->SubSamples); - gf_bs_write_u32(bs, pSamp->sample_delta); - gf_bs_write_u16(bs, subsample_count); - - for (j=0; jSubSamples, j); - if (ptr->version == 1) { - gf_bs_write_u32(bs, pSubSamp->subsample_size); - } else { - gf_bs_write_u16(bs, pSubSamp->subsample_size); - } - gf_bs_write_u8(bs, pSubSamp->subsample_priority); - gf_bs_write_u8(bs, pSubSamp->discardable); - gf_bs_write_u32(bs, pSubSamp->reserved); - } - } - return e; -} - -GF_Err subs_box_size(GF_Box *s) -{ - GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *) s; - u32 entry_count, i; - u16 subsample_count; - - // add 4 byte for entry_count - ptr->size += 4; - entry_count = gf_list_count(ptr->Samples); - for (i=0; iSamples, i); - subsample_count = gf_list_count(pSamp->SubSamples); - // 4 byte for sample_delta, 2 byte for subsample_count - // and 6 + (4 or 2) bytes for each subsample - ptr->size += 4 + 2 + subsample_count * (6 + (ptr->version==1 ? 4 : 2)); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Err subs_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SubSampleInformationBox *ptr = (GF_SubSampleInformationBox *)s; - u32 entry_count, i, j; - u16 subsample_count; - - ISOM_DECREASE_SIZE(ptr, 4); - entry_count = gf_bs_read_u32(bs); - - for (i=0; iSubSamples = gf_list_new(); - pSamp->sample_delta = gf_bs_read_u32(bs); - subsample_count = gf_bs_read_u16(bs); - subs_size=6; - - for (j=0; jversion==1) { - pSubSamp->subsample_size = gf_bs_read_u32(bs); - subs_size+=4; - } else { - pSubSamp->subsample_size = gf_bs_read_u16(bs); - subs_size+=2; - } - pSubSamp->subsample_priority = gf_bs_read_u8(bs); - pSubSamp->discardable = gf_bs_read_u8(bs); - pSubSamp->reserved = gf_bs_read_u32(bs); - subs_size+=6; - - gf_list_add(pSamp->SubSamples, pSubSamp); - } - gf_list_add(ptr->Samples, pSamp); - ISOM_DECREASE_SIZE(ptr, subs_size); - } - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -GF_Box *tfdt_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TFBaseMediaDecodeTimeBox, GF_ISOM_BOX_TYPE_TFDT); - return (GF_Box *)tmp; -} - -void tfdt_box_del(GF_Box *s) -{ - gf_free(s); -} - -/*this is using chpl format according to some NeroRecode samples*/ -GF_Err tfdt_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s; - - if (ptr->version==1) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->baseMediaDecodeTime = gf_bs_read_u64(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->baseMediaDecodeTime = (u32) gf_bs_read_u32(bs); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tfdt_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *) s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - if (ptr->version==1) { - gf_bs_write_u64(bs, ptr->baseMediaDecodeTime); - } else { - gf_bs_write_u32(bs, (u32) ptr->baseMediaDecodeTime); - } - return GF_OK; -} - -GF_Err tfdt_box_size(GF_Box *s) -{ - GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s; - - if (ptr->baseMediaDecodeTime<=0xFFFFFFFF) { - ptr->version = 0; - ptr->size += 4; - } else { - ptr->version = 1; - ptr->size += 8; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ - - -GF_Box *rvcc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_RVCConfigurationBox, GF_ISOM_BOX_TYPE_RVCC); - return (GF_Box *)tmp; -} - -void rvcc_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err rvcc_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s; - ISOM_DECREASE_SIZE(ptr, 2); - ptr->predefined_rvc_config = gf_bs_read_u16(bs); - if (!ptr->predefined_rvc_config) { - ISOM_DECREASE_SIZE(ptr, 2); - ptr->rvc_meta_idx = gf_bs_read_u16(bs); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err rvcc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*) s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, ptr->predefined_rvc_config); - if (!ptr->predefined_rvc_config) { - gf_bs_write_u16(bs, ptr->rvc_meta_idx); - } - return GF_OK; -} - -GF_Err rvcc_box_size(GF_Box *s) -{ - GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox *)s; - ptr->size += 2; - if (! ptr->predefined_rvc_config) ptr->size += 2; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *sbgp_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleGroupBox, GF_ISOM_BOX_TYPE_SBGP); - return (GF_Box *)tmp; -} -void sbgp_box_del(GF_Box *a) -{ - GF_SampleGroupBox *p = (GF_SampleGroupBox *)a; - if (p->sample_entries) gf_free(p->sample_entries); - gf_free(p); -} - -GF_Err sbgp_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_SampleGroupBox *ptr = (GF_SampleGroupBox *)s; - - ISOM_DECREASE_SIZE(ptr, 8); - ptr->grouping_type = gf_bs_read_u32(bs); - - if (ptr->version==1) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->grouping_type_parameter = gf_bs_read_u32(bs); - } - ptr->entry_count = gf_bs_read_u32(bs); - - if (ptr->size < sizeof(GF_SampleGroupEntry)*ptr->entry_count) - return GF_ISOM_INVALID_FILE; - - ptr->sample_entries = gf_malloc(sizeof(GF_SampleGroupEntry)*ptr->entry_count); - if (!ptr->sample_entries) return GF_OUT_OF_MEM; - - for (i=0; ientry_count; i++) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->sample_entries[i].sample_count = gf_bs_read_u32(bs); - ptr->sample_entries[i].group_description_index = gf_bs_read_u32(bs); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err sbgp_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_Err e; - GF_SampleGroupBox *p = (GF_SampleGroupBox*)s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, p->grouping_type); - if (p->version==1) - gf_bs_write_u32(bs, p->grouping_type_parameter); - - gf_bs_write_u32(bs, p->entry_count); - for (i = 0; ientry_count; i++ ) { - gf_bs_write_u32(bs, p->sample_entries[i].sample_count); - gf_bs_write_u32(bs, p->sample_entries[i].group_description_index); - } - return GF_OK; -} - -GF_Err sbgp_box_size(GF_Box *s) -{ - GF_SampleGroupBox *p = (GF_SampleGroupBox*)s; - - p->size += 8; - if (p->grouping_type_parameter) p->version=1; - - if (p->version==1) p->size += 4; - p->size += 8*p->entry_count; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -static void *sgpd_parse_entry(u32 grouping_type, GF_BitStream *bs, u32 entry_size, u32 *total_bytes) -{ - Bool null_size_ok = GF_FALSE; - GF_DefaultSampleGroupDescriptionEntry *def_ptr; - - switch (grouping_type) { - case GF_ISOM_SAMPLE_GROUP_ROLL: - case GF_ISOM_SAMPLE_GROUP_PROL: - { - GF_RollRecoveryEntry *ptr; - GF_SAFEALLOC(ptr, GF_RollRecoveryEntry); - if (!ptr) return NULL; - ptr->roll_distance = gf_bs_read_int(bs, 16); - *total_bytes = 2; - return ptr; - } - case GF_ISOM_SAMPLE_GROUP_RAP: - { - GF_VisualRandomAccessEntry *ptr; - GF_SAFEALLOC(ptr, GF_VisualRandomAccessEntry); - if (!ptr) return NULL; - ptr->num_leading_samples_known = gf_bs_read_int(bs, 1); - ptr->num_leading_samples = gf_bs_read_int(bs, 7); - *total_bytes = 1; - return ptr; - } - case GF_ISOM_SAMPLE_GROUP_SAP: - { - GF_SAPEntry *ptr; - GF_SAFEALLOC(ptr, GF_SAPEntry); - if (!ptr) return NULL; - ptr->dependent_flag = gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 3); - ptr->SAP_type = gf_bs_read_int(bs, 4); - *total_bytes = 1; - return ptr; - } - case GF_ISOM_SAMPLE_GROUP_SYNC: - { - GF_SYNCEntry *ptr; - GF_SAFEALLOC(ptr, GF_SYNCEntry); - if (!ptr) return NULL; - gf_bs_read_int(bs, 2); - ptr->NALU_type = gf_bs_read_int(bs, 6); - *total_bytes = 1; - return ptr; - } - case GF_ISOM_SAMPLE_GROUP_TELE: - { - GF_TemporalLevelEntry *ptr; - GF_SAFEALLOC(ptr, GF_TemporalLevelEntry); - if (!ptr) return NULL; - ptr->level_independently_decodable = gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 7); - *total_bytes = 1; - return ptr; - } - case GF_ISOM_SAMPLE_GROUP_SEIG: - { - GF_CENCSampleEncryptionGroupEntry *ptr; - GF_SAFEALLOC(ptr, GF_CENCSampleEncryptionGroupEntry); - if (!ptr) return NULL; - gf_bs_read_u8(bs); //reserved - ptr->crypt_byte_block = gf_bs_read_int(bs, 4); - ptr->skip_byte_block = gf_bs_read_int(bs, 4); - ptr->IsProtected = gf_bs_read_u8(bs); - ptr->Per_Sample_IV_size = gf_bs_read_u8(bs); - gf_bs_read_data(bs, (char *)ptr->KID, 16); - *total_bytes = 20; - if ((ptr->IsProtected == 1) && !ptr->Per_Sample_IV_size) { - ptr->constant_IV_size = gf_bs_read_u8(bs); - if ((ptr->constant_IV_size != 8) && (ptr->constant_IV_size != 16)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group have invalid constant_IV size\n")); - gf_free(ptr); - return NULL; - } - gf_bs_read_data(bs, (char *)ptr->constant_IV, ptr->constant_IV_size); - *total_bytes += 1 + ptr->constant_IV_size; - } - if (!entry_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] seig sample group does not indicate entry size, deprecated in spec\n")); - } - return ptr; - } - case GF_ISOM_SAMPLE_GROUP_OINF: - { - GF_OperatingPointsInformation *ptr = gf_isom_oinf_new_entry(); - u32 s = (u32) gf_bs_get_position(bs); - gf_isom_oinf_read_entry(ptr, bs); - *total_bytes = (u32) gf_bs_get_position(bs) - s; - if (!entry_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] oinf sample group does not indicate entry size, deprecated in spec\n")); - } - return ptr; - } - case GF_ISOM_SAMPLE_GROUP_LINF: - { - GF_LHVCLayerInformation *ptr = gf_isom_linf_new_entry(); - u32 s = (u32) gf_bs_get_position(bs); - gf_isom_linf_read_entry(ptr, bs); - *total_bytes = (u32) gf_bs_get_position(bs) - s; - if (!entry_size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] linf sample group does not indicate entry size, deprecated in spec\n")); - } - return ptr; - } - - case GF_ISOM_SAMPLE_GROUP_TRIF: - if (! entry_size) { - u32 flags = gf_bs_peek_bits(bs, 24, 0); - if (flags & 0x10000) entry_size=3; - else { - if (flags & 0x80000) entry_size=7; - else entry_size=11; - //have dependency list - if (flags & 0x200000) { - u32 nb_entries = gf_bs_peek_bits(bs, 16, entry_size); - entry_size += 2 + 2*nb_entries; - } - } - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] trif sample group does not indicate entry size, deprecated in spec\n")); - } - break; - case GF_ISOM_SAMPLE_GROUP_NALM: - if (! entry_size) { - u64 start = gf_bs_get_position(bs); - Bool rle, large_size; - u32 entry_count; - gf_bs_read_int(bs, 6); - large_size = gf_bs_read_int(bs, 1); - rle = gf_bs_read_int(bs, 1); - entry_count = gf_bs_read_int(bs, large_size ? 16 : 8); - gf_bs_seek(bs, start); - entry_size = 1 + (large_size ? 2 : 1); - entry_size += entry_count * 2; - if (rle) entry_size += entry_count * (large_size ? 2 : 1); - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] nalm sample group does not indicate entry size, deprecated in spec\n")); - } - break; - - case GF_ISOM_SAMPLE_GROUP_TSAS: - case GF_ISOM_SAMPLE_GROUP_STSA: - null_size_ok = GF_TRUE; - break; - //TODO, add support for these ones ? - case GF_ISOM_SAMPLE_GROUP_TSCL: - entry_size = 20; - break; - case GF_ISOM_SAMPLE_GROUP_LBLI: - entry_size = 2; - break; - default: - break; - } - - if (!entry_size && !null_size_ok) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] %s sample group does not indicate entry size and is not implemented, cannot parse!\n", gf_4cc_to_str( grouping_type) )); - return NULL; - } - GF_SAFEALLOC(def_ptr, GF_DefaultSampleGroupDescriptionEntry); - if (!def_ptr) return NULL; - if (entry_size) { - def_ptr->length = entry_size; - def_ptr->data = (u8 *) gf_malloc(sizeof(u8)*def_ptr->length); - if (!def_ptr->data) { - gf_free(def_ptr); - return NULL; - } - gf_bs_read_data(bs, (char *) def_ptr->data, def_ptr->length); - *total_bytes = entry_size; - } - return def_ptr; -} - -static void sgpd_del_entry(u32 grouping_type, void *entry) -{ - switch (grouping_type) { - case GF_ISOM_SAMPLE_GROUP_SYNC: - case GF_ISOM_SAMPLE_GROUP_ROLL: - case GF_ISOM_SAMPLE_GROUP_PROL: - case GF_ISOM_SAMPLE_GROUP_RAP: - case GF_ISOM_SAMPLE_GROUP_SEIG: - case GF_ISOM_SAMPLE_GROUP_TELE: - case GF_ISOM_SAMPLE_GROUP_SAP: - gf_free(entry); - return; - case GF_ISOM_SAMPLE_GROUP_OINF: - gf_isom_oinf_del_entry(entry); - return; - case GF_ISOM_SAMPLE_GROUP_LINF: - gf_isom_linf_del_entry(entry); - return; - default: - { - GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry; - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); - } - } -} - -void sgpd_write_entry(u32 grouping_type, void *entry, GF_BitStream *bs) -{ - switch (grouping_type) { - case GF_ISOM_SAMPLE_GROUP_ROLL: - case GF_ISOM_SAMPLE_GROUP_PROL: - gf_bs_write_int(bs, ((GF_RollRecoveryEntry*)entry)->roll_distance, 16); - return; - case GF_ISOM_SAMPLE_GROUP_RAP: - gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples_known, 1); - gf_bs_write_int(bs, ((GF_VisualRandomAccessEntry*)entry)->num_leading_samples, 7); - return; - case GF_ISOM_SAMPLE_GROUP_SAP: - gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->dependent_flag, 1); - gf_bs_write_int(bs, 0, 3); - gf_bs_write_int(bs, ((GF_SAPEntry*)entry)->SAP_type, 4); - return; - case GF_ISOM_SAMPLE_GROUP_SYNC: - gf_bs_write_int(bs, 0, 2); - gf_bs_write_int(bs, ((GF_SYNCEntry*)entry)->NALU_type, 6); - return; - case GF_ISOM_SAMPLE_GROUP_TELE: - gf_bs_write_int(bs, ((GF_TemporalLevelEntry*)entry)->level_independently_decodable, 1); - gf_bs_write_int(bs, 0, 7); - return; - case GF_ISOM_SAMPLE_GROUP_SEIG: - gf_bs_write_u8(bs, 0x0); - gf_bs_write_int(bs, ((GF_CENCSampleEncryptionGroupEntry*)entry)->crypt_byte_block, 4); - gf_bs_write_int(bs, ((GF_CENCSampleEncryptionGroupEntry*)entry)->skip_byte_block, 4); - gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected); - gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size); - gf_bs_write_data(bs, (char *)((GF_CENCSampleEncryptionGroupEntry *)entry)->KID, 16); - if ((((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected == 1) && !((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size) { - gf_bs_write_u8(bs, ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size); - gf_bs_write_data(bs, (char *)((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV, ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size); - } - return; - case GF_ISOM_SAMPLE_GROUP_OINF: - gf_isom_oinf_write_entry(entry, bs); - return; - case GF_ISOM_SAMPLE_GROUP_LINF: - gf_isom_linf_write_entry(entry, bs); - return; - default: - { - GF_DefaultSampleGroupDescriptionEntry *ptr = (GF_DefaultSampleGroupDescriptionEntry *)entry; - if (ptr->length) - gf_bs_write_data(bs, (char *) ptr->data, ptr->length); - } - } -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -static u32 sgpd_size_entry(u32 grouping_type, void *entry) -{ - switch (grouping_type) { - case GF_ISOM_SAMPLE_GROUP_ROLL: - case GF_ISOM_SAMPLE_GROUP_PROL: - return 2; - case GF_ISOM_SAMPLE_GROUP_TELE: - case GF_ISOM_SAMPLE_GROUP_RAP: - case GF_ISOM_SAMPLE_GROUP_SAP: - case GF_ISOM_SAMPLE_GROUP_SYNC: - return 1; - case GF_ISOM_SAMPLE_GROUP_TSCL: - return 20; - case GF_ISOM_SAMPLE_GROUP_LBLI: - return 2; - case GF_ISOM_SAMPLE_GROUP_TSAS: - case GF_ISOM_SAMPLE_GROUP_STSA: - return 0; - case GF_ISOM_SAMPLE_GROUP_SEIG: - return ((((GF_CENCSampleEncryptionGroupEntry *)entry)->IsProtected == 1) && !((GF_CENCSampleEncryptionGroupEntry *)entry)->Per_Sample_IV_size) ? 21 + ((GF_CENCSampleEncryptionGroupEntry *)entry)->constant_IV_size : 20; - case GF_ISOM_SAMPLE_GROUP_OINF: - return gf_isom_oinf_size_entry(entry); - case GF_ISOM_SAMPLE_GROUP_LINF: - return gf_isom_linf_size_entry(entry); - default: - return ((GF_DefaultSampleGroupDescriptionEntry *)entry)->length; - } -} -#endif - -GF_Box *sgpd_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleGroupDescriptionBox, GF_ISOM_BOX_TYPE_SGPD); - /*version 0 is deprecated, use v1 by default*/ - tmp->version = 1; - tmp->group_descriptions = gf_list_new(); - return (GF_Box *)tmp; -} - -void sgpd_box_del(GF_Box *a) -{ - GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)a; - while (gf_list_count(p->group_descriptions)) { - void *ptr = gf_list_last(p->group_descriptions); - sgpd_del_entry(p->grouping_type, ptr); - gf_list_rem_last(p->group_descriptions); - } - gf_list_del(p->group_descriptions); - gf_free(p); -} - -GF_Err sgpd_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 entry_count; - GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s; - - ISOM_DECREASE_SIZE(p, 8); - p->grouping_type = gf_bs_read_u32(bs); - - if (p->version>=1) { - ISOM_DECREASE_SIZE(p, 4); - p->default_length = gf_bs_read_u32(bs); - } - if (p->version>=2) { - ISOM_DECREASE_SIZE(p, 4); - p->default_description_index = gf_bs_read_u32(bs); - } - entry_count = gf_bs_read_u32(bs); - - if (entry_count>p->size) - return GF_ISOM_INVALID_FILE; - - while (entry_count) { - void *ptr; - u32 parsed_bytes=0; - u32 size = p->default_length; - if ((p->version>=1) && !size) { - size = gf_bs_read_u32(bs); - ISOM_DECREASE_SIZE(p, 4); - } - ptr = sgpd_parse_entry(p->grouping_type, bs, size, &parsed_bytes); - //don't return an error, just stop parsing so that we skip over the sgpd box - if (!ptr) return GF_OK; - - ISOM_DECREASE_SIZE(p, parsed_bytes); - - gf_list_add(p->group_descriptions, ptr); - entry_count--; - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err sgpd_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s; - GF_Err e; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, p->grouping_type); - if (p->version>=1) gf_bs_write_u32(bs, p->default_length); - if (p->version>=2) gf_bs_write_u32(bs, p->default_description_index); - gf_bs_write_u32(bs, gf_list_count(p->group_descriptions) ); - - for (i=0; igroup_descriptions); i++) { - void *ptr = gf_list_get(p->group_descriptions, i); - if ((p->version >= 1) && !p->default_length) { - u32 size = sgpd_size_entry(p->grouping_type, ptr); - gf_bs_write_u32(bs, size); - } - sgpd_write_entry(p->grouping_type, ptr, bs); - } - return GF_OK; -} - -GF_Err sgpd_box_size(GF_Box *s) -{ - u32 i; - GF_SampleGroupDescriptionBox *p = (GF_SampleGroupDescriptionBox *)s; - - p->size += 8; - - //we force all sample groups to version 1, v0 being deprecated - p->version=1; - p->size += 4; - - if (p->version>=2) p->size += 4; - p->default_length = 0; - - for (i=0; igroup_descriptions); i++) { - void *ptr = gf_list_get(p->group_descriptions, i); - u32 size = sgpd_size_entry(p->grouping_type, ptr); - p->size += size; - if (!p->default_length) { - p->default_length = size; - } else if (p->default_length != size) { - p->default_length = 0; - } - } - if (p->version>=1) { - if (!p->default_length) p->size += gf_list_count(p->group_descriptions)*4; - } - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void saiz_box_del(GF_Box *s) -{ - GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s; - if (ptr == NULL) return; - if (ptr->sample_info_size) gf_free(ptr->sample_info_size); - gf_free(ptr); -} - - -GF_Err saiz_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*)s; - - if (ptr->flags & 1) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->aux_info_type = gf_bs_read_u32(bs); - ptr->aux_info_type_parameter = gf_bs_read_u32(bs); - } - ISOM_DECREASE_SIZE(ptr, 5); - ptr->default_sample_info_size = gf_bs_read_u8(bs); - ptr->sample_count = gf_bs_read_u32(bs); - - if (ptr->default_sample_info_size == 0) { - if (ptr->size < sizeof(u8)*ptr->sample_count) - return GF_ISOM_INVALID_FILE; - - ptr->sample_info_size = gf_malloc(sizeof(u8)*ptr->sample_count); - ptr->sample_alloc = ptr->sample_count; - if (!ptr->sample_info_size) - return GF_OUT_OF_MEM; - - ISOM_DECREASE_SIZE(ptr, ptr->sample_count); - gf_bs_read_data(bs, (char *) ptr->sample_info_size, ptr->sample_count); - } - return GF_OK; -} - -GF_Box *saiz_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoSizeBox, GF_ISOM_BOX_TYPE_SAIZ); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err saiz_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SampleAuxiliaryInfoSizeBox*ptr = (GF_SampleAuxiliaryInfoSizeBox*) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - if (ptr->flags & 1) { - gf_bs_write_u32(bs, ptr->aux_info_type); - gf_bs_write_u32(bs, ptr->aux_info_type_parameter); - } - gf_bs_write_u8(bs, ptr->default_sample_info_size); - gf_bs_write_u32(bs, ptr->sample_count); - if (!ptr->default_sample_info_size) { - if (!ptr->sample_info_size) - gf_bs_write_u8(bs, 0); - else - gf_bs_write_data(bs, (char *) ptr->sample_info_size, ptr->sample_count); - } - return GF_OK; -} - -GF_Err saiz_box_size(GF_Box *s) -{ - GF_SampleAuxiliaryInfoSizeBox *ptr = (GF_SampleAuxiliaryInfoSizeBox*)s; - - if (ptr->aux_info_type || ptr->aux_info_type_parameter) { - ptr->flags |= 1; - } - if (ptr->flags & 1) ptr->size += 8; - ptr->size += 5; - if (ptr->default_sample_info_size==0) ptr->size += ptr->sample_count; - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -void saio_box_del(GF_Box *s) -{ - GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s; - if (ptr == NULL) return; - if (ptr->offsets) gf_free(ptr->offsets); - if (ptr->cached_data) gf_free(ptr->cached_data); - gf_free(ptr); -} - - -GF_Err saio_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *)s; - - if (ptr->flags & 1) { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->aux_info_type = gf_bs_read_u32(bs); - ptr->aux_info_type_parameter = gf_bs_read_u32(bs); - } - ISOM_DECREASE_SIZE(ptr, 4); - ptr->entry_count = gf_bs_read_u32(bs); - - if (ptr->entry_count) { - u32 i; - if (ptr->size < (ptr->version == 0 ? 4 : 8) * ptr->entry_count) - return GF_ISOM_INVALID_FILE; - ptr->offsets = gf_malloc(sizeof(u64)*ptr->entry_count); - if (!ptr->offsets) - return GF_OUT_OF_MEM; - ptr->entry_alloc = ptr->entry_count; - if (ptr->version==0) { - ISOM_DECREASE_SIZE(ptr, 4*ptr->entry_count); - for (i=0; ientry_count; i++) - ptr->offsets[i] = gf_bs_read_u32(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 8*ptr->entry_count); - for (i=0; ientry_count; i++) - ptr->offsets[i] = gf_bs_read_u64(bs); - } - } - return GF_OK; -} - -GF_Box *saio_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleAuxiliaryInfoOffsetBox, GF_ISOM_BOX_TYPE_SAIO); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err saio_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - if (ptr->flags & 1) { - gf_bs_write_u32(bs, ptr->aux_info_type); - gf_bs_write_u32(bs, ptr->aux_info_type_parameter); - } - - - gf_bs_write_u32(bs, ptr->entry_count); - if (ptr->entry_count) { - u32 i; - //store position in bitstream before writing data - offsets can be NULL if a single offset is rewritten later on (cf senc_box_write) - ptr->offset_first_offset_field = gf_bs_get_position(bs); - if (ptr->version==0) { - if (!ptr->offsets) { - gf_bs_write_u32(bs, 0); - } else { - for (i=0; ientry_count; i++) - gf_bs_write_u32(bs, (u32) ptr->offsets[i]); - } - } else { - if (!ptr->offsets) { - gf_bs_write_u64(bs, 0); - } else { - for (i=0; ientry_count; i++) - gf_bs_write_u64(bs, ptr->offsets[i]); - } - } - } - return GF_OK; -} - -GF_Err saio_box_size(GF_Box *s) -{ - GF_SampleAuxiliaryInfoOffsetBox *ptr = (GF_SampleAuxiliaryInfoOffsetBox*)s; - - if (ptr->aux_info_type || ptr->aux_info_type_parameter) { - ptr->flags |= 1; - } - - if (ptr->flags & 1) ptr->size += 8; - ptr->size += 4; - //a little optim here: in cenc, the saio always points to a single data block, only one entry is needed - switch (ptr->aux_info_type) { - case GF_ISOM_CENC_SCHEME: - case GF_ISOM_CBC_SCHEME: - case GF_ISOM_CENS_SCHEME: - case GF_ISOM_CBCS_SCHEME: - if (ptr->offsets) gf_free(ptr->offsets); - ptr->offsets = NULL; - ptr->entry_alloc = 0; - ptr->entry_count = 1; - break; - } - - ptr->size += ((ptr->version==1) ? 8 : 4) * ptr->entry_count; - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - - -void prft_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err prft_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s; - - ISOM_DECREASE_SIZE(ptr, 12); - ptr->refTrackID = gf_bs_read_u32(bs); - ptr->ntp = gf_bs_read_u64(bs); - if (ptr->version==0) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->timestamp = gf_bs_read_u32(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 8); - ptr->timestamp = gf_bs_read_u64(bs); - } - return GF_OK; -} - -GF_Box *prft_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ProducerReferenceTimeBox, GF_ISOM_BOX_TYPE_PRFT); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err prft_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->refTrackID); - gf_bs_write_u64(bs, ptr->ntp); - if (ptr->version==0) { - gf_bs_write_u32(bs, (u32) ptr->timestamp); - } else { - gf_bs_write_u64(bs, ptr->timestamp); - } - - return GF_OK; -} - -GF_Err prft_box_size(GF_Box *s) -{ - GF_ProducerReferenceTimeBox *ptr = (GF_ProducerReferenceTimeBox*)s; - - ptr->size += 4+8+ (ptr->version ? 8 : 4); - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *trgr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackGroupBox, GF_ISOM_BOX_TYPE_TRGR); - tmp->groups = gf_list_new(); - if (!tmp->groups) { - gf_free(tmp); - return NULL; - } - return (GF_Box *)tmp; -} - -void trgr_box_del(GF_Box *s) -{ - GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s; - if (ptr == NULL) return; - gf_list_del(ptr->groups); - gf_free(ptr); -} - - -GF_Err trgr_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s; - return gf_list_add(ptr->groups, a); -} - - -GF_Err trgr_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read_ex(s, bs, trgr_on_child_box, s->type); -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err trgr_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err trgr_box_size(GF_Box *s) -{ - u32 pos=0; - GF_TrackGroupBox *ptr = (GF_TrackGroupBox *) s; - gf_isom_check_position_list(s, ptr->groups, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *trgt_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackGroupTypeBox, GF_ISOM_BOX_TYPE_TRGT); - return (GF_Box *)tmp; -} - -void trgt_box_del(GF_Box *s) -{ - GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err trgt_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->track_group_id = gf_bs_read_u32(bs); - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err trgt_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TrackGroupTypeBox *ptr = (GF_TrackGroupTypeBox *) s; - if (!s) return GF_BAD_PARAM; - s->type = ptr->group_type; - e = gf_isom_full_box_write(s, bs); - s->type = GF_ISOM_BOX_TYPE_TRGT; - if (e) return e; - gf_bs_write_u32(bs, ptr->track_group_id); - return GF_OK; -} - -GF_Err trgt_box_size(GF_Box *s) -{ - GF_TrackGroupBox *ptr = (GF_TrackGroupBox *)s; - - ptr->size+= 4; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *stvi_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_StereoVideoBox, GF_ISOM_BOX_TYPE_STVI); - return (GF_Box *)tmp; -} - -void stvi_box_del(GF_Box *s) -{ - GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s; - if (ptr == NULL) return; - if (ptr->stereo_indication_type) gf_free(ptr->stereo_indication_type); - gf_free(ptr); -} - -GF_Err stvi_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s; - - ISOM_DECREASE_SIZE(ptr, 12); - gf_bs_read_int(bs, 30); - ptr->single_view_allowed = gf_bs_read_int(bs, 2); - ptr->stereo_scheme = gf_bs_read_u32(bs); - ptr->sit_len = gf_bs_read_u32(bs); - ISOM_DECREASE_SIZE(ptr, ptr->sit_len); - - ptr->stereo_indication_type = gf_malloc(sizeof(char)*ptr->sit_len); - if (!ptr->stereo_indication_type) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, ptr->stereo_indication_type, ptr->sit_len); - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err stvi_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_StereoVideoBox *ptr = (GF_StereoVideoBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_int(bs, 0, 30); - gf_bs_write_int(bs, ptr->single_view_allowed, 2); - gf_bs_write_u32(bs, ptr->stereo_scheme); - gf_bs_write_u32(bs, ptr->sit_len); - gf_bs_write_data(bs, ptr->stereo_indication_type, ptr->sit_len); - - return GF_OK; -} - -GF_Err stvi_box_size(GF_Box *s) -{ - GF_StereoVideoBox *ptr = (GF_StereoVideoBox *)s; - - ptr->size+= 12 + ptr->sit_len; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *fiin_box_new() -{ - ISOM_DECL_BOX_ALLOC(FDItemInformationBox, GF_ISOM_BOX_TYPE_FIIN); - return (GF_Box *)tmp; -} - -void fiin_box_del(GF_Box *s) -{ - FDItemInformationBox *ptr = (FDItemInformationBox *)s; - if (ptr == NULL) return; - if (ptr->partition_entries) gf_list_del(ptr->partition_entries); - gf_free(ptr); -} - - -GF_Err fiin_on_child_box(GF_Box *s, GF_Box *a) -{ - FDItemInformationBox *ptr = (FDItemInformationBox *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_PAEN: - if (!ptr->partition_entries) ptr->partition_entries = gf_list_new(); - return gf_list_add(ptr->partition_entries, a); - case GF_ISOM_BOX_TYPE_SEGR: - if (ptr->session_info) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->session_info = (FDSessionGroupBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_GITN: - if (ptr->group_id_to_name) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->group_id_to_name = (GroupIdToNameBox *)a; - return GF_OK; - } - return GF_OK; -} - -GF_Err fiin_box_read(GF_Box *s, GF_BitStream *bs) -{ - FDItemInformationBox *ptr = (FDItemInformationBox *)s; - - ISOM_DECREASE_SIZE(ptr, 2); - gf_bs_read_u16(bs); - return gf_isom_box_array_read(s, bs, fiin_on_child_box); -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err fiin_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - FDItemInformationBox *ptr = (FDItemInformationBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, gf_list_count(ptr->partition_entries) ); - return GF_OK; -} - -GF_Err fiin_box_size(GF_Box *s) -{ - u32 pos=0; - FDItemInformationBox *ptr = (FDItemInformationBox *) s; - s->size+= 2; - gf_isom_check_position_list(s, ptr->partition_entries, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *paen_box_new() -{ - ISOM_DECL_BOX_ALLOC(FDPartitionEntryBox, GF_ISOM_BOX_TYPE_PAEN); - return (GF_Box *)tmp; -} - -void paen_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err paen_on_child_box(GF_Box *s, GF_Box *a) -{ - FDPartitionEntryBox *ptr = (FDPartitionEntryBox *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_FPAR: - if (ptr->blocks_and_symbols) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->blocks_and_symbols = (FilePartitionBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_FECR: - if (ptr->FEC_symbol_locations) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->FEC_symbol_locations = (FECReservoirBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_FIRE: - if (ptr->File_symbol_locations) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->File_symbol_locations = (FileReservoirBox *)a; - return GF_OK; - } - return GF_OK; -} - -GF_Err paen_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, fiin_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err paen_box_write(GF_Box *s, GF_BitStream *bs) -{ - if (!s) return GF_BAD_PARAM; - return gf_isom_box_write_header(s, bs); -} - -GF_Err paen_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -GF_Box *fpar_box_new() -{ - ISOM_DECL_BOX_ALLOC(FilePartitionBox, GF_ISOM_BOX_TYPE_FPAR); - return (GF_Box *)tmp; -} - -void fpar_box_del(GF_Box *s) -{ - FilePartitionBox *ptr = (FilePartitionBox *)s; - if (ptr == NULL) return; - if (ptr->scheme_specific_info) gf_free(ptr->scheme_specific_info); - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - -GF_Err gf_isom_read_null_terminated_string(GF_Box *s, GF_BitStream *bs, u64 size, char **out_str) -{ - u32 len=10; - u32 i=0; - - *out_str = gf_malloc(sizeof(char)*len); - if (! *out_str) return GF_OUT_OF_MEM; - - while (1) { - ISOM_DECREASE_SIZE(s, 1 ); - (*out_str)[i] = gf_bs_read_u8(bs); - if (!(*out_str)[i]) break; - i++; - if (i==len) { - len += 10; - *out_str = gf_realloc(*out_str, sizeof(char)*len); - } - if (gf_bs_available(bs) == 0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] missing null character in null terminated string\n")); - (*out_str)[i] = 0; - return GF_OK; - } - if (i >= size) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] string bigger than container, probably missing null character\n")); - (*out_str)[i] = 0; - return GF_OK; - } - } - return GF_OK; -} - -GF_Err fpar_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_Err e; - FilePartitionBox *ptr = (FilePartitionBox *)s; - - ISOM_DECREASE_SIZE(ptr, ((ptr->version ? 4 : 2) + 12) ); - ptr->itemID = gf_bs_read_int(bs, ptr->version ? 32 : 16); - ptr->packet_payload_size = gf_bs_read_u16(bs); - gf_bs_read_u8(bs); - ptr->FEC_encoding_ID = gf_bs_read_u8(bs); - ptr->FEC_instance_ID = gf_bs_read_u16(bs); - ptr->max_source_block_length = gf_bs_read_u16(bs); - ptr->encoding_symbol_length = gf_bs_read_u16(bs); - ptr->max_number_of_encoding_symbols = gf_bs_read_u16(bs); - - e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_specific_info); - if (e) return e; - - ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) ); - ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16); - if (ptr->nb_entries > UINT_MAX / 6) - return GF_ISOM_INVALID_FILE; - - ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * 6 ); - GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FilePartitionEntry); - if (!ptr->entries) return GF_OUT_OF_MEM; - - for (i=0;i < ptr->nb_entries; i++) { - ptr->entries[i].block_count = gf_bs_read_u16(bs); - ptr->entries[i].block_size = gf_bs_read_u32(bs); - } - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err fpar_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - FilePartitionBox *ptr = (FilePartitionBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_int(bs, ptr->itemID, ptr->version ? 32 : 16); - gf_bs_write_u16(bs, ptr->packet_payload_size); - gf_bs_write_u8(bs, 0); - gf_bs_write_u8(bs, ptr->FEC_encoding_ID); - gf_bs_write_u16(bs, ptr->FEC_instance_ID); - gf_bs_write_u16(bs, ptr->max_source_block_length); - gf_bs_write_u16(bs, ptr->encoding_symbol_length); - gf_bs_write_u16(bs, ptr->max_number_of_encoding_symbols); - if (ptr->scheme_specific_info) { - gf_bs_write_data(bs, ptr->scheme_specific_info, (u32)strlen(ptr->scheme_specific_info) ); - } - //null terminated string - gf_bs_write_u8(bs, 0); - - gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16); - - for (i=0;i < ptr->nb_entries; i++) { - gf_bs_write_u16(bs, ptr->entries[i].block_count); - gf_bs_write_u32(bs, ptr->entries[i].block_size); - } - return GF_OK; -} - -GF_Err fpar_box_size(GF_Box *s) -{ - FilePartitionBox *ptr = (FilePartitionBox *)s; - - ptr->size += 13 + (ptr->version ? 8 : 4); - if (ptr->scheme_specific_info) - ptr->size += strlen(ptr->scheme_specific_info); - - ptr->size+= ptr->nb_entries * 6; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *fecr_box_new() -{ - ISOM_DECL_BOX_ALLOC(FECReservoirBox, GF_ISOM_BOX_TYPE_FECR); - return (GF_Box *)tmp; -} - -void fecr_box_del(GF_Box *s) -{ - FECReservoirBox *ptr = (FECReservoirBox *)s; - if (ptr == NULL) return; - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - -GF_Err fecr_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - FECReservoirBox *ptr = (FECReservoirBox *)s; - - ISOM_DECREASE_SIZE(ptr, (ptr->version ? 4 : 2) ); - ptr->nb_entries = gf_bs_read_int(bs, ptr->version ? 32 : 16); - - ISOM_DECREASE_SIZE(ptr, ptr->nb_entries * (ptr->version ? 8 : 6) ); - GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, FECReservoirEntry); - if (!ptr->entries) return GF_OUT_OF_MEM; - - for (i=0; inb_entries; i++) { - ptr->entries[i].item_id = gf_bs_read_int(bs, ptr->version ? 32 : 16); - ptr->entries[i].symbol_count = gf_bs_read_u32(bs); - } - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err fecr_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - FECReservoirBox *ptr = (FECReservoirBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_int(bs, ptr->nb_entries, ptr->version ? 32 : 16); - for (i=0; inb_entries; i++) { - gf_bs_write_int(bs, ptr->entries[i].item_id, ptr->version ? 32 : 16); - gf_bs_write_u32(bs, ptr->entries[i].symbol_count); - } - return GF_OK; -} - -GF_Err fecr_box_size(GF_Box *s) -{ - FECReservoirBox *ptr = (FECReservoirBox *)s; - ptr->size += (ptr->version ? 4 : 2) + ptr->nb_entries * (ptr->version ? 8 : 6); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *segr_box_new() -{ - ISOM_DECL_BOX_ALLOC(FDSessionGroupBox, GF_ISOM_BOX_TYPE_SEGR); - return (GF_Box *)tmp; -} - -void segr_box_del(GF_Box *s) -{ - u32 i; - FDSessionGroupBox *ptr = (FDSessionGroupBox *)s; - if (ptr == NULL) return; - for (i=0; inum_session_groups; i++) { - if (ptr->session_groups[i].group_ids) gf_free(ptr->session_groups[i].group_ids); - if (ptr->session_groups[i].channels) gf_free(ptr->session_groups[i].channels); - } - if (ptr->session_groups) gf_free(ptr->session_groups); - gf_free(ptr); -} - -GF_Err segr_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i, k; - FDSessionGroupBox *ptr = (FDSessionGroupBox *)s; - - ISOM_DECREASE_SIZE(ptr, 2); - ptr->num_session_groups = gf_bs_read_u16(bs); - if (ptr->size < ptr->num_session_groups) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in segr\n", ptr->num_session_groups)); - ptr->num_session_groups = 0; - return GF_ISOM_INVALID_FILE; - } - - GF_SAFE_ALLOC_N(ptr->session_groups, ptr->num_session_groups, SessionGroupEntry); - if (!ptr->session_groups) return GF_OUT_OF_MEM; - - for (i=0; inum_session_groups; i++) { - ptr->session_groups[i].nb_groups = gf_bs_read_u8(bs); - ISOM_DECREASE_SIZE(ptr, 1); - - ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_groups*4); - - GF_SAFE_ALLOC_N(ptr->session_groups[i].group_ids, ptr->session_groups[i].nb_groups, u32); - if (!ptr->session_groups[i].group_ids) return GF_OUT_OF_MEM; - - for (k=0; ksession_groups[i].nb_groups; k++) { - ptr->session_groups[i].group_ids[k] = gf_bs_read_u32(bs); - } - - ptr->session_groups[i].nb_channels = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(ptr, ptr->session_groups[i].nb_channels*4); - - GF_SAFE_ALLOC_N(ptr->session_groups[i].channels, ptr->session_groups[i].nb_channels, u32); - if (!ptr->session_groups[i].channels) return GF_OUT_OF_MEM; - - for (k=0; ksession_groups[i].nb_channels; k++) { - ptr->session_groups[i].channels[k] = gf_bs_read_u32(bs); - } - } - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err segr_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 i, k; - GF_Err e; - FDSessionGroupBox *ptr = (FDSessionGroupBox *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, ptr->num_session_groups); - for (i=0; inum_session_groups; i++) { - gf_bs_write_u8(bs, ptr->session_groups[i].nb_groups); - for (k=0; ksession_groups[i].nb_groups; k++) { - gf_bs_write_u32(bs, ptr->session_groups[i].group_ids[k]); - } - - gf_bs_write_u16(bs, ptr->session_groups[i].nb_channels); - for (k=0; ksession_groups[i].nb_channels; k++) { - gf_bs_write_u32(bs, ptr->session_groups[i].channels[k]); - } - } - return GF_OK; -} - -GF_Err segr_box_size(GF_Box *s) -{ - u32 i; - FDSessionGroupBox *ptr = (FDSessionGroupBox *)s; - - ptr->size += 2; - - for (i=0; inum_session_groups; i++) { - ptr->size += 1 + 4*ptr->session_groups[i].nb_groups; - ptr->size += 2 + 4*ptr->session_groups[i].nb_channels; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *gitn_box_new() -{ - ISOM_DECL_BOX_ALLOC(GroupIdToNameBox, GF_ISOM_BOX_TYPE_GITN); - return (GF_Box *)tmp; -} - -void gitn_box_del(GF_Box *s) -{ - u32 i; - GroupIdToNameBox *ptr = (GroupIdToNameBox *)s; - if (ptr == NULL) return; - for (i=0; inb_entries; i++) { - if (ptr->entries[i].name) gf_free(ptr->entries[i].name); - } - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - -GF_Err gitn_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_Err e; - GroupIdToNameBox *ptr = (GroupIdToNameBox *)s; - - ISOM_DECREASE_SIZE(ptr, 2); - ptr->nb_entries = gf_bs_read_u16(bs); - if (ptr->size < ptr->nb_entries*4) - return GF_ISOM_INVALID_FILE; - - GF_SAFE_ALLOC_N(ptr->entries, ptr->nb_entries, GroupIdNameEntry); - if (!ptr->entries) return GF_OUT_OF_MEM; - - for (i=0; inb_entries; i++) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->entries[i].group_id = gf_bs_read_u32(bs); - - e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->entries[i].name); - if (e) return e; - } - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err gitn_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GroupIdToNameBox *ptr = (GroupIdToNameBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u16(bs, ptr->nb_entries); - for (i=0; inb_entries; i++) { - gf_bs_write_u32(bs, ptr->entries[i].group_id); - if (ptr->entries[i].name) gf_bs_write_data(bs, ptr->entries[i].name, (u32)strlen(ptr->entries[i].name) ); - gf_bs_write_u8(bs, 0); - } - return GF_OK; -} - -GF_Err gitn_box_size(GF_Box *s) -{ - u32 i; - GroupIdToNameBox *ptr = (GroupIdToNameBox *)s; - ptr->size += 2; - - for (i=0; inb_entries; i++) { - ptr->size += 5; - if (ptr->entries[i].name) ptr->size += strlen(ptr->entries[i].name); - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#ifndef GPAC_DISABLE_ISOM_HINTING - -GF_Box *fdpa_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_FDpacketBox, GF_ISOM_BOX_TYPE_FDPA); - return (GF_Box *)tmp; -} - -void fdpa_box_del(GF_Box *s) -{ - u32 i; - GF_FDpacketBox *ptr = (GF_FDpacketBox *)s; - if (ptr == NULL) return; - - if (ptr->headers) { - for (i=0; iheader_ext_count; i++) { - if (ptr->headers[i].data) gf_free(ptr->headers[i].data); - } - gf_free(ptr->headers); - } - gf_free(ptr); -} - -GF_Err fdpa_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_FDpacketBox *ptr = (GF_FDpacketBox *)s; - - ISOM_DECREASE_SIZE(ptr, 3); - ptr->info.sender_current_time_present = gf_bs_read_int(bs, 1); - ptr->info.expected_residual_time_present = gf_bs_read_int(bs, 1); - ptr->info.session_close_bit = gf_bs_read_int(bs, 1); - ptr->info.object_close_bit = gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 4); - ptr->info.transport_object_identifier = gf_bs_read_u16(bs); - ISOM_DECREASE_SIZE(ptr, 2); - ptr->header_ext_count = gf_bs_read_u16(bs); - if (ptr->size < ptr->header_ext_count*2) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid number of entries %d in fdpa\n", ptr->header_ext_count)); - return GF_ISOM_INVALID_FILE; - } - - GF_SAFE_ALLOC_N(ptr->headers, ptr->header_ext_count, GF_LCTheaderExtension); - if (!ptr->headers) return GF_OUT_OF_MEM; - - for (i=0; iheader_ext_count; i++) { - ptr->headers[i].header_extension_type = gf_bs_read_u8(bs); - ISOM_DECREASE_SIZE(ptr, 1); - - if (ptr->headers[i].header_extension_type > 127) { - ISOM_DECREASE_SIZE(ptr, 3); - gf_bs_read_data(bs, (char *) ptr->headers[i].content, 3); - } else { - ISOM_DECREASE_SIZE(ptr, 1); - ptr->headers[i].data_length = gf_bs_read_u8(bs); - if (ptr->headers[i].data_length) { - ptr->headers[i].data_length = 4*ptr->headers[i].data_length - 2; - if (ptr->size < sizeof(char) * ptr->headers[i].data_length) - return GF_ISOM_INVALID_FILE; - ptr->headers[i].data = gf_malloc(sizeof(char) * ptr->headers[i].data_length); - if (!ptr->headers[i].data) return GF_OUT_OF_MEM; - - ISOM_DECREASE_SIZE(ptr, ptr->headers[i].data_length); - gf_bs_read_data(bs, ptr->headers[i].data, ptr->headers[i].data_length); - } - } - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err fdpa_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_FDpacketBox *ptr = (GF_FDpacketBox *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_int(bs, ptr->info.sender_current_time_present, 1); - gf_bs_write_int(bs, ptr->info.expected_residual_time_present, 1); - gf_bs_write_int(bs, ptr->info.session_close_bit, 1); - gf_bs_write_int(bs, ptr->info.object_close_bit, 1); - gf_bs_write_int(bs, 0, 4); - gf_bs_write_u16(bs, ptr->info.transport_object_identifier); - gf_bs_write_u16(bs, ptr->header_ext_count); - for (i=0; iheader_ext_count; i++) { - gf_bs_write_u8(bs, ptr->headers[i].header_extension_type); - if (ptr->headers[i].header_extension_type > 127) { - gf_bs_write_data(bs, (const char *) ptr->headers[i].content, 3); - } else { - gf_bs_write_u8(bs, ptr->headers[i].data_length ? (ptr->headers[i].data_length+2)/4 : 0); - if (ptr->headers[i].data_length) { - gf_bs_write_data(bs, ptr->headers[i].data, ptr->headers[i].data_length); - } - } - } - return GF_OK; -} - -GF_Err fdpa_box_size(GF_Box *s) -{ - u32 i; - GF_FDpacketBox *ptr = (GF_FDpacketBox *)s; - - ptr->size += 5; - - for (i=0; iheader_ext_count; i++) { - ptr->size += 1; - if (ptr->headers[i].header_extension_type > 127) { - ptr->size += 3; - } else { - ptr->size += 1 + ptr->headers[i].data_length; - } - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *extr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ExtraDataBox, GF_ISOM_BOX_TYPE_EXTR); - return (GF_Box *)tmp; -} - -void extr_box_del(GF_Box *s) -{ - GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s; - if (ptr == NULL) return; - if (ptr->feci) gf_isom_box_del((GF_Box*)ptr->feci); - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - -GF_Err extr_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ExtraDataBox *ptr = (GF_ExtraDataBox *)s; - - e = gf_isom_box_parse((GF_Box**) &ptr->feci, bs); - if (e) return e; - if (!ptr->feci || ptr->feci->size > ptr->size) return GF_ISOM_INVALID_MEDIA; - ptr->data_length = (u32) (ptr->size - ptr->feci->size); - ptr->data = gf_malloc(sizeof(char)*ptr->data_length); - if (!ptr->data) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->data, ptr->data_length); - - return GF_OK; -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err extr_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - if (ptr->feci) { - e = gf_isom_box_write((GF_Box *)ptr->feci, bs); - if (e) return e; - } - gf_bs_write_data(bs, ptr->data, ptr->data_length); - return GF_OK; -} - -GF_Err extr_box_size(GF_Box *s) -{ - GF_ExtraDataBox *ptr = (GF_ExtraDataBox *) s; - ptr->size += ptr->data_length; - if (ptr->feci) { - GF_Err e = gf_isom_box_size((GF_Box*)ptr->feci); - if (e) return e; - ptr->size += ptr->feci->size; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -GF_Box *fdsa_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_HintSample, GF_ISOM_BOX_TYPE_FDSA); - if (!tmp) return NULL; - tmp->packetTable = gf_list_new(); - tmp->hint_subtype = GF_ISOM_BOX_TYPE_FDP_STSD; - return (GF_Box*)tmp; -} - -void fdsa_box_del(GF_Box *s) -{ - GF_HintSample *ptr = (GF_HintSample *)s; - gf_list_del(ptr->packetTable); - gf_free(ptr); -} - -GF_Err fdsa_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_HintSample *ptr = (GF_HintSample *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_FDPA: - gf_list_add(ptr->packetTable, a); - break; - case GF_ISOM_BOX_TYPE_EXTR: - if (ptr->extra_data) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->extra_data = (GF_ExtraDataBox*)a; - break; - } - return GF_OK; -} -GF_Err fdsa_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, fdsa_on_child_box); -} - - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err fdsa_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_HintSample *ptr = (GF_HintSample *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - e = gf_isom_box_array_write(s, ptr->packetTable, bs); - if (e) return e; - if (ptr->extra_data) { - e = gf_isom_box_write((GF_Box *)ptr->extra_data, bs); - if (e) return e; - } - return GF_OK; -} - -GF_Err fdsa_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif /*GPAC_DISABLE_ISOM_HINTING*/ - - -void trik_box_del(GF_Box *s) -{ - GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s; - if (ptr == NULL) return; - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - -GF_Err trik_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s; - ptr->entry_count = (u32) ptr->size; - ptr->entries = (GF_TrickPlayBoxEntry *) gf_malloc(ptr->entry_count * sizeof(GF_TrickPlayBoxEntry) ); - if (!ptr->entries) return GF_OUT_OF_MEM; - - for (i=0; i< ptr->entry_count; i++) { - ptr->entries[i].pic_type = gf_bs_read_int(bs, 2); - ptr->entries[i].dependency_level = gf_bs_read_int(bs, 6); - } - return GF_OK; -} - -GF_Box *trik_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrickPlayBox, GF_ISOM_BOX_TYPE_TRIK); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err trik_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - for (i=0; i < ptr->entry_count; i++ ) { - gf_bs_write_int(bs, ptr->entries[i].pic_type, 2); - gf_bs_write_int(bs, ptr->entries[i].dependency_level, 6); - } - return GF_OK; -} - -GF_Err trik_box_size(GF_Box *s) -{ - GF_TrickPlayBox *ptr = (GF_TrickPlayBox *) s; - ptr->size += 8 * ptr->entry_count; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void bloc_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err bloc_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s; - - ISOM_DECREASE_SIZE(s, 256) - gf_bs_read_data(bs, (char *) ptr->baseLocation, 256); - ISOM_DECREASE_SIZE(s, 256) - gf_bs_read_data(bs, (char *) ptr->basePurlLocation, 256); - ISOM_DECREASE_SIZE(s, 512) - gf_bs_skip_bytes(bs, 512); - return GF_OK; -} - -GF_Box *bloc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_BaseLocationBox, GF_ISOM_BOX_TYPE_TRIK); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err bloc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_BaseLocationBox *ptr = (GF_BaseLocationBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_data(bs, (const char *) ptr->baseLocation, 256); - gf_bs_write_data(bs, (const char *) ptr->basePurlLocation, 256); - for (i=0; i < 64; i++ ) { - gf_bs_write_u64(bs, 0); - } - return GF_OK; -} - -GF_Err bloc_box_size(GF_Box *s) -{ - s->size += 1024; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void ainf_box_del(GF_Box *s) -{ - GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s; - if (ptr->APID) gf_free(ptr->APID); - gf_free(s); -} - -GF_Err ainf_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s; - - ISOM_DECREASE_SIZE(s, 4) - ptr->profile_version = gf_bs_read_u32(bs); - return gf_isom_read_null_terminated_string(s, bs, s->size, &ptr->APID); -} - -GF_Box *ainf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AssetInformationBox, GF_ISOM_BOX_TYPE_AINF); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ainf_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->profile_version); - if (ptr->APID) - gf_bs_write_data(bs, ptr->APID, (u32) strlen(ptr->APID) ); - gf_bs_write_u8(bs, 0); - return GF_OK; -} - -GF_Err ainf_box_size(GF_Box *s) -{ - GF_AssetInformationBox *ptr = (GF_AssetInformationBox *) s; - s->size += 4 + (ptr->APID ? strlen(ptr->APID) : 0 ) + 1; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void mhac_box_del(GF_Box *s) -{ - GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s; - if (ptr->mha_config) gf_free(ptr->mha_config); - gf_free(s); -} - -GF_Err mhac_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s; - - ISOM_DECREASE_SIZE(s, 5) - ptr->configuration_version = gf_bs_read_u8(bs); - ptr->mha_pl_indication = gf_bs_read_u8(bs); - ptr->reference_channel_layout = gf_bs_read_u8(bs); - ptr->mha_config_size = gf_bs_read_u16(bs); - if (ptr->mha_config_size) { - ISOM_DECREASE_SIZE(s, ptr->mha_config_size) - - ptr->mha_config = gf_malloc(sizeof(char)*ptr->mha_config_size); - if (!ptr->mha_config) return GF_OUT_OF_MEM; - - gf_bs_read_data(bs, ptr->mha_config, ptr->mha_config_size); - } - return GF_OK; -} - -GF_Box *mhac_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MHAConfigBox, GF_ISOM_BOX_TYPE_MHAC); - tmp->configuration_version = 1; - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mhac_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->configuration_version); - gf_bs_write_u8(bs, ptr->mha_pl_indication); - gf_bs_write_u8(bs, ptr->reference_channel_layout); - gf_bs_write_u16(bs, ptr->mha_config ? ptr->mha_config_size : 0); - if (ptr->mha_config && ptr->mha_config_size) - gf_bs_write_data(bs, ptr->mha_config, ptr->mha_config_size); - - return GF_OK; -} - -GF_Err mhac_box_size(GF_Box *s) -{ - GF_MHAConfigBox *ptr = (GF_MHAConfigBox *) s; - s->size += 5; - if (ptr->mha_config_size && ptr->mha_config) s->size += ptr->mha_config_size; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void jp2h_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err jp2h_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_J2KHeaderBox *ptr = (GF_J2KHeaderBox *)s; - switch(a->type) { - case GF_ISOM_BOX_TYPE_IHDR: - if (ptr->ihdr) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->ihdr = (GF_J2KImageHeaderBox*)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_COLR: - if (ptr->colr) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->colr = (GF_ColourInformationBox*)a; - return GF_OK; - } - return GF_OK; -} -GF_Err jp2h_box_read(GF_Box *s,GF_BitStream *bs) -{ - return gf_isom_box_array_read_ex(s, bs, jp2h_on_child_box, s->type); -} - -GF_Box *jp2h_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_J2KHeaderBox, GF_ISOM_BOX_TYPE_JP2H); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err jp2h_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err jp2h_box_size(GF_Box *s) -{ - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void ihdr_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err ihdr_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s; - - ISOM_DECREASE_SIZE(s, 14) - - ptr->height = gf_bs_read_u32(bs); - ptr->width = gf_bs_read_u32(bs); - ptr->nb_comp = gf_bs_read_u16(bs); - ptr->bpc = gf_bs_read_u8(bs); - ptr->Comp = gf_bs_read_u8(bs); - ptr->UnkC = gf_bs_read_u8(bs); - ptr->IPR = gf_bs_read_u8(bs); - - return GF_OK; -} - -GF_Box *ihdr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_J2KImageHeaderBox, GF_ISOM_BOX_TYPE_IHDR); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ihdr_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_J2KImageHeaderBox *ptr = (GF_J2KImageHeaderBox *) s; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - gf_bs_write_u32(bs, ptr->height); - gf_bs_write_u32(bs, ptr->width); - gf_bs_write_u16(bs, ptr->nb_comp); - gf_bs_write_u8(bs, ptr->bpc); - gf_bs_write_u8(bs, ptr->Comp); - gf_bs_write_u8(bs, ptr->UnkC); - gf_bs_write_u8(bs, ptr->IPR); - return GF_OK; -} - -GF_Err ihdr_box_size(GF_Box *s) -{ - s->size += 14; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/* Dolby Vision */ - -GF_Box *dvcC_box_new() -{ - GF_DOVIConfigurationBox *tmp = (GF_DOVIConfigurationBox *)gf_malloc(sizeof(GF_DOVIConfigurationBox)); - if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_DOVIConfigurationBox)); - tmp->type = GF_ISOM_BOX_TYPE_DVCC; - return (GF_Box *)tmp; -} - -void dvcC_box_del(GF_Box *s) -{ - GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox*)s; - gf_free(ptr); -} - -GF_Err dvcC_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - u32 data[5]; - GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s; - - //GF_DOVIDecoderConfigurationRecord - ISOM_DECREASE_SIZE(ptr, 24) - ptr->DOVIConfig.dv_version_major = gf_bs_read_u8(bs); - ptr->DOVIConfig.dv_version_minor = gf_bs_read_u8(bs); - ptr->DOVIConfig.dv_profile = gf_bs_read_int(bs, 7); - ptr->DOVIConfig.dv_level = gf_bs_read_int(bs, 6); - ptr->DOVIConfig.rpu_present_flag = gf_bs_read_int(bs, 1); - ptr->DOVIConfig.el_present_flag = gf_bs_read_int(bs, 1); - ptr->DOVIConfig.bl_present_flag = gf_bs_read_int(bs, 1); - - memset(data, 0, sizeof(u32)*5); - gf_bs_read_data(bs, (char*)data, 20); - for (i = 0; i < 5; ++i) { - if (data[i] != 0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] dvcC reserved bytes are not zero\n")); - //return GF_ISOM_INVALID_FILE; - } - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err dvcC_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - - //GF_DOVIDecoderConfigurationRecord - gf_bs_write_u8(bs, ptr->DOVIConfig.dv_version_major); - gf_bs_write_u8(bs, ptr->DOVIConfig.dv_version_minor); - gf_bs_write_int(bs, ptr->DOVIConfig.dv_profile, 7); - gf_bs_write_int(bs, ptr->DOVIConfig.dv_level, 6); - gf_bs_write_int(bs, ptr->DOVIConfig.rpu_present_flag, 1); - gf_bs_write_int(bs, ptr->DOVIConfig.el_present_flag, 1); - gf_bs_write_int(bs, ptr->DOVIConfig.bl_present_flag, 1); - gf_bs_write_u32(bs, 0); - gf_bs_write_u32(bs, 0); - gf_bs_write_u32(bs, 0); - gf_bs_write_u32(bs, 0); - gf_bs_write_u32(bs, 0); - - return GF_OK; -} - -GF_Err dvcC_box_size(GF_Box *s) -{ - GF_DOVIConfigurationBox *ptr = (GF_DOVIConfigurationBox *)s; - - ptr->size += 24; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *dOps_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OpusSpecificBox, GF_ISOM_BOX_TYPE_DOPS); - return (GF_Box *)tmp; -} - -void dOps_box_del(GF_Box *s) -{ - GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s; - if (ptr) gf_free(ptr); -} - -GF_Err dOps_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s; - ptr->version = gf_bs_read_u8(bs); - ptr->OutputChannelCount = gf_bs_read_u8(bs); - ptr->PreSkip = gf_bs_read_u16(bs); - ptr->InputSampleRate = gf_bs_read_u32(bs); - ptr->OutputGain = gf_bs_read_u16(bs); - ptr->ChannelMappingFamily = gf_bs_read_u8(bs); - ISOM_DECREASE_SIZE(ptr, 11) - if (ptr->size) { - ISOM_DECREASE_SIZE(ptr, 2+ptr->OutputChannelCount); - ptr->StreamCount = gf_bs_read_u8(bs); - ptr->CoupledCount = gf_bs_read_u8(bs); - gf_bs_read_data(bs, (char *) ptr->ChannelMapping, ptr->OutputChannelCount); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err dOps_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->version); - gf_bs_write_u8(bs, ptr->OutputChannelCount); - gf_bs_write_u16(bs, ptr->PreSkip); - gf_bs_write_u32(bs, ptr->InputSampleRate); - gf_bs_write_u16(bs, ptr->OutputGain); - gf_bs_write_u8(bs, ptr->ChannelMappingFamily); - if (ptr->ChannelMappingFamily) { - gf_bs_write_u8(bs, ptr->StreamCount); - gf_bs_write_u8(bs, ptr->CoupledCount); - gf_bs_write_data(bs, (char *) ptr->ChannelMapping, ptr->OutputChannelCount); - } - return GF_OK; -} - -GF_Err dOps_box_size(GF_Box *s) -{ - GF_OpusSpecificBox *ptr = (GF_OpusSpecificBox *)s; - ptr->size += 11; - if (ptr->ChannelMappingFamily) - ptr->size += 2 + ptr->OutputChannelCount; - - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void dfla_box_del(GF_Box *s) -{ - GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s; - if (ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - -GF_Err dfla_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s; - ptr->dataSize = (u32) ptr->size; - ptr->size=0; - ptr->data = gf_malloc(ptr->dataSize); - gf_bs_read_data(bs, ptr->data, ptr->dataSize); - return GF_OK; -} - -GF_Box *dfla_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_FLACConfigBox, GF_ISOM_BOX_TYPE_DFLA); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err dfla_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_data(bs, ptr->data, ptr->dataSize); - return GF_OK; -} - -GF_Err dfla_box_size(GF_Box *s) -{ - GF_FLACConfigBox *ptr = (GF_FLACConfigBox *) s; - ptr->size += ptr->dataSize; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void mvcg_box_del(GF_Box *s) -{ - GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s; - if (ptr->entries) gf_free(ptr->entries); - gf_free(ptr); -} - -GF_Err mvcg_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s; - ISOM_DECREASE_SIZE(s, 7) - ptr->multiview_group_id = gf_bs_read_u32(bs); - ptr->num_entries = gf_bs_read_u16(bs); - gf_bs_read_u8(bs); - ptr->entries = gf_malloc(ptr->num_entries * sizeof(MVCIEntry)); - memset(ptr->entries, 0, ptr->num_entries * sizeof(MVCIEntry)); - for (i=0; inum_entries; i++) { - ISOM_DECREASE_SIZE(s, 1) - ptr->entries[i].entry_type = gf_bs_read_u8(bs); - switch (ptr->entries[i].entry_type) { - case 0: - ISOM_DECREASE_SIZE(s, 4) - ptr->entries[i].trackID = gf_bs_read_u32(bs); - break; - case 1: - ISOM_DECREASE_SIZE(s, 6) - ptr->entries[i].trackID = gf_bs_read_u32(bs); - ptr->entries[i].tierID = gf_bs_read_u16(bs); - break; - case 2: - ISOM_DECREASE_SIZE(s, 2) - gf_bs_read_int(bs, 6); - ptr->entries[i].output_view_id = gf_bs_read_int(bs, 10); - break; - case 3: - ISOM_DECREASE_SIZE(s, 4) - gf_bs_read_int(bs, 6) ; - ptr->entries[i].start_view_id = gf_bs_read_int(bs, 10); - ptr->entries[i].view_count = gf_bs_read_u16(bs); - break; - } - } - return gf_isom_box_array_read(s, bs, NULL); -} - -GF_Box *mvcg_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MultiviewGroupBox, GF_ISOM_BOX_TYPE_MVCG); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err mvcg_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - - gf_bs_write_u32(bs, ptr->multiview_group_id); - gf_bs_write_u16(bs, ptr->num_entries); - gf_bs_write_u8(bs, 0); - - for (i=0; inum_entries; i++) { - gf_bs_write_u8(bs, ptr->entries[i].entry_type); - switch (ptr->entries[i].entry_type) { - case 0: - gf_bs_write_u32(bs, ptr->entries[i].trackID); - break; - case 1: - gf_bs_write_u32(bs, ptr->entries[i].trackID); - gf_bs_write_u16(bs, ptr->entries[i].tierID); - break; - case 2: - gf_bs_write_int(bs, 0, 6); - gf_bs_write_int(bs, ptr->entries[i].output_view_id, 10); - break; - case 3: - gf_bs_write_int(bs, 0, 6) ; - gf_bs_write_int(bs, ptr->entries[i].start_view_id, 10); - gf_bs_write_u16(bs, ptr->entries[i].view_count); - break; - } - } - return GF_OK; -} - -GF_Err mvcg_box_size(GF_Box *s) -{ - u32 i; - GF_MultiviewGroupBox *ptr = (GF_MultiviewGroupBox *) s; - - ptr->size += 7; - for (i=0; inum_entries; i++) { - switch (ptr->entries[i].entry_type) { - case 0: - ptr->size += 1 + 4; - break; - case 1: - ptr->size += 1 + 6; - break; - case 2: - ptr->size += 1 + 2; - break; - case 3: - ptr->size += 1 + 4; - break; - } - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void vwid_box_del(GF_Box *s) -{ - u32 i; - GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s; - if (ptr->views) { - for (i=0; inum_views; i++) { - if (ptr->views[i].view_refs) - gf_free(ptr->views[i].view_refs); - } - gf_free(ptr->views); - } - gf_free(ptr); -} - -GF_Err vwid_box_read(GF_Box *s,GF_BitStream *bs) -{ - u32 i; - GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s; - ISOM_DECREASE_SIZE(s, 3) - gf_bs_read_int(bs, 2); - ptr->min_temporal_id = gf_bs_read_int(bs, 3); - ptr->max_temporal_id = gf_bs_read_int(bs, 3); - ptr->num_views = gf_bs_read_u16(bs); - if (6 * ptr->num_views > ptr->size) - return GF_ISOM_INVALID_FILE; - - ptr->views = gf_malloc(sizeof(ViewIDEntry)*ptr->num_views); - for (i=0; inum_views; i++) { - u32 j; - ISOM_DECREASE_SIZE(s, 6) - - gf_bs_read_int(bs, 6); - ptr->views[i].view_id = gf_bs_read_int(bs, 10); - gf_bs_read_int(bs, 6); - ptr->views[i].view_order_index = gf_bs_read_int(bs, 10); - ptr->views[i].texture_in_stream = gf_bs_read_int(bs, 1); - ptr->views[i].texture_in_track = gf_bs_read_int(bs, 1); - ptr->views[i].depth_in_stream = gf_bs_read_int(bs, 1); - ptr->views[i].depth_in_track = gf_bs_read_int(bs, 1); - ptr->views[i].base_view_type = gf_bs_read_int(bs, 2); - ptr->views[i].num_ref_views = gf_bs_read_int(bs, 10); - - if (2 * ptr->views[i].num_ref_views > ptr->size) - return GF_ISOM_INVALID_FILE; - - ptr->views[i].view_refs = gf_malloc(sizeof(ViewIDRefViewEntry)*ptr->views[i].num_ref_views); - for (j=0; jviews[i].num_ref_views; j++) { - ISOM_DECREASE_SIZE(s, 2) - gf_bs_read_int(bs, 4); - ptr->views[i].view_refs[j].dep_comp_idc = gf_bs_read_int(bs, 2); - ptr->views[i].view_refs[j].ref_view_id = gf_bs_read_int(bs, 10); - } - } - return GF_OK; -} - -GF_Box *vwid_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ViewIdentifierBox, GF_ISOM_BOX_TYPE_VWID); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err vwid_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i, j; - GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_int(bs, 0, 2); - gf_bs_write_int(bs, ptr->min_temporal_id, 3); - gf_bs_write_int(bs, ptr->max_temporal_id, 3); - gf_bs_write_u16(bs, ptr->num_views); - - for (i=0; inum_views; i++) { - gf_bs_write_int(bs, 0, 6); - gf_bs_write_int(bs, ptr->views[i].view_id, 10); - gf_bs_write_int(bs, 0, 6); - gf_bs_write_int(bs, ptr->views[i].view_order_index, 10); - - gf_bs_write_int(bs, ptr->views[i].texture_in_stream, 1); - gf_bs_write_int(bs, ptr->views[i].texture_in_track, 1); - gf_bs_write_int(bs, ptr->views[i].depth_in_stream, 1); - gf_bs_write_int(bs, ptr->views[i].depth_in_track, 1); - gf_bs_write_int(bs, ptr->views[i].base_view_type, 2); - gf_bs_write_int(bs, ptr->views[i].num_ref_views, 10); - - for (j=0; jviews[i].num_ref_views; j++) { - gf_bs_write_int(bs, 0, 4); - gf_bs_write_int(bs, ptr->views[i].view_refs[j].dep_comp_idc, 2); - gf_bs_write_int(bs, ptr->views[i].view_refs[j].ref_view_id, 10); - } - } - return GF_OK; -} - -GF_Err vwid_box_size(GF_Box *s) -{ - u32 i; - GF_ViewIdentifierBox *ptr = (GF_ViewIdentifierBox *) s; - ptr->size += 3; - for (i=0; inum_views; i++) { - ptr->size += 6 + 2 * ptr->views[i].num_ref_views; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -void pcmC_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err pcmC_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s; - - ISOM_DECREASE_SIZE(s, 2) - ptr->format_flags = gf_bs_read_u8(bs); - ptr->PCM_sample_size = gf_bs_read_u8(bs); - return GF_OK; -} - -GF_Box *pcmC_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PCMConfigBox, GF_ISOM_BOX_TYPE_PCMC); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err pcmC_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_PCMConfigBox *ptr = (GF_PCMConfigBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->format_flags); - gf_bs_write_u8(bs, ptr->PCM_sample_size); - return GF_OK; -} - -GF_Err pcmC_box_size(GF_Box *s) -{ - s->size += 2; - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -void chnl_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err chnl_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s; - - ISOM_DECREASE_SIZE(s, 1) - ptr->layout.stream_structure = gf_bs_read_u8(bs); - if (ptr->layout.stream_structure & 1) { - ISOM_DECREASE_SIZE(s, 1) - ptr->layout.definedLayout = gf_bs_read_u8(bs); - if (ptr->layout.definedLayout) { - u32 remain = (u32) ptr->size; - if (ptr->layout.stream_structure & 2) remain--; - ptr->layout.channels_count = 0; - while (remain) { - ISOM_DECREASE_SIZE(s, 1) - ptr->layout.layouts[ptr->layout.channels_count].position = gf_bs_read_u8(bs); - remain--; - if (ptr->layout.layouts[ptr->layout.channels_count].position == 126) { - ISOM_DECREASE_SIZE(s, 3) - ptr->layout.layouts[ptr->layout.channels_count].azimuth = gf_bs_read_int(bs, 16); - ptr->layout.layouts[ptr->layout.channels_count].elevation = gf_bs_read_int(bs, 8); - remain-=3; - } - } - } else { - ISOM_DECREASE_SIZE(s, 8) - ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs); - } - } - if (ptr->layout.stream_structure & 2) { - ISOM_DECREASE_SIZE(s, 1) - ptr->layout.object_count = gf_bs_read_u8(bs); - } - return GF_OK; -} - -GF_Box *chnl_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ChannelLayoutBox, GF_ISOM_BOX_TYPE_CHNL); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err chnl_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u8(bs, ptr->layout.stream_structure); - if (ptr->layout.stream_structure & 1) { - gf_bs_write_u8(bs, ptr->layout.definedLayout); - if (ptr->layout.definedLayout==0) { - u32 i; - for (i=0; ilayout.channels_count; i++) { - gf_bs_write_u8(bs, ptr->layout.layouts[i].position); - if (ptr->layout.layouts[i].position==126) { - gf_bs_write_int(bs, ptr->layout.layouts[i].azimuth, 16); - gf_bs_write_int(bs, ptr->layout.layouts[i].elevation, 8); - } - } - } else { - gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap); - } - } - if (ptr->layout.stream_structure & 2) { - gf_bs_write_u8(bs, ptr->layout.object_count); - } - return GF_OK; -} - -GF_Err chnl_box_size(GF_Box *s) -{ - GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s; - s->size += 1; - if (ptr->layout.stream_structure & 1) { - s->size += 1; - if (ptr->layout.definedLayout==0) { - u32 i; - for (i=0; ilayout.channels_count; i++) { - s->size+=1; - if (ptr->layout.layouts[i].position==126) - s->size+=3; - } - } else { - s->size += 8; - } - } - if (ptr->layout.stream_structure & 2) { - s->size += 1; - } - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -GF_Box *emsg_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_EventMessageBox, GF_ISOM_BOX_TYPE_EMSG); - return (GF_Box *)tmp; -} - -void emsg_box_del(GF_Box *s) -{ - GF_EventMessageBox *ptr = (GF_EventMessageBox *) s; - if (ptr == NULL) return; - if (ptr->scheme_id_uri) gf_free(ptr->scheme_id_uri); - if (ptr->value) gf_free(ptr->value); - if (ptr->message_data) gf_free(ptr->message_data); - gf_free(ptr); -} - -GF_Err emsg_box_read(GF_Box *s,GF_BitStream *bs) -{ - GF_Err e; - GF_EventMessageBox *ptr = (GF_EventMessageBox*) s; - - if (ptr->version==0) { - e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri); - if (e) return e; - e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value); - if (e) return e; - - ISOM_DECREASE_SIZE(ptr, 16); - ptr->timescale = gf_bs_read_u32(bs); - ptr->presentation_time_delta = gf_bs_read_u32(bs); - ptr->event_duration = gf_bs_read_u32(bs); - ptr->event_id = gf_bs_read_u32(bs); - } else if (ptr->version==1) { - ISOM_DECREASE_SIZE(ptr, 20); - ptr->timescale = gf_bs_read_u32(bs); - ptr->presentation_time_delta = gf_bs_read_u64(bs); - ptr->event_duration = gf_bs_read_u32(bs); - ptr->event_id = gf_bs_read_u32(bs); - - e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->scheme_id_uri); - if (e) return e; - e = gf_isom_read_null_terminated_string(s, bs, ptr->size, &ptr->value); - if (e) return e; - } else { - return GF_OK; - } - if (ptr->size) { - if (ptr->size>0xFFFFFFFUL) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[IsoMedia] emsg message data size too big ("LLU") to be loaded\n", ptr->size)); - return GF_OUT_OF_MEM; - } - ptr->message_data_size = (u32) ptr->size; - ptr->message_data = gf_malloc(ptr->message_data_size); - if (!ptr->message_data) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->message_data, ptr->message_data_size); - ptr->size = 0; - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err emsg_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 len; - GF_EventMessageBox *ptr = (GF_EventMessageBox*) s; - - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - if (ptr->version==1) { - gf_bs_write_u32(bs, ptr->timescale); - gf_bs_write_u64(bs, ptr->presentation_time_delta); - gf_bs_write_u32(bs, ptr->event_duration); - gf_bs_write_u32(bs, ptr->event_id); - } - - len = ptr->scheme_id_uri ? (u32) strlen(ptr->scheme_id_uri) : 0; - if (len) gf_bs_write_data(bs, ptr->scheme_id_uri, len); - gf_bs_write_u8(bs, 0); - - len = ptr->value ? (u32) strlen(ptr->value) : 0; - if (len) gf_bs_write_data(bs, ptr->value, len); - gf_bs_write_u8(bs, 0); - - if (ptr->version==0) { - gf_bs_write_u32(bs, ptr->timescale); - gf_bs_write_u32(bs, (u32) ptr->presentation_time_delta); - gf_bs_write_u32(bs, ptr->event_duration); - gf_bs_write_u32(bs, ptr->event_id); - } - if (ptr->message_data) - gf_bs_write_data(bs, ptr->message_data, ptr->message_data_size); - return GF_OK; -} - -GF_Err emsg_box_size(GF_Box *s) -{ - GF_EventMessageBox *ptr = (GF_EventMessageBox*) s; - - ptr->size += 4; - if (ptr->version) { - ptr->size += 20; - } else { - ptr->size += 16; - } - ptr->size+=2; //1 NULL-terminated strings - if (ptr->scheme_id_uri) ptr->size += strlen(ptr->scheme_id_uri); - if (ptr->value) ptr->size += strlen(ptr->value); - if (ptr->message_data) - ptr->size += ptr->message_data_size; - - return GF_OK; -} -#endif // GPAC_DISABLE_ISOM_WRITE - -#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/thirdparty/gpacmp4/box_code_drm.c b/src/thirdparty/gpacmp4/box_code_drm.c deleted file mode 100644 index 32c5e166b..000000000 --- a/src/thirdparty/gpacmp4/box_code_drm.c +++ /dev/null @@ -1,1812 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Cyril Concolato, Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2005-2019 - * All rights reserved - * - * This file is part of GPAC / ISO Media File Format sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include - -#ifndef GPAC_DISABLE_ISOM - -/* ProtectionInfo Box */ -GF_Box *sinf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ProtectionSchemeInfoBox, GF_ISOM_BOX_TYPE_SINF); - return (GF_Box *)tmp; -} - -void sinf_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err sinf_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_FRMA: - if (ptr->original_format) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->original_format = (GF_OriginalFormatBox*)a; - break; - case GF_ISOM_BOX_TYPE_SCHM: - if (ptr->scheme_type) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->scheme_type = (GF_SchemeTypeBox*)a; - break; - case GF_ISOM_BOX_TYPE_SCHI: - if (ptr->info) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->info = (GF_SchemeInformationBox*)a; - break; - } - return GF_OK; -} - -GF_Err sinf_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, sinf_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err sinf_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err sinf_box_size(GF_Box *s) -{ - u32 pos=0; - GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s; - gf_isom_check_position(s, (GF_Box *)ptr->original_format, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->scheme_type, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->info, &pos); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/* OriginalFormat Box */ -GF_Box *frma_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OriginalFormatBox, GF_ISOM_BOX_TYPE_FRMA); - return (GF_Box *)tmp; -} - -void frma_box_del(GF_Box *s) -{ - GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err frma_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - ptr->data_format = gf_bs_read_u32(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err frma_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->data_format); - return GF_OK; -} - -GF_Err frma_box_size(GF_Box *s) -{ - GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s; - ptr->size += 4; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/* SchemeType Box */ -GF_Box *schm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SchemeTypeBox, GF_ISOM_BOX_TYPE_SCHM); - return (GF_Box *)tmp; -} - -void schm_box_del(GF_Box *s) -{ - GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s; - if (ptr == NULL) return; - if (ptr->URI) gf_free(ptr->URI); - gf_free(ptr); -} - -GF_Err schm_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s; - - ISOM_DECREASE_SIZE(ptr, 8); - ptr->scheme_type = gf_bs_read_u32(bs); - ptr->scheme_version = gf_bs_read_u32(bs); - - if (ptr->size && (ptr->flags & 0x000001)) { - u32 len = (u32) (ptr->size); - ptr->URI = (char*)gf_malloc(sizeof(char)*len); - if (!ptr->URI) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->URI, len); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err schm_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u32(bs, ptr->scheme_type); - gf_bs_write_u32(bs, ptr->scheme_version); - if (ptr->flags & 0x000001) { - if (ptr->URI) - gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI)+1); - else - gf_bs_write_u8(bs, 0); - } - return GF_OK; -} - -GF_Err schm_box_size(GF_Box *s) -{ - GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s; - if (!s) return GF_BAD_PARAM; - ptr->size += 8; - if (ptr->flags & 0x000001) ptr->size += 1 + (ptr->URI ? strlen(ptr->URI) : 0); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/* SchemeInformation Box */ -GF_Box *schi_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SchemeInformationBox, GF_ISOM_BOX_TYPE_SCHI); - return (GF_Box *)tmp; -} - -void schi_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err schi_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_IKMS: - if (ptr->ikms) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->ikms = (GF_ISMAKMSBox*)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_ISFM: - if (ptr->isfm) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->isfm = (GF_ISMASampleFormatBox*)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_ISLT: - if (ptr->islt) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->islt = (GF_ISMACrypSaltBox*)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_ODKM: - if (ptr->odkm) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->odkm = (GF_OMADRMKMSBox*)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_TENC: - if (ptr->tenc) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->tenc = (GF_TrackEncryptionBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_ADKM: - if (ptr->adkm) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->adkm = (GF_AdobeDRMKeyManagementSystemBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_UUID: - if (((GF_UUIDBox*)a)->internal_4cc==GF_ISOM_BOX_UUID_TENC) { - if (ptr->piff_tenc) return GF_ISOM_INVALID_FILE; - ptr->piff_tenc = (GF_PIFFTrackEncryptionBox *)a; - return GF_OK; - } else { - return GF_OK; - } - } - return GF_OK; -} - -GF_Err schi_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, schi_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err schi_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_write_header(s, bs); -} - -GF_Err schi_box_size(GF_Box *s) -{ - u32 pos=0; - GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s; - - gf_isom_check_position(s, (GF_Box *)ptr->ikms, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->isfm, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->islt, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->odkm, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->tenc, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->adkm, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->piff_tenc, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/* ISMAKMS Box */ -GF_Box *iKMS_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ISMAKMSBox, GF_ISOM_BOX_TYPE_IKMS); - return (GF_Box *)tmp; -} - -void iKMS_box_del(GF_Box *s) -{ - GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s; - if (ptr == NULL) return; - if (ptr->URI) gf_free(ptr->URI); - gf_free(ptr); -} - -GF_Err iKMS_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 len; - GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s; - - len = (u32) (ptr->size); - ptr->URI = (char*) gf_malloc(sizeof(char)*len); - if (!ptr->URI) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->URI, len); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err iKMS_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->URI) - gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI)); - gf_bs_write_u8(bs, 0); - return GF_OK; -} - -GF_Err iKMS_box_size(GF_Box *s) -{ - GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s; - ptr->size += (ptr->URI ? strlen(ptr->URI) : 0) + 1; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/* ISMASampleFormat Box */ -GF_Box *iSFM_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ISMASampleFormatBox, GF_ISOM_BOX_TYPE_ISFM); - return (GF_Box *)tmp; -} - -void iSFM_box_del(GF_Box *s) -{ - GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err iSFM_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s; - - ISOM_DECREASE_SIZE(ptr, 3); - ptr->selective_encryption = gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 7); - ptr->key_indicator_length = gf_bs_read_u8(bs); - ptr->IV_length = gf_bs_read_u8(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err iSFM_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_int(bs, ptr->selective_encryption, 1); - gf_bs_write_int(bs, 0, 7); - gf_bs_write_u8(bs, ptr->key_indicator_length); - gf_bs_write_u8(bs, ptr->IV_length); - return GF_OK; -} - -GF_Err iSFM_box_size(GF_Box *s) -{ - GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s; - ptr->size += 3; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -/* ISMASampleFormat Box */ -GF_Box *iSLT_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ISMACrypSaltBox, GF_ISOM_BOX_TYPE_ISLT); - return (GF_Box *)tmp; -} - -void iSLT_box_del(GF_Box *s) -{ - GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - - -GF_Err iSLT_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s; - if (ptr == NULL) return GF_BAD_PARAM; - ISOM_DECREASE_SIZE(ptr, 8); - ptr->salt = gf_bs_read_u64(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err iSLT_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u64(bs, ptr->salt); - return GF_OK; -} - -GF_Err iSLT_box_size(GF_Box *s) -{ - s->size += 8; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -/* OMADRMCommonHeader Box */ -GF_Box *ohdr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OMADRMCommonHeaderBox, GF_ISOM_BOX_TYPE_OHDR); - tmp->child_boxes = gf_list_new(); - return (GF_Box *)tmp; -} - -void ohdr_box_del(GF_Box *s) -{ - GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s; - if (ptr == NULL) return; - if (ptr->ContentID) gf_free(ptr->ContentID); - if (ptr->RightsIssuerURL) gf_free(ptr->RightsIssuerURL); - if (ptr->TextualHeaders) gf_free(ptr->TextualHeaders); - gf_free(ptr); -} - -GF_Err ohdr_box_read(GF_Box *s, GF_BitStream *bs) -{ - u16 cid_len, ri_len; - GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s; - - ISOM_DECREASE_SIZE(ptr, (1+1+8+2+2+2) ); - ptr->EncryptionMethod = gf_bs_read_u8(bs); - ptr->PaddingScheme = gf_bs_read_u8(bs); - ptr->PlaintextLength = gf_bs_read_u64(bs); - cid_len = gf_bs_read_u16(bs); - ri_len = gf_bs_read_u16(bs); - ptr->TextualHeadersLen = gf_bs_read_u16(bs); - - if (ptr->sizeTextualHeadersLen) return GF_ISOM_INVALID_FILE; - - if (cid_len) { - ptr->ContentID = (char *)gf_malloc(sizeof(char)*(cid_len+1)); - if (!ptr->ContentID) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->ContentID, cid_len); - ptr->ContentID[cid_len]=0; - } - - if (ri_len) { - ptr->RightsIssuerURL = (char *)gf_malloc(sizeof(char)*(ri_len+1)); - if (!ptr->RightsIssuerURL) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->RightsIssuerURL, ri_len); - ptr->RightsIssuerURL[ri_len]=0; - } - - if (ptr->TextualHeadersLen) { - ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen+1)); - if (!ptr->TextualHeaders) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen); - ptr->TextualHeaders[ptr->TextualHeadersLen] = 0; - } - - ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) ); - - return gf_isom_box_array_read(s, bs, NULL); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err ohdr_box_write(GF_Box *s, GF_BitStream *bs) -{ - u16 cid_len, ri_len; - GF_Err e; - GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->EncryptionMethod); - gf_bs_write_u8(bs, ptr->PaddingScheme); - gf_bs_write_u64(bs, ptr->PlaintextLength); - - cid_len = ptr->ContentID ? (u16) strlen(ptr->ContentID) : 0; - gf_bs_write_u16(bs, cid_len); - ri_len = ptr->RightsIssuerURL ? (u16) strlen(ptr->RightsIssuerURL) : 0; - gf_bs_write_u16(bs, ri_len); - gf_bs_write_u16(bs, ptr->TextualHeadersLen); - - if (cid_len) gf_bs_write_data(bs, ptr->ContentID, (u32) strlen(ptr->ContentID)); - if (ri_len) gf_bs_write_data(bs, ptr->RightsIssuerURL, (u32) strlen(ptr->RightsIssuerURL)); - if (ptr->TextualHeadersLen) gf_bs_write_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen); - - ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) ); - return GF_OK; -} - -GF_Err ohdr_box_size(GF_Box *s) -{ - GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s; - ptr->size += 1+1+8+2+2+2; - if (ptr->ContentID) ptr->size += strlen(ptr->ContentID); - if (ptr->RightsIssuerURL) ptr->size += strlen(ptr->RightsIssuerURL); - if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/* OMADRMGroupID Box */ -GF_Box *grpi_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OMADRMGroupIDBox, GF_ISOM_BOX_TYPE_GRPI); - return (GF_Box *)tmp; -} - -void grpi_box_del(GF_Box *s) -{ - GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s; - if (ptr == NULL) return; - if (ptr->GroupID) gf_free(ptr->GroupID); - if (ptr->GroupKey) gf_free(ptr->GroupKey); - gf_free(ptr); -} - -GF_Err grpi_box_read(GF_Box *s, GF_BitStream *bs) -{ - u16 gid_len; - GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox*)s; - - ISOM_DECREASE_SIZE(ptr, (1+2+2) ); - gid_len = gf_bs_read_u16(bs); - ptr->GKEncryptionMethod = gf_bs_read_u8(bs); - ptr->GKLength = gf_bs_read_u16(bs); - - if (ptr->sizeGKLength) return GF_ISOM_INVALID_FILE; - - ptr->GroupID = gf_malloc(sizeof(char)*(gid_len+1)); - if (!ptr->GroupID) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->GroupID, gid_len); - ptr->GroupID[gid_len]=0; - - ptr->GroupKey = (char *)gf_malloc(sizeof(char)*ptr->GKLength); - if (!ptr->GroupKey) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->GroupKey, ptr->GKLength); - ISOM_DECREASE_SIZE(ptr, (gid_len+ptr->GKLength) ); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err grpi_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u16 gid_len; - GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gid_len = ptr->GroupID ? (u16) strlen(ptr->GroupID) : 0; - gf_bs_write_u16(bs, gid_len); - gf_bs_write_u8(bs, ptr->GKEncryptionMethod); - gf_bs_write_u16(bs, ptr->GKLength); - gf_bs_write_data(bs, ptr->GroupID, gid_len); - gf_bs_write_data(bs, ptr->GroupKey, ptr->GKLength); - return GF_OK; -} - -GF_Err grpi_box_size(GF_Box *s) -{ - GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s; - ptr->size += 2+2+1 + ptr->GKLength; - if (ptr->GroupID) ptr->size += strlen(ptr->GroupID); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -/* OMADRMMutableInformation Box */ -GF_Box *mdri_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OMADRMMutableInformationBox, GF_ISOM_BOX_TYPE_MDRI); - return (GF_Box *)tmp; -} - -void mdri_box_del(GF_Box *s) -{ - GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err mdri_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, NULL); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err mdri_box_write(GF_Box *s, GF_BitStream *bs) -{ -// GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - return GF_OK; -} - -GF_Err mdri_box_size(GF_Box *s) -{ - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - -/* OMADRMTransactionTracking Box */ -GF_Box *odtt_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OMADRMTransactionTrackingBox, GF_ISOM_BOX_TYPE_ODTT); - return (GF_Box *)tmp; -} - -void odtt_box_del(GF_Box *s) -{ - GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s; - gf_free(ptr); -} - -GF_Err odtt_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox *)s; - - gf_bs_read_data(bs, ptr->TransactionID, 16); - ISOM_DECREASE_SIZE(ptr, 16); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err odtt_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_data(bs, ptr->TransactionID, 16); - return GF_OK; -} - -GF_Err odtt_box_size(GF_Box *s) -{ - s->size += 16; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - -/* OMADRMRightsObject Box */ -GF_Box *odrb_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OMADRMRightsObjectBox, GF_ISOM_BOX_TYPE_ODRB); - return (GF_Box *)tmp; -} - -void odrb_box_del(GF_Box *s) -{ - GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s; - if (ptr->oma_ro) gf_free(ptr->oma_ro); - gf_free(ptr); -} - -GF_Err odrb_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s; - - ptr->oma_ro_size = (u32) ptr->size; - ptr->oma_ro = (char*) gf_malloc(sizeof(char)*ptr->oma_ro_size); - if (!ptr->oma_ro) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->oma_ro, ptr->oma_ro_size); - ptr->size = 0; - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err odrb_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_data(bs, ptr->oma_ro, ptr->oma_ro_size); - return GF_OK; -} - -GF_Err odrb_box_size(GF_Box *s) -{ - GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s; - s->size += ptr->oma_ro_size; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -/* OMADRMKMS Box */ -GF_Box *odkm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_OMADRMKMSBox, GF_ISOM_BOX_TYPE_ODKM); - return (GF_Box *)tmp; -} - -void odkm_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err odkm_Add(GF_Box *s, GF_Box *a) -{ - GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_OHDR: - if (ptr->hdr) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->hdr = (GF_OMADRMCommonHeaderBox *)a; - return GF_OK; - case GF_ISOM_BOX_TYPE_ODAF: - if (ptr->fmt) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->fmt = (GF_OMADRMAUFormatBox*)a; - return GF_OK; - } - return GF_OK; -} - -GF_Err odkm_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, odkm_Add); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err odkm_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err odkm_box_size(GF_Box *s) -{ - u32 pos=0; - GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s; - gf_isom_check_position(s, (GF_Box *)ptr->hdr, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->fmt, &pos); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - - - - -GF_Box *pssh_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_PSSH); - return (GF_Box *)tmp; -} - -void pssh_box_del(GF_Box *s) -{ - GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s; - if (ptr == NULL) return; - if (ptr->private_data) gf_free(ptr->private_data); - if (ptr->KIDs) gf_free(ptr->KIDs); - gf_free(ptr); -} - -GF_Err pssh_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *)s; - - gf_bs_read_data(bs, (char *) ptr->SystemID, 16); - ISOM_DECREASE_SIZE(ptr, 16); - if (ptr->version > 0) { - ptr->KID_count = gf_bs_read_u32(bs); - ISOM_DECREASE_SIZE(ptr, 4); - if (ptr->KID_count) { - u32 i; - if (ptr->size < ptr->KID_count * sizeof(bin128)) - return GF_ISOM_INVALID_FILE; - ptr->KIDs = gf_malloc(ptr->KID_count*sizeof(bin128)); - if (!ptr->KIDs) - return GF_OUT_OF_MEM; - for (i=0; iKID_count; i++) { - gf_bs_read_data(bs, (char *) ptr->KIDs[i], 16); - ISOM_DECREASE_SIZE(ptr, 16); - } - } - } - ptr->private_data_size = gf_bs_read_u32(bs); - ISOM_DECREASE_SIZE(ptr, 4); - if (ptr->private_data_size) { - if (ptr->size < ptr->private_data_size) - return GF_ISOM_INVALID_FILE; - ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size); - if (!ptr->private_data) - return GF_OUT_OF_MEM; - gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size); - ISOM_DECREASE_SIZE(ptr, ptr->private_data_size); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err pssh_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_data(bs, (char *) ptr->SystemID, 16); - if (ptr->version > 0) { - u32 i; - gf_bs_write_u32(bs, ptr->KID_count); - for (i=0; iKID_count; i++) - gf_bs_write_data(bs, (char *) ptr->KIDs[i], 16); - } - if (ptr->private_data) { - gf_bs_write_u32(bs, ptr->private_data_size); - gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size); - } else - gf_bs_write_u32(bs, 0); - return GF_OK; -} - -GF_Err pssh_box_size(GF_Box *s) -{ - GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s; - - if (ptr->KID_count && !ptr->version) { - ptr->version = 1; - } - - ptr->size += 16; - if (ptr->version) ptr->size += 4 + 16*ptr->KID_count; - ptr->size += 4 + (ptr->private_data ? ptr->private_data_size : 0); - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - - -GF_Box *tenc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_TrackEncryptionBox, GF_ISOM_BOX_TYPE_TENC); - return (GF_Box *)tmp; -} - -void tenc_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err tenc_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s; - - ISOM_DECREASE_SIZE(ptr, 20); - - gf_bs_read_u8(bs); //reserved - if (!ptr->version) { - gf_bs_read_u8(bs); //reserved - } else { - ptr->crypt_byte_block = gf_bs_read_int(bs, 4); - ptr->skip_byte_block = gf_bs_read_int(bs, 4); - } - ptr->isProtected = gf_bs_read_u8(bs); - ptr->Per_Sample_IV_Size = gf_bs_read_u8(bs); - gf_bs_read_data(bs, (char *) ptr->KID, 16); - - - if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) { - ptr->constant_IV_size = gf_bs_read_u8(bs); - if (ptr->constant_IV_size > sizeof(ptr->constant_IV)) - return GF_ISOM_INVALID_FILE; - - ISOM_DECREASE_SIZE(ptr, (1 + ptr->constant_IV_size) ); - gf_bs_read_data(bs, (char *) ptr->constant_IV, ptr->constant_IV_size); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err tenc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u8(bs, 0x0); //reserved - if (!ptr->version) { - gf_bs_write_u8(bs, 0x0); //reserved - } else { - gf_bs_write_int(bs, ptr->crypt_byte_block, 4); - gf_bs_write_int(bs, ptr->skip_byte_block, 4); - } - gf_bs_write_u8(bs, ptr->isProtected); - gf_bs_write_u8(bs, ptr->Per_Sample_IV_Size); - gf_bs_write_data(bs, (char *) ptr->KID, 16); - if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) { - gf_bs_write_u8(bs, ptr->constant_IV_size); - gf_bs_write_data(bs,(char *) ptr->constant_IV, ptr->constant_IV_size); - } - return GF_OK; -} - -GF_Err tenc_box_size(GF_Box *s) -{ - GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s; - ptr->size += 20; - if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) { - ptr->size += 1 + ptr->constant_IV_size; - } - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *piff_tenc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PIFFTrackEncryptionBox, GF_ISOM_BOX_TYPE_UUID); - tmp->internal_4cc = GF_ISOM_BOX_UUID_TENC; - return (GF_Box *)tmp; -} - -void piff_tenc_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err piff_tenc_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s; - - ISOM_DECREASE_SIZE(ptr, 4); - //PIFF TENC extends UUID and fullbox - ptr->version = gf_bs_read_u8(bs); - ptr->flags = gf_bs_read_u24(bs); - - ISOM_DECREASE_SIZE(ptr, 20); - ptr->AlgorithmID = gf_bs_read_int(bs, 24); - ptr->IV_size = gf_bs_read_u8(bs); - gf_bs_read_data(bs, (char *) ptr->KID, 16); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err piff_tenc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox *) s; - if (!s) return GF_BAD_PARAM; - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->version); - gf_bs_write_u24(bs, ptr->flags); - - gf_bs_write_int(bs, ptr->AlgorithmID, 24); - gf_bs_write_u8(bs, ptr->IV_size); - gf_bs_write_data(bs, (char *) ptr->KID, 16); - return GF_OK; -} - -GF_Err piff_tenc_box_size(GF_Box *s) -{ - GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s; - ptr->size += 24; - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - - -GF_Box *piff_psec_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_UUID); - tmp->internal_4cc = GF_ISOM_BOX_UUID_PSEC; - tmp->is_piff = GF_TRUE; - return (GF_Box *)tmp; -} - -void piff_psec_box_del(GF_Box *s) -{ - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s; - while (gf_list_count(ptr->samp_aux_info)) { - GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0); - if (sai) gf_isom_cenc_samp_aux_info_del(sai); - gf_list_rem(ptr->samp_aux_info, 0); - } - if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info); - gf_free(s); -} - - -GF_Err piff_psec_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - //PIFF PSEC extends UUID and fullbox - ptr->version = gf_bs_read_u8(bs); - ptr->flags = gf_bs_read_u24(bs); - - if (ptr->flags & 1) { - ISOM_DECREASE_SIZE(ptr, 20); - ptr->AlgorithmID = gf_bs_read_int(bs, 24); - ptr->IV_size = gf_bs_read_u8(bs); - gf_bs_read_data(bs, (char *) ptr->KID, 16); - } - if (ptr->IV_size == 0) - ptr->IV_size = 8; //default to 8 - - ptr->bs_offset = gf_bs_get_position(bs); - - /*u32 sample_count = */gf_bs_read_u32(bs); - ISOM_DECREASE_SIZE(ptr, 4); - if (ptr->IV_size != 8 && ptr->IV_size != 16) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] PIFF PSEC box incorrect IV size: %u - shall be 8 or 16\n", ptr->IV_size)); - return GF_BAD_PARAM; - } - //as for senc, we skip parsing of the box until we have all saiz/saio info - gf_bs_skip_bytes(bs, ptr->size); - ptr->size = 0; - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs) -{ - GF_Err e; - u64 pos, new_pos; - if (!ptr->cenc_saio) return GF_OK; - - pos = gf_bs_get_position(bs); - if (pos>0xFFFFFFFFULL) { - if (ptr->cenc_saio && !ptr->cenc_saio->version) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] saio offset larger than 32-bits but box version 0 enforced. Retry without \"saio32\" option\n")); - return GF_BAD_PARAM; - } - } - e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field); - if (e) return e; - //force using version 1 for saio box i.e offset has 64 bits -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - if (ptr->traf) { - new_pos = pos - ptr->traf->moof_start_in_bs; - } else -#endif - { - new_pos = pos; - } - - if (ptr->cenc_saio->offsets) { - u32 i; - u64 old_offset = ptr->cenc_saio->offsets[0]; - for (i=0; icenc_saio->entry_count; i++) { - if (ptr->cenc_saio->version) { - gf_bs_write_u64(bs, new_pos + ptr->cenc_saio->offsets[i] - old_offset); - } else { - gf_bs_write_u32(bs, (u32) (new_pos + ptr->cenc_saio->offsets[i] - old_offset)); - } - ptr->cenc_saio->offsets[i] = new_pos + ptr->cenc_saio->offsets[i] - old_offset; - } - } else { - if (ptr->cenc_saio->version) { - gf_bs_write_u64(bs, new_pos); - } else { - gf_bs_write_u32(bs, (u32) new_pos); - } - } - - return gf_bs_seek(bs, pos); -} - -GF_Err piff_psec_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 sample_count; - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s; - if (!s) return GF_BAD_PARAM; - - sample_count = gf_list_count(ptr->samp_aux_info); - if (!sample_count) { - ptr->size = 0; - return GF_OK; - } - e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->version); - gf_bs_write_u24(bs, ptr->flags); - - if (ptr->flags & 1) { - gf_bs_write_int(bs, ptr->AlgorithmID, 24); - gf_bs_write_u8(bs, ptr->IV_size); - gf_bs_write_data(bs, (char *) ptr->KID, 16); - } - sample_count = gf_list_count(ptr->samp_aux_info); - gf_bs_write_u32(bs, sample_count); - if (sample_count) { - u32 i, j; - e = store_senc_info((GF_SampleEncryptionBox *)ptr, bs); - if (e) return e; - - for (i = 0; i < sample_count; i++) { - GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i); - if (! sai->IV_size) continue; - gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size); - gf_bs_write_u16(bs, sai->subsample_count); - for (j = 0; j < sai->subsample_count; j++) { - gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data); - gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data); - } - } - } - return GF_OK; -} - -GF_Err piff_psec_box_size(GF_Box *s) -{ - u32 i, sample_count; - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s; - - sample_count = gf_list_count(ptr->samp_aux_info); - if (!sample_count) { - ptr->size = 0; - return GF_OK; - } - - ptr->size += 4; - if (ptr->flags & 1) { - ptr->size += 20; - } - ptr->size += 4; - - for (i = 0; i < sample_count; i++) { - GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i); - if (! sai->IV_size) continue; - ptr->size += 2 + sai->IV_size + 6*sai->subsample_count; - } - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - - -GF_Box *piff_pssh_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PIFFProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_UUID); - tmp->internal_4cc = GF_ISOM_BOX_UUID_PSSH; - return (GF_Box *)tmp; -} - -void piff_pssh_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err piff_pssh_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s; - - ISOM_DECREASE_SIZE(ptr, 24); - //PIFF PSSH extends UUID and fullbox - ptr->version = gf_bs_read_u8(bs); - ptr->flags = gf_bs_read_u24(bs); - gf_bs_read_data(bs, (char *) ptr->SystemID, 16); - ptr->private_data_size = gf_bs_read_u32(bs); - - if (ptr->size < sizeof(char)*ptr->private_data_size) - return GF_ISOM_INVALID_FILE; - ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size); - if (!ptr->private_data) - return GF_OUT_OF_MEM; - - ISOM_DECREASE_SIZE(ptr, ptr->private_data_size); - gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err piff_pssh_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s; - GF_Err e = gf_isom_box_write_header(s, bs); - if (e) return e; - gf_bs_write_u8(bs, ptr->version); - gf_bs_write_u24(bs, ptr->flags); - - gf_bs_write_data(bs, (char *) ptr->SystemID, 16); - gf_bs_write_u32(bs, ptr->private_data_size); - gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size); - return GF_OK; -} - -GF_Err piff_pssh_box_size(GF_Box *s) -{ - GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s; - - ptr->size += 24 + ptr->private_data_size; - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *senc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_SENC); - return (GF_Box *)tmp; -} - -void senc_box_del(GF_Box *s) -{ - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s; - while (gf_list_count(ptr->samp_aux_info)) { - GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0); - if (sai) gf_isom_cenc_samp_aux_info_del(sai); - gf_list_rem(ptr->samp_aux_info, 0); - } - if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info); - gf_free(s); -} - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS -GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, GF_TrackFragmentBox *traf, GF_SampleEncryptionBox *senc) -#else -GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, void *traf, GF_SampleEncryptionBox *senc) -#endif -{ - GF_Err e; - Bool parse_failed = GF_FALSE; - u32 i, j, count, sample_number; - u32 senc_size = (u32) senc->size; - u32 subs_size = 0, def_IV_size; - u64 pos = gf_bs_get_position(bs); - Bool do_warn = GF_TRUE; - -#ifdef GPAC_DISABLE_ISOM_FRAGMENTS - if (!traf) - return GF_BAD_PARAM; -#endif - - gf_bs_seek(bs, senc->bs_offset); - - //BOX + version/flags - if (senc_size<12) return GF_BAD_PARAM; - senc_size -= 12; - - if (senc->is_piff) { - //UUID - if (senc_size<16) return GF_BAD_PARAM; - senc_size -= 16; - } - if (senc->flags & 2) subs_size = 8; - - if (senc_size<4) return GF_BAD_PARAM; - - sample_number = 1; -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - if (trak) sample_number += trak->sample_count_at_seg_start; -#endif - - count = gf_bs_read_u32(bs); - senc_size -= 4; - - def_IV_size = 0; - //check the target size if we have one subsample - if (senc_size >= count * (16 + subs_size)) { - def_IV_size = 16; - } - else if (senc_size >= count * (8 + subs_size)) { - def_IV_size = 8; - } - else if (senc_size >= count * (subs_size)) { - def_IV_size = 0; - } - - if (!senc->samp_aux_info) senc->samp_aux_info = gf_list_new(); - for (i=0; iIV_size, NULL, NULL, NULL, NULL, NULL); - if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] could not get cenc info for sample %d: %s\n", sample_number, gf_error_to_string(e) )); - gf_isom_cenc_samp_aux_info_del(sai); - return e; - } - } - //no init movie setup (segment dump/inspaction, assume default encrypted and 16 bytes IV - else { - if (do_warn) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] no moov found, cannot get cenc default info, assuming isEncrypted, IV size %d (computed from senc size)\n", def_IV_size)); - do_warn = GF_FALSE; - } - is_encrypted = GF_TRUE; - sai->IV_size = def_IV_size; - } - if (senc_size < sai->IV_size) { - parse_failed = GF_TRUE; - gf_isom_cenc_samp_aux_info_del(sai); - break; - } - - sample_number++; - - //subsample info is only signaled for encrypted samples - if (is_encrypted) { - if (sai->IV_size > GF_ARRAY_LENGTH(sai->IV)) { - gf_isom_cenc_samp_aux_info_del(sai); - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI size\n" )); - return GF_ISOM_INVALID_FILE; - } - if (sai->IV_size) { - gf_bs_read_data(bs, (char *)sai->IV, sai->IV_size); - senc_size -= sai->IV_size; - } - - if (senc->flags & 0x00000002) { - sai->subsample_count = gf_bs_read_u16(bs); - sai->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sai->subsample_count*sizeof(GF_CENCSubSampleEntry)); - if (!sai->subsamples) return GF_OUT_OF_MEM; - - if ((s32) senc_size < 2 + sai->subsample_count * 6) { - parse_failed = GF_TRUE; - gf_isom_cenc_samp_aux_info_del(sai); - break; - } - - for (j = 0; j < sai->subsample_count; j++) { - if (gf_bs_get_size(bs) - gf_bs_get_position(bs) < 6) { - gf_isom_cenc_samp_aux_info_del(sai); - if (trak && trak->moov && trak->moov->mov && trak->moov->mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) { - gf_bs_seek(bs, pos); - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI size\n" )); - return GF_OK; - } - return GF_ISOM_INVALID_FILE; - } - sai->subsamples[j].bytes_clear_data = gf_bs_read_u16(bs); - sai->subsamples[j].bytes_encrypted_data = gf_bs_read_u32(bs); - } - senc_size -= 2 + sai->subsample_count * 6; - } - } else { - i--; - } - gf_list_add(senc->samp_aux_info, sai); - } - gf_bs_seek(bs, pos); - if (parse_failed) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] cannot parse senc, missing IV/crypto state\n")); - } - return GF_OK; -} - - -GF_Err senc_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s; - ISOM_DECREASE_SIZE(ptr, 4); - //WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS - ptr->version = gf_bs_read_u8(bs); - ptr->flags = gf_bs_read_u24(bs); - - ptr->bs_offset = gf_bs_get_position(bs); - gf_bs_skip_bytes(bs, ptr->size); - ptr->size = 0; - ptr->load_needed = GF_TRUE; - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - - -GF_Err senc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i, j; - u32 sample_count; - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s; - - sample_count = gf_list_count(ptr->samp_aux_info); - if (!sample_count) { - ptr->size = 0; - return GF_OK; - } - - e = gf_isom_box_write_header(s, bs); - if (e) return e; - //WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS - gf_bs_write_u8(bs, ptr->version); - gf_bs_write_u24(bs, ptr->flags); - - gf_bs_write_u32(bs, sample_count); - - e = store_senc_info(ptr, bs); - if (e) return e; - - for (i = 0; i < sample_count; i++) { - GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i); - - //for cbcs scheme, IV_size is 0, constant IV shall be used. It is written in tenc box rather than in sai - if (sai->IV_size) - gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size); - - if (ptr->flags & 0x00000002) { - gf_bs_write_u16(bs, sai->subsample_count); - for (j = 0; j < sai->subsample_count; j++) { - gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data); - gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data); - } - } - } - return GF_OK; -} - -GF_Err senc_box_size(GF_Box *s) -{ - u32 sample_count; - u32 i; - GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s; - sample_count = gf_list_count(ptr->samp_aux_info); - - if (!sample_count) { - ptr->size = 0; - return GF_OK; - } - - //WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS - ptr->size += 4; //version and flags - - ptr->size += 4; //sample count - for (i = 0; i < sample_count; i++) { - GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i); - - ptr->size += sai->IV_size; - - if (ptr->flags & 0x00000002) - ptr->size += 2 + 6*sai->subsample_count; - } - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *adkm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeDRMKeyManagementSystemBox, GF_ISOM_BOX_TYPE_ADKM); - tmp->version = 1; - tmp->flags = 0; - return (GF_Box *)tmp; -} - -void adkm_box_del(GF_Box *s) -{ - GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s; - if (!ptr) return; - gf_free(s); -} - -GF_Err adkm_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_AHDR: - if (ptr->header) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->header = (GF_AdobeDRMHeaderBox *)a; - break; - case GF_ISOM_BOX_TYPE_ADAF: - if (ptr->au_format) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->au_format = (GF_AdobeDRMAUFormatBox *)a; - break; - } - return GF_OK; -} - -GF_Err adkm_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, adkm_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err adkm_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err adkm_box_size(GF_Box *s) -{ - u32 pos=0; - GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s; - gf_isom_check_position(s, (GF_Box *)ptr->header, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->au_format, &pos); - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *ahdr_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeDRMHeaderBox, GF_ISOM_BOX_TYPE_AHDR); - tmp->version = 2; - tmp->flags = 0; - return (GF_Box *)tmp; -} - -void ahdr_box_del(GF_Box *s) -{ - gf_free(s); -} - - -GF_Err ahdr_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_APRM: - if (ptr->std_enc_params) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->std_enc_params = (GF_AdobeStdEncryptionParamsBox *)a; - break; - } - return GF_OK; -} - -GF_Err ahdr_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, ahdr_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err ahdr_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err ahdr_box_size(GF_Box *s) -{ - u32 pos=0; - GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s; - gf_isom_check_position(s, (GF_Box *)ptr->std_enc_params, &pos); - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *aprm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeStdEncryptionParamsBox, GF_ISOM_BOX_TYPE_APRM); - tmp->version = 1; - tmp->flags = 0; - return (GF_Box *)tmp; -} - -void aprm_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err aprm_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_AEIB: - if (ptr->enc_info) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->enc_info = (GF_AdobeEncryptionInfoBox *)a; - break; - case GF_ISOM_BOX_TYPE_AKEY: - if (ptr->key_info) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->key_info = (GF_AdobeKeyInfoBox *)a; - break; - } - return GF_OK; -} - -GF_Err aprm_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, aprm_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err aprm_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err aprm_box_size(GF_Box *s) -{ - u32 pos=0; - GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s; - gf_isom_check_position(s, (GF_Box *)ptr->enc_info, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->key_info, &pos); - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *aeib_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeEncryptionInfoBox, GF_ISOM_BOX_TYPE_AEIB); - tmp->version = 1; - tmp->flags = 0; - return (GF_Box *)tmp; -} - -void aeib_box_del(GF_Box *s) -{ - GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s; - if (!ptr) return; - if (ptr->enc_algo) gf_free(ptr->enc_algo); - gf_free(ptr); -} - -GF_Err aeib_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s; - u32 len; - - len = (u32) ptr->size - 1; - if (len) { - ptr->enc_algo = (char *)gf_malloc(len*sizeof(char)); - if (!ptr->enc_algo) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->enc_algo, len); - } - ptr->key_length = gf_bs_read_u8(bs); - ptr->size = 0; - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err aeib_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->enc_algo) { - gf_bs_write_data(bs, (char *) ptr->enc_algo, (u32) strlen(ptr->enc_algo)); - gf_bs_write_u8(bs, 0); //string end - } - gf_bs_write_u8(bs, ptr->key_length); - return GF_OK; -} - -GF_Err aeib_box_size(GF_Box *s) -{ - GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s; - if (ptr->enc_algo) - ptr->size += strlen(ptr->enc_algo) + 1; - ptr->size += 1; //KeyLength - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *akey_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeKeyInfoBox, GF_ISOM_BOX_TYPE_AKEY); - tmp->version = 1; - tmp->flags = 0; - return (GF_Box *)tmp; -} - -void akey_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err akey_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_FLXS: - if (ptr->params) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->params = (GF_AdobeFlashAccessParamsBox *)a; - break; - } - return GF_OK; -} - -GF_Err akey_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, akey_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err akey_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err akey_box_size(GF_Box *s) -{ - u32 pos=0; - GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s; - gf_isom_check_position(s, (GF_Box *)ptr->params, &pos); - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *flxs_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeFlashAccessParamsBox, GF_ISOM_BOX_TYPE_FLXS); - return (GF_Box *)tmp; -} - -void flxs_box_del(GF_Box *s) -{ - GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s; - if (!ptr) return; - if (ptr->metadata) - gf_free(ptr->metadata); - gf_free(ptr); -} - -GF_Err flxs_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s; - u32 len; - - len = (u32) ptr->size; - if (len) { - ptr->metadata = (char *)gf_malloc(len*sizeof(char)); - if (!ptr->metadata) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->metadata, len); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err flxs_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_box_write_header(s, bs); - if (e) return e; - if (ptr->metadata) { - gf_bs_write_data(bs, ptr->metadata, (u32) strlen(ptr->metadata)); - gf_bs_write_u8(bs, 0); //string end - } - return GF_OK; -} - -GF_Err flxs_box_size(GF_Box *s) -{ - GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s; - if (ptr->metadata) - ptr->size += strlen(ptr->metadata) + 1; - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - -GF_Box *adaf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_AdobeDRMAUFormatBox, GF_ISOM_BOX_TYPE_ADAF); - return (GF_Box *)tmp; -} - -void adaf_box_del(GF_Box *s) -{ - gf_free(s); -} - -GF_Err adaf_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s; - - ISOM_DECREASE_SIZE(ptr, 3); - ptr->selective_enc = gf_bs_read_u8(bs); - gf_bs_read_u8(bs);//resersed - ptr->IV_length = gf_bs_read_u8(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err adaf_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox *) s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - - gf_bs_write_u8(bs, ptr->selective_enc); - gf_bs_write_u8(bs, 0x0); - gf_bs_write_u8(bs, ptr->IV_length); - return GF_OK; -} - -GF_Err adaf_box_size(GF_Box *s) -{ - GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s; - ptr->size += 3; - return GF_OK; -} -#endif //GPAC_DISABLE_ISOM_WRITE - - -#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/thirdparty/gpacmp4/box_code_meta.c b/src/thirdparty/gpacmp4/box_code_meta.c deleted file mode 100644 index 1d54fa665..000000000 --- a/src/thirdparty/gpacmp4/box_code_meta.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Cyril Concolato / Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2005-2019 - * All rights reserved - * - * This file is part of GPAC / ISO Media File Format sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include - -#ifndef GPAC_DISABLE_ISOM - -GF_Box *meta_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_MetaBox, GF_ISOM_BOX_TYPE_META); - tmp->child_boxes = gf_list_new(); - return (GF_Box *)tmp; -} - -void meta_reset(GF_Box *s) -{ - GF_MetaBox *ptr = (GF_MetaBox *)s; - if (ptr == NULL) return; - - //destroy all boxes - if (ptr->child_boxes) gf_isom_box_array_del(ptr->child_boxes); - ptr->child_boxes = NULL; - - //reset pointers (destroyed above) - ptr->handler = NULL; - ptr->primary_resource = NULL; - ptr->file_locations = NULL; - ptr->item_locations = NULL; - ptr->protections = NULL; - ptr->item_infos = NULL; - ptr->IPMP_control = NULL; - ptr->item_refs = NULL; - ptr->item_props = NULL; -} - -void meta_box_del(GF_Box *s) -{ - meta_reset(s); - gf_free(s); -} - - -GF_Err meta_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_MetaBox *ptr = (GF_MetaBox *)s; - switch (a->type) { - case GF_ISOM_BOX_TYPE_HDLR: - if (ptr->handler) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->handler = (GF_HandlerBox*)a; - break; - case GF_ISOM_BOX_TYPE_PITM: - if (ptr->primary_resource) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->primary_resource = (GF_PrimaryItemBox*)a; - break; - case GF_ISOM_BOX_TYPE_DINF: - if (ptr->file_locations) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->file_locations = (GF_DataInformationBox*)a; - break; - case GF_ISOM_BOX_TYPE_ILOC: - if (ptr->item_locations) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->item_locations = (GF_ItemLocationBox*)a; - break; - case GF_ISOM_BOX_TYPE_IPRO: - if (ptr->protections) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->protections = (GF_ItemProtectionBox*)a; - break; - case GF_ISOM_BOX_TYPE_IINF: - if (ptr->item_infos) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->item_infos = (GF_ItemInfoBox*)a; - break; - case GF_ISOM_BOX_TYPE_IREF: - if (ptr->item_refs) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->item_refs = (GF_ItemReferenceBox*)a; - break; - case GF_ISOM_BOX_TYPE_IPRP: - if (ptr->item_props) ERROR_ON_DUPLICATED_BOX(a, ptr) - ptr->item_props = (GF_ItemPropertiesBox*)a; - break; - } - return GF_OK; -} - -GF_Err meta_box_read(GF_Box *s, GF_BitStream *bs) -{ - u64 pos = gf_bs_get_position(bs); - u64 size = s->size; - GF_Err e = gf_isom_box_array_read(s, bs, meta_on_child_box); - /*try to hack around QT files which don't use a full box for meta, rewind 4 bytes*/ - if (e && (pos>4) ) { - gf_bs_seek(bs, pos-4); - meta_reset(s); - s->size = size+4; - e = gf_isom_box_array_read(s, bs, meta_on_child_box); - } - return e; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err meta_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err meta_box_size(GF_Box *s) -{ - u32 pos=0; - GF_MetaBox *ptr = (GF_MetaBox *)s; - - gf_isom_check_position(s, (GF_Box *)ptr->handler, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->primary_resource, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->file_locations, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->item_locations, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->protections, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->item_infos, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->item_refs, &pos); - gf_isom_check_position(s, (GF_Box *)ptr->item_props, &pos); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *xml_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_XMLBox, GF_ISOM_BOX_TYPE_XML); - return (GF_Box *)tmp; -} - -void xml_box_del(GF_Box *s) -{ - GF_XMLBox *ptr = (GF_XMLBox *)s; - if (ptr == NULL) return; - if (ptr->xml) gf_free(ptr->xml); - gf_free(ptr); -} - -GF_Err xml_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_XMLBox *ptr = (GF_XMLBox *)s; - return gf_isom_read_null_terminated_string(s, bs, s->size, &ptr->xml); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err xml_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_XMLBox *ptr = (GF_XMLBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->xml) gf_bs_write_data(bs, ptr->xml, (u32) strlen(ptr->xml)); - gf_bs_write_u8(bs, 0); - return GF_OK; -} - -GF_Err xml_box_size(GF_Box *s) -{ - GF_XMLBox *ptr = (GF_XMLBox *)s; - if (!s) return GF_BAD_PARAM; - ptr->size += (ptr->xml ? strlen(ptr->xml) : 0) + 1; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *bxml_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_BinaryXMLBox, GF_ISOM_BOX_TYPE_BXML); - return (GF_Box *)tmp; -} - -void bxml_box_del(GF_Box *s) -{ - GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s; - if (ptr == NULL) return; - if (ptr->data_length && ptr->data) gf_free(ptr->data); - gf_free(ptr); -} - -GF_Err bxml_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s; - - ptr->data_length = (u32)(ptr->size); - ptr->data = (char*)gf_malloc(sizeof(char)*ptr->data_length); - if (!ptr->data) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ptr->data, ptr->data_length); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err bxml_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->data_length) gf_bs_write_data(bs, ptr->data, ptr->data_length); - return GF_OK; -} - -GF_Err bxml_box_size(GF_Box *s) -{ - GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s; - if (!s) return GF_BAD_PARAM; - ptr->size += ptr->data_length; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *iloc_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ItemLocationBox, GF_ISOM_BOX_TYPE_ILOC); - tmp->location_entries = gf_list_new(); - return (GF_Box *)tmp; -} - -void iloc_entry_del(GF_ItemLocationEntry *location) -{ - u32 j, extent_count; - extent_count = gf_list_count(location->extent_entries); - for (j = 0; j < extent_count; j++) { - GF_ItemExtentEntry *extent = (GF_ItemExtentEntry *)gf_list_get(location->extent_entries, j); - gf_free(extent); - } - gf_list_del(location->extent_entries); - gf_free(location); -} - -void iloc_box_del(GF_Box *s) -{ - u32 i, item_count; - GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s; - if (ptr == NULL) return; - item_count = gf_list_count(ptr->location_entries); - for (i = 0; i < item_count; i++) { - GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i); - iloc_entry_del(location); - } - gf_list_del(ptr->location_entries); - gf_free(ptr); -} - -GF_Err iloc_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 item_count, extent_count, i, j; - GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s; - - ISOM_DECREASE_SIZE(ptr, 2) - ptr->offset_size = gf_bs_read_int(bs, 4); - ptr->length_size = gf_bs_read_int(bs, 4); - ptr->base_offset_size = gf_bs_read_int(bs, 4); - if (ptr->version == 1 || ptr->version == 2) { - ptr->index_size = gf_bs_read_int(bs, 4); - } else { - gf_bs_read_int(bs, 4); - } - if (ptr->version < 2) { - ISOM_DECREASE_SIZE(ptr, 2) - item_count = gf_bs_read_u16(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 4) - item_count = gf_bs_read_u32(bs); - } - - for (i = 0; i < item_count; i++) { - GF_ItemLocationEntry *location_entry = (GF_ItemLocationEntry *)gf_malloc(sizeof(GF_ItemLocationEntry)); - if (!location_entry) return GF_OUT_OF_MEM; - - gf_list_add(ptr->location_entries, location_entry); - if (ptr->version < 2) { - ISOM_DECREASE_SIZE(ptr, 2) - location_entry->item_ID = gf_bs_read_u16(bs); - } else { - ISOM_DECREASE_SIZE(ptr, 4) - location_entry->item_ID = gf_bs_read_u32(bs); - } - if (ptr->version == 1 || ptr->version == 2) { - ISOM_DECREASE_SIZE(ptr, 2) - location_entry->construction_method = gf_bs_read_u16(bs); - } - else { - location_entry->construction_method = 0; - } - ISOM_DECREASE_SIZE(ptr, (2 + ptr->base_offset_size) ) - location_entry->data_reference_index = gf_bs_read_u16(bs); - location_entry->base_offset = gf_bs_read_int(bs, 8*ptr->base_offset_size); -#ifndef GPAC_DISABLE_ISOM_WRITE - location_entry->original_base_offset = location_entry->base_offset; -#endif - - ISOM_DECREASE_SIZE(ptr, 2) - extent_count = gf_bs_read_u16(bs); - location_entry->extent_entries = gf_list_new(); - for (j = 0; j < extent_count; j++) { - GF_ItemExtentEntry *extent_entry = (GF_ItemExtentEntry *)gf_malloc(sizeof(GF_ItemExtentEntry)); - if (!extent_entry) return GF_OUT_OF_MEM; - - gf_list_add(location_entry->extent_entries, extent_entry); - if ((ptr->version == 1 || ptr->version == 2) && ptr->index_size > 0) { - ISOM_DECREASE_SIZE(ptr, ptr->index_size) - extent_entry->extent_index = gf_bs_read_int(bs, 8 * ptr->index_size); - } - else { - extent_entry->extent_index = 0; - } - ISOM_DECREASE_SIZE(ptr, (ptr->offset_size+ptr->length_size) ) - - extent_entry->extent_offset = gf_bs_read_int(bs, 8*ptr->offset_size); - extent_entry->extent_length = gf_bs_read_int(bs, 8*ptr->length_size); -#ifndef GPAC_DISABLE_ISOM_WRITE - extent_entry->original_extent_offset = extent_entry->extent_offset; -#endif - } - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err iloc_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i, j, item_count, extent_count; - GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_int(bs, ptr->offset_size, 4); - gf_bs_write_int(bs, ptr->length_size, 4); - gf_bs_write_int(bs, ptr->base_offset_size, 4); - gf_bs_write_int(bs, ptr->index_size, 4); - item_count = gf_list_count(ptr->location_entries); - if (ptr->version < 2) { - gf_bs_write_u16(bs, item_count); - } - else { - gf_bs_write_u32(bs, item_count); - } - for (i = 0; i < item_count; i++) { - GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i); - if (ptr->version < 2) { - gf_bs_write_u16(bs, location->item_ID); - } - else { - gf_bs_write_u32(bs, location->item_ID); - } - if (ptr->version == 1 || ptr->version == 2) { - gf_bs_write_u16(bs, location->construction_method); - } - gf_bs_write_u16(bs, location->data_reference_index); - gf_bs_write_long_int(bs, location->base_offset, 8*ptr->base_offset_size); - extent_count = gf_list_count(location->extent_entries); - gf_bs_write_u16(bs, extent_count); - for (j=0; jextent_entries, j); - if ((ptr->version == 1 || ptr->version == 2) && ptr->index_size > 0) { - gf_bs_write_long_int(bs, extent->extent_index, 8 * ptr->index_size); - } - gf_bs_write_long_int(bs, extent->extent_offset, 8*ptr->offset_size); - gf_bs_write_long_int(bs, extent->extent_length, 8*ptr->length_size); - } - } - return GF_OK; -} - -GF_Err iloc_box_size(GF_Box *s) -{ - u32 i, item_count, extent_count; - GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s; - if (!s) return GF_BAD_PARAM; - if (ptr->index_size) { - ptr->version = 1; - } - item_count = gf_list_count(ptr->location_entries); - for (i = 0; i < item_count; i++) { - GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i); - if (location->construction_method) { - ptr->version = 1; - } - if (location->item_ID > 0xFFFF) { - ptr->version = 2; - } - } - ptr->size += 4; - if (ptr->version == 2) { - ptr->size += 2; // 32 bits item count instead of 16 bits - } - for (i = 0; i < item_count; i++) { - GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i); - extent_count = gf_list_count(location->extent_entries); - ptr->size += 6 + ptr->base_offset_size + extent_count*(ptr->offset_size + ptr->length_size); - if (ptr->version == 2) { - ptr->size += 2; //32 bits item ID instead of 16 bits - } - if (ptr->version == 1 || ptr->version == 2) { - ptr->size += 2; // construction_method - ptr->size += extent_count*ptr->index_size; - } - } - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *pitm_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_PrimaryItemBox, GF_ISOM_BOX_TYPE_PITM); - return (GF_Box *)tmp; -} - -void pitm_box_del(GF_Box *s) -{ - GF_PrimaryItemBox *ptr = (GF_PrimaryItemBox *)s; - if (ptr == NULL) return; - gf_free(ptr); -} - -GF_Err pitm_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_PrimaryItemBox *ptr = (GF_PrimaryItemBox *)s; - ISOM_DECREASE_SIZE(ptr, 2) - ptr->item_ID = gf_bs_read_u16(bs); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err pitm_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - GF_PrimaryItemBox *ptr = (GF_PrimaryItemBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - gf_bs_write_u16(bs, ptr->item_ID); - return GF_OK; -} - -GF_Err pitm_box_size(GF_Box *s) -{ - GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s; - if (!s) return GF_BAD_PARAM; - ptr->size += 2; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *ipro_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ItemProtectionBox, GF_ISOM_BOX_TYPE_IPRO); - tmp->protection_information = gf_list_new(); - return (GF_Box *)tmp; -} - -void ipro_box_del(GF_Box *s) -{ - GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s; - if (ptr == NULL) return; - gf_list_del(ptr->protection_information); - gf_free(ptr); -} - -GF_Err ipro_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s; - if (a->type == GF_ISOM_BOX_TYPE_SINF) - return gf_list_add(ptr->protection_information, a); - - return GF_OK; -} -GF_Err ipro_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read(s, bs, ipro_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err ipro_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 count; - GF_Err e; - GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - count = gf_list_count(ptr->protection_information); - gf_bs_write_u16(bs, count); - return GF_OK; -} - -GF_Err ipro_box_size(GF_Box *s) -{ - GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s; - u32 pos=0; - gf_isom_check_position_list(s, ptr->protection_information, &pos); - s->size += 2; - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *infe_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ItemInfoEntryBox, GF_ISOM_BOX_TYPE_INFE); - return (GF_Box *)tmp; -} - -void infe_box_del(GF_Box *s) -{ - GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s; - if (ptr == NULL) return; - if (ptr->item_name) gf_free(ptr->item_name); - if (ptr->full_path) gf_free(ptr->full_path); - if (ptr->content_type) gf_free(ptr->content_type); - if (ptr->content_encoding) gf_free(ptr->content_encoding); - gf_free(ptr); -} - -GF_Err infe_box_read(GF_Box *s, GF_BitStream *bs) -{ - char *buf; - u32 buf_len, i, string_len, string_start; - GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4); - ptr->item_ID = gf_bs_read_u16(bs); - ptr->item_protection_index = gf_bs_read_u16(bs); - - if (ptr->version == 2) { - ISOM_DECREASE_SIZE(ptr, 4); - ptr->item_type = gf_bs_read_u32(bs); - } - buf_len = (u32) (ptr->size); - buf = (char*)gf_malloc(buf_len); - if (!buf) return GF_OUT_OF_MEM; - if (buf_len != gf_bs_read_data(bs, buf, buf_len)) { - gf_free(buf); - return GF_ISOM_INVALID_FILE; - } - string_len = 1; - string_start = 0; - for (i = 0; i < buf_len; i++) { - if (buf[i] == 0) { - if (!ptr->item_name) { - ptr->item_name = (char*)gf_malloc(sizeof(char)*string_len); - if (!ptr->item_name) return GF_OUT_OF_MEM; - memcpy(ptr->item_name, buf+string_start, string_len); - } else if (!ptr->content_type) { - ptr->content_type = (char*)gf_malloc(sizeof(char)*string_len); - if (!ptr->content_type) return GF_OUT_OF_MEM; - memcpy(ptr->content_type, buf+string_start, string_len); - } else { - ptr->content_encoding = (char*)gf_malloc(sizeof(char)*string_len); - if (!ptr->content_encoding) return GF_OUT_OF_MEM; - memcpy(ptr->content_encoding, buf+string_start, string_len); - } - string_start += string_len; - string_len = 0; - if (ptr->content_encoding && ptr->version == 1) { - break; - } - } - string_len++; - } - gf_free(buf); - if (!ptr->item_name || (!ptr->content_type && ptr->version < 2)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isoff] Infe without name or content type !\n")); - } - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err infe_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 len; - GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - if (ptr->version == 3) { - gf_bs_write_u32(bs, ptr->item_ID); - } - else { - gf_bs_write_u16(bs, ptr->item_ID); - } - gf_bs_write_u16(bs, ptr->item_protection_index); - if (ptr->version >= 2) { - gf_bs_write_u32(bs, ptr->item_type); - } - if (ptr->item_name) { - len = (u32) strlen(ptr->item_name)+1; - gf_bs_write_data(bs, ptr->item_name, len); - } else { - gf_bs_write_byte(bs, 0, 1); - } - if (ptr->item_type == GF_META_ITEM_TYPE_MIME || ptr->item_type == GF_META_ITEM_TYPE_URI) { - if (ptr->content_type) { - len = (u32)strlen(ptr->content_type) + 1; - gf_bs_write_data(bs, ptr->content_type, len); - } - else { - gf_bs_write_byte(bs, 0, 1); - } - } - if (ptr->item_type == GF_META_ITEM_TYPE_MIME) { - if (ptr->content_encoding) { - len = (u32)strlen(ptr->content_encoding) + 1; - gf_bs_write_data(bs, ptr->content_encoding, len); - } - else { - gf_bs_write_byte(bs, 0, 1); - } - } - return GF_OK; -} - -GF_Err infe_box_size(GF_Box *s) -{ - GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s; - if (!s) return GF_BAD_PARAM; - if (ptr->item_type) { - ptr->version = 2; - if (ptr->item_ID > 0xFFFF) { - ptr->version = 3; - } - } - else { - ptr->version = 0; - } - ptr->size += 4; - if (ptr->version == 3) { - ptr->size += 2; // item_ID on 32 bits (+2 bytes) - } - if (ptr->version >= 2) { - ptr->size += 4; // item_type size - } - if (ptr->item_name) ptr->size += strlen(ptr->item_name)+1; - else ptr->size += 1; - if (ptr->item_type == GF_META_ITEM_TYPE_MIME || ptr->item_type == GF_META_ITEM_TYPE_URI) { - if (ptr->content_type) ptr->size += strlen(ptr->content_type) + 1; - else ptr->size += 1; - } - if (ptr->item_type == GF_META_ITEM_TYPE_MIME) { - if (ptr->content_encoding) ptr->size += strlen(ptr->content_encoding) + 1; - else ptr->size += 1; - } - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Box *iinf_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ItemInfoBox, GF_ISOM_BOX_TYPE_IINF); - tmp->item_infos = gf_list_new(); - return (GF_Box *)tmp; -} - -void iinf_box_del(GF_Box *s) -{ - GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s; - if (ptr == NULL) return; - gf_list_del(ptr->item_infos); - gf_free(ptr); -} - -GF_Err iinf_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s; - - if (a->type == GF_ISOM_BOX_TYPE_INFE) { - return gf_list_add(ptr->item_infos, a); - } else { - return GF_OK; - } -} - -GF_Err iinf_box_read(GF_Box *s, GF_BitStream *bs) -{ - GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s; - - if (ptr->version == 0) { - ISOM_DECREASE_SIZE(s, 2) - gf_bs_read_u16(bs); - } else { - ISOM_DECREASE_SIZE(s, 4) - gf_bs_read_u32(bs); - } - return gf_isom_box_array_read(s, bs, iinf_on_child_box); -} - -#ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err iinf_box_write(GF_Box *s, GF_BitStream *bs) -{ - u32 count; - GF_Err e; - GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s; - if (!s) return GF_BAD_PARAM; - e = gf_isom_full_box_write(s, bs); - if (e) return e; - count = gf_list_count(ptr->item_infos); - if (ptr->version == 0) - gf_bs_write_u16(bs, count); - else - gf_bs_write_u32(bs, count); - - return GF_OK; -} - -GF_Err iinf_box_size(GF_Box *s) -{ - u32 pos=0; - GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s; - if (!s) return GF_BAD_PARAM; - ptr->size += (ptr->version == 0) ? 2 : 4; - gf_isom_check_position_list(s, ptr->item_infos, &pos); - return GF_OK; -} -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -GF_Err iref_on_child_box(GF_Box *s, GF_Box *a) -{ - GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s; - return gf_list_add(ptr->references, a); -} - -void iref_box_del(GF_Box *s) -{ - GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s; - if (ptr == NULL) return; - gf_list_del(ptr->references); - gf_free(ptr); -} - - -GF_Err iref_box_read(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_box_array_read_ex(s, bs, iref_on_child_box, s->type); -} - -GF_Box *iref_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ItemReferenceBox, GF_ISOM_BOX_TYPE_IREF); - tmp->references = gf_list_new(); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err iref_box_write(GF_Box *s, GF_BitStream *bs) -{ - return gf_isom_full_box_write(s, bs); -} - -GF_Err iref_box_size(GF_Box *s) -{ - u32 pos=0; - GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s; - gf_isom_check_position_list(s, ptr->references, &pos); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -void ireftype_box_del(GF_Box *s) -{ - GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s; - if (!ptr) return; - if (ptr->to_item_IDs) gf_free(ptr->to_item_IDs); - gf_free(ptr); -} - -GF_Err ireftype_box_read(GF_Box *s, GF_BitStream *bs) -{ - u32 i; - GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s; - - ISOM_DECREASE_SIZE(ptr, 4) - ptr->from_item_id = gf_bs_read_u16(bs); - ptr->reference_count = gf_bs_read_u16(bs); - if (ptr->size < ptr->reference_count*2) - return GF_ISOM_INVALID_FILE; - - ptr->to_item_IDs = (u32 *)gf_malloc(ptr->reference_count * sizeof(u32)); - if (!ptr->to_item_IDs) return GF_OUT_OF_MEM; - - for (i=0; i < ptr->reference_count; i++) { - ISOM_DECREASE_SIZE(ptr, 2) - ptr->to_item_IDs[i] = gf_bs_read_u16(bs); - } - return GF_OK; -} - -GF_Box *ireftype_box_new() -{ - ISOM_DECL_BOX_ALLOC(GF_ItemReferenceTypeBox, GF_ISOM_BOX_TYPE_REFI); - return (GF_Box *)tmp; -} - -#ifndef GPAC_DISABLE_ISOM_WRITE - -GF_Err ireftype_box_write(GF_Box *s, GF_BitStream *bs) -{ - GF_Err e; - u32 i; - GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s; - ptr->type = ptr->reference_type; - e = gf_isom_box_write_header(s, bs); - ptr->type = GF_ISOM_BOX_TYPE_REFI; - if (e) return e; - gf_bs_write_u16(bs, ptr->from_item_id); - gf_bs_write_u16(bs, ptr->reference_count); - for (i = 0; i < ptr->reference_count; i++) { - gf_bs_write_u16(bs, ptr->to_item_IDs[i]); - } - return GF_OK; -} - - -GF_Err ireftype_box_size(GF_Box *s) -{ - GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s; - ptr->size += 4 + (ptr->reference_count * sizeof(u16)); - return GF_OK; -} - -#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#endif /*GPAC_DISABLE_ISOM*/ - diff --git a/src/thirdparty/gpacmp4/box_dump.c b/src/thirdparty/gpacmp4/box_dump.c deleted file mode 100644 index 699a908f7..000000000 --- a/src/thirdparty/gpacmp4/box_dump.c +++ /dev/null @@ -1,5790 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2000-2020 - * All rights reserved - * - * This file is part of GPAC / ISO Media File Format sub-project - * - * GPAC is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * GPAC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include - -#ifndef GPAC_DISABLE_ISOM_DUMP - - -static void dump_data(FILE *trace, char *data, u32 dataLength) -{ - u32 i; - gf_fprintf(trace, "data:application/octet-string,"); - for (i=0; i': - gf_fprintf(trace, ">"); - break; - case '<': - gf_fprintf(trace, "<"); - break; - default: - gf_fprintf(trace, "%c", (u8) data[i]); - break; - } - } -} - - -GF_Err gf_isom_box_array_dump(GF_List *list, FILE * trace) -{ - u32 i; - GF_Box *a; - if (!list) return GF_OK; - i=0; - while ((a = (GF_Box *)gf_list_enum(list, &i))) { - gf_isom_box_dump(a, trace); - } - return GF_OK; -} - -static Bool dump_skip_samples = GF_FALSE; -GF_EXPORT -GF_Err gf_isom_dump(GF_ISOFile *mov, FILE * trace, Bool skip_init, Bool skip_samples) -{ - u32 i; - const char *fname; - GF_Box *box; - if (!mov || !trace) return GF_BAD_PARAM; - - gf_fprintf(trace, "\n"); - - fname = strrchr(mov->fileName, '/'); - if (!fname) fname = strrchr(mov->fileName, '\\'); - if (!fname) fname = mov->fileName; - else fname+=1; - gf_fprintf(trace, "\n", fname); - - dump_skip_samples = skip_samples; - i=0; - if (skip_init) - i = mov->nb_box_init_seg; - - while ((box = (GF_Box *)gf_list_enum(mov->TopBoxes, &i))) { - if (box->type==GF_ISOM_BOX_TYPE_UNKNOWN) { - gf_fprintf(trace, "\n"); - } else if (box->type==GF_ISOM_BOX_TYPE_UUID) { - } else if (!gf_isom_box_is_file_level(box)) { - gf_fprintf(trace, "\n", gf_4cc_to_str(box->type)); - } - gf_isom_box_dump(box, trace); - } - gf_fprintf(trace, "\n"); - return GF_OK; -} - -GF_Err reftype_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_TrackReferenceTypeBox *p = (GF_TrackReferenceTypeBox *)a; - if (!p->reference_type) return GF_OK; - p->type = p->reference_type; - - gf_isom_box_dump_start(a, "TrackReferenceTypeBox", trace); - gf_fprintf(trace, ">\n"); - for (i=0; itrackIDCount; i++) { - gf_fprintf(trace, "\n", p->trackIDs[i]); - } - if (!p->size) - gf_fprintf(trace, "\n"); - - gf_isom_box_dump_done("TrackReferenceTypeBox", a, trace); - p->type = GF_ISOM_BOX_TYPE_REFT; - return GF_OK; -} - -GF_Err ireftype_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_ItemReferenceTypeBox *p = (GF_ItemReferenceTypeBox *)a; - if (!p->reference_type) return GF_OK; - - p->type = p->reference_type; - gf_isom_box_dump_start(a, "ItemReferenceBox", trace); - gf_fprintf(trace, "from_item_id=\"%d\">\n", p->from_item_id); - for (i = 0; i < p->reference_count; i++) { - gf_fprintf(trace, "\n", p->to_item_IDs[i]); - } - if (!p->size) - gf_fprintf(trace, "\n"); - - gf_isom_box_dump_done("ItemReferenceBox", a, trace); - - p->type = GF_ISOM_BOX_TYPE_REFI; - return GF_OK; -} - -GF_Err free_box_dump(GF_Box *a, FILE * trace) -{ - GF_FreeSpaceBox *p = (GF_FreeSpaceBox *)a; - gf_isom_box_dump_start(a, (a->type==GF_ISOM_BOX_TYPE_FREE) ? "FreeSpaceBox" : "SkipBox", trace); - gf_fprintf(trace, "dataSize=\"%d\">\n", p->dataSize); - gf_isom_box_dump_done( (a->type==GF_ISOM_BOX_TYPE_FREE) ? "FreeSpaceBox" : "SkipBox", a, trace); - return GF_OK; -} - -GF_Err wide_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "WideBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("WideBox", a, trace); - return GF_OK; -} - -GF_Err mdat_box_dump(GF_Box *a, FILE * trace) -{ - GF_MediaDataBox *p; - const char *name = (a->type==GF_ISOM_BOX_TYPE_IDAT ? "ItemDataBox" : "MediaDataBox"); - p = (GF_MediaDataBox *)a; - gf_isom_box_dump_start(a, name, trace); - gf_fprintf(trace, "dataSize=\""LLD"\">\n", p->dataSize); - gf_isom_box_dump_done(name, a, trace); - return GF_OK; -} - -GF_Err moov_box_dump(GF_Box *a, FILE * trace) -{ - GF_MovieBox *p = (GF_MovieBox *) a; - gf_isom_box_dump_start(a, "MovieBox", trace); - if (p->compressed_diff) - gf_fprintf(trace, "compressedSize=\""LLU"\"", p->size - p->compressed_diff); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MovieBox", a, trace); - return GF_OK; -} - -GF_Err mvhd_box_dump(GF_Box *a, FILE * trace) -{ - GF_MovieHeaderBox *p; - - p = (GF_MovieHeaderBox *) a; - - gf_isom_box_dump_start(a, "MovieHeaderBox", trace); - gf_fprintf(trace, "CreationTime=\""LLD"\" ", p->creationTime); - gf_fprintf(trace, "ModificationTime=\""LLD"\" ", p->modificationTime); - gf_fprintf(trace, "TimeScale=\"%d\" ", p->timeScale); - gf_fprintf(trace, "Duration=\""LLD"\" ", p->duration); - gf_fprintf(trace, "NextTrackID=\"%d\">\n", p->nextTrackID); - - gf_isom_box_dump_done("MovieHeaderBox", a, trace); - return GF_OK; -} - -GF_Err mdhd_box_dump(GF_Box *a, FILE * trace) -{ - GF_MediaHeaderBox *p; - - p = (GF_MediaHeaderBox *)a; - gf_isom_box_dump_start(a, "MediaHeaderBox", trace); - gf_fprintf(trace, "CreationTime=\""LLD"\" ", p->creationTime); - gf_fprintf(trace, "ModificationTime=\""LLD"\" ", p->modificationTime); - gf_fprintf(trace, "TimeScale=\"%d\" ", p->timeScale); - gf_fprintf(trace, "Duration=\""LLD"\" ", p->duration); - gf_fprintf(trace, "LanguageCode=\"%c%c%c\">\n", p->packedLanguage[0], p->packedLanguage[1], p->packedLanguage[2]); - gf_isom_box_dump_done("MediaHeaderBox", a, trace); - return GF_OK; -} - -GF_Err vmhd_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "VideoMediaHeaderBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("VideoMediaHeaderBox", a, trace); - return GF_OK; -} - -GF_Err gmin_box_dump(GF_Box *a, FILE * trace) -{ - GF_GenericMediaHeaderInfoBox *p = (GF_GenericMediaHeaderInfoBox *)a; - gf_isom_box_dump_start(a, "GenericMediaHeaderInformationBox", trace); - gf_fprintf(trace, " graphicsMode=\"%d\" opcolorRed=\"%d\" opcolorGreen=\"%d\" opcolorBlue=\"%d\" balance=\"%d\">\n", - p->graphics_mode, p->op_color_red, p->op_color_green, p->op_color_blue, p->balance); - gf_isom_box_dump_done("GenericMediaHeaderInformationBox", a, trace); - return GF_OK; -} - -GF_Err clef_box_dump(GF_Box *a, FILE * trace) -{ - Float w, h; - const char *name = "TrackCleanApertureDimensionsBox"; - GF_ApertureBox *p = (GF_ApertureBox *)a; - if (p->type==GF_QT_BOX_TYPE_PROF) - name = "TrackProductionApertureDimensionsBox"; - else if (p->type==GF_QT_BOX_TYPE_ENOF) - name = "TrackEncodedPixelsDimensionsBox"; - - gf_isom_box_dump_start(a, name, trace); - w = (Float) (p->width&0xFFFF); - w /= 0xFFFF; - w += (p->width>>16); - - h = (Float) (p->height&0xFFFF); - h /= 0xFFFF; - h += (p->height>>16); - - gf_fprintf(trace, " width=\"%g\" height=\"%g\">\n", w, h); - gf_isom_box_dump_done(name, a, trace); - return GF_OK; -} - -GF_Err smhd_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "SoundMediaHeaderBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("SoundMediaHeaderBox", a, trace); - return GF_OK; -} - -GF_Err hmhd_box_dump(GF_Box *a, FILE * trace) -{ - GF_HintMediaHeaderBox *p; - - p = (GF_HintMediaHeaderBox *)a; - - gf_isom_box_dump_start(a, "HintMediaHeaderBox", trace); - gf_fprintf(trace, "MaximumPDUSize=\"%d\" ", p->maxPDUSize); - gf_fprintf(trace, "AveragePDUSize=\"%d\" ", p->avgPDUSize); - gf_fprintf(trace, "MaxBitRate=\"%d\" ", p->maxBitrate); - gf_fprintf(trace, "AverageBitRate=\"%d\">\n", p->avgBitrate); - - gf_isom_box_dump_done("HintMediaHeaderBox", a, trace); - return GF_OK; -} - -GF_Err nmhd_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "MPEGMediaHeaderBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MPEGMediaHeaderBox", a, trace); - return GF_OK; -} - -GF_Err stbl_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "SampleTableBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("SampleTableBox", a, trace); - return GF_OK; -} - -GF_Err dinf_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "DataInformationBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("DataInformationBox", a, trace); - return GF_OK; -} - -GF_Err url_box_dump(GF_Box *a, FILE * trace) -{ - GF_DataEntryURLBox *p; - - p = (GF_DataEntryURLBox *)a; - gf_isom_box_dump_start(a, "URLDataEntryBox", trace); - if (p->location) { - gf_fprintf(trace, " URL=\"%s\">\n", p->location); - } else { - gf_fprintf(trace, ">\n"); - if (p->size) { - if (! (p->flags & 1) ) { - gf_fprintf(trace, "\n"); - } else { - gf_fprintf(trace, "\n"); - } - } - } - gf_isom_box_dump_done("URLDataEntryBox", a, trace); - return GF_OK; -} - -GF_Err urn_box_dump(GF_Box *a, FILE * trace) -{ - GF_DataEntryURNBox *p; - - p = (GF_DataEntryURNBox *)a; - gf_isom_box_dump_start(a, "URNDataEntryBox", trace); - if (p->nameURN) gf_fprintf(trace, " URN=\"%s\"", p->nameURN); - if (p->location) gf_fprintf(trace, " URL=\"%s\"", p->location); - gf_fprintf(trace, ">\n"); - - gf_isom_box_dump_done("URNDataEntryBox", a, trace); - return GF_OK; -} - -GF_Err alis_box_dump(GF_Box *a, FILE * trace) -{ -// GF_DataEntryAliasBox *p = (GF_DataEntryAliasBox *)a; - gf_isom_box_dump_start(a, "AliasDataEntryBox", trace); - gf_fprintf(trace, ">\n"); - - gf_isom_box_dump_done("AliasDataEntryBox", a, trace); - return GF_OK; -} - -GF_Err cprt_box_dump(GF_Box *a, FILE * trace) -{ - GF_CopyrightBox *p; - - p = (GF_CopyrightBox *)a; - gf_isom_box_dump_start(a, "CopyrightBox", trace); - gf_fprintf(trace, "LanguageCode=\"%s\" CopyrightNotice=\"%s\">\n", p->packedLanguageCode, p->notice); - gf_isom_box_dump_done("CopyrightBox", a, trace); - return GF_OK; -} - -GF_Err kind_box_dump(GF_Box *a, FILE * trace) -{ - GF_KindBox *p; - - p = (GF_KindBox *)a; - gf_isom_box_dump_start(a, "KindBox", trace); - gf_fprintf(trace, "schemeURI=\"%s\" value=\"%s\">\n", p->schemeURI, (p->value ? p->value : "")); - gf_isom_box_dump_done("KindBox", a, trace); - return GF_OK; -} - - -static char *format_duration(u64 dur, u32 timescale, char *szDur) -{ - u32 h, m, s, ms; - if (!timescale) return NULL; - dur = (u32) (( ((Double) (s64) dur)/timescale)*1000); - h = (u32) (dur / 3600000); - dur -= h*3600000; - m = (u32) (dur / 60000); - dur -= m*60000; - s = (u32) (dur/1000); - dur -= s*1000; - ms = (u32) (dur); - - if (h<=24) { - sprintf(szDur, "%02d:%02d:%02d.%03d", h, m, s, ms); - } else { - u32 d = (u32) (dur / 3600000 / 24); - h = (u32) (dur/3600000)-24*d; - if (d<=365) { - sprintf(szDur, "%d Days, %02d:%02d:%02d.%03d", d, h, m, s, ms); - } else { - u32 y=0; - while (d>365) { - y++; - d-=365; - if (y%4) d--; - } - sprintf(szDur, "%d Years %d Days, %02d:%02d:%02d.%03d", y, d, h, m, s, ms); - } - } - return szDur; -} - -static void dump_escape_string(FILE * trace, char *name) -{ - u32 i, len = name ? (u32) strlen(name) : 0; - for (i=0; i\n"); - - if (p->size) { - count = gf_list_count(p->list); - for (i=0; ilist, i); - gf_fprintf(trace, "name); - gf_fprintf(trace, "\" startTime=\"%s\" />\n", format_duration(ce->start_time, 1000*10000, szDur)); - } - } else { - gf_fprintf(trace, "\n"); - } -#ifdef GPAC_ENABLE_COVERAGE - if (gf_sys_is_cov_mode()) { - format_duration(0, 0, NULL); - dump_escape_string(NULL, NULL); - } -#endif - gf_isom_box_dump_done("ChapterListBox", a, trace); - return GF_OK; -} - -GF_Err pdin_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_ProgressiveDownloadBox *p = (GF_ProgressiveDownloadBox *)a; - gf_isom_box_dump_start(a, "ProgressiveDownloadBox", trace); - gf_fprintf(trace, ">\n"); - - if (p->size) { - for (i=0; icount; i++) { - gf_fprintf(trace, "\n", p->rates[i], p->times[i]); - } - } else { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("ProgressiveDownloadBox", a, trace); - return GF_OK; -} - -GF_Err hdlr_box_dump(GF_Box *a, FILE * trace) -{ - GF_HandlerBox *p = (GF_HandlerBox *)a; - gf_isom_box_dump_start(a, "HandlerBox", trace); - if (p->nameUTF8 && (u32) p->nameUTF8[0] == strlen(p->nameUTF8)-1) { - gf_fprintf(trace, "hdlrType=\"%s\" Name=\"%s\" ", gf_4cc_to_str(p->handlerType), p->nameUTF8+1); - } else { - gf_fprintf(trace, "hdlrType=\"%s\" Name=\"%s\" ", gf_4cc_to_str(p->handlerType), p->nameUTF8); - } - gf_fprintf(trace, "reserved1=\"%d\" reserved2=\"", p->reserved1); - dump_data(trace, (char *) p->reserved2, 12); - gf_fprintf(trace, "\""); - - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("HandlerBox", a, trace); - return GF_OK; -} - -GF_Err iods_box_dump(GF_Box *a, FILE * trace) -{ - GF_ObjectDescriptorBox *p; - - p = (GF_ObjectDescriptorBox *)a; - gf_isom_box_dump_start(a, "ObjectDescriptorBox", trace); - gf_fprintf(trace, ">\n"); - - if (p->descriptor) { -#ifndef GPAC_DISABLE_OD_DUMP - gf_odf_dump_desc(p->descriptor, trace, 1, GF_TRUE); -#else - gf_fprintf(trace, "\n"); -#endif - } else if (p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("ObjectDescriptorBox", a, trace); - return GF_OK; -} - -GF_Err trak_box_dump(GF_Box *a, FILE * trace) -{ - GF_TrackBox *p; - - p = (GF_TrackBox *)a; - gf_isom_box_dump_start(a, "TrackBox", trace); - gf_fprintf(trace, ">\n"); - if (p->size && !p->Header) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("TrackBox", a, trace); - return GF_OK; -} - -GF_Err mp4s_box_dump(GF_Box *a, FILE * trace) -{ - GF_MPEGSampleEntryBox *p; - - p = (GF_MPEGSampleEntryBox *)a; - gf_isom_box_dump_start(a, "MPEGSystemsSampleDescriptionBox", trace); - gf_fprintf(trace, "DataReferenceIndex=\"%d\">\n", p->dataReferenceIndex); - if (!p->esd && p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("MPEGSystemsSampleDescriptionBox", a, trace); - return GF_OK; -} - - -GF_Err video_sample_entry_box_dump(GF_Box *a, FILE * trace) -{ - Bool full_dump=GF_FALSE; - GF_MPEGVisualSampleEntryBox *p = (GF_MPEGVisualSampleEntryBox *)a; - const char *name; - - switch (p->type) { - case GF_ISOM_SUBTYPE_AVC_H264: - case GF_ISOM_SUBTYPE_AVC2_H264: - case GF_ISOM_SUBTYPE_AVC3_H264: - case GF_ISOM_SUBTYPE_AVC4_H264: - name = "AVCSampleEntryBox"; - break; - case GF_ISOM_SUBTYPE_MVC_H264: - name = "MVCSampleEntryBox"; - break; - case GF_ISOM_SUBTYPE_SVC_H264: - name = "SVCSampleEntryBox"; - break; - case GF_ISOM_SUBTYPE_HVC1: - case GF_ISOM_SUBTYPE_HEV1: - case GF_ISOM_SUBTYPE_HVC2: - case GF_ISOM_SUBTYPE_HEV2: - name = "HEVCSampleEntryBox"; - break; - case GF_ISOM_SUBTYPE_LHV1: - case GF_ISOM_SUBTYPE_LHE1: - name = "LHEVCSampleEntryBox"; - break; - case GF_ISOM_SUBTYPE_AV01: - name = "AV1SampleEntryBox"; - break; - case GF_ISOM_SUBTYPE_3GP_H263: - name = "H263SampleDescriptionBox"; - break; - case GF_ISOM_SUBTYPE_MJP2: - name = "MJ2KSampleDescriptionBox"; - 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: - name = "ProResSampleEntryBox"; - full_dump=GF_TRUE; - break; - case GF_QT_SUBTYPE_RAW: - name = "RGBSampleEntryBox"; - full_dump=GF_TRUE; - break; - case GF_QT_SUBTYPE_YUV422: - name = "YUV422SampleEntryBox"; - full_dump=GF_TRUE; - break; - case GF_QT_SUBTYPE_YUV422_10: - name = "YUV422_10_SampleEntryBox"; - full_dump=GF_TRUE; - break; - case GF_QT_SUBTYPE_YUV444: - name = "YUV444SampleEntryBox"; - full_dump=GF_TRUE; - break; - case GF_QT_SUBTYPE_YUV444_10: - name = "YUV444_10_SampleEntryBox"; - full_dump=GF_TRUE; - break; - default: - //DO NOT TOUCH FOR NOW, this breaks all hashes - name = "MPEGVisualSampleDescriptionBox"; - break; - } - - - gf_isom_box_dump_start(a, name, trace); - - gf_fprintf(trace, " DataReferenceIndex=\"%d\" Width=\"%d\" Height=\"%d\"", p->dataReferenceIndex, p->Width, p->Height); - - if (full_dump) { - Float dpih, dpiv; - gf_fprintf(trace, " Version=\"%d\" Revision=\"%d\" Vendor=\"%s\" TemporalQuality=\"%d\" SpatialQuality=\"%d\" FramesPerSample=\"%d\" ColorTableIndex=\"%d\"", - p->version, p->revision, gf_4cc_to_str(p->vendor), p->temporal_quality, p->spatial_quality, p->frames_per_sample, p->color_table_index); - - dpih = (Float) (p->horiz_res&0xFFFF); - dpih /= 0xFFFF; - dpih += (p->vert_res>>16); - dpiv = (Float) (p->vert_res&0xFFFF); - dpiv /= 0xFFFF; - dpiv += (p->vert_res>>16); - - gf_fprintf(trace, " XDPI=\"%g\" YDPI=\"%g\" BitDepth=\"%d\"", dpih, dpiv, p->bit_depth); - } else { - //dump reserved info - gf_fprintf(trace, " XDPI=\"%d\" YDPI=\"%d\" BitDepth=\"%d\"", p->horiz_res, p->vert_res, p->bit_depth); - } - if (strlen((const char*)p->compressor_name) ) { - if (isalnum(p->compressor_name[0])) { - gf_fprintf(trace, " CompressorName=\"%s\"\n", p->compressor_name); - } else { - gf_fprintf(trace, " CompressorName=\"%s\"\n", p->compressor_name+1); - } - } - - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done(name, a, trace); - return GF_OK; -} - - -void base_audio_entry_dump(GF_AudioSampleEntryBox *p, FILE * trace) -{ - gf_fprintf(trace, " DataReferenceIndex=\"%d\"", p->dataReferenceIndex); - if (p->version) - gf_fprintf(trace, " Version=\"%d\"", p->version); - gf_fprintf(trace, " SampleRate=\"%d\"", p->samplerate_hi); - gf_fprintf(trace, " Channels=\"%d\" BitsPerSample=\"%d\"", p->channel_count, p->bitspersample); - if (p->qtff_mode) { - gf_fprintf(trace, " isQTFF=\"%d\"", p->qtff_mode); - gf_fprintf(trace, " qtRevisionLevel=\"%d\"", p->revision); - gf_fprintf(trace, " qtVendor=\"%d\"", p->vendor); - gf_fprintf(trace, " qtCompressionId=\"%d\"", p->compression_id); - gf_fprintf(trace, " qtPacketSize=\"%d\"", p->packet_size); - if (p->version == 1) { - gf_fprintf(trace, " qtSamplesPerPacket=\"%d\"", p->extensions[0]<<24 | p->extensions[1]<<16 | p->extensions[2]<<8 | p->extensions[3]); - gf_fprintf(trace, " qtBytesPerPacket=\"%d\"", p->extensions[4]<<24 | p->extensions[5]<<16 | p->extensions[6]<<8 | p->extensions[7]); - gf_fprintf(trace, " qtBytesPerFrame=\"%d\"", p->extensions[8]<<24 | p->extensions[9]<<16 | p->extensions[10]<<8 | p->extensions[11]); - gf_fprintf(trace, " qtBytesPerSample=\"%d\"", p->extensions[12]<<24 | p->extensions[13]<<16 | p->extensions[14]<<8 | p->extensions[15]); - } - } -} - -GF_Err audio_sample_entry_box_dump(GF_Box *a, FILE * trace) -{ - char *szName; - const char *error=NULL; - GF_MPEGAudioSampleEntryBox *p = (GF_MPEGAudioSampleEntryBox *)a; - - switch (p->type) { - case GF_ISOM_SUBTYPE_3GP_AMR: - szName = "AMRSampleDescriptionBox"; - if (!p->cfg_3gpp) - error = ""; - break; - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - szName = "AMR_WB_SampleDescriptionBox"; - if (!p->cfg_3gpp) - error = ""; - break; - case GF_ISOM_SUBTYPE_3GP_EVRC: - szName = "EVRCSampleDescriptionBox"; - if (!p->cfg_3gpp) - error = ""; - break; - case GF_ISOM_SUBTYPE_3GP_QCELP: - szName = "QCELPSampleDescriptionBox"; - if (!p->cfg_3gpp) - error = ""; - break; - case GF_ISOM_SUBTYPE_3GP_SMV: - szName = "SMVSampleDescriptionBox"; - if (!p->cfg_3gpp) - error = ""; - break; - case GF_ISOM_BOX_TYPE_MP4A: - szName = "MPEGAudioSampleDescriptionBox"; - if (!p->esd) - error = ""; - break; - case GF_ISOM_BOX_TYPE_AC3: - szName = "AC3SampleEntryBox"; - if (!p->cfg_ac3) - error = ""; - break; - case GF_ISOM_BOX_TYPE_EC3: - szName = "EC3SampleEntryBox"; - if (!p->cfg_ac3) - error = ""; - break; - case GF_ISOM_BOX_TYPE_MHA1: - case GF_ISOM_BOX_TYPE_MHA2: - if (!p->cfg_mha) - error = ""; - case GF_ISOM_BOX_TYPE_MHM1: - case GF_ISOM_BOX_TYPE_MHM2: - szName = "MHASampleEntry"; - break; - default: - szName = "AudioSampleDescriptionBox"; - break; - } - - gf_isom_box_dump_start(a, szName, trace); - base_audio_entry_dump((GF_AudioSampleEntryBox *)p, trace); - gf_fprintf(trace, ">\n"); - - if (error) { - gf_fprintf(trace, "%s\n", error); - } - gf_isom_box_dump_done(szName, a, trace); - return GF_OK; -} - -GF_Err gen_sample_entry_box_dump(GF_Box *a, FILE * trace) -{ - char *szName; - GF_SampleEntryBox *p = (GF_SampleEntryBox *)a; - - switch (p->type) { - case GF_QT_SUBTYPE_C608: - szName = "ClosedCaption"; - break; - default: - szName = "GenericSampleDescriptionBox"; - break; - } - - gf_isom_box_dump_start(a, szName, trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done(szName, a, trace); - return GF_OK; -} - -GF_Err gnrm_box_dump(GF_Box *a, FILE * trace) -{ - GF_GenericSampleEntryBox *p = (GF_GenericSampleEntryBox *)a; - if (p->EntryType) - a->type = p->EntryType; - - gf_isom_box_dump_start(a, "SampleDescriptionEntryBox", trace); - gf_fprintf(trace, "DataReferenceIndex=\"%d\" ExtensionDataSize=\"%d\">\n", p->dataReferenceIndex, p->data_size); - a->type = GF_ISOM_BOX_TYPE_GNRM; - gf_isom_box_dump_done("SampleDescriptionEntryBox", a, trace); - return GF_OK; -} - -GF_Err gnrv_box_dump(GF_Box *a, FILE * trace) -{ - GF_GenericVisualSampleEntryBox *p = (GF_GenericVisualSampleEntryBox *)a; - if (p->EntryType) - a->type = p->EntryType; - - gf_isom_box_dump_start(a, "VisualSampleDescriptionBox", trace); - gf_fprintf(trace, "DataReferenceIndex=\"%d\" Version=\"%d\" Revision=\"%d\" Vendor=\"%d\" TemporalQuality=\"%d\" SpacialQuality=\"%d\" Width=\"%d\" Height=\"%d\" HorizontalResolution=\"%d\" VerticalResolution=\"%d\" CompressorName=\"%s\" BitDepth=\"%d\">\n", - p->dataReferenceIndex, p->version, p->revision, p->vendor, p->temporal_quality, p->spatial_quality, p->Width, p->Height, p->horiz_res, p->vert_res, isalnum(p->compressor_name[0]) ? p->compressor_name : p->compressor_name+1, p->bit_depth); - a->type = GF_ISOM_BOX_TYPE_GNRV; - gf_isom_box_dump_done("VisualSampleDescriptionBox", a, trace); - return GF_OK; -} - -GF_Err gnra_box_dump(GF_Box *a, FILE * trace) -{ - GF_GenericAudioSampleEntryBox *p = (GF_GenericAudioSampleEntryBox *)a; - if (p->EntryType) - a->type = p->EntryType; - - gf_isom_box_dump_start(a, "AudioSampleDescriptionBox", trace); - gf_fprintf(trace, "DataReferenceIndex=\"%d\" Version=\"%d\" Revision=\"%d\" Vendor=\"%d\" ChannelCount=\"%d\" BitsPerSample=\"%d\" Samplerate=\"%d\">\n", - p->dataReferenceIndex, p->version, p->revision, p->vendor, p->channel_count, p->bitspersample, p->samplerate_hi); - a->type = GF_ISOM_BOX_TYPE_GNRA; - gf_isom_box_dump_done("AudioSampleDescriptionBox", a, trace); - return GF_OK; -} - -GF_Err edts_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "EditBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("EditBox", a, trace); - return GF_OK; -} - -GF_Err udta_box_dump(GF_Box *a, FILE * trace) -{ - GF_UserDataBox *p; - GF_UserDataMap *map; - u32 i; - - p = (GF_UserDataBox *)a; - gf_isom_box_dump_start(a, "UserDataBox", trace); - gf_fprintf(trace, ">\n"); - - i=0; - while ((map = (GF_UserDataMap *)gf_list_enum(p->recordList, &i))) { - gf_isom_box_array_dump(map->boxes, trace); - } - gf_isom_box_dump_done("UserDataBox", a, trace); - return GF_OK; -} - -GF_Err dref_box_dump(GF_Box *a, FILE * trace) -{ -// GF_DataReferenceBox *p = (GF_DataReferenceBox *)a; - gf_isom_box_dump_start(a, "DataReferenceBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("DataReferenceBox", a, trace); - return GF_OK; -} - -GF_Err stsd_box_dump(GF_Box *a, FILE * trace) -{ - GF_SampleDescriptionBox *p = (GF_SampleDescriptionBox *)a; - gf_isom_box_dump_start(a, "SampleDescriptionBox", trace); - if (p->version) - gf_fprintf(trace, " version=\"%d\"", p->version); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("SampleDescriptionBox", a, trace); - return GF_OK; -} - -GF_Err stts_box_dump(GF_Box *a, FILE * trace) -{ - GF_TimeToSampleBox *p; - u32 i, nb_samples; - - if (dump_skip_samples) - return GF_OK; - - p = (GF_TimeToSampleBox *)a; - gf_isom_box_dump_start(a, "TimeToSampleBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->nb_entries); - - nb_samples = 0; - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", p->entries[i].sampleDelta, p->entries[i].sampleCount); - nb_samples += p->entries[i].sampleCount; - } - if (p->size) - gf_fprintf(trace, "\n", nb_samples); - else - gf_fprintf(trace, "\n"); - - gf_isom_box_dump_done("TimeToSampleBox", a, trace); - return GF_OK; -} - -GF_Err ctts_box_dump(GF_Box *a, FILE * trace) -{ - GF_CompositionOffsetBox *p; - u32 i, nb_samples; - p = (GF_CompositionOffsetBox *)a; - - if (dump_skip_samples) - return GF_OK; - - gf_isom_box_dump_start(a, "CompositionOffsetBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->nb_entries); - - nb_samples = 0; - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", p->entries[i].decodingOffset, p->entries[i].sampleCount); - nb_samples += p->entries[i].sampleCount; - } - if (p->size) - gf_fprintf(trace, "\n", nb_samples); - else - gf_fprintf(trace, "\n"); - - gf_isom_box_dump_done("CompositionOffsetBox", a, trace); - return GF_OK; -} - -GF_Err cslg_box_dump(GF_Box *a, FILE * trace) -{ - GF_CompositionToDecodeBox *p; - - p = (GF_CompositionToDecodeBox *)a; - gf_isom_box_dump_start(a, "CompositionToDecodeBox", trace); - gf_fprintf(trace, "compositionToDTSShift=\"%d\" leastDecodeToDisplayDelta=\"%d\" greatestDecodeToDisplayDelta=\"%d\" compositionStartTime=\"%d\" compositionEndTime=\"%d\">\n", p->compositionToDTSShift, p->leastDecodeToDisplayDelta, p->greatestDecodeToDisplayDelta, p->compositionStartTime, p->compositionEndTime); - gf_isom_box_dump_done("CompositionToDecodeBox", a, trace); - return GF_OK; -} - -GF_Err ccst_box_dump(GF_Box *a, FILE * trace) -{ - GF_CodingConstraintsBox *p = (GF_CodingConstraintsBox *)a; - gf_isom_box_dump_start(a, "CodingConstraintsBox", trace); - gf_fprintf(trace, "all_ref_pics_intra=\"%d\" intra_pred_used=\"%d\" max_ref_per_pic=\"%d\" reserved=\"%d\">\n", p->all_ref_pics_intra, p->intra_pred_used, p->max_ref_per_pic, p->reserved); - gf_isom_box_dump_done("CodingConstraintsBox", a, trace); - return GF_OK; -} - -GF_Err stsh_box_dump(GF_Box *a, FILE * trace) -{ - GF_ShadowSyncBox *p; - u32 i; - GF_StshEntry *t; - - p = (GF_ShadowSyncBox *)a; - gf_isom_box_dump_start(a, "SyncShadowBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", gf_list_count(p->entries)); - i=0; - while ((t = (GF_StshEntry *)gf_list_enum(p->entries, &i))) { - gf_fprintf(trace, "\n", t->shadowedSampleNumber, t->syncSampleNumber); - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("SyncShadowBox", a, trace); - return GF_OK; -} - -GF_Err elst_box_dump(GF_Box *a, FILE * trace) -{ - GF_EditListBox *p; - u32 i; - GF_EdtsEntry *t; - - p = (GF_EditListBox *)a; - gf_isom_box_dump_start(a, "EditListBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", gf_list_count(p->entryList)); - - i=0; - while ((t = (GF_EdtsEntry *)gf_list_enum(p->entryList, &i))) { - gf_fprintf(trace, "\n", t->segmentDuration, t->mediaTime, t->mediaRate); - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("EditListBox", a, trace); - return GF_OK; -} - -GF_Err stsc_box_dump(GF_Box *a, FILE * trace) -{ - GF_SampleToChunkBox *p; - u32 i, nb_samples; - - if (dump_skip_samples) - return GF_OK; - - p = (GF_SampleToChunkBox *)a; - gf_isom_box_dump_start(a, "SampleToChunkBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->nb_entries); - - nb_samples = 0; - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", p->entries[i].firstChunk, p->entries[i].samplesPerChunk, p->entries[i].sampleDescriptionIndex); - if (i+1nb_entries) { - nb_samples += (p->entries[i+1].firstChunk - p->entries[i].firstChunk) * p->entries[i].samplesPerChunk; - } else { - nb_samples += p->entries[i].samplesPerChunk; - } - } - if (p->size) - gf_fprintf(trace, "\n", nb_samples); - else - gf_fprintf(trace, "\n"); - - gf_isom_box_dump_done("SampleToChunkBox", a, trace); - return GF_OK; -} - -GF_Err stsz_box_dump(GF_Box *a, FILE * trace) -{ - GF_SampleSizeBox *p; - u32 i; - p = (GF_SampleSizeBox *)a; - if (dump_skip_samples) - return GF_OK; - - if (a->type == GF_ISOM_BOX_TYPE_STSZ) { - gf_isom_box_dump_start(a, "SampleSizeBox", trace); - } - else { - gf_isom_box_dump_start(a, "CompactSampleSizeBox", trace); - } - - gf_fprintf(trace, "SampleCount=\"%d\"", p->sampleCount); - if (a->type == GF_ISOM_BOX_TYPE_STSZ) { - if (p->sampleSize) { - gf_fprintf(trace, " ConstantSampleSize=\"%d\"", p->sampleSize); - } - } else { - gf_fprintf(trace, " SampleSizeBits=\"%d\"", p->sampleSize); - } - gf_fprintf(trace, ">\n"); - - if ((a->type != GF_ISOM_BOX_TYPE_STSZ) || !p->sampleSize) { - if (!p->sizes && p->size) { - gf_fprintf(trace, "\n"); - } else if (p->sizes) { - for (i=0; isampleCount; i++) { - gf_fprintf(trace, "\n", p->sizes[i]); - } - } - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done((a->type == GF_ISOM_BOX_TYPE_STSZ) ? "SampleSizeBox" : "CompactSampleSizeBox", a, trace); - return GF_OK; -} - -GF_Err stco_box_dump(GF_Box *a, FILE * trace) -{ - GF_ChunkOffsetBox *p; - u32 i; - - if (dump_skip_samples) - return GF_OK; - - p = (GF_ChunkOffsetBox *)a; - gf_isom_box_dump_start(a, "ChunkOffsetBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->nb_entries); - - if (!p->offsets && p->size) { - gf_fprintf(trace, "\n"); - } else if (p->offsets) { - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", p->offsets[i]); - } - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("ChunkOffsetBox", a, trace); - return GF_OK; -} - -GF_Err stss_box_dump(GF_Box *a, FILE * trace) -{ - GF_SyncSampleBox *p; - u32 i; - - if (dump_skip_samples) - return GF_OK; - - p = (GF_SyncSampleBox *)a; - gf_isom_box_dump_start(a, "SyncSampleBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->nb_entries); - - if (!p->sampleNumbers && p->size) { - gf_fprintf(trace, "\n"); - } else if (p->sampleNumbers) { - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", p->sampleNumbers[i]); - } - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("SyncSampleBox", a, trace); - return GF_OK; -} - -GF_Err stdp_box_dump(GF_Box *a, FILE * trace) -{ - GF_DegradationPriorityBox *p; - u32 i; - - if (dump_skip_samples) - return GF_OK; - - p = (GF_DegradationPriorityBox *)a; - gf_isom_box_dump_start(a, "DegradationPriorityBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->nb_entries); - - if (!p->priorities && p->size) { - gf_fprintf(trace, "\n"); - } else if (p->priorities) { - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", p->priorities[i]); - } - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("DegradationPriorityBox", a, trace); - return GF_OK; -} - -GF_Err sdtp_box_dump(GF_Box *a, FILE * trace) -{ - GF_SampleDependencyTypeBox *p; - u32 i; - - if (dump_skip_samples) - return GF_OK; - - p = (GF_SampleDependencyTypeBox*)a; - gf_isom_box_dump_start(a, "SampleDependencyTypeBox", trace); - gf_fprintf(trace, "SampleCount=\"%d\">\n", p->sampleCount); - - if (!p->sample_info) { - gf_fprintf(trace, "\n"); - } else { - for (i=0; isampleCount; i++) { - const char *type; - u8 flag = p->sample_info[i]; - gf_fprintf(trace, "> 6) & 3) { - case 1: type="openGOP"; break; - case 2: type="no"; break; - case 3: type="SAP2"; break; - default: - case 0: type="unknown"; break; - } - gf_fprintf(trace, "isLeading=\"%s\" ", type); - - switch ( (flag >> 4) & 3) { - case 1: type="yes"; break; - case 2: type="no"; break; - case 3: type="RESERVED"; break; - default: - case 0: type="unknown"; break; - } - gf_fprintf(trace, "dependsOnOther=\"%s\" ", type); - - switch ( (flag >> 2) & 3) { - case 1: type="yes"; break; - case 2: type="no"; break; - case 3: type="RESERVED"; break; - default: - case 0: type="unknown"; break; - } - gf_fprintf(trace, "dependedOn=\"%s\" ", type); - - switch ( flag & 3) { - case 1: type="yes"; break; - case 2: type="no"; break; - case 3: type="RESERVED"; break; - default: - case 0: type="unknown"; break; - } - gf_fprintf(trace, "hasRedundancy=\"%s\"/>\n", type); - } - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("SampleDependencyTypeBox", a, trace); - return GF_OK; -} - -GF_Err co64_box_dump(GF_Box *a, FILE * trace) -{ - GF_ChunkLargeOffsetBox *p; - u32 i; - - if (dump_skip_samples) - return GF_OK; - - p = (GF_ChunkLargeOffsetBox *)a; - gf_isom_box_dump_start(a, "ChunkLargeOffsetBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->nb_entries); - - if (!p->offsets && p->size) { - gf_fprintf(trace, "\n"); -#endif - } else if (p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("MPEG4ESDescriptorBox", a, trace); - return GF_OK; -} - -GF_Err minf_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "MediaInformationBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MediaInformationBox", a, trace); - return GF_OK; -} - -GF_Err tkhd_box_dump(GF_Box *a, FILE * trace) -{ - GF_TrackHeaderBox *p; - p = (GF_TrackHeaderBox *)a; - gf_isom_box_dump_start(a, "TrackHeaderBox", trace); - - gf_fprintf(trace, "CreationTime=\""LLD"\" ModificationTime=\""LLD"\" TrackID=\"%u\" Duration=\""LLD"\"", - p->creationTime, p->modificationTime, p->trackID, p->duration); - - if (p->alternate_group) gf_fprintf(trace, " AlternateGroupID=\"%d\"", p->alternate_group); - if (p->volume) { - gf_fprintf(trace, " Volume=\"%.2f\"", (Float)p->volume / 256); - } else if (p->width || p->height) { - gf_fprintf(trace, " Width=\"%.2f\" Height=\"%.2f\"", (Float)p->width / 65536, (Float)p->height / 65536); - if (p->layer) gf_fprintf(trace, " Layer=\"%d\"", p->layer); - } - gf_fprintf(trace, ">\n"); - if (p->width || p->height) { - gf_fprintf(trace, "matrix[0], p->matrix[1], p->matrix[2]); - gf_fprintf(trace, "m21=\"0x%.8x\" m22=\"0x%.8x\" m23=\"0x%.8x\" ", p->matrix[3], p->matrix[4], p->matrix[5]); - gf_fprintf(trace, "m31=\"0x%.8x\" m32=\"0x%.8x\" m33=\"0x%.8x\"/>\n", p->matrix[6], p->matrix[7], p->matrix[8]); - } - - gf_isom_box_dump_done("TrackHeaderBox", a, trace); - return GF_OK; -} - -GF_Err tref_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "TrackReferenceBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("TrackReferenceBox", a, trace); - return GF_OK; -} - -GF_Err mdia_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "MediaBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MediaBox", a, trace); - return GF_OK; -} - -GF_Err mfra_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "MovieFragmentRandomAccessBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MovieFragmentRandomAccessBox", a, trace); - return GF_OK; -} - -GF_Err tfra_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_TrackFragmentRandomAccessBox *p = (GF_TrackFragmentRandomAccessBox *)a; - gf_isom_box_dump_start(a, "TrackFragmentRandomAccessBox", trace); - gf_fprintf(trace, "TrackId=\"%u\" number_of_entries=\"%u\">\n", p->track_id, p->nb_entries); - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", - p->entries[i].time, p->entries[i].moof_offset, - p->entries[i].traf_number, p->entries[i].trun_number, p->entries[i].sample_number); - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("TrackFragmentRandomAccessBox", a, trace); - return GF_OK; -} - -GF_Err mfro_box_dump(GF_Box *a, FILE * trace) -{ - GF_MovieFragmentRandomAccessOffsetBox *p = (GF_MovieFragmentRandomAccessOffsetBox *)a; - - gf_isom_box_dump_start(a, "MovieFragmentRandomAccessOffsetBox", trace); - - gf_fprintf(trace, "container_size=\"%d\" >\n", p->container_size); - gf_isom_box_dump_done("MovieFragmentRandomAccessOffsetBox", a, trace); - return GF_OK; -} - - -GF_Err elng_box_dump(GF_Box *a, FILE * trace) -{ - GF_ExtendedLanguageBox *p = (GF_ExtendedLanguageBox *)a; - gf_isom_box_dump_start(a, "ExtendedLanguageBox", trace); - gf_fprintf(trace, "LanguageCode=\"%s\">\n", p->extended_language); - gf_isom_box_dump_done("ExtendedLanguageBox", a, trace); - return GF_OK; -} - -GF_Err unkn_box_dump(GF_Box *a, FILE * trace) -{ - const char *name = "UnknownBox"; - GF_UnknownBox *u = (GF_UnknownBox *)a; - if (!a->type && (a->size==8)) - name = "TerminatorBox"; - - gf_isom_box_dump_start(a, name, trace); - - if (u->dataSize && u->dataSize<100) - dump_data_attribute(trace, "data", u->data, u->dataSize); - - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done(name, a, trace); -#ifdef GPAC_ENABLE_COVERAGE - if (gf_sys_is_cov_mode()) { - dump_data_string(NULL, NULL, 0); - } -#endif - return GF_OK; -} - -GF_Err uuid_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "UUIDBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("UUIDBox", a, trace); - return GF_OK; -} - -GF_Err void_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "VoidBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("VoidBox", a, trace); - return GF_OK; -} - -GF_Err ftyp_box_dump(GF_Box *a, FILE * trace) -{ - GF_FileTypeBox *p; - u32 i; - - p = (GF_FileTypeBox *)a; - gf_isom_box_dump_start(a, (a->type == GF_ISOM_BOX_TYPE_FTYP ? "FileTypeBox" : "SegmentTypeBox"), trace); - gf_fprintf(trace, "MajorBrand=\"%s\" MinorVersion=\"%d\">\n", gf_4cc_to_str(p->majorBrand), p->minorVersion); - - for (i=0; ialtCount; i++) { - gf_fprintf(trace, "\n", gf_4cc_to_str(p->altBrand[i])); - } - if (!p->type) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done((a->type == GF_ISOM_BOX_TYPE_FTYP ? "FileTypeBox" : "SegmentTypeBox"), a, trace); - return GF_OK; -} - -GF_Err padb_box_dump(GF_Box *a, FILE * trace) -{ - GF_PaddingBitsBox *p; - u32 i; - - p = (GF_PaddingBitsBox *)a; - gf_isom_box_dump_start(a, "PaddingBitsBox", trace); - gf_fprintf(trace, "EntryCount=\"%d\">\n", p->SampleCount); - for (i=0; iSampleCount; i+=1) { - gf_fprintf(trace, "\n", p->padbits[i]); - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("PaddingBitsBox", a, trace); - return GF_OK; -} - -GF_Err gppc_box_dump(GF_Box *a, FILE * trace) -{ - GF_3GPPConfigBox *p = (GF_3GPPConfigBox *)a; - switch (p->cfg.type) { - case GF_ISOM_SUBTYPE_3GP_AMR: - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - gf_isom_box_dump_start(a, "AMRConfigurationBox", trace); - gf_fprintf(trace, "Vendor=\"%s\" Version=\"%d\"", gf_4cc_to_str(p->cfg.vendor), p->cfg.decoder_version); - gf_fprintf(trace, " FramesPerSample=\"%d\" SupportedModes=\"%x\" ModeRotating=\"%d\"", p->cfg.frames_per_sample, p->cfg.AMR_mode_set, p->cfg.AMR_mode_change_period); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("AMRConfigurationBox", a, trace); - break; - case GF_ISOM_SUBTYPE_3GP_EVRC: - gf_isom_box_dump_start(a, "EVRCConfigurationBox", trace); - gf_fprintf(trace, "Vendor=\"%s\" Version=\"%d\" FramesPerSample=\"%d\" >\n", gf_4cc_to_str(p->cfg.vendor), p->cfg.decoder_version, p->cfg.frames_per_sample); - gf_isom_box_dump_done("EVRCConfigurationBox", a, trace); - break; - case GF_ISOM_SUBTYPE_3GP_QCELP: - gf_isom_box_dump_start(a, "QCELPConfigurationBox", trace); - gf_fprintf(trace, "Vendor=\"%s\" Version=\"%d\" FramesPerSample=\"%d\" >\n", gf_4cc_to_str(p->cfg.vendor), p->cfg.decoder_version, p->cfg.frames_per_sample); - gf_isom_box_dump_done("QCELPConfigurationBox", a, trace); - break; - case GF_ISOM_SUBTYPE_3GP_SMV: - gf_isom_box_dump_start(a, "SMVConfigurationBox", trace); - gf_fprintf(trace, "Vendor=\"%s\" Version=\"%d\" FramesPerSample=\"%d\" >\n", gf_4cc_to_str(p->cfg.vendor), p->cfg.decoder_version, p->cfg.frames_per_sample); - gf_isom_box_dump_done("SMVConfigurationBox", a, trace); - break; - case GF_ISOM_SUBTYPE_3GP_H263: - gf_isom_box_dump_start(a, "H263ConfigurationBox", trace); - gf_fprintf(trace, "Vendor=\"%s\" Version=\"%d\"", gf_4cc_to_str(p->cfg.vendor), p->cfg.decoder_version); - gf_fprintf(trace, " Profile=\"%d\" Level=\"%d\"", p->cfg.H263_profile, p->cfg.H263_level); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("H263ConfigurationBox", a, trace); - break; - default: - break; - } - return GF_OK; -} - - -GF_Err avcc_box_dump(GF_Box *a, FILE * trace) -{ - u32 i, count; - GF_AVCConfigurationBox *p = (GF_AVCConfigurationBox *) a; - const char *name = (p->type==GF_ISOM_BOX_TYPE_MVCC) ? "MVC" : (p->type==GF_ISOM_BOX_TYPE_SVCC) ? "SVC" : "AVC"; - char boxname[256]; - sprintf(boxname, "%sConfigurationBox", name); - gf_isom_box_dump_start(a, boxname, trace); - gf_fprintf(trace, ">\n"); - - gf_fprintf(trace, "<%sDecoderConfigurationRecord", name); - - if (! p->config) { - if (p->size) { - gf_fprintf(trace, ">\n"); - gf_fprintf(trace, "\n"); - } else { - - gf_fprintf(trace, " configurationVersion=\"\" AVCProfileIndication=\"\" profile_compatibility=\"\" AVCLevelIndication=\"\" nal_unit_size=\"\" complete_representation=\"\""); - - gf_fprintf(trace, " chroma_format=\"\" luma_bit_depth=\"\" chroma_bit_depth=\"\""); - gf_fprintf(trace, ">\n"); - - gf_fprintf(trace, "\n"); - gf_fprintf(trace, "\n"); - gf_fprintf(trace, "\n"); - } - gf_fprintf(trace, "\n", name); - gf_isom_box_dump_done(boxname, a, trace); - return GF_OK; - } - - gf_fprintf(trace, " configurationVersion=\"%d\" AVCProfileIndication=\"%d\" profile_compatibility=\"%d\" AVCLevelIndication=\"%d\" nal_unit_size=\"%d\"", p->config->configurationVersion, p->config->AVCProfileIndication, p->config->profile_compatibility, p->config->AVCLevelIndication, p->config->nal_unit_size); - - - if ((p->type==GF_ISOM_BOX_TYPE_SVCC) || (p->type==GF_ISOM_BOX_TYPE_MVCC) ) - gf_fprintf(trace, " complete_representation=\"%d\"", p->config->complete_representation); - - if (p->type==GF_ISOM_BOX_TYPE_AVCC) { - if (gf_avc_is_rext_profile(p->config->AVCProfileIndication)) { - gf_fprintf(trace, " chroma_format=\"%s\" luma_bit_depth=\"%d\" chroma_bit_depth=\"%d\"", gf_avc_hevc_get_chroma_format_name(p->config->chroma_format), p->config->luma_bit_depth, p->config->chroma_bit_depth); - } - } - - gf_fprintf(trace, ">\n"); - - count = gf_list_count(p->config->sequenceParameterSets); - for (i=0; iconfig->sequenceParameterSets, i); - gf_fprintf(trace, "size); - dump_data(trace, c->data, c->size); - gf_fprintf(trace, "\"/>\n"); - } - count = gf_list_count(p->config->pictureParameterSets); - for (i=0; iconfig->pictureParameterSets, i); - gf_fprintf(trace, "size); - dump_data(trace, c->data, c->size); - gf_fprintf(trace, "\"/>\n"); - } - - if (p->config->sequenceParameterSetExtensions) { - count = gf_list_count(p->config->sequenceParameterSetExtensions); - for (i=0; iconfig->sequenceParameterSetExtensions, i); - gf_fprintf(trace, "size); - dump_data(trace, c->data, c->size); - gf_fprintf(trace, "\"/>\n"); - } - } - - gf_fprintf(trace, "\n", name); - - gf_isom_box_dump_done(boxname, a, trace); - return GF_OK; -} - -GF_Err hvcc_box_dump(GF_Box *a, FILE * trace) -{ - u32 i, count; - const char *name = (a->type==GF_ISOM_BOX_TYPE_HVCC) ? "HEVC" : "L-HEVC"; - char boxname[256]; - GF_HEVCConfigurationBox *p = (GF_HEVCConfigurationBox *) a; - - sprintf(boxname, "%sConfigurationBox", name); - gf_isom_box_dump_start(a, boxname, trace); - gf_fprintf(trace, ">\n"); - - if (! p->config) { - if (p->size) { - gf_fprintf(trace, "\n"); - } else { - gf_fprintf(trace, "<%sDecoderConfigurationRecord nal_unit_size=\"\" configurationVersion=\"\" ", name); - if (a->type==GF_ISOM_BOX_TYPE_HVCC) { - gf_fprintf(trace, "profile_space=\"\" tier_flag=\"\" profile_idc=\"\" general_profile_compatibility_flags=\"\" progressive_source_flag=\"\" interlaced_source_flag=\"\" non_packed_constraint_flag=\"\" frame_only_constraint_flag=\"\" constraint_indicator_flags=\"\" level_idc=\"\" "); - } - gf_fprintf(trace, "min_spatial_segmentation_idc=\"\" parallelismType=\"\" "); - - if (a->type==GF_ISOM_BOX_TYPE_HVCC) - gf_fprintf(trace, "chroma_format=\"\" luma_bit_depth=\"\" chroma_bit_depth=\"\" avgFrameRate=\"\" constantFrameRate=\"\" numTemporalLayers=\"\" temporalIdNested=\"\""); - - gf_fprintf(trace, ">\n"); - gf_fprintf(trace, "\n"); - gf_fprintf(trace, "\n"); - gf_fprintf(trace, "\n"); - gf_fprintf(trace, "\n", name); - } - gf_fprintf(trace, "\n", name); - return GF_OK; - } - - gf_fprintf(trace, "<%sDecoderConfigurationRecord nal_unit_size=\"%d\" ", name, p->config->nal_unit_size); - gf_fprintf(trace, "configurationVersion=\"%u\" ", p->config->configurationVersion); - if (a->type==GF_ISOM_BOX_TYPE_HVCC) { - gf_fprintf(trace, "profile_space=\"%u\" ", p->config->profile_space); - gf_fprintf(trace, "tier_flag=\"%u\" ", p->config->tier_flag); - gf_fprintf(trace, "profile_idc=\"%u\" ", p->config->profile_idc); - gf_fprintf(trace, "general_profile_compatibility_flags=\"%X\" ", p->config->general_profile_compatibility_flags); - gf_fprintf(trace, "progressive_source_flag=\"%u\" ", p->config->progressive_source_flag); - gf_fprintf(trace, "interlaced_source_flag=\"%u\" ", p->config->interlaced_source_flag); - gf_fprintf(trace, "non_packed_constraint_flag=\"%u\" ", p->config->non_packed_constraint_flag); - gf_fprintf(trace, "frame_only_constraint_flag=\"%u\" ", p->config->frame_only_constraint_flag); - gf_fprintf(trace, "constraint_indicator_flags=\""LLX"\" ", p->config->constraint_indicator_flags); - gf_fprintf(trace, "level_idc=\"%d\" ", p->config->level_idc); - } - gf_fprintf(trace, "min_spatial_segmentation_idc=\"%u\" ", p->config->min_spatial_segmentation_idc); - gf_fprintf(trace, "parallelismType=\"%u\" ", p->config->parallelismType); - - if (a->type==GF_ISOM_BOX_TYPE_HVCC) - gf_fprintf(trace, "chroma_format=\"%s\" luma_bit_depth=\"%u\" chroma_bit_depth=\"%u\" avgFrameRate=\"%u\" constantFrameRate=\"%u\" numTemporalLayers=\"%u\" temporalIdNested=\"%u\"", - gf_avc_hevc_get_chroma_format_name(p->config->chromaFormat), p->config->luma_bit_depth, p->config->chroma_bit_depth, p->config->avgFrameRate, p->config->constantFrameRate, p->config->numTemporalLayers, p->config->temporalIdNested); - - gf_fprintf(trace, ">\n"); - - count = gf_list_count(p->config->param_array); - for (i=0; iconfig->param_array, i); - gf_fprintf(trace, "\n", ar->type, ar->array_completeness); - nalucount = gf_list_count(ar->nalus); - for (j=0; jnalus, j); - gf_fprintf(trace, "size); - dump_data(trace, c->data, c->size); - gf_fprintf(trace, "\"/>\n"); - } - gf_fprintf(trace, "\n"); - } - - gf_fprintf(trace, "\n", name); - - gf_isom_box_dump_done(boxname, a, trace); - return GF_OK; -} - -GF_Err av1c_box_dump(GF_Box *a, FILE *trace) { - GF_AV1ConfigurationBox *ptr = (GF_AV1ConfigurationBox*)a; - gf_fprintf(trace, "\n"); - if (ptr->config) { - u32 i, obu_count = gf_list_count(ptr->config->obu_array); - - gf_fprintf(trace, "config->version, (u32)ptr->config->seq_profile, (u32)ptr->config->seq_level_idx_0, (u32)ptr->config->seq_tier_0); - gf_fprintf(trace, "high_bitdepth=\"%u\" twelve_bit=\"%u\" monochrome=\"%u\" ", (u32)ptr->config->high_bitdepth, (u32)ptr->config->twelve_bit, (u32)ptr->config->monochrome); - gf_fprintf(trace, "chroma_subsampling_x=\"%u\" chroma_subsampling_y=\"%u\" chroma_sample_position=\"%u\" ", (u32)ptr->config->chroma_subsampling_x, (u32)ptr->config->chroma_subsampling_y, (u32)ptr->config->chroma_sample_position); - gf_fprintf(trace, "initial_presentation_delay=\"%u\" OBUs_count=\"%u\">\n", ptr->config->initial_presentation_delay_minus_one+1, obu_count); - - for (i=0; iconfig->obu_array, i); - gf_fprintf(trace, "obu_type, gf_av1_get_obu_name(obu_a->obu_type), (u32) obu_a->obu_length); - dump_data(trace, (char *)obu_a->obu, (u32) obu_a->obu_length); - gf_fprintf(trace, "\"/>\n"); - } - gf_fprintf(trace, "\n"); - } - gf_fprintf(trace, "\n"); - return GF_OK; -} - - -GF_Err vpcc_box_dump(GF_Box *a, FILE *trace) { - GF_VPConfigurationBox *ptr = (GF_VPConfigurationBox*)a; - gf_fprintf(trace, "\n"); - if (ptr->config) { - gf_fprintf(trace, "config->profile); - gf_fprintf(trace, " level=\"%u\"", ptr->config->level); - gf_fprintf(trace, " bit_depth=\"%u\"", ptr->config->bit_depth); - gf_fprintf(trace, " chroma_subsampling=\"%u\"", ptr->config->chroma_subsampling); - gf_fprintf(trace, " video_fullRange_flag=\"%u\"", ptr->config->video_fullRange_flag); - gf_fprintf(trace, " colour_primaries=\"%u\"", ptr->config->colour_primaries); - gf_fprintf(trace, " transfer_characteristics=\"%u\"", ptr->config->transfer_characteristics); - gf_fprintf(trace, " matrix_coefficients=\"%u\"", ptr->config->matrix_coefficients); - gf_fprintf(trace, " codec_initdata_size=\"%u\"", ptr->config->codec_initdata_size); - - gf_fprintf(trace, ">\n\n"); - } - gf_fprintf(trace, "\n"); - return GF_OK; -} - -GF_Err SmDm_box_dump(GF_Box *a, FILE *trace) { - GF_SMPTE2086MasteringDisplayMetadataBox * ptr = (GF_SMPTE2086MasteringDisplayMetadataBox *)a; - if (!a) return GF_BAD_PARAM; - gf_isom_box_dump_start(a, "SMPTE2086MasteringDisplayMetadataBox", trace); - gf_fprintf(trace, "primaryRChromaticity_x=\"%u\" ", ptr->primaryRChromaticity_x); - gf_fprintf(trace, "primaryRChromaticity_y=\"%u\" ", ptr->primaryRChromaticity_y); - gf_fprintf(trace, "primaryGChromaticity_x=\"%u\" ", ptr->primaryGChromaticity_x); - gf_fprintf(trace, "primaryGChromaticity_y=\"%u\" ", ptr->primaryGChromaticity_y); - gf_fprintf(trace, "primaryBChromaticity_x=\"%u\" ", ptr->primaryBChromaticity_x); - gf_fprintf(trace, "primaryBChromaticity_y=\"%u\" ", ptr->primaryBChromaticity_y); - gf_fprintf(trace, "whitePointChromaticity_x=\"%u\" ", ptr->whitePointChromaticity_x); - gf_fprintf(trace, "whitePointChromaticity_y=\"%u\" ", ptr->whitePointChromaticity_y); - gf_fprintf(trace, "luminanceMax=\"%u\" ", ptr->luminanceMax); - gf_fprintf(trace, "luminanceMin=\"%u\">\n", ptr->luminanceMin); - gf_isom_box_dump_done("SMPTE2086MasteringDisplayMetadataBox", a, trace); - return GF_OK; -} - -GF_Err CoLL_box_dump(GF_Box *a, FILE *trace) { - GF_VPContentLightLevelBox * ptr = (GF_VPContentLightLevelBox *)a; - if (!a) return GF_BAD_PARAM; - gf_isom_box_dump_start(a, "VPContentLightLevelBox", trace); - gf_fprintf(trace, "maxCLL=\"%u\" maxFALL=\"%u\">\n", ptr->maxCLL, ptr->maxFALL); - gf_isom_box_dump_done("VPContentLightLevelBox", a, trace); - return GF_OK; -} - -GF_Err m4ds_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_Descriptor *desc; - GF_MPEG4ExtensionDescriptorsBox *p = (GF_MPEG4ExtensionDescriptorsBox *) a; - gf_isom_box_dump_start(a, "MPEG4ExtensionDescriptorsBox", trace); - gf_fprintf(trace, ">\n"); - - i=0; - while ((desc = (GF_Descriptor *)gf_list_enum(p->descriptors, &i))) { -#ifndef GPAC_DISABLE_OD_DUMP - gf_odf_dump_desc(desc, trace, 1, GF_TRUE); -#else - gf_fprintf(trace, "\n"); -#endif - } - gf_isom_box_dump_done("MPEG4ExtensionDescriptorsBox", a, trace); - return GF_OK; -} - -GF_Err btrt_box_dump(GF_Box *a, FILE * trace) -{ - GF_BitRateBox *p = (GF_BitRateBox*)a; - gf_isom_box_dump_start(a, "BitRateBox", trace); - gf_fprintf(trace, "BufferSizeDB=\"%d\" avgBitRate=\"%d\" maxBitRate=\"%d\">\n", p->bufferSizeDB, p->avgBitrate, p->maxBitrate); - gf_isom_box_dump_done("BitRateBox", a, trace); - return GF_OK; -} - -GF_Err ftab_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_FontTableBox *p = (GF_FontTableBox *)a; - gf_isom_box_dump_start(a, "FontTableBox", trace); - gf_fprintf(trace, ">\n"); - for (i=0; ientry_count; i++) { - gf_fprintf(trace, "\n", p->fonts[i].fontID, p->fonts[i].fontName ? p->fonts[i].fontName : "NULL"); - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("FontTableBox", a, trace); - return GF_OK; -} - -static void tx3g_dump_rgba8(FILE * trace, char *name, u32 col) -{ - gf_fprintf(trace, "%s=\"%x %x %x %x\"", name, (col>>16)&0xFF, (col>>8)&0xFF, (col)&0xFF, (col>>24)&0xFF); -} -static void tx3g_dump_rgb16(FILE * trace, char *name, char col[6]) -{ - gf_fprintf(trace, "%s=\"%x %x %x\"", name, *((u16*)col), *((u16*)(col+2)), *((u16*)(col+4))); -} -static void tx3g_dump_box(FILE * trace, GF_BoxRecord *rec) -{ - gf_fprintf(trace, "\n", rec->top, rec->left, rec->bottom, rec->right); -} -static void tx3g_dump_style(FILE * trace, GF_StyleRecord *rec) -{ - gf_fprintf(trace, "startCharOffset, rec->endCharOffset, rec->fontID); - if (!rec->style_flags) { - gf_fprintf(trace, "Normal"); - } else { - if (rec->style_flags & 1) gf_fprintf(trace, "Bold "); - if (rec->style_flags & 2) gf_fprintf(trace, "Italic "); - if (rec->style_flags & 4) gf_fprintf(trace, "Underlined "); - } - gf_fprintf(trace, "\" fontSize=\"%d\" ", rec->font_size); - tx3g_dump_rgba8(trace, "textColor", rec->text_color); - gf_fprintf(trace, "/>\n"); -} - -GF_Err tx3g_box_dump(GF_Box *a, FILE * trace) -{ - GF_Tx3gSampleEntryBox *p = (GF_Tx3gSampleEntryBox *)a; - gf_isom_box_dump_start(a, "Tx3gSampleEntryBox", trace); - gf_fprintf(trace, "dataReferenceIndex=\"%d\" displayFlags=\"%x\" horizontal-justification=\"%d\" vertical-justification=\"%d\" ", - p->dataReferenceIndex, p->displayFlags, p->horizontal_justification, p->vertical_justification); - - tx3g_dump_rgba8(trace, "backgroundColor", p->back_color); - gf_fprintf(trace, ">\n"); - gf_fprintf(trace, "\n"); - tx3g_dump_box(trace, &p->default_box); - - gf_fprintf(trace, "\n"); - tx3g_dump_style(trace, &p->default_style); - gf_fprintf(trace, "\n"); - gf_isom_box_dump_done("Tx3gSampleEntryBox", a, trace); - return GF_OK; -} - -GF_Err text_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextSampleEntryBox *p = (GF_TextSampleEntryBox *)a; - gf_isom_box_dump_start(a, "TextSampleEntryBox", trace); - gf_fprintf(trace, "dataReferenceIndex=\"%d\" displayFlags=\"%x\" textJustification=\"%d\" ", - p->dataReferenceIndex, p->displayFlags, p->textJustification); - if (p->textName) - gf_fprintf(trace, "textName=\"%s\" ", p->textName); - tx3g_dump_rgb16(trace, "background-color", p->background_color); - tx3g_dump_rgb16(trace, " foreground-color", p->foreground_color); - gf_fprintf(trace, ">\n"); - - gf_fprintf(trace, "\n"); - tx3g_dump_box(trace, &p->default_box); - gf_isom_box_dump_done("DefaultBox", a, trace); - gf_isom_box_dump_done("TextSampleEntryBox", a, trace); - return GF_OK; -} - -GF_Err styl_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_TextStyleBox*p = (GF_TextStyleBox*)a; - gf_isom_box_dump_start(a, "TextStyleBox", trace); - gf_fprintf(trace, ">\n"); - for (i=0; ientry_count; i++) tx3g_dump_style(trace, &p->styles[i]); - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("TextStyleBox", a, trace); - return GF_OK; -} -GF_Err hlit_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextHighlightBox*p = (GF_TextHighlightBox*)a; - gf_isom_box_dump_start(a, "TextHighlightBox", trace); - gf_fprintf(trace, "startcharoffset=\"%d\" endcharoffset=\"%d\">\n", p->startcharoffset, p->endcharoffset); - gf_isom_box_dump_done("TextHighlightBox", a, trace); - return GF_OK; -} -GF_Err hclr_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextHighlightColorBox*p = (GF_TextHighlightColorBox*)a; - gf_isom_box_dump_start(a, "TextHighlightColorBox", trace); - tx3g_dump_rgba8(trace, "highlight_color", p->hil_color); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("TextHighlightColorBox", a, trace); - return GF_OK; -} - -GF_Err krok_box_dump(GF_Box *a, FILE * trace) -{ - u32 i; - GF_TextKaraokeBox*p = (GF_TextKaraokeBox*)a; - gf_isom_box_dump_start(a, "TextKaraokeBox", trace); - gf_fprintf(trace, "highlight_starttime=\"%d\">\n", p->highlight_starttime); - for (i=0; inb_entries; i++) { - gf_fprintf(trace, "\n", p->records[i].highlight_endtime, p->records[i].start_charoffset, p->records[i].end_charoffset); - } - if (!p->size) { - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("TextKaraokeBox", a, trace); - return GF_OK; -} -GF_Err dlay_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextScrollDelayBox*p = (GF_TextScrollDelayBox*)a; - gf_isom_box_dump_start(a, "TextScrollDelayBox", trace); - gf_fprintf(trace, "scroll_delay=\"%d\">\n", p->scroll_delay); - gf_isom_box_dump_done("TextScrollDelayBox", a, trace); - return GF_OK; -} -GF_Err href_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextHyperTextBox*p = (GF_TextHyperTextBox*)a; - gf_isom_box_dump_start(a, "TextHyperTextBox", trace); - gf_fprintf(trace, "startcharoffset=\"%d\" endcharoffset=\"%d\" URL=\"%s\" altString=\"%s\">\n", p->startcharoffset, p->endcharoffset, p->URL ? p->URL : "NULL", p->URL_hint ? p->URL_hint : "NULL"); - gf_isom_box_dump_done("TextHyperTextBox", a, trace); - return GF_OK; -} -GF_Err tbox_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextBoxBox*p = (GF_TextBoxBox*)a; - gf_isom_box_dump_start(a, "TextBoxBox", trace); - gf_fprintf(trace, ">\n"); - tx3g_dump_box(trace, &p->box); - gf_isom_box_dump_done("TextBoxBox", a, trace); - return GF_OK; -} -GF_Err blnk_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextBlinkBox*p = (GF_TextBlinkBox*)a; - gf_isom_box_dump_start(a, "TextBlinkBox", trace); - gf_fprintf(trace, "start_charoffset=\"%d\" end_charoffset=\"%d\">\n", p->startcharoffset, p->endcharoffset); - gf_isom_box_dump_done("TextBlinkBox", a, trace); - return GF_OK; -} -GF_Err twrp_box_dump(GF_Box *a, FILE * trace) -{ - GF_TextWrapBox*p = (GF_TextWrapBox*)a; - gf_isom_box_dump_start(a, "TextWrapBox", trace); - gf_fprintf(trace, "wrap_flag=\"%s\">\n", p->wrap_flag ? ( (p->wrap_flag>1) ? "Reserved" : "Automatic" ) : "No Wrap"); - gf_isom_box_dump_done("TextWrapBox", a, trace); - return GF_OK; -} - - -GF_Err meta_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "MetaBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MetaBox", a, trace); - return GF_OK; -} - - -GF_Err xml_box_dump(GF_Box *a, FILE * trace) -{ - GF_XMLBox *p = (GF_XMLBox *)a; - gf_isom_box_dump_start(a, "XMLBox", trace); - gf_fprintf(trace, ">\n"); - gf_fprintf(trace, "xml) - gf_fwrite(p->xml, strlen(p->xml), trace); - gf_fprintf(trace, "]]>\n"); - gf_isom_box_dump_done("XMLBox", a, trace); - return GF_OK; -} - - -GF_Err bxml_box_dump(GF_Box *a, FILE * trace) -{ - GF_BinaryXMLBox *p = (GF_BinaryXMLBox *)a; - gf_isom_box_dump_start(a, "BinaryXMLBox", trace); - gf_fprintf(trace, "binarySize=\"%d\">\n", p->data_length); - gf_isom_box_dump_done("BinaryXMLBox", a, trace); - return GF_OK; -} - - -GF_Err pitm_box_dump(GF_Box *a, FILE * trace) -{ - GF_PrimaryItemBox *p = (GF_PrimaryItemBox *)a; - gf_isom_box_dump_start(a, "PrimaryItemBox", trace); - gf_fprintf(trace, "item_ID=\"%d\">\n", p->item_ID); - gf_isom_box_dump_done("PrimaryItemBox", a, trace); - return GF_OK; -} - -GF_Err ipro_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "ItemProtectionBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("ItemProtectionBox", a, trace); - return GF_OK; -} - -GF_Err infe_box_dump(GF_Box *a, FILE * trace) -{ - GF_ItemInfoEntryBox *p = (GF_ItemInfoEntryBox *)a; - gf_isom_box_dump_start(a, "ItemInfoEntryBox", trace); - gf_fprintf(trace, "item_ID=\"%d\" item_protection_index=\"%d\" item_name=\"%s\" content_type=\"%s\" content_encoding=\"%s\" item_type=\"%s\">\n", p->item_ID, p->item_protection_index, p->item_name, p->content_type, p->content_encoding, gf_4cc_to_str(p->item_type)); - gf_isom_box_dump_done("ItemInfoEntryBox", a, trace); - return GF_OK; -} - -GF_Err iinf_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "ItemInfoBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("ItemInfoBox", a, trace); - return GF_OK; -} - -GF_Err iloc_box_dump(GF_Box *a, FILE * trace) -{ - u32 i, j, count, count2; - GF_ItemLocationBox *p = (GF_ItemLocationBox*)a; - gf_isom_box_dump_start(a, "ItemLocationBox", trace); - gf_fprintf(trace, "offset_size=\"%d\" length_size=\"%d\" base_offset_size=\"%d\" index_size=\"%d\">\n", p->offset_size, p->length_size, p->base_offset_size, p->index_size); - count = gf_list_count(p->location_entries); - for (i=0; ilocation_entries, i); - count2 = gf_list_count(ie->extent_entries); - gf_fprintf(trace, "\n", ie->item_ID, ie->data_reference_index, ie->base_offset, ie->construction_method); - for (j=0; jextent_entries, j); - gf_fprintf(trace, "\n", iee->extent_offset, iee->extent_length, iee->extent_index); - } - gf_fprintf(trace, "\n"); - } - if (!p->size) { - gf_fprintf(trace, "\n"); - gf_fprintf(trace, "\n"); - gf_fprintf(trace, "\n"); - } - gf_isom_box_dump_done("ItemLocationBox", a, trace); - return GF_OK; -} - -GF_Err iref_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "ItemReferenceBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("ItemReferenceBox", a, trace); - return GF_OK; -} - -GF_Err hinf_box_dump(GF_Box *a, FILE * trace) -{ -// GF_HintInfoBox *p = (GF_HintInfoBox *)a; - gf_isom_box_dump_start(a, "HintInfoBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("HintInfoBox", a, trace); - return GF_OK; -} - -GF_Err trpy_box_dump(GF_Box *a, FILE * trace) -{ - GF_TRPYBox *p = (GF_TRPYBox *)a; - gf_isom_box_dump_start(a, "LargeTotalRTPBytesBox", trace); - gf_fprintf(trace, "RTPBytesSent=\""LLD"\">\n", p->nbBytes); - gf_isom_box_dump_done("LargeTotalRTPBytesBox", a, trace); - return GF_OK; -} - -GF_Err totl_box_dump(GF_Box *a, FILE * trace) -{ - GF_TOTLBox *p; - - p = (GF_TOTLBox *)a; - gf_isom_box_dump_start(a, "TotalRTPBytesBox", trace); - gf_fprintf(trace, "RTPBytesSent=\"%d\">\n", p->nbBytes); - gf_isom_box_dump_done("TotalRTPBytesBox", a, trace); - return GF_OK; -} - -GF_Err nump_box_dump(GF_Box *a, FILE * trace) -{ - GF_NUMPBox *p; - - p = (GF_NUMPBox *)a; - gf_isom_box_dump_start(a, "LargeTotalPacketBox", trace); - gf_fprintf(trace, "PacketsSent=\""LLD"\">\n", p->nbPackets); - gf_isom_box_dump_done("LargeTotalPacketBox", a, trace); - return GF_OK; -} - -GF_Err npck_box_dump(GF_Box *a, FILE * trace) -{ - GF_NPCKBox *p; - p = (GF_NPCKBox *)a; - gf_isom_box_dump_start(a, "TotalPacketBox", trace); - gf_fprintf(trace, "packetsSent=\"%d\">\n", p->nbPackets); - gf_isom_box_dump_done("TotalPacketBox", a, trace); - return GF_OK; -} - -GF_Err tpyl_box_dump(GF_Box *a, FILE * trace) -{ - GF_NTYLBox *p; - p = (GF_NTYLBox *)a; - gf_isom_box_dump_start(a, "LargeTotalMediaBytesBox", trace); - gf_fprintf(trace, "BytesSent=\""LLD"\">\n", p->nbBytes); - gf_isom_box_dump_done("LargeTotalMediaBytesBox", a, trace); - return GF_OK; -} - -GF_Err tpay_box_dump(GF_Box *a, FILE * trace) -{ - GF_TPAYBox *p; - p = (GF_TPAYBox *)a; - gf_isom_box_dump_start(a, "TotalMediaBytesBox", trace); - gf_fprintf(trace, "BytesSent=\"%d\">\n", p->nbBytes); - gf_isom_box_dump_done("TotalMediaBytesBox", a, trace); - return GF_OK; -} - -GF_Err maxr_box_dump(GF_Box *a, FILE * trace) -{ - GF_MAXRBox *p; - p = (GF_MAXRBox *)a; - gf_isom_box_dump_start(a, "MaxDataRateBox", trace); - gf_fprintf(trace, "MaxDataRate=\"%d\" Granularity=\"%d\">\n", p->maxDataRate, p->granularity); - gf_isom_box_dump_done("MaxDataRateBox", a, trace); - return GF_OK; -} - -GF_Err dmed_box_dump(GF_Box *a, FILE * trace) -{ - GF_DMEDBox *p; - - p = (GF_DMEDBox *)a; - gf_isom_box_dump_start(a, "BytesFromMediaTrackBox", trace); - gf_fprintf(trace, "BytesSent=\""LLD"\">\n", p->nbBytes); - gf_isom_box_dump_done("BytesFromMediaTrackBox", a, trace); - return GF_OK; -} - -GF_Err dimm_box_dump(GF_Box *a, FILE * trace) -{ - GF_DIMMBox *p; - p = (GF_DIMMBox *)a; - gf_isom_box_dump_start(a, "ImmediateDataBytesBox", trace); - gf_fprintf(trace, "BytesSent=\""LLD"\">\n", p->nbBytes); - gf_isom_box_dump_done("ImmediateDataBytesBox", a, trace); - return GF_OK; -} - -GF_Err drep_box_dump(GF_Box *a, FILE * trace) -{ - GF_DREPBox *p; - p = (GF_DREPBox *)a; - gf_isom_box_dump_start(a, "RepeatedDataBytesBox", trace); - gf_fprintf(trace, "RepeatedBytes=\""LLD"\">\n", p->nbBytes); - gf_isom_box_dump_done("RepeatedDataBytesBox", a, trace); - return GF_OK; -} - -GF_Err tssy_box_dump(GF_Box *a, FILE * trace) -{ - GF_TimeStampSynchronyBox *p = (GF_TimeStampSynchronyBox *)a; - gf_isom_box_dump_start(a, "TimeStampSynchronyBox", trace); - gf_fprintf(trace, "timestamp_sync=\"%d\">\n", p->timestamp_sync); - gf_isom_box_dump_done("TimeStampSynchronyBox", a, trace); - return GF_OK; -} - -GF_Err rssr_box_dump(GF_Box *a, FILE * trace) -{ - GF_ReceivedSsrcBox *p = (GF_ReceivedSsrcBox *)a; - gf_isom_box_dump_start(a, "ReceivedSsrcBox", trace); - gf_fprintf(trace, "SSRC=\"%d\">\n", p->ssrc); - gf_isom_box_dump_done("ReceivedSsrcBox", a, trace); - return GF_OK; -} - -GF_Err tmin_box_dump(GF_Box *a, FILE * trace) -{ - GF_TMINBox *p; - p = (GF_TMINBox *)a; - gf_isom_box_dump_start(a, "MinTransmissionTimeBox", trace); - gf_fprintf(trace, "MinimumTransmitTime=\"%d\">\n", p->minTime); - gf_isom_box_dump_done("MinTransmissionTimeBox", a, trace); - return GF_OK; -} - -GF_Err tmax_box_dump(GF_Box *a, FILE * trace) -{ - GF_TMAXBox *p; - p = (GF_TMAXBox *)a; - gf_isom_box_dump_start(a, "MaxTransmissionTimeBox", trace); - gf_fprintf(trace, "MaximumTransmitTime=\"%d\">\n", p->maxTime); - gf_isom_box_dump_done("MaxTransmissionTimeBox", a, trace); - return GF_OK; -} - -GF_Err pmax_box_dump(GF_Box *a, FILE * trace) -{ - GF_PMAXBox *p; - p = (GF_PMAXBox *)a; - gf_isom_box_dump_start(a, "MaxPacketSizeBox", trace); - gf_fprintf(trace, "MaximumSize=\"%d\">\n", p->maxSize); - gf_isom_box_dump_done("MaxPacketSizeBox", a, trace); - return GF_OK; -} - -GF_Err dmax_box_dump(GF_Box *a, FILE * trace) -{ - GF_DMAXBox *p; - p = (GF_DMAXBox *)a; - gf_isom_box_dump_start(a, "MaxPacketDurationBox", trace); - gf_fprintf(trace, "MaximumDuration=\"%d\">\n", p->maxDur); - gf_isom_box_dump_done("MaxPacketDurationBox", a, trace); - return GF_OK; -} - -GF_Err payt_box_dump(GF_Box *a, FILE * trace) -{ - GF_PAYTBox *p; - p = (GF_PAYTBox *)a; - gf_isom_box_dump_start(a, "PayloadTypeBox", trace); - gf_fprintf(trace, "PayloadID=\"%d\" PayloadString=\"%s\">\n", p->payloadCode, p->payloadString); - gf_isom_box_dump_done("PayloadTypeBox", a, trace); - return GF_OK; -} - -GF_Err name_box_dump(GF_Box *a, FILE * trace) -{ - GF_NameBox *p; - p = (GF_NameBox *)a; - gf_isom_box_dump_start(a, "NameBox", trace); - gf_fprintf(trace, "Name=\"%s\">\n", p->string); - gf_isom_box_dump_done("NameBox", a, trace); - return GF_OK; -} - -GF_Err rely_box_dump(GF_Box *a, FILE * trace) -{ - GF_RelyHintBox *p; - p = (GF_RelyHintBox *)a; - gf_isom_box_dump_start(a, "RelyTransmissionBox", trace); - gf_fprintf(trace, "preferred=\"%d\" required=\"%d\">\n", p->preferred, p->required); - gf_isom_box_dump_done("RelyTransmissionBox", a, trace); - return GF_OK; -} - -GF_Err snro_box_dump(GF_Box *a, FILE * trace) -{ - GF_SeqOffHintEntryBox *p; - p = (GF_SeqOffHintEntryBox *)a; - gf_isom_box_dump_start(a, "PacketSequenceOffsetBox", trace); - gf_fprintf(trace, "SeqNumOffset=\"%d\">\n", p->SeqOffset); - gf_isom_box_dump_done("PacketSequenceOffsetBox", a, trace); - return GF_OK; -} - -GF_Err tims_box_dump(GF_Box *a, FILE * trace) -{ - GF_TSHintEntryBox *p; - p = (GF_TSHintEntryBox *)a; - gf_isom_box_dump_start(a, "RTPTimeScaleBox", trace); - gf_fprintf(trace, "TimeScale=\"%d\">\n", p->timeScale); - gf_isom_box_dump_done("RTPTimeScaleBox", a, trace); - return GF_OK; -} - -GF_Err tsro_box_dump(GF_Box *a, FILE * trace) -{ - GF_TimeOffHintEntryBox *p; - p = (GF_TimeOffHintEntryBox *)a; - gf_isom_box_dump_start(a, "TimeStampOffsetBox", trace); - gf_fprintf(trace, "TimeStampOffset=\"%d\">\n", p->TimeOffset); - gf_isom_box_dump_done("TimeStampOffsetBox", a, trace); - return GF_OK; -} - - -GF_Err ghnt_box_dump(GF_Box *a, FILE * trace) -{ - char *name; - GF_HintSampleEntryBox *p; - p = (GF_HintSampleEntryBox *)a; - - if (a->type == GF_ISOM_BOX_TYPE_RTP_STSD) { - name = "RTPHintSampleEntryBox"; - } else if (a->type == GF_ISOM_BOX_TYPE_SRTP_STSD) { - name = "SRTPHintSampleEntryBox"; - } else if (a->type == GF_ISOM_BOX_TYPE_FDP_STSD) { - name = "FDPHintSampleEntryBox"; - } else if (a->type == GF_ISOM_BOX_TYPE_RRTP_STSD) { - name = "RTPReceptionHintSampleEntryBox"; - } else if (a->type == GF_ISOM_BOX_TYPE_RTCP_STSD) { - name = "RTCPReceptionHintSampleEntryBox"; - } else { - name = "GenericHintSampleEntryBox"; - } - gf_isom_box_dump_start(a, name, trace); - gf_fprintf(trace, "DataReferenceIndex=\"%d\" HintTrackVersion=\"%d\" LastCompatibleVersion=\"%d\"", p->dataReferenceIndex, p->HintTrackVersion, p->LastCompatibleVersion); - if ((a->type == GF_ISOM_BOX_TYPE_RTP_STSD) || (a->type == GF_ISOM_BOX_TYPE_SRTP_STSD) || (a->type == GF_ISOM_BOX_TYPE_RRTP_STSD) || (a->type == GF_ISOM_BOX_TYPE_RTCP_STSD)) { - gf_fprintf(trace, " MaxPacketSize=\"%d\"", p->MaxPacketSize); - } else if (a->type == GF_ISOM_BOX_TYPE_FDP_STSD) { - gf_fprintf(trace, " partition_entry_ID=\"%d\" FEC_overhead=\"%d\"", p->partition_entry_ID, p->FEC_overhead); - } - gf_fprintf(trace, ">\n"); - - gf_isom_box_dump_done(name, a, trace); - return GF_OK; -} - -GF_Err hnti_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "HintTrackInfoBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("HintTrackInfoBox", a, trace); - return GF_OK; -} - -GF_Err sdp_box_dump(GF_Box *a, FILE * trace) -{ - GF_SDPBox *p = (GF_SDPBox *)a; - gf_isom_box_dump_start(a, "SDPBox", trace); - gf_fprintf(trace, ">\n"); - if (p->sdpText) - gf_fprintf(trace, "\n", p->sdpText); - gf_isom_box_dump_done("SDPBox", a, trace); - return GF_OK; -} - -GF_Err rtp_hnti_box_dump(GF_Box *a, FILE * trace) -{ - GF_RTPBox *p = (GF_RTPBox *)a; - gf_isom_box_dump_start(a, "RTPMovieHintInformationBox", trace); - gf_fprintf(trace, "descriptionformat=\"%s\">\n", gf_4cc_to_str(p->subType)); - if (p->sdpText) - gf_fprintf(trace, "\n", p->sdpText); - gf_isom_box_dump_done("RTPMovieHintInformationBox", a, trace); - return GF_OK; -} - -GF_Err rtpo_box_dump(GF_Box *a, FILE * trace) -{ - GF_RTPOBox *p; - p = (GF_RTPOBox *)a; - gf_isom_box_dump_start(a, "RTPTimeOffsetBox", trace); - gf_fprintf(trace, "PacketTimeOffset=\"%d\">\n", p->timeOffset); - gf_isom_box_dump_done("RTPTimeOffsetBox", a, trace); - return GF_OK; -} - -#ifndef GPAC_DISABLE_ISOM_FRAGMENTS - -GF_Err mvex_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "MovieExtendsBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MovieExtendsBox", a, trace); - return GF_OK; -} - -GF_Err mehd_box_dump(GF_Box *a, FILE * trace) -{ - GF_MovieExtendsHeaderBox *p = (GF_MovieExtendsHeaderBox*)a; - gf_isom_box_dump_start(a, "MovieExtendsHeaderBox", trace); - gf_fprintf(trace, "fragmentDuration=\""LLD"\" >\n", p->fragment_duration); - gf_isom_box_dump_done("MovieExtendsHeaderBox", a, trace); - return GF_OK; -} - -void sample_flags_dump(const char *name, u32 sample_flags, FILE * trace) -{ - gf_fprintf(trace, "<%s", name); - gf_fprintf(trace, " IsLeading=\"%d\"", GF_ISOM_GET_FRAG_LEAD(sample_flags) ); - gf_fprintf(trace, " SampleDependsOn=\"%d\"", GF_ISOM_GET_FRAG_DEPENDS(sample_flags) ); - gf_fprintf(trace, " SampleIsDependedOn=\"%d\"", GF_ISOM_GET_FRAG_DEPENDED(sample_flags) ); - gf_fprintf(trace, " SampleHasRedundancy=\"%d\"", GF_ISOM_GET_FRAG_REDUNDANT(sample_flags) ); - gf_fprintf(trace, " SamplePadding=\"%d\"", GF_ISOM_GET_FRAG_PAD(sample_flags) ); - gf_fprintf(trace, " SampleSync=\"%d\"", GF_ISOM_GET_FRAG_SYNC(sample_flags)); - gf_fprintf(trace, " SampleDegradationPriority=\"%d\"", GF_ISOM_GET_FRAG_DEG(sample_flags)); - gf_fprintf(trace, "/>\n"); -} - -GF_Err trex_box_dump(GF_Box *a, FILE * trace) -{ - GF_TrackExtendsBox *p; - p = (GF_TrackExtendsBox *)a; - gf_isom_box_dump_start(a, "TrackExtendsBox", trace); - gf_fprintf(trace, "TrackID=\"%d\"", p->trackID); - gf_fprintf(trace, " SampleDescriptionIndex=\"%d\" SampleDuration=\"%d\" SampleSize=\"%d\"", p->def_sample_desc_index, p->def_sample_duration, p->def_sample_size); - gf_fprintf(trace, ">\n"); - sample_flags_dump("DefaultSampleFlags", p->def_sample_flags, trace); - gf_isom_box_dump_done("TrackExtendsBox", a, trace); - return GF_OK; -} - -GF_Err trep_box_dump(GF_Box *a, FILE * trace) -{ - GF_TrackExtensionPropertiesBox *p = (GF_TrackExtensionPropertiesBox*)a; - gf_isom_box_dump_start(a, "TrackExtensionPropertiesBox", trace); - gf_fprintf(trace, "TrackID=\"%d\">\n", p->trackID); - gf_isom_box_dump_done("TrackExtensionPropertiesBox", a, trace); - return GF_OK; -} - -GF_Err moof_box_dump(GF_Box *a, FILE * trace) -{ - GF_MovieFragmentBox *p; - p = (GF_MovieFragmentBox *)a; - gf_isom_box_dump_start(a, "MovieFragmentBox", trace); - gf_fprintf(trace, "TrackFragments=\"%d\"", gf_list_count(p->TrackList)); - if (p->compressed_diff) - gf_fprintf(trace, " compressedSize=\""LLU"\"", p->size - p->compressed_diff); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("MovieFragmentBox", a, trace); - return GF_OK; -} - -GF_Err mfhd_box_dump(GF_Box *a, FILE * trace) -{ - GF_MovieFragmentHeaderBox *p; - p = (GF_MovieFragmentHeaderBox *)a; - gf_isom_box_dump_start(a, "MovieFragmentHeaderBox", trace); - gf_fprintf(trace, "FragmentSequenceNumber=\"%d\">\n", p->sequence_number); - gf_isom_box_dump_done("MovieFragmentHeaderBox", a, trace); - return GF_OK; -} - -GF_Err traf_box_dump(GF_Box *a, FILE * trace) -{ - gf_isom_box_dump_start(a, "TrackFragmentBox", trace); - gf_fprintf(trace, ">\n"); - gf_isom_box_dump_done("TrackFragmentBox", a, trace); - return GF_OK; -} - -static void frag_dump_sample_flags(FILE * trace, u32 flags, u32 field_idx) -{ - if (!field_idx) return; - if (field_idx==1) { - gf_fprintf(trace, " IsLeading=\"%d\" DependsOn=\"%d\"", GF_ISOM_GET_FRAG_LEAD(flags), GF_ISOM_GET_FRAG_DEPENDS(flags)); - } else if (field_idx==2) { - gf_fprintf(trace, " IsLeading=\"%d\" DependsOn=\"%d\" IsDependedOn=\"%d\" HasRedundancy=\"%d\" SamplePadding=\"%d\" Sync=\"%d\"", - GF_ISOM_GET_FRAG_LEAD(flags), GF_ISOM_GET_FRAG_DEPENDS(flags), GF_ISOM_GET_FRAG_DEPENDED(flags), GF_ISOM_GET_FRAG_REDUNDANT(flags), GF_ISOM_GET_FRAG_PAD(flags), GF_ISOM_GET_FRAG_SYNC(flags)); - } else { - gf_fprintf(trace, " SamplePadding=\"%d\" Sync=\"%d\" DegradationPriority=\"%d\" IsLeading=\"%d\" DependsOn=\"%d\" IsDependedOn=\"%d\" HasRedundancy=\"%d\"", - GF_ISOM_GET_FRAG_PAD(flags), GF_ISOM_GET_FRAG_SYNC(flags), GF_ISOM_GET_FRAG_DEG(flags), - GF_ISOM_GET_FRAG_LEAD(flags), GF_ISOM_GET_FRAG_DEPENDS(flags), GF_ISOM_GET_FRAG_DEPENDED(flags), GF_ISOM_GET_FRAG_REDUNDANT(flags)); - } -} - -GF_Err tfhd_box_dump(GF_Box *a, FILE * trace) -{ - GF_TrackFragmentHeaderBox *p; - p = (GF_TrackFragmentHeaderBox *)a; - gf_isom_box_dump_start(a, "TrackFragmentHeaderBox", trace); - gf_fprintf(trace, "TrackID=\"%u\"", p->trackID); - - if (p->flags & GF_ISOM_TRAF_BASE_OFFSET) { - gf_fprintf(trace, " BaseDataOffset=\""LLU"\"", p->base_data_offset); - } else { - gf_fprintf(trace, " BaseDataOffset=\"%s\"", (p->flags & GF_ISOM_MOOF_BASE_OFFSET) ? "moof" : "moof-or-previous-traf"); - } - - if (p->flags & GF_ISOM_TRAF_SAMPLE_DESC) - gf_fprintf(trace, " SampleDescriptionIndex=\"%u\"", p->sample_desc_index); - if (p->flags & GF_ISOM_TRAF_SAMPLE_DUR) - gf_fprintf(trace, " SampleDuration=\"%u\"", p->def_sample_duration); - if (p->flags & GF_ISOM_TRAF_SAMPLE_SIZE) - gf_fprintf(trace, " SampleSize=\"%u\"", p->def_sample_size); - - if (p->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) { - frag_dump_sample_flags(trace, p->def_sample_flags, 3); - } - - gf_fprintf(trace, ">\n"); - - gf_isom_box_dump_done("TrackFragmentHeaderBox", a, trace); - return GF_OK; -} - -GF_Err tfxd_box_dump(GF_Box *a, FILE * trace) -{ - GF_MSSTimeExtBox *ptr = (GF_MSSTimeExtBox*)a; - if (!a) return GF_BAD_PARAM; - gf_isom_box_dump_start(a, "MSSTimeExtensionBox", trace); - gf_fprintf(trace, "AbsoluteTime=\""LLU"\" FragmentDuration=\""LLU"\">\n", ptr->absolute_time_in_track_timescale, ptr->fragment_duration_in_track_timescale); - gf_fprintf(trace, "\n", ptr->version, ptr->flags); - gf_isom_box_dump_done("MSSTimeExtensionBox", a, trace); - return GF_OK; -} - -GF_Err trun_box_dump(GF_Box *a, FILE * trace) -{ - u32 i, flags; - Bool full_dump = GF_FALSE; - GF_TrackFragmentRunBox *p; - - p = (GF_TrackFragmentRunBox *)a; - flags = p->flags; -#ifdef GF_ENABLE_CTRN - if (p->use_ctrn) { - p->flags = p->ctrn_flags; - p->type = GF_ISOM_BOX_TYPE_CTRN; - } - gf_isom_box_dump_start(a, p->use_ctrn ? "CompactTrackRunBox" : "TrackRunBox", trace); -#else - gf_isom_box_dump_start(a, "TrackRunBox", trace); -#endif - p->flags = flags; - p->type = GF_ISOM_BOX_TYPE_TRUN; - gf_fprintf(trace, "SampleCount=\"%d\"", p->sample_count); - - if (p->flags & GF_ISOM_TRUN_DATA_OFFSET) - gf_fprintf(trace, " DataOffset=\"%d\"", p->data_offset); - -#ifdef GF_ENABLE_CTRN - if (p->use_ctrn) { - if (p->ctrn_flags & GF_ISOM_CTRN_DATAOFFSET_16) - gf_fprintf(trace, " dataOffset16Bits=\"yes\""); - - if (p->ctso_multiplier) - gf_fprintf(trace, " ctsoMultiplier=\"%d\"", p->ctso_multiplier); - - if (p->ctrn_flags & GF_ISOM_CTRN_INHERIT_DUR) - gf_fprintf(trace, " inheritDuration=\"yes\""); - if (p->ctrn_flags & GF_ISOM_CTRN_INHERIT_SIZE) - gf_fprintf(trace, " inheritSize=\"yes\""); - if (p->ctrn_flags & GF_ISOM_CTRN_INHERIT_FLAGS) - gf_fprintf(trace, " inheritFlags=\"yes\""); - if (p->ctrn_flags & GF_ISOM_CTRN_INHERIT_CTSO) - gf_fprintf(trace, " inheritCTSOffset=\"yes\""); - - gf_fprintf(trace, " firstSampleDurationBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_first_dur)); - gf_fprintf(trace, " firstSampleSizeBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_first_size)); - gf_fprintf(trace, " firstSampleFlagsBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_first_sample_flags)); - gf_fprintf(trace, " firstSampleCTSOBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_first_ctts)); - gf_fprintf(trace, " sampleDurationBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_dur)); - gf_fprintf(trace, " sampleSizeBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_size)); - gf_fprintf(trace, " sampleFlagsBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_sample_flags)); - gf_fprintf(trace, " sampleCTSOBits=\"%d\"", gf_isom_ctrn_field_size_bits(p->ctrn_ctts)); - if (p->ctrn_flags & 0x00FFFF00) - full_dump = GF_TRUE; - - gf_fprintf(trace, ">\n"); - } else -#endif - { - gf_fprintf(trace, ">\n"); - - if (p->flags & GF_ISOM_TRUN_FIRST_FLAG) { - sample_flags_dump("FirstSampleFlags", p->first_sample_flags, trace); - } - if (p->flags & (GF_ISOM_TRUN_DURATION|GF_ISOM_TRUN_SIZE|GF_ISOM_TRUN_CTS_OFFSET|GF_ISOM_TRUN_FLAGS)) { - full_dump = GF_TRUE; - } - } - - if (full_dump) { - for (i=0; inb_samples; i++) { - GF_TrunEntry *ent = &p->samples[i]; - - gf_fprintf(trace, "use_ctrn) { - if ((i==1) && (p->ctrn_flags&GF_ISOM_CTRN_FIRST_SAMPLE) ) { - if (p->ctrn_first_dur) - gf_fprintf(trace, " Duration=\"%u\"", ent->Duration); - if (p->ctrn_first_size) - gf_fprintf(trace, " Size=\"%u\"", ent->size); - if (p->ctrn_first_ctts) { - if (p->version == 0) - gf_fprintf(trace, " CTSOffset=\"%u\"", (u32) ent->CTS_Offset); - else - gf_fprintf(trace, " CTSOffset=\"%d\"", ent->CTS_Offset); - } - if (p->ctrn_first_sample_flags) - frag_dump_sample_flags(trace, ent->flags, p->ctrn_first_sample_flags); - } else { - if (p->ctrn_dur) - gf_fprintf(trace, " Duration=\"%u\"", ent->Duration); - if (p->ctrn_size) - gf_fprintf(trace, " Size=\"%u\"", ent->size); - if (p->ctrn_ctts) { - if (p->version == 0) - gf_fprintf(trace, " CTSOffset=\"%u\"", (u32) ent->CTS_Offset); - else - gf_fprintf(trace, " CTSOffset=\"%d\"", ent->CTS_Offset); - } - if (p->ctrn_sample_flags) - frag_dump_sample_flags(trace, ent->flags, p->ctrn_sample_flags); - } - } else -#endif - { - - if (p->flags & GF_ISOM_TRUN_DURATION) - gf_fprintf(trace, " Duration=\"%u\"", ent->Duration); - if (p->flags & GF_ISOM_TRUN_SIZE) - gf_fprintf(trace, " Size=\"%u\"", ent->size); - if (p->flags & GF_ISOM_TRUN_CTS_OFFSET) - { - if (p->version == 0) - gf_fprintf(trace, " CTSOffset=\"%u\"", (u32) ent->CTS_Offset); - else - gf_fprintf(trace, " CTSOffset=\"%d\"", ent->CTS_Offset); - } - - if (p->flags & GF_ISOM_TRUN_FLAGS) { - frag_dump_sample_flags(trace, ent->flags, 3); - } - } - gf_fprintf(trace, "/>\n"); - } - } else if (p->size) { - gf_fprintf(trace, "\n"); - } else { - gf_fprintf(trace, "\n"); - } - -#ifdef GF_ENABLE_CTRN - gf_isom_box_dump_done(p->use_ctrn ? "CompactTrackRunBox" : "TrackRunBox", a, trace); -#else - gf_isom_box_dump_done("TrackRunBox", a, trace); -#endif - return GF_OK; -} - -#endif - -#ifndef GPAC_DISABLE_ISOM_HINTING - -GF_Err DTE_Dump(GF_List *dte, FILE * trace) -{ - u32 i, count; - - count = gf_list_count(dte); - for (i=0; isource) { - case 0: - gf_fprintf(trace, "\n"); - break; - case 1: - i_p = (GF_ImmediateDTE *) p; - gf_fprintf(trace, "\n", i_p->dataLength); - break; - case 2: - s_p = (GF_SampleDTE *) p; - gf_fprintf(trace, "\n", - s_p->dataLength, s_p->byteOffset, s_p->sampleNumber, s_p->trackRefIndex); - break; - case 3: - sd_p = (GF_StreamDescDTE *) p; - gf_fprintf(trace, "\n", - sd_p->dataLength, sd_p->byteOffset, sd_p->streamDescIndex, sd_p->trackRefIndex); - break; - default: - gf_fprintf(trace, "\n"); - break; - } - } - return GF_OK; -} - - -GF_EXPORT -GF_Err gf_isom_dump_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u32 SampleNum, FILE * trace) -{ - GF_ISOSample *tmp; - GF_HintSampleEntryBox *entry; - u32 descIndex, count, count2, i; - GF_Err e=GF_OK; - GF_BitStream *bs; - GF_HintSample *s; - GF_TrackBox *trak; - GF_RTPPacket *pck; - char *szName; - - trak = gf_isom_get_track_from_file(the_file, trackNumber); - if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM; - - tmp = gf_isom_get_sample(the_file, trackNumber, SampleNum, &descIndex); - if (!tmp) return GF_BAD_PARAM; - - e = Media_GetSampleDesc(trak->Media, descIndex, (GF_SampleEntryBox **) &entry, &count); - if (e) { - gf_isom_sample_del(&tmp); - return e; - } - - //check we can read the sample - switch (entry->type) { - case GF_ISOM_BOX_TYPE_RTP_STSD: - case GF_ISOM_BOX_TYPE_SRTP_STSD: - case GF_ISOM_BOX_TYPE_RRTP_STSD: - szName = "RTP"; - break; - case GF_ISOM_BOX_TYPE_RTCP_STSD: - szName = "RCTP"; - break; - case GF_ISOM_BOX_TYPE_FDP_STSD: - szName = "FDP"; - break; - default: - gf_isom_sample_del(&tmp); - return GF_NOT_SUPPORTED; - } - - bs = gf_bs_new(tmp->data, tmp->dataLength, GF_BITSTREAM_READ); - s = gf_isom_hint_sample_new(entry->type); - s->trackID = trak->Header->trackID; - s->sampleNumber = SampleNum; - - gf_isom_hint_sample_read(s, bs, tmp->dataLength); - gf_bs_del(bs); - - count = gf_list_count(s->packetTable); - - gf_fprintf(trace, "<%sHintSample SampleNumber=\"%d\" DecodingTime=\""LLD"\" RandomAccessPoint=\"%d\" PacketCount=\"%u\" reserved=\"%u\">\n", szName, SampleNum, tmp->DTS, tmp->IsRAP, s->packetCount, s->reserved); - - if (s->hint_subtype==GF_ISOM_BOX_TYPE_FDP_STSD) { - e = gf_isom_box_dump((GF_Box*) s, trace); - goto err_exit; - } - - if (s->packetCount != count) { - gf_fprintf(trace, "\n", szName, s->packetCount, count); - } - - - for (i=0; ipacketTable, i); - - if (pck->hint_subtype==GF_ISOM_BOX_TYPE_RTCP_STSD) { - GF_RTCPPacket *rtcp_pck = (GF_RTCPPacket *) pck; - gf_fprintf(trace, "Version, rtcp_pck->Padding, rtcp_pck->Count, rtcp_pck->PayloadType); - - if (rtcp_pck->data) dump_data_attribute(trace, "payload", (char*)rtcp_pck->data, rtcp_pck->length); - gf_fprintf(trace, ">\n"); - gf_fprintf(trace, "\n"); - - } else { - gf_fprintf(trace, "P_bit, pck->X_bit, pck->M_bit, pck->payloadType); - - gf_fprintf(trace, " SequenceNumber=\"%d\" RepeatedPacket=\"%d\" DropablePacket=\"%d\" RelativeTransmissionTime=\"%d\" FullPacketSize=\"%d\">\n", - pck->SequenceNumber, pck->R_bit, pck->B_bit, pck->relativeTransTime, gf_isom_hint_rtp_length(pck)); - - - //TLV is made of Boxes - count2 = gf_list_count(pck->TLV); - if (count2) { - gf_fprintf(trace, "\n", count2); - gf_fprintf(trace, "\n"); - } - //DTE is made of NON boxes - count2 = gf_list_count(pck->DataTable); - if (count2) { - gf_fprintf(trace, "\n", count2); - DTE_Dump(pck->DataTable, trace); - gf_fprintf(trace, "\n"); - } - gf_fprintf(trace, "\n"); - } - } - -err_exit: - gf_fprintf(trace, "\n", szName); - gf_isom_sample_del(&tmp); - gf_isom_hint_sample_del(s); - return e; -} - -#endif /*GPAC_DISABLE_ISOM_HINTING*/ - -static void tx3g_dump_box_nobox(FILE * trace, GF_BoxRecord *rec) -{ - gf_fprintf(trace, "\n", rec->top, rec->left, rec->bottom, rec->right); -} - -static void tx3g_print_char_offsets(FILE * trace, u32 start, u32 end, u32 *shift_offset, u32 so_count) -{ - u32 i; - if (shift_offset) { - for (i=0; ishift_offset[i]) { - start --; - break; - } - } - for (i=0; ishift_offset[i]) { - end --; - break; - } - } - } - if (start || end) gf_fprintf(trace, "fromChar=\"%d\" toChar=\"%d\" ", start, end); -} - -static void tx3g_dump_style_nobox(FILE * trace, GF_StyleRecord *rec, u32 *shift_offset, u32 so_count) -{ - gf_fprintf(trace, "