From fe78793d19ee5d40dd9aca7ad9605e7ca5044d71 Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 23 Nov 2024 22:05:49 +0800 Subject: [PATCH] remove submodule libwebm and keep source Signed-off-by: 21pages --- .gitmodules | 3 - src/sys/libwebm | 1 - src/sys/libwebm/.clang-format | 152 + src/sys/libwebm/.cmake-format.py | 240 + src/sys/libwebm/.gitattributes | 6 + src/sys/libwebm/.gitignore | 36 + src/sys/libwebm/.mailmap | 6 + src/sys/libwebm/.pylintrc | 441 + src/sys/libwebm/.style.yapf | 2 + src/sys/libwebm/AUTHORS.TXT | 5 + src/sys/libwebm/Android.mk | 23 + src/sys/libwebm/CMakeLists.txt | 474 + src/sys/libwebm/CONTRIBUTING.md | 41 + src/sys/libwebm/LICENSE.TXT | 30 + src/sys/libwebm/Makefile.unix | 57 + src/sys/libwebm/PATENTS.TXT | 23 + src/sys/libwebm/PRESUBMIT.py | 202 + src/sys/libwebm/README.libwebm | 143 + src/sys/libwebm/codereview.settings | 4 + src/sys/libwebm/common/common.sh | 62 + src/sys/libwebm/common/file_util.cc | 93 + src/sys/libwebm/common/file_util.h | 44 + src/sys/libwebm/common/hdr_util.cc | 220 + src/sys/libwebm/common/hdr_util.h | 71 + src/sys/libwebm/common/indent.cc | 29 + src/sys/libwebm/common/indent.h | 48 + src/sys/libwebm/common/libwebm_util.cc | 110 + src/sys/libwebm/common/libwebm_util.h | 65 + src/sys/libwebm/common/video_frame.cc | 45 + src/sys/libwebm/common/video_frame.h | 68 + src/sys/libwebm/common/vp9_header_parser.cc | 269 + src/sys/libwebm/common/vp9_header_parser.h | 129 + .../libwebm/common/vp9_header_parser_tests.cc | 181 + src/sys/libwebm/common/vp9_level_stats.cc | 269 + src/sys/libwebm/common/vp9_level_stats.h | 208 + .../libwebm/common/vp9_level_stats_tests.cc | 192 + src/sys/libwebm/common/webm_constants.h | 20 + src/sys/libwebm/common/webm_endian.cc | 85 + src/sys/libwebm/common/webm_endian.h | 38 + src/sys/libwebm/common/webmids.h | 193 + src/sys/libwebm/dumpvtt.cc | 91 + src/sys/libwebm/hdr_util.hpp | 15 + src/sys/libwebm/infra/README.md | 23 + src/sys/libwebm/infra/common.sh | 65 + src/sys/libwebm/infra/compile.sh | 128 + src/sys/libwebm/infra/compile_android.sh | 80 + src/sys/libwebm/infra/run_unit_tests.sh | 200 + src/sys/libwebm/iosbuild.sh | 207 + src/sys/libwebm/m2ts/tests/webm2pes_tests.cc | 158 + src/sys/libwebm/m2ts/vpxpes2ts.cc | 217 + src/sys/libwebm/m2ts/vpxpes2ts.h | 45 + src/sys/libwebm/m2ts/vpxpes2ts_main.cc | 33 + src/sys/libwebm/m2ts/vpxpes_parser.cc | 409 + src/sys/libwebm/m2ts/vpxpes_parser.h | 177 + src/sys/libwebm/m2ts/webm2pes.cc | 552 ++ src/sys/libwebm/m2ts/webm2pes.h | 274 + src/sys/libwebm/m2ts/webm2pes_main.cc | 33 + src/sys/libwebm/mkvmuxer.hpp | 15 + src/sys/libwebm/mkvmuxer/mkvmuxer.cc | 4204 +++++++++ src/sys/libwebm/mkvmuxer/mkvmuxer.h | 1924 ++++ src/sys/libwebm/mkvmuxer/mkvmuxertypes.h | 28 + src/sys/libwebm/mkvmuxer/mkvmuxerutil.cc | 743 ++ src/sys/libwebm/mkvmuxer/mkvmuxerutil.h | 115 + src/sys/libwebm/mkvmuxer/mkvwriter.cc | 92 + src/sys/libwebm/mkvmuxer/mkvwriter.h | 51 + src/sys/libwebm/mkvmuxer_sample.cc | 802 ++ src/sys/libwebm/mkvmuxertypes.hpp | 15 + src/sys/libwebm/mkvmuxerutil.hpp | 18 + src/sys/libwebm/mkvparser.hpp | 15 + src/sys/libwebm/mkvparser/mkvparser.cc | 8103 +++++++++++++++++ src/sys/libwebm/mkvparser/mkvparser.h | 1147 +++ src/sys/libwebm/mkvparser/mkvreader.cc | 135 + src/sys/libwebm/mkvparser/mkvreader.h | 45 + src/sys/libwebm/mkvparser_sample.cc | 459 + src/sys/libwebm/mkvreader.hpp | 15 + src/sys/libwebm/mkvwriter.hpp | 15 + src/sys/libwebm/sample_muxer_metadata.cc | 391 + src/sys/libwebm/sample_muxer_metadata.h | 137 + src/sys/libwebm/testing/mkvmuxer_tests.cc | 1010 ++ src/sys/libwebm/testing/mkvparser_fuzzer.cc | 160 + src/sys/libwebm/testing/mkvparser_tests.cc | 823 ++ src/sys/libwebm/testing/test_util.cc | 215 + src/sys/libwebm/testing/test_util.h | 87 + .../testdata/accurate_cluster_duration.webm | Bin 0 -> 376 bytes .../accurate_cluster_duration_last_frame.webm | Bin 0 -> 384 bytes .../accurate_cluster_duration_two_tracks.webm | Bin 0 -> 533 bytes .../testdata/bbb_480p_vp9_opus_1second.webm | Bin 0 -> 45863 bytes .../testdata/block_with_additional.webm | Bin 0 -> 348 bytes .../libwebm/testing/testdata/chapters.webm | Bin 0 -> 346 bytes src/sys/libwebm/testing/testdata/colour.webm | Bin 0 -> 416 bytes .../testdata/cues_before_clusters.webm | Bin 0 -> 380 bytes .../testing/testdata/discard_padding.webm | Bin 0 -> 341 bytes .../testing/testdata/estimate_duration.webm | Bin 0 -> 365 bytes .../testdata/fixed_size_cluster_timecode.webm | Bin 0 -> 368 bytes .../testing/testdata/force_new_cluster.webm | Bin 0 -> 363 bytes .../testing/testdata/invalid/README.libwebm | 24 + .../invalid_vp9_bitstream-bug_1416.webm | Bin 0 -> 12847 bytes .../invalid_vp9_bitstream-bug_1417.webm | Bin 0 -> 11448 bytes .../primarychromaticity_fieldtoolarge.webm | 1 + .../invalid/projection_float_overflow.webm | Bin 0 -> 172 bytes .../testing/testdata/long_tag_string.webm | Bin 0 -> 474 bytes .../testdata/max_cluster_duration.webm | Bin 0 -> 395 bytes .../testing/testdata/max_cluster_size.webm | Bin 0 -> 368 bytes .../testing/testdata/metadata_block.webm | Bin 0 -> 314 bytes .../libwebm/testing/testdata/output_cues.webm | Bin 0 -> 394 bytes .../libwebm/testing/testdata/projection.webm | Bin 0 -> 317 bytes .../testing/testdata/segment_duration.webm | Bin 0 -> 341 bytes .../testing/testdata/segment_info.webm | Bin 0 -> 284 bytes .../testdata/set_cues_track_number.webm | Bin 0 -> 412 bytes .../testdata/set_pixelwidth_pixelheight.webm | Bin 0 -> 302 bytes .../testdata/set_segment_duration.webm | Bin 0 -> 301 bytes .../testing/testdata/simple_block.webm | Bin 0 -> 301 bytes .../testdata/test_stereo_left_right.webm | Bin 0 -> 11592 bytes src/sys/libwebm/testing/testdata/tracks.webm | Bin 0 -> 363 bytes .../testing/testdata/webm_doctype.webm | Bin 0 -> 285 bytes src/sys/libwebm/testing/video_frame_tests.cc | 75 + src/sys/libwebm/vttdemux.cc | 1004 ++ src/sys/libwebm/vttreader.h | 15 + src/sys/libwebm/webm_info.cc | 1336 +++ src/sys/libwebm/webm_parser/README.md | 325 + src/sys/libwebm/webm_parser/demo/demo.cc | 1161 +++ src/sys/libwebm/webm_parser/doxygen.config | 319 + .../00805c2543756a5fd85652d03bfbbd2eb6192ca5 | 1 + .../00d120eb143bb02c48d7c863e5826d2ad1a6da4b | 1 + .../018dee8285e9e20ca3996bb2dc0284b5c57ba75a | 1 + .../020edb59637c1e6439f19aa3a5a9d50c3377dbe9 | 1 + .../0247ce2b1a71752a3af11e1065ca90afa0df9d30 | 1 + .../028b19f7d79f5da7a2af13a0c1e2d13f7eaf24cd | 1 + .../029ab55b16df41881f8de2351205201da334550a | 1 + .../029be5e90913b19cf5890559cf3f98aa909f0a84 | Bin 0 -> 5 bytes .../02fb96539b84bbd12de84ff05cbc9dc3faa96b7e | Bin 0 -> 58 bytes .../0349f5632d21faa36b85520ad0b524d561f5e13f | Bin 0 -> 35 bytes .../036fc9daf7fb1b4274dd668cfd883248ebbad967 | 1 + .../037a4edc18e475ec81081e47277cbf51f1316680 | Bin 0 -> 20 bytes .../0481dad9a7d0e6fab0c703bba9b3268db96c6793 | Bin 0 -> 37 bytes .../04dc2407e7142f5618aa5105377925b0b0ed544b | Bin 0 -> 137 bytes .../04fa2f34ff4a4406d136e5aaba5debe7d8129a06 | Bin 0 -> 41 bytes .../054fd0041ad81cfad0a85e3c59195485492a4493 | Bin 0 -> 158 bytes .../056b83ab2457979ea021e7118ab847eba265df15 | Bin 0 -> 36 bytes .../058326151c1d4a490964d495d35adcf15178030f | Bin 0 -> 28 bytes .../05847b5be0eb200d6a6b340c939c7a654b55003e | Bin 0 -> 33 bytes .../05b600ae9a9072ac2865247e69ed0736a0c58316 | Bin 0 -> 15 bytes .../05cf976698b55df1fcd03bc07446bb9283dad9d7 | 1 + .../05d4dfda5e264fffda243f2991a86e96141f579a | 1 + .../061217fc0b6af0ec3851d9728e03ed9b30c702d5 | 1 + .../077b53a7163e51c48e8cdaf4209bb837823ffba9 | 1 + .../07c3ade9713892bb75db2d93b48ef40b262a54e6 | 1 + .../07eaf3c7437032f60c905f6f8e3dfc193491b602 | 1 + .../07f67b922b503354b2aebcdcc4ab7b6d3150b048 | Bin 0 -> 63 bytes .../08af8d91bb21835c50330e997d973cac8ff67766 | Bin 0 -> 60 bytes .../0a18f05bb16402756202160225aec9c5a654f1ae | Bin 0 -> 192 bytes .../0b60823983971ee17a2590678f0fc0762c21bb73 | Bin 0 -> 84 bytes .../0bae7f0976af0f75974047b5f2cf4c9645412066 | 1 + .../0c1862b4065eefab2535ecc6951295e38069a82e | Bin 0 -> 79 bytes .../0c2f51d5ffc69e69680bf3d6edb91d76c353ad14 | 1 + .../0c3af72d69f18103383c9cd41a7f2676a9d28a40 | Bin 0 -> 20 bytes .../0c43df7fc9d06187249187583c3c082520701289 | 1 + .../0cadf5ecf58a394560a1f6db72a2e21264445d13 | 1 + .../0cd91a4e7bec912beb3b47a685b89d5be24d0046 | 1 + .../0d0da60f91f9489af113d8484d9b6871622523d5 | 1 + .../0d30a4f88e53de1ce4bf1ec724016f2f4c11bc9b | Bin 0 -> 90 bytes .../0d6b3b1d024e7aa73fbc58b157ab53df048a2f2c | Bin 0 -> 27 bytes .../0d94310cfd8a9acdbc7fb82ad9c73cdf3f64f926 | Bin 0 -> 281 bytes .../0f5741483be8f4f6eddcb70ea418fb0c08da9443 | Bin 0 -> 20 bytes .../109e125f729f84d69c3e3a614123547a094534ad | 1 + .../10d257a4a314e20644fbc469cdebafe16c7f46a8 | 1 + .../10d951f88995a2176878501a2633b9bb4822ff96 | 1 + .../111b8f8318a269bbe0f7d9f1cebfdc1cb43c982b | 1 + .../11c122ce1f7d993f809a4eb5db17c738f279a707 | Bin 0 -> 53 bytes .../11e288617056809208561f2a9112fd0664d378d2 | 1 + .../124fde9cfe7157773d8febcbb0829914bf4d17d3 | Bin 0 -> 128 bytes .../1386cc740c80ede6dfea5f3bb1d4fe1501ab5e91 | 1 + .../13dd373ccb0c534402c6f7c4a0bdd723a26bc2c1 | 1 + .../13fc3d2b32d789c84be6349bb585c308289b4c3e | 1 + .../148357130d1e5ac4059ad2bb6c63d78e2523f7d2 | Bin 0 -> 45147 bytes .../15366a3aafe2590c2e3183c088dde4cc100cb956 | 1 + .../15feeb939fa90b25f57622a0abd9155ca88ad08b | Bin 0 -> 88 bytes .../16282b78a2018eb78544316554a92fe1003859e3 | 1 + .../1717628a6d6ea868febec5fb196edcf4b9eb284d | 1 + .../17921b1e28600e7e3faf67fc68b397ecab4e2a52 | 1 + .../17b8276355dd2368647b7756431820f5275cc3e2 | Bin 0 -> 79 bytes .../17d0aece97973ab23a467486b177ea9722e1b90b | 1 + .../17e80cf8c247d17acad56c88750da34893fcb4fd | Bin 0 -> 19 bytes .../18040e106688eb1d54323927a403439ecfde6626 | 1 + .../1813261b3141faa01431c82e06292485516d3327 | 1 + .../184ee2343d4b9f62c69383692829fd852ad8855d | 1 + .../186035a2f5c09ccd6b7d15de46f8561c98d8897d | 1 + .../186292900ad9d43881b71765158c32d78d80c8f3 | Bin 0 -> 84 bytes .../18fd762b91406d37b85a7b342a91434a15f17290 | Bin 0 -> 25 bytes .../19334eee05eeb18c549498e7ca2e792a2a4e04f3 | 1 + .../1a9a5df35779dd6e9e1de171b9bb0d316d2b64a5 | 1 + .../1ab3d30f60743c2a1d3043773aae3a04f83c07c0 | 1 + .../1ad84ed46f3fda305150bac93958a5a390e23a67 | 1 + .../1b40a997150aa03c23ecc6efe445a2d7c3dd8368 | Bin 0 -> 17 bytes .../1b6b3bab9032cd420f350b6bb252942484f6b527 | 1 + .../1b7765cb05c94581461ffcd38d38b7b272d8e9d6 | 1 + .../1b89e3fe0cbd4c2291a74bf21969a9d9d851cbf1 | 1 + .../1b95d4da08fe949a60f63cd59213d42d30dbd381 | 1 + .../1bac1200e05bb3269d019903241791c917a12bd0 | Bin 0 -> 53 bytes .../1bb8f5f81b7f6c1d58e1f7bb13fa561fe1a146bc | 1 + .../1c56068c6dd17e9a824db6da78d64f933267a8c0 | 1 + .../1c8db8b9d88dd3483b6f81e4224c4f985046e6ac | Bin 0 -> 85 bytes .../1d29a77924602a79c0f546535a885f59cbbbc405 | 1 + .../1d75a65733da627e5c401625bff522eadf098315 | 1 + .../1df9507cc2a54a369646d6d34d846d3fcc172479 | Bin 0 -> 45874 bytes .../1e7a571be5aa542c3dfec1223d2e089a3075ce1f | 1 + .../20a6b040258fbfa09bb37c6fc07106b2e43bada7 | 1 + .../20e8ca854d3c0c375dc943142a04ee2260f0d1fd | Bin 0 -> 26 bytes .../212ee7d21a8cb25249644cab4f959db111f3a3c0 | Bin 0 -> 106 bytes .../224ce7b415f7950118880fce0594734aef489fec | Bin 0 -> 45 bytes .../226e70c1beddace83862791a6555c80475640bd0 | Bin 0 -> 88 bytes .../233d53e3eb21b6ea6feebd6e59e3ef888a840f49 | Bin 0 -> 21 bytes .../237f7aee90f206d3a6b138cc908b8921b544e190 | Bin 0 -> 15 bytes .../23e1ac0f77f1283cf6e9fa044df3ec51bff27fd4 | 1 + .../23fcee6c71a8f5a22447df688724c0250fb77a70 | Bin 0 -> 20 bytes .../2459eb855d8c6ebac13cb74d996565d78130f4dd | 1 + .../259188e5fb0c09046df96f6d565c59e0d146f198 | 1 + .../26f07f8e28e7521ed282fe5c3938c1ae225816b9 | 1 + .../276425d65d58453d03a3444c9f6662d08d449af7 | 1 + .../27d62874ec87a2552e7c842da65de113aa69f7aa | Bin 0 -> 50585 bytes .../281b259280ada5d07b07a22cbe9a78c7b0fba94b | 1 + .../299ed12b98673c6c4adbcf886cb70db8adde6aa1 | 1 + .../2a40feb7480d0b31c36d5626761e948d0ae52792 | Bin 0 -> 179 bytes .../2a6d7e2b829ed28307b551eda0d96f1834bff899 | 1 + .../2a8dda90aa286175b5c683b57fae1dc7e6ac1e7e | Bin 0 -> 31596 bytes .../2a9588e6fab82016b545462cff2ed014c0345551 | 1 + .../2b1d57a8e8fa7164c9ba00957c9486010754560c | 1 + .../2b475d1a8f2fe4fbba92e1424f0ea96d95b12fb7 | 1 + .../2bb80c6d0e2eadd73018eb2a8cae37d41602ee79 | Bin 0 -> 18 bytes .../2c1389f882e256e260e37e8a67af7e32d0f4e0fc | 1 + .../2c1f94c76e4eec607cce5311323620f349912e73 | 1 + .../2c962c7fbceaacf8247ac9b70c8eeb1f814e435b | 1 + .../2c9aaabacf3a3b48dec4a85767cc5d38a1736aff | 1 + .../2cf086299f983d0afc7f95c5e0c86b657448af33 | Bin 0 -> 40 bytes .../2d0d96b95e9a3316d1ff0ef019ada509bbde4c9d | Bin 0 -> 41 bytes .../2d414d5dfd20055393df3208009840da9cfabca9 | Bin 0 -> 24 bytes .../2df967edcc00ac5c8e00037f1a43680600af5cba | Bin 0 -> 166 bytes .../2e6b09f1eca05ce2bba920fb78f9bca2a883fda0 | 1 + .../2e8bde3549723e13849b604f4deedd51c71dfef5 | Bin 0 -> 113 bytes .../2f6e92a71918d01c16762d5ca59b328f1341d326 | 1 + .../306e2cf9aebe012cb0769b1b2a6ea68af2e8ed44 | 1 + .../30f7348d35de0c47d2044736cb115972b800569d | Bin 0 -> 173 bytes .../310798b8d94a3a2fe649a4c871458b4d74fdcf32 | 1 + .../31ea606a9859bb29d7f98162d254348021e0d932 | 1 + .../3230fc31ab8d408c484aa28bbe36431f71101243 | Bin 0 -> 59 bytes .../328b7c92996e480d1f11efe847c3be4b5dc0f8eb | Bin 0 -> 207 bytes .../32e58bb3d00863115f33707e0c8af722036676fd | Bin 0 -> 50 bytes .../32fc8547b6145c502d98e5e0c296ebd05badfdb9 | 1 + .../334cddba889265a1263feb77a2afdc454ca54f5e | 1 + .../33c9f9990890d2baf0c30d74b34b486082782413 | Bin 0 -> 150 bytes .../341f3e8689e57eeab4234fcdd6d2b8f800b9ab34 | 1 + .../3457e356eac79bf1c30b59940532d360dba2c1a9 | 1 + .../351185a29bdbc7bf0d584479001fb47c32c61e5b | 1 + .../35ae0d43c6bfc5f4b45f16877157832fddafce77 | Bin 0 -> 145 bytes .../35b2f81c573b15304cb9b13f00008b460da78942 | 1 + .../35d9256a4d7ef3ee54384616178af3a8092d0981 | 1 + .../36352efd680a747f0f2c93d760559d69399a4102 | 1 + .../3685ffbcfe28b166ced0a783b012a446f9cfea46 | 1 + .../36def8b2661197d594756f116a750822ae1d65d5 | 1 + .../371950308853fb3b1b3a940c0598bfdfeb1d0f9c | 1 + .../3765e9174971dbac9cfeb7e485ca61dc4941f7a9 | 1 + .../37cae036ce7ff5d0671f32d3757579f248609c9c | 1 + .../38460ea06ee847ff3d5733415c299b44b0866e58 | 1 + .../3865de2fec3f353513d86b28e43bf936d4707f97 | 1 + .../3867b18060c307e0d04e0098f195d699e4b3294f | 1 + .../391920720c3609b7c1f7b51162ce3ec99329a0b4 | Bin 0 -> 148 bytes .../395027454c7d5babff9544414c04a39d712eed1c | 1 + .../3a258c9ed48e634ed8d495f07caf21dbc6978205 | Bin 0 -> 19 bytes .../3a397485197e6b99c77158132eaf211389615fe5 | 1 + .../3a66b34706b686fe0fa8ca8f10c829758b2ebb07 | 1 + .../3ba666ad891fa8009dfc961aa3c215bbfd2d81d2 | Bin 0 -> 16 bytes .../3ba9769c7c23cc3c80542ad123a371cf4f69e858 | Bin 0 -> 41 bytes .../3beb4432302433e303a9ccaf34637dd3a910028e | Bin 0 -> 157 bytes .../3c6cdebc450d20a58150a9c71335b45a6a5ee0e5 | 1 + .../3c867362eb6a20f573a890db87749fce3c719d14 | Bin 0 -> 44 bytes .../3cd69ddcd34bd874e3abade696f95c949c17198d | 1 + .../3de495ebac4b80064b79844f3a9453270caec251 | Bin 0 -> 11 bytes .../3e04542bcc462ded0025b53371f709d8fcd25c21 | Bin 0 -> 17 bytes .../3e94196e55a9214083bda470772d71aedc17eb5f | Bin 0 -> 60 bytes .../3ec4ac00bb967a335b5caae0ae51488f2fda6583 | Bin 0 -> 9 bytes .../3eec38c0ac3a96856d3210a0357857e70b07a9cb | 1 + .../3ef82ba46238fa46b89148a230d23e741ba5f1da | 1 + .../3fbd43f81888ca60e5bfe49b47e23cb115d5cd7d | 1 + .../3fe56e5b06653e8a37c99da190ff8d44d14bfc06 | 1 + .../3febffec3be8b1f4bcb76a01c1d713600d8e4adb | 1 + .../43380e5a9dd29ca847e9b5bfba12a0a95d94d0da | Bin 0 -> 30 bytes .../435d3ff6ddc43ac582e740ead969397fd2bfc7f5 | Bin 0 -> 24 bytes .../448120a37132488f48ab6c46a146c995948958cc | 1 + .../46db501d3e9a8808118333740a22bf9c808af239 | Bin 0 -> 13 bytes .../47a2ca2b47aa1993cb655b77a0273ff139dd2280 | Bin 0 -> 42 bytes .../490576c8f6c235e1ed921c4932bac028070c806a | 1 + .../4930b86bf0dfb02836b0319d21aa4a63a8dd894d | 1 + .../49667ff0b09901223117e74d2506bc37a5ae1580 | 1 + .../49906adf7313330e29be20d51fb36e9bdf1939c3 | Bin 0 -> 41 bytes .../49c0e3eed81c1827e755c70c9c6d9606e7f54b22 | Bin 0 -> 26 bytes .../4a3e77f5bc061fc8121ef7ebd2b8e3ebb0bdd609 | 1 + .../4a454e01ef09b175f3864b654cfc1104a850e871 | Bin 0 -> 192 bytes .../4acd9df9a7ee34e48c6c80777159b089f417a69a | Bin 0 -> 17 bytes .../4af5564129d7b4c9c4736a3e511926c29348a4a4 | 1 + .../4b3957bcbe5975399e34485cf0e5229169ab67b9 | 1 + .../4c9e40aa8a439a500f073cf5a1e060a16ad12a6f | Bin 0 -> 80 bytes .../4cb5ff0e26f5bd0bb1fca846b4843db69095f18b | 1 + .../4ce80549344cf5b0432e39e7b5382407f0763e8c | 1 + .../4d10ae0032f04fa01148a54fae6838c44e4bb5bd | 1 + .../4db2ded939a16fb1907dc2bad7acf67a64e38c0c | 1 + .../4dc3a9a9477fb452ba7a4026bbc01d4cdd3d4990 | Bin 0 -> 18 bytes .../4e1fb006a2268fa5fc70ca6b241bbc71faa6d7ff | 1 + .../4e871bbc5089f9550533641ddf6850f8722dfc36 | Bin 0 -> 86 bytes .../4eeb4507868732d3705d1ab10f6a31f70f579556 | 1 + .../4f21f3584c99e97453ebe513ed44c86530fbebba | 1 + .../5103160695cd56d281faa45d9267013488cc7bde | 1 + .../521103054e395afd0f9612b47c71cfa0e62151b9 | Bin 0 -> 163 bytes .../523511e33c8788ebb1b703d7c5ad12b5da03964e | Bin 0 -> 28 bytes .../525aedb7462311393cd01939e4734d01db48535b | 1 + .../53809012a8d5cfee839c3d0961b7fdc9468329a7 | 1 + .../53c01d820d125e57b28410ca5b3a9c72c18d4102 | 1 + .../53c27071f53df6b8d2e5c419edf95b7792b278e7 | 1 + .../53d5307f2e7852b183839fe93c20647004d151ec | Bin 0 -> 114 bytes .../5466c59c9c0eff34800e19cc92faf07469865ea9 | 1 + .../54bf8d6f1f846243b6f4de81605779b0acb78406 | 1 + .../54fd1711209fb1c0781092374132c66e79e2241b | 1 + .../5506797514c0b214f5faa9764a9e149cd1df9d28 | 1 + .../5566c6d599866f5e523c54e6575d7b9e557a2539 | Bin 0 -> 53 bytes .../55c3d55780427eb00bde252348db1c2ede22526c | 1 + .../5600abaefe804c50a353bbfdd0f9e10ffc102f81 | 1 + .../5611ddd40488973ee6c64c45ad57d6eefe6da100 | 1 + .../56b0ddd4e44492b45ebb7e9438b0a5556c244bfb | 1 + .../5729395b452092152b06fbb8976e9bf1fda06439 | Bin 0 -> 207 bytes .../57cce6fac7c0992eb338e0e538d3e0ee3fe7f1cd | 1 + .../5822672f068da89546838004ae59552e12e132f7 | Bin 0 -> 20 bytes .../59ce13e9a22e88dac879841256ff66f02cd2f8cc | 1 + .../5a020527fc80b0de64e279fc44635687e014a9cf | Bin 0 -> 122 bytes .../5a645b30948850f8efb7bdd11944bdf3112c7bfe | 1 + .../5b2f727461cde3c02ffdfb300adb0b4a09734911 | 1 + .../5b5531d859ab5bbb034345bbaa2852e9d8a1e1ef | 1 + .../5b980cb94e35769ec92a140ca00d34977e7da5ec | Bin 0 -> 10 bytes .../5bfec2fe795176646fa0babecf97c04045bd4814 | Bin 0 -> 348 bytes .../5c28d94242e9a5ba7e7324e59e5dd12f3e31e51c | Bin 0 -> 63 bytes .../5c67728ab04ba3dfe4b2636cf609f9617c4a5974 | 1 + .../5cd36053e269c97f5359b0a075d80bf1e23b5f47 | 1 + .../5d6f99c2afbf68a1b15a17e07945c11db8579e5f | Bin 0 -> 88 bytes .../5dd149b1b8509f456c16c4ac6dac3c7d6aa217ed | Bin 0 -> 99 bytes .../5e84011c6b092e9f0d6ba60f12fc0fae95a622ca | Bin 0 -> 56 bytes .../5f56766993de2b8c2db87116090af546e1add3b0 | 1 + .../60571c8be9bee3b13428613df66ff36cf54309ec | 1 + .../60ac245f262ee1ff177d351a4fe246060fb4538b | Bin 0 -> 86 bytes .../6120aafb0db1715400e47d0a61fb9f6d8665a736 | 1 + .../61953a8f7a9f0613020d297a6d350abeeaf6e58c | 1 + .../61c0a7fef46c0c1b081b1c2b40835805e5989b54 | 1 + .../620d85870206e88db0bc3ee978c24c0bbc1821ba | Bin 0 -> 60 bytes .../621131d8e28a67a6b4fb03c611f4375873d69678 | 1 + .../624cbd42e3ebf35a3a0ba55b3b4969b99054f84d | Bin 0 -> 348 bytes .../6290103200631075988aa3566d8d8922599f8b6d | 1 + .../62a329f65143f1571dc4a2fbb256800c8ce4d89f | Bin 0 -> 52 bytes .../62f8a53cfb4dd625dcb31ee2ba258db3916a3bd0 | 1 + .../6318dc574b3ad7291fee7e01bfeaa674eb0feb48 | 1 + .../6457a079debb9b532255e3e6ddf276b29808b49d | Bin 0 -> 3 bytes .../646061a4526506a0b3c62629f4f77b6072c8f9c3 | 1 + .../6538d0517865c8832ee9bec87609b7bd4facb025 | 1 + .../653de28e2f085334e30ec1c964540b432a3cfbc6 | 1 + .../657c9c42bf3e1c79a6dcb9071bf123367dc37734 | Bin 0 -> 40 bytes .../65ebba0df08a5484686905e99631a4ead845c08b | 1 + .../66dd27c22fe09842ac4c4f51fdef4bea500b6a70 | 1 + .../66e25df2bd43c840337a49e0cb5b386e9d290d80 | Bin 0 -> 59 bytes .../6714df1ac1c54d4c30add212454e9513c6880767 | 1 + .../68a6f9c2f62e9f57667de9563b5d612ec2f2c829 | Bin 0 -> 37 bytes .../69089b76cc62fe00615702bdd1f339e259194d42 | 1 + .../69d8622d24c7315f344c424297986170f7ef2243 | 1 + .../6a700d958cb3a7565d5a6b74540486874d52b4c7 | 1 + .../6a852150c5c2a12d325e78056687a8ea97b25fe7 | 1 + .../6ac8c9f754d5ff3c0cd3f3f585de99dd73944bbe | Bin 0 -> 46 bytes .../6ace27a48f12990e2169cc099007aa5fa11962d2 | 1 + .../6b10397dc3bff2ccf57be4fe3ff9d8d1acb8c76e | Bin 0 -> 156 bytes .../6c3f1d96c06b853551f685dde821142928f55acf | Bin 0 -> 25 bytes .../6c8de4d4bbb5294154c3b140d43836757b9f08ac | 1 + .../6cf122ee328af5cf6f18d5f9546b0fe761951b8d | Bin 0 -> 128 bytes .../6cfbbc25caa217e22fd7ca3e92d2051c5f661bdb | 1 + .../6d703bc900e74d1a576bebcccb63e3b2701ae86d | 1 + .../6e1afa81dfcd6833705d84b45881f085c19b2211 | 1 + .../6e244ec3b81e0d2f8b5810854859e1b8140422d9 | 1 + .../6e323b4c733df90d55c754e099fb5a13bd9701cb | 1 + .../6e36720f3f55dc0cd5d585c6770572964719b5b8 | Bin 0 -> 56 bytes .../6e8384ab115ac92bb7787121cfb03582e2d72585 | 1 + .../6ebf8b74dca1657f5f7ffadeccd629984473dcb4 | Bin 0 -> 19 bytes .../6ec18dcca0d820fff04c03c3a1bce37dd8ada41d | 1 + .../6eceebb8f46545393d217ab0111ff7dd29bc99f7 | 1 + .../6ee071f654fd6b7b25725a8bdd880bb6836e8c81 | Bin 0 -> 80 bytes .../6f1088b3d1f4cdfbc37d9b8cfc1ff4c3bde2f205 | 1 + .../6f79e36e880664c9b3b610140d2485fb6a6e5039 | 1 + .../6fbea59066b2b97fa45259aa87c40c4310070019 | 1 + .../7056b9c294f0cff7b4ace611a19363b2fc096bb3 | 1 + .../7073dca40b911fb22f738c99aff43a10ae6c4db5 | Bin 0 -> 22 bytes .../7164d8ca3f4c3d621cc5eed7b59e3495e7b017a0 | Bin 0 -> 18 bytes .../71e3e01b3cfcd4228402cbf19b5282c965f042df | 1 + .../720d36ea7f9616b1a1d47fa5b746e8657b5f973f | Bin 0 -> 188 bytes .../72ccbcbc53c7fa54247a81bd1d0e62dd0779494b | 1 + .../736c0460f94c089c9e270857a4222a21ffd9e13f | Bin 0 -> 5 bytes .../745e32f46833c075c8e68552e0fbbcdd5ec52641 | Bin 0 -> 15 bytes .../74aa7256477af2c0e2511df16376dee323f3ccb6 | Bin 0 -> 69 bytes .../7528086eea404dccc3ee5b214befbc2a95676feb | 1 + .../7528f9f08f80c8e85951aa1db2dc616e992c1a62 | Bin 0 -> 26 bytes .../75af94f9695c375e5eb620849f0213ad41e8f205 | Bin 0 -> 39 bytes .../75e1ff2e016b7b80ecb7a6a1f4c3238a2a2ed130 | Bin 0 -> 18 bytes .../76129c3bdedafb3bda93f53266bd17bffdc30682 | Bin 0 -> 90 bytes .../7670db89e0c3fe492c91458de219c3be34a3dcb7 | Bin 0 -> 118 bytes .../7673d7fdf630637c6ae2b96694a047044c1a9cb0 | Bin 0 -> 20 bytes .../76903905e654ddc59acf57380bf3dc1ea136bad9 | 1 + .../76d36e3cf3d31e0f76af08bd7ba5571f679057a1 | 1 + .../775ce646f7dbf50199b8e8df85c9441b8a0a5447 | Bin 0 -> 59 bytes .../7770a6fd33ce821e60c78b0cb67a7e8c8bb74269 | 1 + .../781b24e3433ba400df3ccddf56cb8fc7b1fd52ce | 1 + .../784db9d87b31ffb040ad212e4018b30c3535ad18 | Bin 0 -> 121 bytes .../7880e2ae55d255065ad415c4c625e1b63bfd2a93 | 1 + .../78cb3d726e4f9e8bc89b399fa514c3b600bf8e5a | Bin 0 -> 185 bytes .../79ba60931988a5974328a73fe091bdf6f5992891 | Bin 0 -> 24 bytes .../79cdb8dec1ad07b389f544a511f89b347429837e | Bin 0 -> 52 bytes .../7ab8c6a65c39907f4afa4e2b294303aebb6b22d8 | 1 + .../7b12a398a1860ac2f3930d5020e422aec061f177 | 1 + .../7bf1682743405f3d5b3433830eadae4ea311807d | 1 + .../7c7ef0e305f37f833708b375271d59300d120d84 | 1 + .../7d06bd4a7de57953ef09c2e18ca67aa7ff367c76 | 1 + .../7d31bd53bb7eb7b1f354c5f85d376390760ab16f | Bin 0 -> 32 bytes .../7d67ef4d0c681655d4b4e93e848d56865630390b | Bin 0 -> 17 bytes .../7db9fe869081fdc855913dd000de0d493f5d5192 | Bin 0 -> 33 bytes .../7f20c1e73451c3321c30223db91b891753ef77dd | 1 + .../7fd4d999983c3fbf22763853e90ec10b03c70b17 | 1 + .../80039ce7eff40359bee041d75e371b55117aad3a | 1 + .../8104a007bc88a0a8d81ce1fd26d8b2333061e920 | 1 + .../81320c48ed6eea94712c5e8594c0799fbfe30d10 | Bin 0 -> 80 bytes .../81425ca3d0afb88cc10d412dcc9795905eacd6d9 | 1 + .../819b4bd08ae7d758990aea8ab9739f3cb97fd42c | Bin 0 -> 156 bytes .../8206d92b710c04ce0bd706cec25fbb72014c79bf | Bin 0 -> 64 bytes .../822926c528d16c0a9ca4c48a25651f6a0730d797 | 1 + .../82d80b6051f0750777bdc37319851741144b3671 | 1 + .../830c73748baaa10c2016d04b408a7f481882cd89 | Bin 0 -> 88 bytes .../8315ca46618bd0771353336407396df293e8c182 | 1 + .../831c152337e8b2993b8cddfde7553a8c9e64631f | Bin 0 -> 67 bytes .../832fad0e723027e5bd74726b1722a838183dada7 | 1 + .../83b78d2ad8afd0729de45b4d9fdd765a949d8073 | 1 + .../84a04bf3e15345f5c992bc6732a42b95857631a7 | 1 + .../84d3a72c434074ee0d810fb2357047efd23f58f6 | Bin 0 -> 126 bytes .../8659fe309298ca90f201ac7ced95b9d0de510eeb | 1 + .../866cf21064b9e20eded44e2e096fd9ce6185ce86 | Bin 0 -> 8 bytes .../8864c6c9319ef120d3accb7b70c32c8f5c1ebccb | Bin 0 -> 10 bytes .../88f01cffe9972bf447a21034c45f6b943ea3ec07 | Bin 0 -> 36 bytes .../88f15d430469d209b72cd098405efd15a6d18b05 | Bin 0 -> 120 bytes .../8936b35f29084151fa3755d81030386940523c07 | 1 + .../89a42d72ffe0b23309a9da4e15b8854c1cf939ea | 1 + .../8a0cf07d2592231bd579e4399538d9f490e3e5b9 | 1 + .../8a5d1c05f894414aa5aaa66cf901c52dfcb119a1 | 1 + .../8aa514b6e6fef8d045aa049fdb52fa8adcf722d4 | Bin 0 -> 25 bytes .../8b0dcd4400fe19cf6a268af780990f47dba08189 | 1 + .../8c4655e6528071edd445715ff1559f399dc9d47c | Bin 0 -> 176 bytes .../8c695cbcc43e37ce25194c4b61b3d87488b308a1 | 1 + .../8c9dc3c5a839f90f29256ef8c8f1369bc7383817 | 1 + .../8cdcf83eb89d7e5c87cfa1b8811c95f738747a6a | 1 + .../8d0c6e6b3d74233685c3a2c1793d1a7b0ae2e34d | Bin 0 -> 18 bytes .../8d444e8b311d158f854a03ca35d2c7865cd2c46b | 1 + .../8dc289730cc03ecbbed57d04cdca538a4fd08059 | 1 + .../8dc58cfcb396a60db921901f1b0807c4f4f37619 | 1 + .../8e05be75b7c14c463af277559dc8ea7841a733c8 | 1 + .../8e7eef00a7a6719e77544b57d1d98ff83a37e55a | 1 + .../8ed6ef9af5555ce4ff12b23139add9621e7ad930 | Bin 0 -> 92 bytes .../8f39f83b71d49805a451f81a5a451f5f3d74927d | Bin 0 -> 63 bytes .../8f403efbef079f1775b63bcf1061983e4c5d2162 | 1 + .../8f8f956eaaf8f7f5e65002be888b946218f0f7ce | 1 + .../90a03241b5cc656b7c2a4ef55664b0320fa3bd43 | 1 + .../925a91e7c25a43d9da8b63eba51ed66a52d833aa | Bin 0 -> 42 bytes .../92de5c217802ec24886240188dca293325eb17c9 | 1 + .../939da66e1fc8bb9854865066ee47b6ac4b933aa9 | Bin 0 -> 107 bytes .../93a91331e7c3c060f461ae1f22e2bbf4747ffe33 | Bin 0 -> 64 bytes .../94f6dfc499cbf2e84ffe1d69cb751ada9f2f2e3a | 1 + .../9539fef8ffb9f7c542061f1af1f3f98e9a714cc3 | Bin 0 -> 1132 bytes .../953c9a616ea56067225c88fccc6423496f2501a6 | Bin 0 -> 39 bytes .../95a60268c555a77c1010d75bb44142af47635486 | 1 + .../95e410025b965cf6ab2e8e2d3559efbe71c1a972 | Bin 0 -> 44 bytes .../9671f253d1eb7cd504a5617058ce4c01a80c897e | Bin 0 -> 15 bytes .../9698d3424f1581a6bbb66c764f14c95a74b87675 | Bin 0 -> 64 bytes .../96f7f38de1f8601311733984cf51cec35500dabe | 1 + .../970ab6333aa5ccf8c2dc14bb56814f7bb4303b94 | Bin 0 -> 53 bytes .../98978113d2116dc4bdbb10265fa32bd95230bdb6 | 1 + .../989e2872d2a34de543f23c5061db68212d8258f7 | Bin 0 -> 21 bytes .../98ca9a00ad571c4454fce709d5405e5aca2a363c | 1 + .../9965361765a4151902ec04fb21d9247b3a5ed10d | 1 + .../99d6fe94a50faa50db9d7eb38d74bc3cc8417dc1 | Bin 0 -> 39 bytes .../9a6869cec3dc84f2051bfaf0ee0d3552aa221f89 | Bin 0 -> 218 bytes .../9cc1f26de1e3a7df8c7c03b95ff73ce9709c85f1 | Bin 0 -> 18 bytes .../9cc5b552abbd551485135fa87eab739a0a784057 | Bin 0 -> 26 bytes .../9cca361865a4fbff75abdbb79c1e91706780576c | 1 + .../9d8e99f07604d6cb05ef613d41cbfb93b2aff787 | 1 + .../9ecd61eaf2681a882473247a603b9f30c2663d49 | 1 + .../9f0a3b7c0814b4f80c0745161c8769f63098981b | Bin 0 -> 19 bytes .../9f711c29ccf3f54d44000d7ef6299585674be288 | Bin 0 -> 188 bytes .../9fae60819c28d4fcc88a6a1b93dcf69b4e458203 | Bin 0 -> 6 bytes .../a02431cf7c501a5b368c91e41283419d8fa9fb03 | Bin 0 -> 2 bytes .../a0ac6c3c83817637bbbcb11a5106c57aa6654afb | Bin 0 -> 12 bytes .../a15fdfa620d19a92d9eaa9f3f13010e53f902796 | 1 + .../a18e76ae792a054c2f6d0d01e0e78d58678b35e3 | 1 + .../a19d04f18f574e561d793ac0dfcffe2b38183eb1 | 1 + .../a26fb85be3d2bb8a2360bb4d9533a1651bd12d99 | Bin 0 -> 50 bytes .../a2e860fae30005a9e75b61f54f3d019c44090fcc | 1 + .../a3071bfcb7b2fd3c4286ea42e1f7940754b55697 | Bin 0 -> 56 bytes .../a4ac408fb9d6def070ad3a76312ca092863048e5 | 1 + .../a4fafc117cbfde8c240deccc8997c7966d9109ba | 1 + .../a59ffb5f6122e45136352585d3b53294a71346d0 | 1 + .../a5b3a3c48727c26dfd625f247069d2cdbfa031f0 | Bin 0 -> 52 bytes .../a5c829fbcd9fd760bc55bc8ab6901b8d401b65f6 | 1 + .../a5fbbce038cad4f5e0c0f97fa69ebc3601123e5c | Bin 0 -> 40 bytes .../a6e57b33e7a219168280e51bc98a44de40f0f9ca | 1 + .../a78afe9e4e9f02a10ebadac64171ad49749a6965 | 1 + .../a823a019c0b19c97a1d35722cd843109ab016c17 | 22 + .../a8468104c65a6002fd3a9d4ac39f3ee34c21ce4a | 1 + .../a899424027f1d69a05384355858311a6fa3940a3 | 1 + .../a8a5de5a86a16952aacdf602120f27807294c3ec | 1 + .../aa65229e62d7cb8048d2f5911226b177e8e53cab | 1 + .../aaa96713f8ccb0bbd5c8e91715d4b86e7b338676 | Bin 0 -> 36 bytes .../aae6354e5ba12ee3ad89fabfd72f5368a639d30f | Bin 0 -> 43 bytes .../ab6f3dc497f93f251ebacc153409b1eb8e05e2db | 1 + .../abf5b18d1c1155d3e455c8b781948498f364965e | Bin 0 -> 27 bytes .../abfe5dbf594a2f22173fae7ca8de28b4e3a40099 | 1 + .../ac842f2cc55d7f193273a35f8af3521bfe2317d0 | Bin 0 -> 63 bytes .../ac923c36dd85ff5cb2a0c5b29c701999c5f2eaa0 | Bin 0 -> 40 bytes .../acc6e100b519d6408a8c6d8aed19203d874a187a | Bin 0 -> 59 bytes .../aceb250195867e7d9bbf6eb6e0055251e4bb5d67 | Bin 0 -> 86 bytes .../acf1dd17e6a2848dfe17fb0d76cef2ce7d59ebdd | 1 + .../ad94c2bda2ae4afa0f7264070fd642bf37aae596 | Bin 0 -> 91 bytes .../adad2ca7ab313add6e955f704719e03d5229e4d0 | 1 + .../adb1f8cd3b68c076d81311071aee2a1c3785c7cb | 1 + .../ade30c327d9f51daf37cb3e39fdb15125b84a257 | 1 + .../ae783661f52d36f9d6b87c8394ee6f2d61dae640 | 1 + .../ae8da06c3c69076c06108219e19c8b36dba05a5c | 1 + .../aec8a29238dba3c37f45f2e2e4e64b0e7fa60a74 | 1 + .../affba8e4061bf260b1bdf8a815675cc3b4ebefa5 | Bin 0 -> 63 bytes .../b01c4e2657a230e2b600a20da6f107b0dfe2467c | 1 + .../b0798ecae4d9e56eefb0c1d95b657865938e62d6 | Bin 0 -> 37 bytes .../b0ab4f92df810edf4371baad1d4bbd95d360c607 | 1 + .../b14e5f5f6d29b6b71e7fec03eaf7d8237c0c6b2e | Bin 0 -> 178 bytes .../b1708df7f6dee0f2feb11f8b6330be0fcffc1f58 | Bin 0 -> 7 bytes .../b1af4f4e86890fad6fac96a23956405c550778be | Bin 0 -> 39 bytes .../b1efd9e687d79e3f5a75eba02bd80bedb72350ba | Bin 0 -> 59 bytes .../b25b0fbf46cef1d888fe900445c9ab95330f44cd | 1 + .../b2786e0b9d6e7b39165eb4e87e3110362e9e6660 | 1 + .../b332536a77d6efcd379cfc2f9828291516cc1ff4 | 1 + .../b33962eca397f59591dbb9668e622cf99f2d7cda | Bin 0 -> 91 bytes .../b38b6e93da1b43441f88aa53370a9f00b35c3326 | Bin 0 -> 62 bytes .../b3e01674a1e4dd78e748782fcfc3add5523f51d8 | 1 + .../b53e7ef9aad70fcd80986696ebc586c03495b8ed | 1 + .../b540412c01f960f95edd2a1bc03f1b4447f2b4f2 | Bin 0 -> 5 bytes .../b62c2c591db32b26e997aa4ece577742db84428a | 1 + .../b62d99583f30c15c3c2dbed2f69c5e45075d7640 | 1 + .../b62f98976c11d79674b019ea78a7ce4d6d78b479 | Bin 0 -> 2 bytes .../b6787dabeb5cd64ac85f1ec5a7cbeecfd48b2c5f | 1 + .../b82ebcf4d09ba28d835cb9667da603e46e3438eb | 1 + .../b85c6bc2473aa12e22f91db3546dfa9d85d8b3d1 | Bin 0 -> 27 bytes .../b86e98660980680890bcbf02cacdf568d530fa64 | Bin 0 -> 48 bytes .../b8d9beea35762009941189674c2cfcd14f81254a | 1 + .../ba517141fc9a468142a8d03d4ee395b4d4f30edc | 1 + .../bb0a596017cfc2185505d28065ab3cd238d0e2ea | 1 + .../bb6232815b373e441e2acfcca015f75c680eafac | Bin 0 -> 39 bytes .../bbdf4fa36ba9d645399f72c74033fd9c2631aebb | 1 + .../bc53c9f93974b4f13382c1d49b1e3ec374005ee2 | 1 + .../bcacc9bcd3b9cc7dbda9c52c6e4a06a756a9de90 | Bin 0 -> 45 bytes .../bcc55f432bcf39c6ffc6d7e950612b35e9ea2ec8 | Bin 0 -> 42 bytes .../bdb1cc868d6ced390f5d35c5f43da9f464fac464 | 1 + .../bf67bb08e0abde692748031c297bc1c7910542f4 | Bin 0 -> 34 bytes .../bfc07c62ef2770d53d9188b260f531a8128a5c5e | Bin 0 -> 53 bytes .../bfed121df31ff73b770ed7f27fc7f4da2fa73e0c | Bin 0 -> 24 bytes .../c01816206d93691165e6e3a1924cf9fbc9cf39bd | 1 + .../c02be525edae59ad9d0d9dcbd790629dc9aaee9b | Bin 0 -> 130 bytes .../c094ce0c13ee9a4ca37817d9f7dddc11b2d60177 | 1 + .../c0aab5486ad2e80bcc12fca9fb6653984aa68274 | 1 + .../c13ca850db259c032cf24cdf6f2833c9d74529d0 | 1 + .../c1a8da6cdc8988e6a69961413803acbd1ee935e0 | 1 + .../c25abc82a0470129f2d098ac65fabf34c4e11188 | Bin 0 -> 61 bytes .../c2787d2cf1d95cbcd8b9bcd15d50f67f7e92ad9f | Bin 0 -> 53 bytes .../c2895ff545ebdc4140951c0ca956524d7a364b77 | 1 + .../c2cc55849ff4858bf80f1a4713187618d14a496d | Bin 0 -> 35277 bytes .../c2d63b1d75cf53ee3b955bb143036ca93ef3a256 | Bin 0 -> 105 bytes .../c372a27f78a62ebc013958fa4953a8bc792db53c | 1 + .../c392963b395a7f92b3bef63fd34bc31ecd3029f3 | Bin 0 -> 108 bytes .../c3b2749ab6c4d303bfd5da9ea9c8807e9f92d259 | Bin 0 -> 25 bytes .../c4dd3c8cdd8d7c95603dd67f1cd873d5f9148b29 | 1 + .../c52fa8d16e520980e470d76e3fb4f6a612f0f3cf | Bin 0 -> 28 bytes .../c56fb214efcd707e6fa68b803d9e7686fc2f4336 | 1 + .../c5902afe54998ebc5d8d59043227d379a8c2eee0 | Bin 0 -> 16 bytes .../c6a16abeea323833079e97b1830610aa6c6eba91 | 1 + .../c6fcfd2a1f91a7f6a8c124f2637e60645be01006 | Bin 0 -> 25 bytes .../c75b02a90370df1f54de2f63a4da8db22f2cf719 | 1 + .../c77cb763d73db279aebfb42d2b5dca3d705d3df7 | Bin 0 -> 91 bytes .../c864ac8bce0353ecc7d5cb0ce5a1e77a5239201e | 1 + .../c877c08a79a7408aed779d4a430c5db1bce26314 | 1 + .../c8aff6e2e2dfb18be385483b871ac86ff6eac63f | Bin 0 -> 200 bytes .../c8c1c1f970bc809a75ad076bdb06275b6f72d078 | 1 + .../c995d52934ac188971f02d5dbdb3cdd70cb03267 | 1 + .../c9e7fc3e0e1015a1c15992447f678a495c3ea5dc | 1 + .../ca5b619ce1bbe23d519f5764d53458d2b85eb9fa | Bin 0 -> 121 bytes .../cb0556c65c7381192c94324a3b1b8afb7e33fecc | Bin 0 -> 54 bytes .../cb1a093e6810c7f6c002a2a54ea390cf769c9949 | Bin 0 -> 52 bytes .../cc1487af64aeefd7080e7678a04870dc85a7928a | Bin 0 -> 25 bytes .../cc71d2c9f5eae12acee133bd9e50d84881a1bd88 | Bin 0 -> 5 bytes .../ccb8f962426683663972534c15354f70c3b34a10 | 1 + .../cd0771c4754dfcd9c89b9b8a02df96fed974850d | 1 + .../cd8899c66cbd92ee57f94e000744b32662258ba3 | Bin 0 -> 20 bytes .../cdf83138f69f0f7c66c13b56028610ac39038b3c | 1 + .../ce0138cd7718397b365d4c15b0b14f666c307419 | 1 + .../cec5c7e50ef1d865c879563d1a6d677adb86695c | 1 + .../ceff1dfaf2de4e33d2e3c20aeb7ba4b98f97784c | 1 + .../cf04b5d28cea1971478806979b256a030a671541 | 1 + .../cf1cf6ad5b3554c3ffc86a859319445158665ea7 | 1 + .../cf2338960588d4a5f02a47f3ee96a556224aad75 | Bin 0 -> 199 bytes .../cfb09018afa0eb1a829e556d9f8bceff40cb36bc | 1 + .../cfbe3d66d7eb3199440e8e911a93044cc3165c6c | Bin 0 -> 227 bytes .../d0a91f7984904976de592cb68e8832853fbec9bc | Bin 0 -> 20 bytes .../d22f52563c16725ce4a924dc05d6ac7d64798c43 | Bin 0 -> 154 bytes .../d2709a1c9d96e72cb844eedca8bfe8440cdb0ef8 | 1 + .../d2e385f61ad4b5d45a10a5a6cb85d72e84dea54b | 1 + .../d2facb213561b30a5bcd012e4e01d0d5b0b26957 | 1 + .../d300e5e46a825e5892fae1ba3c466c836f9e1da2 | Bin 0 -> 63 bytes .../d302c69c881e230e6433283007d318ba437025c3 | 1 + .../d30c1b65bc141d1a15d4ed622ba182c96dacdf92 | Bin 0 -> 22 bytes .../d3adf09fe6fb1534157c1dc68eb61365b46b1c35 | 1 + .../d3c74d3a64dba86f98a31bb726587ec97a7e4531 | 1 + .../d3c9846ab319f12fc646c23a532c780daa9e993f | 1 + .../d3f03301b52cf4a830c7dd200ed8ccbc09e6ec94 | Bin 0 -> 18 bytes .../d4800745440dace38766db3520ffe7baa0bd78f2 | Bin 0 -> 4 bytes .../d4d6271bba704ba08c2678eb8b1bc4e457144f50 | Bin 0 -> 20 bytes .../d54020f766061e80f445690c2b5694ed8af21e9d | 1 + .../d588515f125ebe968fe6a81cb6df7cfc41969e68 | 1 + .../d5ee5e4dc8fad9f1da43102d8322beb005a047c0 | 1 + .../d62459bb217d3050bcd9e29a6327cf81f5ed68b9 | 1 + .../d6acbf1cb46845618ed0d5a322c8bd4879d16422 | 1 + .../d6fc8cdbb0f1517159531098e900e2dcc91edba0 | 1 + .../d7a9bbd9875a60edf9c528b298ea72a2fad7d3d7 | Bin 0 -> 59 bytes .../d82e70046a544e95e81f6271dd2695f2599f0574 | 1 + .../d84bc8dca7c8fcd227254c06f5b88eaaf7cd5fde | 1 + .../d8bcb7dd21205e7126e700323b1d58817e9d9a6d | Bin 0 -> 39 bytes .../d8e2628b4092b9bbab4f02041647f950503eeb48 | Bin 0 -> 33 bytes .../d8ee4c2b79863a237c432efe7d43d99c8d0afb9b | Bin 0 -> 53 bytes .../d8ee9724bf16ff336387723dcf27319c3be72e01 | 1 + .../d9379969bc956ad623e4bab8bbe47270a880a62d | 1 + .../d9ccb79b0e070dcc2f5ed8e15d99bc5ef86ecff7 | 1 + .../db83586ca6266e03067e9a9772ea728ab770ad9a | Bin 0 -> 25 bytes .../dcc63c06ed2790d1380bdb9281fe8677f439c76d | Bin 0 -> 53 bytes .../dd509e9a4660ec34b8f9dc23441c6df4ff97c34d | 1 + .../dd72f8ff3a067dc7871438b6023e1ed0a4c5787b | 1 + .../dd75880c5ad488885260f4031a763c86a8084406 | Bin 0 -> 111 bytes .../dd962d74d04aa4aed270fd8e6b0ae9c4ac35fd19 | 1 + .../dd9aa9a49dd790b2ce99c5af1933232d46a7f80d | 1 + .../ddad7630818a1caa8054d2d7280a1d01bdb33ca3 | Bin 0 -> 18 bytes .../ddb2eaf33960ce69d579a551a7b05733adcd52aa | Bin 0 -> 41 bytes .../de0d98cb997c0a0f7be127a46d8a24d8a003931d | Bin 0 -> 47 bytes .../de0ff884898c83fb880498f1b8328f78701e6534 | 1 + .../de9e0ed8ae29220e5b65e5b97eb3b254ccbe7e0c | Bin 0 -> 45106 bytes .../dec5e8ffb35aa707d127a11a49e47cb59954e969 | 1 + .../df1b205e339e7199b5094fcf0ec3b8a8ca7a692c | Bin 0 -> 53 bytes .../df254daba2299f3ff2367e284efc53a3296d136b | 1 + .../dfdcde31231b8b3d3fd4e0ef8ea88885f488c4db | Bin 0 -> 64 bytes .../e01962d7dc1b94e5c4424ec7adae16a7c03b9773 | 1 + .../e058723f2964bf1405ae043ddb99efb17d821e15 | 1 + .../e09e306ef596dcd0e44bd3ef3c5f7019c7343f84 | 1 + .../e154eb76d096c1e545dcad591a58a02c37cd71ff | 1 + .../e198d2e4f2f3528c2ff46d769a9281ebb3cfb44a | 1 + .../e2068af1e903f4a81cd6fa5f4022e62070c259ec | Bin 0 -> 39 bytes .../e2890330b5655cb277a581b8dd2eeba0d9061ba5 | 1 + .../e2e0767d055a7042c24a7acd5d5b6b7c093ad065 | 1 + .../e394a8e21e2c43c42135daa034ad5aabb06acffb | Bin 0 -> 145 bytes .../e3b200e97ec226a197e91f12103aaa53d5c37b0e | 1 + .../e45b077cda64c380ae1b0910bc81d010c27e1c93 | 1 + .../e45e71ca01ebe01b01b0ca99b8f20a756c36b967 | 1 + .../e4ff4bd938c3737a02862fc0656a1859d384d066 | 1 + .../e5a1acb7e6f71bc1a2fedaa6173764dfd04c844c | 1 + .../e6081eeff4ddb76e88e87ef9e4b5f199f5f11c28 | Bin 0 -> 63 bytes .../e73c42dd266c4d9671da0c7af09e98c02fc052fd | Bin 0 -> 86 bytes .../e7b4559a77df21b73285243a8350b844775bb380 | Bin 0 -> 21 bytes .../e7dd34a80646a8c38ae1ec3a27c1358bab13b360 | 1 + .../e80b344f943ff0ad9219277c4578d3b4100b71dc | 1 + .../e86e26200290d9d428c5e98e191ec874eb918fb6 | 1 + .../e873a3b8f5c3b716e6446df34279b837cf8d2c30 | Bin 0 -> 53 bytes .../e8fb71319db98d8e8cd131a4eb82879bfbec14d0 | Bin 0 -> 123 bytes .../e93c3f14614595a2675993438b4c1bfaafdc02d0 | 1 + .../e93faef2d77b7c467ae280ba433928d66d63ea63 | 1 + .../e95401b11d974ba63270668d3c32c29e95ae85da | 1 + .../e9723cebe688912f684bcd19b48e5bc8efafaf2a | 1 + .../e9a4389895c006d4b912e8ac1169229e6b2a66da | Bin 0 -> 56 bytes .../e9dc3d10b47ea580404c8e80b844a9978fcf4747 | 1 + .../e9e2ac24e5674e7ee424e2b270e5abe84f1a15c9 | 1 + .../ea2b4df24b526aad253ab175334cb934b9d80b83 | Bin 0 -> 30 bytes .../ea681d11486feeab2f080b06ddd2533575b7ace4 | 1 + .../ebb747925360528a9f366f9a57730883c636b2c7 | Bin 0 -> 56 bytes .../ec39abab70a8e1ff072eb082caa6ca77b1ae8087 | Bin 0 -> 138 bytes .../ecdd96d6cab2dc714a0b0ada1c4fcb18c75298e4 | 1 + .../ed008faa6c9001951f50588a1597e03931501343 | 1 + .../ed12e272a27a2fbdbfe5a6e78e49ed722ebd3c69 | 1 + .../ed799ba0608690ac68dd85c588004197b86e02bf | 1 + .../edd982c5bd3030bde8c044760e9a678c2a9306f4 | 1 + .../ee82c97e35ec92ec3b0bbf911904a050b3aca633 | Bin 0 -> 192 bytes .../ef11f14feee00e3c198015e6bc76688e970e2d8c | 1 + .../efa12e91e0d63c2353c120ca1ded7b36afbf57eb | Bin 0 -> 59 bytes .../efa14cba9bbaf749067b7bb8515a5d8a289fa389 | 1 + .../eff9bf13cd33ea50a8eacc5f2839cc4b5d67b2de | 1 + .../f0143756917f0b2e374bd03e731cd64168180054 | 1 + .../f0b9dcd4e1845f774bb0f42653b11040baee0765 | Bin 0 -> 118 bytes .../f1a41ceb420b6b3df50b10f27108c133d4d07508 | Bin 0 -> 24 bytes .../f39378fd978c6cdb4a8d08cdffc9034e2ca5b687 | 1 + .../f39707a104112d13d9d6bcfbef0efe8dfd98270c | 1 + .../f4341645a7d466113655d63c5aa00855904166c5 | 1 + .../f5511a42d83f94619ff8ca6c940cacc32bdc4834 | Bin 0 -> 192 bytes .../f57a39fa918249e6941b4e770e15a8131ac16ea5 | 1 + .../f5ac272a1dbf362e265210869aaf70ca410f1703 | 1 + .../f64c5ca1de57bcf323741f56754f53c642be8ab0 | 1 + .../f64dcdee393b4b0a3343f8e684c9db91a6eaeb6e | Bin 0 -> 53 bytes .../f69d2954da077043c6ae085e2771a702689314d5 | Bin 0 -> 82 bytes .../f74e2203adb9c94ba80f7cc3214e3b3040e5675d | Bin 0 -> 90 bytes .../f7906e7dc01323b9d3d6e298e8dc2386c8d152f6 | 1 + .../f825cac511f3dc38a5ecf3aab3691b4c49ca8f0e | Bin 0 -> 59 bytes .../f84c3f9e305172f2ae15dff0b4d955324b3a398e | Bin 0 -> 19 bytes .../f87cfad97831c33610fbbe34a04369bd93862464 | Bin 0 -> 72 bytes .../f8ebd7703fd3ba1a135b243fd947dbd61907d0f4 | 1 + .../f926f6b2337650f8b518422c2f63a8869f47c742 | 1 + .../f939897b9fbe865c96020927dc81de9dc255d385 | 1 + .../f985f995ca7d1b691e6ae3b3ef57e8b3c7aa7129 | 1 + .../fa79e8ad34cabea4d3c434cc02ea1499069fcafc | Bin 0 -> 47004 bytes .../fa7a8dfdd46845ab0fd9b5b7004e37d0232941bf | 1 + .../fcb3054fde86111e2c346aa71af2456a1705902c | 1 + .../fce30dcdf2f23b14c580c282a39e065d7aacbfe8 | 1 + .../fd15b8dd6c27bc65f90e1c988e0245b1ad7d51c5 | 1 + .../fd608012362d161cc7f3d30e1700c51f4ccef4ac | Bin 0 -> 52 bytes .../fdce5b4f3a038ce7cfeee4deb9a4644edb78189a | 3 + .../fe203731ada762e02bf843b82e33daee4c2efbf5 | 1 + .../fe46e6ef4cd5788d89a101c77123387e3fc9d206 | Bin 0 -> 80 bytes .../fe7ac2ef276b817af3487bab5fe089186ca0484b | 1 + .../fe7ef7c0e835873b7b1cd780f248114f18adf13a | Bin 0 -> 35 bytes .../ff5274cad94d590347d6cdba7637078f82e3d44a | Bin 0 -> 107 bytes .../ffff6a92363e0e55a9688d9bc025cd8dea3b50d4 | 1 + src/sys/libwebm/webm_parser/fuzzing/webm.dict | 152 + .../webm_parser/fuzzing/webm_fuzzer.cc | 76 + .../webm_parser/include/webm/buffer_reader.h | 138 + .../webm_parser/include/webm/callback.h | 363 + .../webm_parser/include/webm/dom_types.h | 1781 ++++ .../webm_parser/include/webm/element.h | 208 + .../webm_parser/include/webm/file_reader.h | 103 + src/sys/libwebm/webm_parser/include/webm/id.h | 1085 +++ .../webm_parser/include/webm/istream_reader.h | 99 + .../libwebm/webm_parser/include/webm/reader.h | 94 + .../libwebm/webm_parser/include/webm/status.h | 166 + .../webm_parser/include/webm/webm_parser.h | 133 + src/sys/libwebm/webm_parser/src/ancestory.cc | 334 + src/sys/libwebm/webm_parser/src/ancestory.h | 83 + .../libwebm/webm_parser/src/audio_parser.h | 84 + src/sys/libwebm/webm_parser/src/bit_utils.cc | 26 + src/sys/libwebm/webm_parser/src/bit_utils.h | 24 + .../webm_parser/src/block_additions_parser.h | 30 + .../webm_parser/src/block_group_parser.h | 71 + .../webm_parser/src/block_header_parser.cc | 76 + .../webm_parser/src/block_header_parser.h | 65 + .../webm_parser/src/block_more_parser.h | 32 + .../libwebm/webm_parser/src/block_parser.cc | 285 + .../libwebm/webm_parser/src/block_parser.h | 126 + src/sys/libwebm/webm_parser/src/bool_parser.h | 95 + .../libwebm/webm_parser/src/buffer_reader.cc | 110 + src/sys/libwebm/webm_parser/src/byte_parser.h | 144 + src/sys/libwebm/webm_parser/src/callback.cc | 155 + .../webm_parser/src/chapter_atom_parser.h | 42 + .../webm_parser/src/chapter_display_parser.h | 34 + .../libwebm/webm_parser/src/chapters_parser.h | 28 + .../libwebm/webm_parser/src/cluster_parser.h | 48 + .../libwebm/webm_parser/src/colour_parser.h | 55 + .../src/content_enc_aes_settings_parser.h | 32 + .../webm_parser/src/content_encoding_parser.h | 38 + .../src/content_encodings_parser.h | 30 + .../src/content_encryption_parser.h | 37 + .../webm_parser/src/cue_point_parser.h | 38 + .../src/cue_track_positions_parser.h | 39 + src/sys/libwebm/webm_parser/src/cues_parser.h | 27 + .../libwebm/webm_parser/src/date_parser.cc | 72 + src/sys/libwebm/webm_parser/src/date_parser.h | 64 + src/sys/libwebm/webm_parser/src/ebml_parser.h | 48 + .../webm_parser/src/edition_entry_parser.h | 35 + .../libwebm/webm_parser/src/element_parser.h | 102 + .../libwebm/webm_parser/src/file_reader.cc | 142 + .../libwebm/webm_parser/src/float_parser.cc | 77 + .../libwebm/webm_parser/src/float_parser.h | 65 + .../webm_parser/src/id_element_parser.cc | 49 + .../webm_parser/src/id_element_parser.h | 56 + src/sys/libwebm/webm_parser/src/id_parser.cc | 75 + src/sys/libwebm/webm_parser/src/id_parser.h | 45 + src/sys/libwebm/webm_parser/src/info_parser.h | 44 + src/sys/libwebm/webm_parser/src/int_parser.h | 121 + .../libwebm/webm_parser/src/istream_reader.cc | 133 + .../libwebm/webm_parser/src/master_parser.cc | 298 + .../libwebm/webm_parser/src/master_parser.h | 227 + .../webm_parser/src/master_value_parser.h | 533 ++ .../src/mastering_metadata_parser.h | 57 + src/sys/libwebm/webm_parser/src/parser.h | 34 + .../libwebm/webm_parser/src/parser_utils.cc | 34 + .../libwebm/webm_parser/src/parser_utils.h | 64 + .../webm_parser/src/projection_parser.h | 40 + .../webm_parser/src/recursive_parser.h | 93 + .../webm_parser/src/seek_head_parser.h | 27 + src/sys/libwebm/webm_parser/src/seek_parser.h | 37 + .../libwebm/webm_parser/src/segment_parser.cc | 86 + .../libwebm/webm_parser/src/segment_parser.h | 53 + .../webm_parser/src/simple_tag_parser.h | 37 + .../libwebm/webm_parser/src/size_parser.cc | 56 + src/sys/libwebm/webm_parser/src/size_parser.h | 43 + .../libwebm/webm_parser/src/skip_callback.h | 63 + .../libwebm/webm_parser/src/skip_parser.cc | 59 + src/sys/libwebm/webm_parser/src/skip_parser.h | 35 + .../libwebm/webm_parser/src/slices_parser.h | 30 + src/sys/libwebm/webm_parser/src/tag_parser.h | 37 + src/sys/libwebm/webm_parser/src/tags_parser.h | 27 + .../libwebm/webm_parser/src/targets_parser.h | 35 + .../webm_parser/src/time_slice_parser.h | 30 + .../webm_parser/src/track_entry_parser.h | 65 + .../libwebm/webm_parser/src/tracks_parser.h | 27 + .../libwebm/webm_parser/src/unknown_parser.cc | 49 + .../libwebm/webm_parser/src/unknown_parser.h | 38 + .../libwebm/webm_parser/src/var_int_parser.cc | 71 + .../libwebm/webm_parser/src/var_int_parser.h | 56 + .../libwebm/webm_parser/src/video_parser.h | 122 + .../webm_parser/src/virtual_block_parser.cc | 72 + .../webm_parser/src/virtual_block_parser.h | 69 + .../libwebm/webm_parser/src/void_parser.cc | 49 + src/sys/libwebm/webm_parser/src/void_parser.h | 41 + .../libwebm/webm_parser/src/webm_parser.cc | 282 + .../test_utils/element_parser_test.h | 114 + .../webm_parser/test_utils/limited_reader.cc | 113 + .../webm_parser/test_utils/limited_reader.h | 115 + .../webm_parser/test_utils/mock_callback.h | 247 + .../webm_parser/test_utils/parser_test.h | 108 + .../webm_parser/tests/audio_parser_test.cc | 161 + .../webm_parser/tests/bit_utils_test.cc | 24 + .../tests/block_additions_parser_test.cc | 82 + .../tests/block_group_parser_test.cc | 234 + .../tests/block_header_parser_test.cc | 55 + .../tests/block_more_parser_test.cc | 79 + .../webm_parser/tests/block_parser_test.cc | 865 ++ .../webm_parser/tests/bool_parser_test.cc | 70 + .../webm_parser/tests/buffer_reader_test.cc | 165 + .../webm_parser/tests/byte_parser_test.cc | 117 + .../webm_parser/tests/callback_test.cc | 148 + .../tests/chapter_atom_parser_test.cc | 209 + .../tests/chapter_display_parser_test.cc | 117 + .../webm_parser/tests/chapters_parser_test.cc | 54 + .../webm_parser/tests/cluster_parser_test.cc | 266 + .../webm_parser/tests/colour_parser_test.cc | 285 + .../content_enc_aes_settings_parser_test.cc | 68 + .../tests/content_encoding_parser_test.cc | 120 + .../tests/content_encodings_parser_test.cc | 82 + .../tests/content_encryption_parser_test.cc | 107 + .../tests/cue_point_parser_test.cc | 87 + .../tests/cue_track_positions_parser_test.cc | 140 + .../webm_parser/tests/cues_parser_test.cc | 53 + .../webm_parser/tests/date_parser_test.cc | 55 + .../webm_parser/tests/ebml_parser_test.cc | 128 + .../tests/edition_entry_parser_test.cc | 77 + .../libwebm/webm_parser/tests/element_test.cc | 47 + .../webm_parser/tests/float_parser_test.cc | 63 + .../tests/id_element_parser_test.cc | 51 + .../webm_parser/tests/id_parser_test.cc | 56 + .../webm_parser/tests/info_parser_test.cc | 105 + .../webm_parser/tests/int_parser_test.cc | 113 + .../webm_parser/tests/istream_reader_test.cc | 131 + .../webm_parser/tests/limited_reader_test.cc | 250 + .../webm_parser/tests/master_parser_test.cc | 382 + .../tests/master_value_parser_test.cc | 366 + .../tests/mastering_metadata_parser_test.cc | 208 + .../webm_parser/tests/parser_utils_test.cc | 100 + .../tests/projection_parser_test.cc | 144 + .../tests/recursive_parser_test.cc | 90 + .../tests/seek_head_parser_test.cc | 54 + .../webm_parser/tests/seek_parser_test.cc | 67 + .../webm_parser/tests/segment_parser_test.cc | 369 + .../tests/simple_tag_parser_test.cc | 205 + .../webm_parser/tests/size_parser_test.cc | 61 + .../webm_parser/tests/skip_parser_test.cc | 42 + .../webm_parser/tests/slices_parser_test.cc | 80 + .../webm_parser/tests/tag_parser_test.cc | 92 + .../webm_parser/tests/tags_parser_test.cc | 61 + .../webm_parser/tests/targets_parser_test.cc | 102 + .../tests/time_slice_parser_test.cc | 63 + .../tests/track_entry_parser_test.cc | 245 + .../webm_parser/tests/tracks_parser_test.cc | 55 + .../webm_parser/tests/unknown_parser_test.cc | 57 + .../webm_parser/tests/var_int_parser_test.cc | 53 + .../webm_parser/tests/video_parser_test.cc | 446 + .../tests/virtual_block_parser_test.cc | 74 + .../webm_parser/tests/void_parser_test.cc | 56 + .../webm_parser/tests/webm_parser_test.cc | 339 + .../webm_parser/tests/webm_parser_tests.cc | 13 + src/sys/libwebm/webmids.hpp | 23 + src/sys/libwebm/webvtt/vttreader.cc | 54 + src/sys/libwebm/webvtt/vttreader.h | 44 + src/sys/libwebm/webvtt/webvttparser.cc | 706 ++ src/sys/libwebm/webvtt/webvttparser.h | 158 + src/sys/libwebm/webvttparser.h | 15 + 896 files changed, 53309 insertions(+), 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 src/sys/libwebm create mode 100644 src/sys/libwebm/.clang-format create mode 100644 src/sys/libwebm/.cmake-format.py create mode 100644 src/sys/libwebm/.gitattributes create mode 100644 src/sys/libwebm/.gitignore create mode 100644 src/sys/libwebm/.mailmap create mode 100644 src/sys/libwebm/.pylintrc create mode 100644 src/sys/libwebm/.style.yapf create mode 100644 src/sys/libwebm/AUTHORS.TXT create mode 100644 src/sys/libwebm/Android.mk create mode 100644 src/sys/libwebm/CMakeLists.txt create mode 100644 src/sys/libwebm/CONTRIBUTING.md create mode 100644 src/sys/libwebm/LICENSE.TXT create mode 100644 src/sys/libwebm/Makefile.unix create mode 100644 src/sys/libwebm/PATENTS.TXT create mode 100644 src/sys/libwebm/PRESUBMIT.py create mode 100644 src/sys/libwebm/README.libwebm create mode 100644 src/sys/libwebm/codereview.settings create mode 100644 src/sys/libwebm/common/common.sh create mode 100644 src/sys/libwebm/common/file_util.cc create mode 100644 src/sys/libwebm/common/file_util.h create mode 100644 src/sys/libwebm/common/hdr_util.cc create mode 100644 src/sys/libwebm/common/hdr_util.h create mode 100644 src/sys/libwebm/common/indent.cc create mode 100644 src/sys/libwebm/common/indent.h create mode 100644 src/sys/libwebm/common/libwebm_util.cc create mode 100644 src/sys/libwebm/common/libwebm_util.h create mode 100644 src/sys/libwebm/common/video_frame.cc create mode 100644 src/sys/libwebm/common/video_frame.h create mode 100644 src/sys/libwebm/common/vp9_header_parser.cc create mode 100644 src/sys/libwebm/common/vp9_header_parser.h create mode 100644 src/sys/libwebm/common/vp9_header_parser_tests.cc create mode 100644 src/sys/libwebm/common/vp9_level_stats.cc create mode 100644 src/sys/libwebm/common/vp9_level_stats.h create mode 100644 src/sys/libwebm/common/vp9_level_stats_tests.cc create mode 100644 src/sys/libwebm/common/webm_constants.h create mode 100644 src/sys/libwebm/common/webm_endian.cc create mode 100644 src/sys/libwebm/common/webm_endian.h create mode 100644 src/sys/libwebm/common/webmids.h create mode 100644 src/sys/libwebm/dumpvtt.cc create mode 100644 src/sys/libwebm/hdr_util.hpp create mode 100644 src/sys/libwebm/infra/README.md create mode 100644 src/sys/libwebm/infra/common.sh create mode 100644 src/sys/libwebm/infra/compile.sh create mode 100644 src/sys/libwebm/infra/compile_android.sh create mode 100644 src/sys/libwebm/infra/run_unit_tests.sh create mode 100644 src/sys/libwebm/iosbuild.sh create mode 100644 src/sys/libwebm/m2ts/tests/webm2pes_tests.cc create mode 100644 src/sys/libwebm/m2ts/vpxpes2ts.cc create mode 100644 src/sys/libwebm/m2ts/vpxpes2ts.h create mode 100644 src/sys/libwebm/m2ts/vpxpes2ts_main.cc create mode 100644 src/sys/libwebm/m2ts/vpxpes_parser.cc create mode 100644 src/sys/libwebm/m2ts/vpxpes_parser.h create mode 100644 src/sys/libwebm/m2ts/webm2pes.cc create mode 100644 src/sys/libwebm/m2ts/webm2pes.h create mode 100644 src/sys/libwebm/m2ts/webm2pes_main.cc create mode 100644 src/sys/libwebm/mkvmuxer.hpp create mode 100644 src/sys/libwebm/mkvmuxer/mkvmuxer.cc create mode 100644 src/sys/libwebm/mkvmuxer/mkvmuxer.h create mode 100644 src/sys/libwebm/mkvmuxer/mkvmuxertypes.h create mode 100644 src/sys/libwebm/mkvmuxer/mkvmuxerutil.cc create mode 100644 src/sys/libwebm/mkvmuxer/mkvmuxerutil.h create mode 100644 src/sys/libwebm/mkvmuxer/mkvwriter.cc create mode 100644 src/sys/libwebm/mkvmuxer/mkvwriter.h create mode 100644 src/sys/libwebm/mkvmuxer_sample.cc create mode 100644 src/sys/libwebm/mkvmuxertypes.hpp create mode 100644 src/sys/libwebm/mkvmuxerutil.hpp create mode 100644 src/sys/libwebm/mkvparser.hpp create mode 100644 src/sys/libwebm/mkvparser/mkvparser.cc create mode 100644 src/sys/libwebm/mkvparser/mkvparser.h create mode 100644 src/sys/libwebm/mkvparser/mkvreader.cc create mode 100644 src/sys/libwebm/mkvparser/mkvreader.h create mode 100644 src/sys/libwebm/mkvparser_sample.cc create mode 100644 src/sys/libwebm/mkvreader.hpp create mode 100644 src/sys/libwebm/mkvwriter.hpp create mode 100644 src/sys/libwebm/sample_muxer_metadata.cc create mode 100644 src/sys/libwebm/sample_muxer_metadata.h create mode 100644 src/sys/libwebm/testing/mkvmuxer_tests.cc create mode 100644 src/sys/libwebm/testing/mkvparser_fuzzer.cc create mode 100644 src/sys/libwebm/testing/mkvparser_tests.cc create mode 100644 src/sys/libwebm/testing/test_util.cc create mode 100644 src/sys/libwebm/testing/test_util.h create mode 100644 src/sys/libwebm/testing/testdata/accurate_cluster_duration.webm create mode 100644 src/sys/libwebm/testing/testdata/accurate_cluster_duration_last_frame.webm create mode 100644 src/sys/libwebm/testing/testdata/accurate_cluster_duration_two_tracks.webm create mode 100644 src/sys/libwebm/testing/testdata/bbb_480p_vp9_opus_1second.webm create mode 100644 src/sys/libwebm/testing/testdata/block_with_additional.webm create mode 100644 src/sys/libwebm/testing/testdata/chapters.webm create mode 100644 src/sys/libwebm/testing/testdata/colour.webm create mode 100644 src/sys/libwebm/testing/testdata/cues_before_clusters.webm create mode 100644 src/sys/libwebm/testing/testdata/discard_padding.webm create mode 100644 src/sys/libwebm/testing/testdata/estimate_duration.webm create mode 100644 src/sys/libwebm/testing/testdata/fixed_size_cluster_timecode.webm create mode 100644 src/sys/libwebm/testing/testdata/force_new_cluster.webm create mode 100644 src/sys/libwebm/testing/testdata/invalid/README.libwebm create mode 100644 src/sys/libwebm/testing/testdata/invalid/invalid_vp9_bitstream-bug_1416.webm create mode 100644 src/sys/libwebm/testing/testdata/invalid/invalid_vp9_bitstream-bug_1417.webm create mode 100644 src/sys/libwebm/testing/testdata/invalid/primarychromaticity_fieldtoolarge.webm create mode 100644 src/sys/libwebm/testing/testdata/invalid/projection_float_overflow.webm create mode 100644 src/sys/libwebm/testing/testdata/long_tag_string.webm create mode 100644 src/sys/libwebm/testing/testdata/max_cluster_duration.webm create mode 100644 src/sys/libwebm/testing/testdata/max_cluster_size.webm create mode 100644 src/sys/libwebm/testing/testdata/metadata_block.webm create mode 100644 src/sys/libwebm/testing/testdata/output_cues.webm create mode 100644 src/sys/libwebm/testing/testdata/projection.webm create mode 100644 src/sys/libwebm/testing/testdata/segment_duration.webm create mode 100644 src/sys/libwebm/testing/testdata/segment_info.webm create mode 100644 src/sys/libwebm/testing/testdata/set_cues_track_number.webm create mode 100644 src/sys/libwebm/testing/testdata/set_pixelwidth_pixelheight.webm create mode 100644 src/sys/libwebm/testing/testdata/set_segment_duration.webm create mode 100644 src/sys/libwebm/testing/testdata/simple_block.webm create mode 100644 src/sys/libwebm/testing/testdata/test_stereo_left_right.webm create mode 100644 src/sys/libwebm/testing/testdata/tracks.webm create mode 100644 src/sys/libwebm/testing/testdata/webm_doctype.webm create mode 100644 src/sys/libwebm/testing/video_frame_tests.cc create mode 100644 src/sys/libwebm/vttdemux.cc create mode 100644 src/sys/libwebm/vttreader.h create mode 100644 src/sys/libwebm/webm_info.cc create mode 100644 src/sys/libwebm/webm_parser/README.md create mode 100644 src/sys/libwebm/webm_parser/demo/demo.cc create mode 100644 src/sys/libwebm/webm_parser/doxygen.config create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/00805c2543756a5fd85652d03bfbbd2eb6192ca5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/00d120eb143bb02c48d7c863e5826d2ad1a6da4b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/018dee8285e9e20ca3996bb2dc0284b5c57ba75a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/020edb59637c1e6439f19aa3a5a9d50c3377dbe9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0247ce2b1a71752a3af11e1065ca90afa0df9d30 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/028b19f7d79f5da7a2af13a0c1e2d13f7eaf24cd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/029ab55b16df41881f8de2351205201da334550a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/029be5e90913b19cf5890559cf3f98aa909f0a84 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/02fb96539b84bbd12de84ff05cbc9dc3faa96b7e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0349f5632d21faa36b85520ad0b524d561f5e13f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/036fc9daf7fb1b4274dd668cfd883248ebbad967 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/037a4edc18e475ec81081e47277cbf51f1316680 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0481dad9a7d0e6fab0c703bba9b3268db96c6793 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/04dc2407e7142f5618aa5105377925b0b0ed544b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/04fa2f34ff4a4406d136e5aaba5debe7d8129a06 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/054fd0041ad81cfad0a85e3c59195485492a4493 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/056b83ab2457979ea021e7118ab847eba265df15 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/058326151c1d4a490964d495d35adcf15178030f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/05847b5be0eb200d6a6b340c939c7a654b55003e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/05b600ae9a9072ac2865247e69ed0736a0c58316 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/05cf976698b55df1fcd03bc07446bb9283dad9d7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/05d4dfda5e264fffda243f2991a86e96141f579a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/061217fc0b6af0ec3851d9728e03ed9b30c702d5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/077b53a7163e51c48e8cdaf4209bb837823ffba9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/07c3ade9713892bb75db2d93b48ef40b262a54e6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/07eaf3c7437032f60c905f6f8e3dfc193491b602 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/07f67b922b503354b2aebcdcc4ab7b6d3150b048 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/08af8d91bb21835c50330e997d973cac8ff67766 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0a18f05bb16402756202160225aec9c5a654f1ae create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0b60823983971ee17a2590678f0fc0762c21bb73 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0bae7f0976af0f75974047b5f2cf4c9645412066 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0c1862b4065eefab2535ecc6951295e38069a82e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0c2f51d5ffc69e69680bf3d6edb91d76c353ad14 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0c3af72d69f18103383c9cd41a7f2676a9d28a40 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0c43df7fc9d06187249187583c3c082520701289 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0cadf5ecf58a394560a1f6db72a2e21264445d13 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0cd91a4e7bec912beb3b47a685b89d5be24d0046 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0d0da60f91f9489af113d8484d9b6871622523d5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0d30a4f88e53de1ce4bf1ec724016f2f4c11bc9b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0d6b3b1d024e7aa73fbc58b157ab53df048a2f2c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0d94310cfd8a9acdbc7fb82ad9c73cdf3f64f926 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/0f5741483be8f4f6eddcb70ea418fb0c08da9443 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/109e125f729f84d69c3e3a614123547a094534ad create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/10d257a4a314e20644fbc469cdebafe16c7f46a8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/10d951f88995a2176878501a2633b9bb4822ff96 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/111b8f8318a269bbe0f7d9f1cebfdc1cb43c982b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/11c122ce1f7d993f809a4eb5db17c738f279a707 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/11e288617056809208561f2a9112fd0664d378d2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/124fde9cfe7157773d8febcbb0829914bf4d17d3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1386cc740c80ede6dfea5f3bb1d4fe1501ab5e91 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/13dd373ccb0c534402c6f7c4a0bdd723a26bc2c1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/13fc3d2b32d789c84be6349bb585c308289b4c3e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/148357130d1e5ac4059ad2bb6c63d78e2523f7d2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/15366a3aafe2590c2e3183c088dde4cc100cb956 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/15feeb939fa90b25f57622a0abd9155ca88ad08b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/16282b78a2018eb78544316554a92fe1003859e3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1717628a6d6ea868febec5fb196edcf4b9eb284d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/17921b1e28600e7e3faf67fc68b397ecab4e2a52 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/17b8276355dd2368647b7756431820f5275cc3e2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/17d0aece97973ab23a467486b177ea9722e1b90b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/17e80cf8c247d17acad56c88750da34893fcb4fd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/18040e106688eb1d54323927a403439ecfde6626 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1813261b3141faa01431c82e06292485516d3327 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/184ee2343d4b9f62c69383692829fd852ad8855d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/186035a2f5c09ccd6b7d15de46f8561c98d8897d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/186292900ad9d43881b71765158c32d78d80c8f3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/18fd762b91406d37b85a7b342a91434a15f17290 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/19334eee05eeb18c549498e7ca2e792a2a4e04f3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1a9a5df35779dd6e9e1de171b9bb0d316d2b64a5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1ab3d30f60743c2a1d3043773aae3a04f83c07c0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1ad84ed46f3fda305150bac93958a5a390e23a67 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1b40a997150aa03c23ecc6efe445a2d7c3dd8368 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1b6b3bab9032cd420f350b6bb252942484f6b527 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1b7765cb05c94581461ffcd38d38b7b272d8e9d6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1b89e3fe0cbd4c2291a74bf21969a9d9d851cbf1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1b95d4da08fe949a60f63cd59213d42d30dbd381 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1bac1200e05bb3269d019903241791c917a12bd0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1bb8f5f81b7f6c1d58e1f7bb13fa561fe1a146bc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1c56068c6dd17e9a824db6da78d64f933267a8c0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1c8db8b9d88dd3483b6f81e4224c4f985046e6ac create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1d29a77924602a79c0f546535a885f59cbbbc405 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1d75a65733da627e5c401625bff522eadf098315 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1df9507cc2a54a369646d6d34d846d3fcc172479 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/1e7a571be5aa542c3dfec1223d2e089a3075ce1f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/20a6b040258fbfa09bb37c6fc07106b2e43bada7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/20e8ca854d3c0c375dc943142a04ee2260f0d1fd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/212ee7d21a8cb25249644cab4f959db111f3a3c0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/224ce7b415f7950118880fce0594734aef489fec create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/226e70c1beddace83862791a6555c80475640bd0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/233d53e3eb21b6ea6feebd6e59e3ef888a840f49 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/237f7aee90f206d3a6b138cc908b8921b544e190 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/23e1ac0f77f1283cf6e9fa044df3ec51bff27fd4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/23fcee6c71a8f5a22447df688724c0250fb77a70 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2459eb855d8c6ebac13cb74d996565d78130f4dd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/259188e5fb0c09046df96f6d565c59e0d146f198 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/26f07f8e28e7521ed282fe5c3938c1ae225816b9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/276425d65d58453d03a3444c9f6662d08d449af7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/27d62874ec87a2552e7c842da65de113aa69f7aa create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/281b259280ada5d07b07a22cbe9a78c7b0fba94b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/299ed12b98673c6c4adbcf886cb70db8adde6aa1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2a40feb7480d0b31c36d5626761e948d0ae52792 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2a6d7e2b829ed28307b551eda0d96f1834bff899 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2a8dda90aa286175b5c683b57fae1dc7e6ac1e7e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2a9588e6fab82016b545462cff2ed014c0345551 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2b1d57a8e8fa7164c9ba00957c9486010754560c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2b475d1a8f2fe4fbba92e1424f0ea96d95b12fb7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2bb80c6d0e2eadd73018eb2a8cae37d41602ee79 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2c1389f882e256e260e37e8a67af7e32d0f4e0fc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2c1f94c76e4eec607cce5311323620f349912e73 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2c962c7fbceaacf8247ac9b70c8eeb1f814e435b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2c9aaabacf3a3b48dec4a85767cc5d38a1736aff create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2cf086299f983d0afc7f95c5e0c86b657448af33 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2d0d96b95e9a3316d1ff0ef019ada509bbde4c9d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2d414d5dfd20055393df3208009840da9cfabca9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2df967edcc00ac5c8e00037f1a43680600af5cba create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2e6b09f1eca05ce2bba920fb78f9bca2a883fda0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2e8bde3549723e13849b604f4deedd51c71dfef5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/2f6e92a71918d01c16762d5ca59b328f1341d326 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/306e2cf9aebe012cb0769b1b2a6ea68af2e8ed44 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/30f7348d35de0c47d2044736cb115972b800569d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/310798b8d94a3a2fe649a4c871458b4d74fdcf32 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/31ea606a9859bb29d7f98162d254348021e0d932 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3230fc31ab8d408c484aa28bbe36431f71101243 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/328b7c92996e480d1f11efe847c3be4b5dc0f8eb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/32e58bb3d00863115f33707e0c8af722036676fd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/32fc8547b6145c502d98e5e0c296ebd05badfdb9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/334cddba889265a1263feb77a2afdc454ca54f5e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/33c9f9990890d2baf0c30d74b34b486082782413 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/341f3e8689e57eeab4234fcdd6d2b8f800b9ab34 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3457e356eac79bf1c30b59940532d360dba2c1a9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/351185a29bdbc7bf0d584479001fb47c32c61e5b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/35ae0d43c6bfc5f4b45f16877157832fddafce77 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/35b2f81c573b15304cb9b13f00008b460da78942 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/35d9256a4d7ef3ee54384616178af3a8092d0981 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/36352efd680a747f0f2c93d760559d69399a4102 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3685ffbcfe28b166ced0a783b012a446f9cfea46 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/36def8b2661197d594756f116a750822ae1d65d5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/371950308853fb3b1b3a940c0598bfdfeb1d0f9c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3765e9174971dbac9cfeb7e485ca61dc4941f7a9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/37cae036ce7ff5d0671f32d3757579f248609c9c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/38460ea06ee847ff3d5733415c299b44b0866e58 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3865de2fec3f353513d86b28e43bf936d4707f97 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3867b18060c307e0d04e0098f195d699e4b3294f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/391920720c3609b7c1f7b51162ce3ec99329a0b4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/395027454c7d5babff9544414c04a39d712eed1c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3a258c9ed48e634ed8d495f07caf21dbc6978205 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3a397485197e6b99c77158132eaf211389615fe5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3a66b34706b686fe0fa8ca8f10c829758b2ebb07 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3ba666ad891fa8009dfc961aa3c215bbfd2d81d2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3ba9769c7c23cc3c80542ad123a371cf4f69e858 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3beb4432302433e303a9ccaf34637dd3a910028e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3c6cdebc450d20a58150a9c71335b45a6a5ee0e5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3c867362eb6a20f573a890db87749fce3c719d14 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3cd69ddcd34bd874e3abade696f95c949c17198d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3de495ebac4b80064b79844f3a9453270caec251 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3e04542bcc462ded0025b53371f709d8fcd25c21 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3e94196e55a9214083bda470772d71aedc17eb5f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3ec4ac00bb967a335b5caae0ae51488f2fda6583 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3eec38c0ac3a96856d3210a0357857e70b07a9cb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3ef82ba46238fa46b89148a230d23e741ba5f1da create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3fbd43f81888ca60e5bfe49b47e23cb115d5cd7d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3fe56e5b06653e8a37c99da190ff8d44d14bfc06 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/3febffec3be8b1f4bcb76a01c1d713600d8e4adb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/43380e5a9dd29ca847e9b5bfba12a0a95d94d0da create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/435d3ff6ddc43ac582e740ead969397fd2bfc7f5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/448120a37132488f48ab6c46a146c995948958cc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/46db501d3e9a8808118333740a22bf9c808af239 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/47a2ca2b47aa1993cb655b77a0273ff139dd2280 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/490576c8f6c235e1ed921c4932bac028070c806a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4930b86bf0dfb02836b0319d21aa4a63a8dd894d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/49667ff0b09901223117e74d2506bc37a5ae1580 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/49906adf7313330e29be20d51fb36e9bdf1939c3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/49c0e3eed81c1827e755c70c9c6d9606e7f54b22 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4a3e77f5bc061fc8121ef7ebd2b8e3ebb0bdd609 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4a454e01ef09b175f3864b654cfc1104a850e871 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4acd9df9a7ee34e48c6c80777159b089f417a69a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4af5564129d7b4c9c4736a3e511926c29348a4a4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4b3957bcbe5975399e34485cf0e5229169ab67b9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4c9e40aa8a439a500f073cf5a1e060a16ad12a6f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4cb5ff0e26f5bd0bb1fca846b4843db69095f18b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4ce80549344cf5b0432e39e7b5382407f0763e8c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4d10ae0032f04fa01148a54fae6838c44e4bb5bd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4db2ded939a16fb1907dc2bad7acf67a64e38c0c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4dc3a9a9477fb452ba7a4026bbc01d4cdd3d4990 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4e1fb006a2268fa5fc70ca6b241bbc71faa6d7ff create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4e871bbc5089f9550533641ddf6850f8722dfc36 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4eeb4507868732d3705d1ab10f6a31f70f579556 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/4f21f3584c99e97453ebe513ed44c86530fbebba create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5103160695cd56d281faa45d9267013488cc7bde create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/521103054e395afd0f9612b47c71cfa0e62151b9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/523511e33c8788ebb1b703d7c5ad12b5da03964e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/525aedb7462311393cd01939e4734d01db48535b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/53809012a8d5cfee839c3d0961b7fdc9468329a7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/53c01d820d125e57b28410ca5b3a9c72c18d4102 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/53c27071f53df6b8d2e5c419edf95b7792b278e7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/53d5307f2e7852b183839fe93c20647004d151ec create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5466c59c9c0eff34800e19cc92faf07469865ea9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/54bf8d6f1f846243b6f4de81605779b0acb78406 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/54fd1711209fb1c0781092374132c66e79e2241b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5506797514c0b214f5faa9764a9e149cd1df9d28 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5566c6d599866f5e523c54e6575d7b9e557a2539 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/55c3d55780427eb00bde252348db1c2ede22526c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5600abaefe804c50a353bbfdd0f9e10ffc102f81 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5611ddd40488973ee6c64c45ad57d6eefe6da100 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/56b0ddd4e44492b45ebb7e9438b0a5556c244bfb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5729395b452092152b06fbb8976e9bf1fda06439 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/57cce6fac7c0992eb338e0e538d3e0ee3fe7f1cd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5822672f068da89546838004ae59552e12e132f7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/59ce13e9a22e88dac879841256ff66f02cd2f8cc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5a020527fc80b0de64e279fc44635687e014a9cf create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5a645b30948850f8efb7bdd11944bdf3112c7bfe create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5b2f727461cde3c02ffdfb300adb0b4a09734911 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5b5531d859ab5bbb034345bbaa2852e9d8a1e1ef create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5b980cb94e35769ec92a140ca00d34977e7da5ec create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5bfec2fe795176646fa0babecf97c04045bd4814 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5c28d94242e9a5ba7e7324e59e5dd12f3e31e51c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5c67728ab04ba3dfe4b2636cf609f9617c4a5974 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5cd36053e269c97f5359b0a075d80bf1e23b5f47 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5d6f99c2afbf68a1b15a17e07945c11db8579e5f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5dd149b1b8509f456c16c4ac6dac3c7d6aa217ed create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5e84011c6b092e9f0d6ba60f12fc0fae95a622ca create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/5f56766993de2b8c2db87116090af546e1add3b0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/60571c8be9bee3b13428613df66ff36cf54309ec create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/60ac245f262ee1ff177d351a4fe246060fb4538b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6120aafb0db1715400e47d0a61fb9f6d8665a736 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/61953a8f7a9f0613020d297a6d350abeeaf6e58c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/61c0a7fef46c0c1b081b1c2b40835805e5989b54 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/620d85870206e88db0bc3ee978c24c0bbc1821ba create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/621131d8e28a67a6b4fb03c611f4375873d69678 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/624cbd42e3ebf35a3a0ba55b3b4969b99054f84d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6290103200631075988aa3566d8d8922599f8b6d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/62a329f65143f1571dc4a2fbb256800c8ce4d89f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/62f8a53cfb4dd625dcb31ee2ba258db3916a3bd0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6318dc574b3ad7291fee7e01bfeaa674eb0feb48 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6457a079debb9b532255e3e6ddf276b29808b49d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/646061a4526506a0b3c62629f4f77b6072c8f9c3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6538d0517865c8832ee9bec87609b7bd4facb025 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/653de28e2f085334e30ec1c964540b432a3cfbc6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/657c9c42bf3e1c79a6dcb9071bf123367dc37734 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/65ebba0df08a5484686905e99631a4ead845c08b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/66dd27c22fe09842ac4c4f51fdef4bea500b6a70 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/66e25df2bd43c840337a49e0cb5b386e9d290d80 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6714df1ac1c54d4c30add212454e9513c6880767 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/68a6f9c2f62e9f57667de9563b5d612ec2f2c829 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/69089b76cc62fe00615702bdd1f339e259194d42 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/69d8622d24c7315f344c424297986170f7ef2243 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6a700d958cb3a7565d5a6b74540486874d52b4c7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6a852150c5c2a12d325e78056687a8ea97b25fe7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6ac8c9f754d5ff3c0cd3f3f585de99dd73944bbe create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6ace27a48f12990e2169cc099007aa5fa11962d2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6b10397dc3bff2ccf57be4fe3ff9d8d1acb8c76e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6c3f1d96c06b853551f685dde821142928f55acf create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6c8de4d4bbb5294154c3b140d43836757b9f08ac create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6cf122ee328af5cf6f18d5f9546b0fe761951b8d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6cfbbc25caa217e22fd7ca3e92d2051c5f661bdb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6d703bc900e74d1a576bebcccb63e3b2701ae86d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6e1afa81dfcd6833705d84b45881f085c19b2211 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6e244ec3b81e0d2f8b5810854859e1b8140422d9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6e323b4c733df90d55c754e099fb5a13bd9701cb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6e36720f3f55dc0cd5d585c6770572964719b5b8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6e8384ab115ac92bb7787121cfb03582e2d72585 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6ebf8b74dca1657f5f7ffadeccd629984473dcb4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6ec18dcca0d820fff04c03c3a1bce37dd8ada41d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6eceebb8f46545393d217ab0111ff7dd29bc99f7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6ee071f654fd6b7b25725a8bdd880bb6836e8c81 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6f1088b3d1f4cdfbc37d9b8cfc1ff4c3bde2f205 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6f79e36e880664c9b3b610140d2485fb6a6e5039 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/6fbea59066b2b97fa45259aa87c40c4310070019 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7056b9c294f0cff7b4ace611a19363b2fc096bb3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7073dca40b911fb22f738c99aff43a10ae6c4db5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7164d8ca3f4c3d621cc5eed7b59e3495e7b017a0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/71e3e01b3cfcd4228402cbf19b5282c965f042df create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/720d36ea7f9616b1a1d47fa5b746e8657b5f973f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/72ccbcbc53c7fa54247a81bd1d0e62dd0779494b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/736c0460f94c089c9e270857a4222a21ffd9e13f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/745e32f46833c075c8e68552e0fbbcdd5ec52641 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/74aa7256477af2c0e2511df16376dee323f3ccb6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7528086eea404dccc3ee5b214befbc2a95676feb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7528f9f08f80c8e85951aa1db2dc616e992c1a62 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/75af94f9695c375e5eb620849f0213ad41e8f205 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/75e1ff2e016b7b80ecb7a6a1f4c3238a2a2ed130 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/76129c3bdedafb3bda93f53266bd17bffdc30682 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7670db89e0c3fe492c91458de219c3be34a3dcb7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7673d7fdf630637c6ae2b96694a047044c1a9cb0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/76903905e654ddc59acf57380bf3dc1ea136bad9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/76d36e3cf3d31e0f76af08bd7ba5571f679057a1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/775ce646f7dbf50199b8e8df85c9441b8a0a5447 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7770a6fd33ce821e60c78b0cb67a7e8c8bb74269 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/781b24e3433ba400df3ccddf56cb8fc7b1fd52ce create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/784db9d87b31ffb040ad212e4018b30c3535ad18 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7880e2ae55d255065ad415c4c625e1b63bfd2a93 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/78cb3d726e4f9e8bc89b399fa514c3b600bf8e5a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/79ba60931988a5974328a73fe091bdf6f5992891 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/79cdb8dec1ad07b389f544a511f89b347429837e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7ab8c6a65c39907f4afa4e2b294303aebb6b22d8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7b12a398a1860ac2f3930d5020e422aec061f177 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7bf1682743405f3d5b3433830eadae4ea311807d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7c7ef0e305f37f833708b375271d59300d120d84 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7d06bd4a7de57953ef09c2e18ca67aa7ff367c76 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7d31bd53bb7eb7b1f354c5f85d376390760ab16f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7d67ef4d0c681655d4b4e93e848d56865630390b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7db9fe869081fdc855913dd000de0d493f5d5192 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7f20c1e73451c3321c30223db91b891753ef77dd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/7fd4d999983c3fbf22763853e90ec10b03c70b17 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/80039ce7eff40359bee041d75e371b55117aad3a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8104a007bc88a0a8d81ce1fd26d8b2333061e920 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/81320c48ed6eea94712c5e8594c0799fbfe30d10 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/81425ca3d0afb88cc10d412dcc9795905eacd6d9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/819b4bd08ae7d758990aea8ab9739f3cb97fd42c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8206d92b710c04ce0bd706cec25fbb72014c79bf create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/822926c528d16c0a9ca4c48a25651f6a0730d797 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/82d80b6051f0750777bdc37319851741144b3671 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/830c73748baaa10c2016d04b408a7f481882cd89 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8315ca46618bd0771353336407396df293e8c182 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/831c152337e8b2993b8cddfde7553a8c9e64631f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/832fad0e723027e5bd74726b1722a838183dada7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/83b78d2ad8afd0729de45b4d9fdd765a949d8073 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/84a04bf3e15345f5c992bc6732a42b95857631a7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/84d3a72c434074ee0d810fb2357047efd23f58f6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8659fe309298ca90f201ac7ced95b9d0de510eeb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/866cf21064b9e20eded44e2e096fd9ce6185ce86 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8864c6c9319ef120d3accb7b70c32c8f5c1ebccb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/88f01cffe9972bf447a21034c45f6b943ea3ec07 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/88f15d430469d209b72cd098405efd15a6d18b05 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8936b35f29084151fa3755d81030386940523c07 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/89a42d72ffe0b23309a9da4e15b8854c1cf939ea create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8a0cf07d2592231bd579e4399538d9f490e3e5b9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8a5d1c05f894414aa5aaa66cf901c52dfcb119a1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8aa514b6e6fef8d045aa049fdb52fa8adcf722d4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8b0dcd4400fe19cf6a268af780990f47dba08189 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8c4655e6528071edd445715ff1559f399dc9d47c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8c695cbcc43e37ce25194c4b61b3d87488b308a1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8c9dc3c5a839f90f29256ef8c8f1369bc7383817 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8cdcf83eb89d7e5c87cfa1b8811c95f738747a6a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8d0c6e6b3d74233685c3a2c1793d1a7b0ae2e34d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8d444e8b311d158f854a03ca35d2c7865cd2c46b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8dc289730cc03ecbbed57d04cdca538a4fd08059 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8dc58cfcb396a60db921901f1b0807c4f4f37619 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8e05be75b7c14c463af277559dc8ea7841a733c8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8e7eef00a7a6719e77544b57d1d98ff83a37e55a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8ed6ef9af5555ce4ff12b23139add9621e7ad930 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8f39f83b71d49805a451f81a5a451f5f3d74927d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8f403efbef079f1775b63bcf1061983e4c5d2162 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/8f8f956eaaf8f7f5e65002be888b946218f0f7ce create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/90a03241b5cc656b7c2a4ef55664b0320fa3bd43 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/925a91e7c25a43d9da8b63eba51ed66a52d833aa create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/92de5c217802ec24886240188dca293325eb17c9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/939da66e1fc8bb9854865066ee47b6ac4b933aa9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/93a91331e7c3c060f461ae1f22e2bbf4747ffe33 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/94f6dfc499cbf2e84ffe1d69cb751ada9f2f2e3a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9539fef8ffb9f7c542061f1af1f3f98e9a714cc3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/953c9a616ea56067225c88fccc6423496f2501a6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/95a60268c555a77c1010d75bb44142af47635486 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/95e410025b965cf6ab2e8e2d3559efbe71c1a972 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9671f253d1eb7cd504a5617058ce4c01a80c897e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9698d3424f1581a6bbb66c764f14c95a74b87675 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/96f7f38de1f8601311733984cf51cec35500dabe create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/970ab6333aa5ccf8c2dc14bb56814f7bb4303b94 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/98978113d2116dc4bdbb10265fa32bd95230bdb6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/989e2872d2a34de543f23c5061db68212d8258f7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/98ca9a00ad571c4454fce709d5405e5aca2a363c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9965361765a4151902ec04fb21d9247b3a5ed10d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/99d6fe94a50faa50db9d7eb38d74bc3cc8417dc1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9a6869cec3dc84f2051bfaf0ee0d3552aa221f89 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9cc1f26de1e3a7df8c7c03b95ff73ce9709c85f1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9cc5b552abbd551485135fa87eab739a0a784057 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9cca361865a4fbff75abdbb79c1e91706780576c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9d8e99f07604d6cb05ef613d41cbfb93b2aff787 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9ecd61eaf2681a882473247a603b9f30c2663d49 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9f0a3b7c0814b4f80c0745161c8769f63098981b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9f711c29ccf3f54d44000d7ef6299585674be288 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/9fae60819c28d4fcc88a6a1b93dcf69b4e458203 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a02431cf7c501a5b368c91e41283419d8fa9fb03 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a0ac6c3c83817637bbbcb11a5106c57aa6654afb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a15fdfa620d19a92d9eaa9f3f13010e53f902796 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a18e76ae792a054c2f6d0d01e0e78d58678b35e3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a19d04f18f574e561d793ac0dfcffe2b38183eb1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a26fb85be3d2bb8a2360bb4d9533a1651bd12d99 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a2e860fae30005a9e75b61f54f3d019c44090fcc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a3071bfcb7b2fd3c4286ea42e1f7940754b55697 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a4ac408fb9d6def070ad3a76312ca092863048e5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a4fafc117cbfde8c240deccc8997c7966d9109ba create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a59ffb5f6122e45136352585d3b53294a71346d0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a5b3a3c48727c26dfd625f247069d2cdbfa031f0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a5c829fbcd9fd760bc55bc8ab6901b8d401b65f6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a5fbbce038cad4f5e0c0f97fa69ebc3601123e5c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a6e57b33e7a219168280e51bc98a44de40f0f9ca create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a78afe9e4e9f02a10ebadac64171ad49749a6965 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a823a019c0b19c97a1d35722cd843109ab016c17 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a8468104c65a6002fd3a9d4ac39f3ee34c21ce4a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a899424027f1d69a05384355858311a6fa3940a3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/a8a5de5a86a16952aacdf602120f27807294c3ec create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/aa65229e62d7cb8048d2f5911226b177e8e53cab create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/aaa96713f8ccb0bbd5c8e91715d4b86e7b338676 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/aae6354e5ba12ee3ad89fabfd72f5368a639d30f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ab6f3dc497f93f251ebacc153409b1eb8e05e2db create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/abf5b18d1c1155d3e455c8b781948498f364965e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/abfe5dbf594a2f22173fae7ca8de28b4e3a40099 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ac842f2cc55d7f193273a35f8af3521bfe2317d0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ac923c36dd85ff5cb2a0c5b29c701999c5f2eaa0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/acc6e100b519d6408a8c6d8aed19203d874a187a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/aceb250195867e7d9bbf6eb6e0055251e4bb5d67 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/acf1dd17e6a2848dfe17fb0d76cef2ce7d59ebdd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ad94c2bda2ae4afa0f7264070fd642bf37aae596 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/adad2ca7ab313add6e955f704719e03d5229e4d0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/adb1f8cd3b68c076d81311071aee2a1c3785c7cb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ade30c327d9f51daf37cb3e39fdb15125b84a257 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ae783661f52d36f9d6b87c8394ee6f2d61dae640 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ae8da06c3c69076c06108219e19c8b36dba05a5c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/aec8a29238dba3c37f45f2e2e4e64b0e7fa60a74 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/affba8e4061bf260b1bdf8a815675cc3b4ebefa5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b01c4e2657a230e2b600a20da6f107b0dfe2467c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b0798ecae4d9e56eefb0c1d95b657865938e62d6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b0ab4f92df810edf4371baad1d4bbd95d360c607 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b14e5f5f6d29b6b71e7fec03eaf7d8237c0c6b2e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b1708df7f6dee0f2feb11f8b6330be0fcffc1f58 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b1af4f4e86890fad6fac96a23956405c550778be create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b1efd9e687d79e3f5a75eba02bd80bedb72350ba create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b25b0fbf46cef1d888fe900445c9ab95330f44cd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b2786e0b9d6e7b39165eb4e87e3110362e9e6660 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b332536a77d6efcd379cfc2f9828291516cc1ff4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b33962eca397f59591dbb9668e622cf99f2d7cda create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b38b6e93da1b43441f88aa53370a9f00b35c3326 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b3e01674a1e4dd78e748782fcfc3add5523f51d8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b53e7ef9aad70fcd80986696ebc586c03495b8ed create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b540412c01f960f95edd2a1bc03f1b4447f2b4f2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b62c2c591db32b26e997aa4ece577742db84428a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b62d99583f30c15c3c2dbed2f69c5e45075d7640 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b62f98976c11d79674b019ea78a7ce4d6d78b479 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b6787dabeb5cd64ac85f1ec5a7cbeecfd48b2c5f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b82ebcf4d09ba28d835cb9667da603e46e3438eb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b85c6bc2473aa12e22f91db3546dfa9d85d8b3d1 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b86e98660980680890bcbf02cacdf568d530fa64 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/b8d9beea35762009941189674c2cfcd14f81254a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ba517141fc9a468142a8d03d4ee395b4d4f30edc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bb0a596017cfc2185505d28065ab3cd238d0e2ea create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bb6232815b373e441e2acfcca015f75c680eafac create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bbdf4fa36ba9d645399f72c74033fd9c2631aebb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bc53c9f93974b4f13382c1d49b1e3ec374005ee2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bcacc9bcd3b9cc7dbda9c52c6e4a06a756a9de90 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bcc55f432bcf39c6ffc6d7e950612b35e9ea2ec8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bdb1cc868d6ced390f5d35c5f43da9f464fac464 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bf67bb08e0abde692748031c297bc1c7910542f4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bfc07c62ef2770d53d9188b260f531a8128a5c5e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/bfed121df31ff73b770ed7f27fc7f4da2fa73e0c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c01816206d93691165e6e3a1924cf9fbc9cf39bd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c02be525edae59ad9d0d9dcbd790629dc9aaee9b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c094ce0c13ee9a4ca37817d9f7dddc11b2d60177 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c0aab5486ad2e80bcc12fca9fb6653984aa68274 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c13ca850db259c032cf24cdf6f2833c9d74529d0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c1a8da6cdc8988e6a69961413803acbd1ee935e0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c25abc82a0470129f2d098ac65fabf34c4e11188 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c2787d2cf1d95cbcd8b9bcd15d50f67f7e92ad9f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c2895ff545ebdc4140951c0ca956524d7a364b77 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c2cc55849ff4858bf80f1a4713187618d14a496d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c2d63b1d75cf53ee3b955bb143036ca93ef3a256 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c372a27f78a62ebc013958fa4953a8bc792db53c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c392963b395a7f92b3bef63fd34bc31ecd3029f3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c3b2749ab6c4d303bfd5da9ea9c8807e9f92d259 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c4dd3c8cdd8d7c95603dd67f1cd873d5f9148b29 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c52fa8d16e520980e470d76e3fb4f6a612f0f3cf create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c56fb214efcd707e6fa68b803d9e7686fc2f4336 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c5902afe54998ebc5d8d59043227d379a8c2eee0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c6a16abeea323833079e97b1830610aa6c6eba91 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c6fcfd2a1f91a7f6a8c124f2637e60645be01006 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c75b02a90370df1f54de2f63a4da8db22f2cf719 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c77cb763d73db279aebfb42d2b5dca3d705d3df7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c864ac8bce0353ecc7d5cb0ce5a1e77a5239201e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c877c08a79a7408aed779d4a430c5db1bce26314 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c8aff6e2e2dfb18be385483b871ac86ff6eac63f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c8c1c1f970bc809a75ad076bdb06275b6f72d078 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c995d52934ac188971f02d5dbdb3cdd70cb03267 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/c9e7fc3e0e1015a1c15992447f678a495c3ea5dc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ca5b619ce1bbe23d519f5764d53458d2b85eb9fa create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cb0556c65c7381192c94324a3b1b8afb7e33fecc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cb1a093e6810c7f6c002a2a54ea390cf769c9949 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cc1487af64aeefd7080e7678a04870dc85a7928a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cc71d2c9f5eae12acee133bd9e50d84881a1bd88 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ccb8f962426683663972534c15354f70c3b34a10 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cd0771c4754dfcd9c89b9b8a02df96fed974850d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cd8899c66cbd92ee57f94e000744b32662258ba3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cdf83138f69f0f7c66c13b56028610ac39038b3c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ce0138cd7718397b365d4c15b0b14f666c307419 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cec5c7e50ef1d865c879563d1a6d677adb86695c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ceff1dfaf2de4e33d2e3c20aeb7ba4b98f97784c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cf04b5d28cea1971478806979b256a030a671541 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cf1cf6ad5b3554c3ffc86a859319445158665ea7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cf2338960588d4a5f02a47f3ee96a556224aad75 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cfb09018afa0eb1a829e556d9f8bceff40cb36bc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/cfbe3d66d7eb3199440e8e911a93044cc3165c6c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d0a91f7984904976de592cb68e8832853fbec9bc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d22f52563c16725ce4a924dc05d6ac7d64798c43 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d2709a1c9d96e72cb844eedca8bfe8440cdb0ef8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d2e385f61ad4b5d45a10a5a6cb85d72e84dea54b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d2facb213561b30a5bcd012e4e01d0d5b0b26957 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d300e5e46a825e5892fae1ba3c466c836f9e1da2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d302c69c881e230e6433283007d318ba437025c3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d30c1b65bc141d1a15d4ed622ba182c96dacdf92 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d3adf09fe6fb1534157c1dc68eb61365b46b1c35 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d3c74d3a64dba86f98a31bb726587ec97a7e4531 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d3c9846ab319f12fc646c23a532c780daa9e993f create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d3f03301b52cf4a830c7dd200ed8ccbc09e6ec94 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d4800745440dace38766db3520ffe7baa0bd78f2 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d4d6271bba704ba08c2678eb8b1bc4e457144f50 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d54020f766061e80f445690c2b5694ed8af21e9d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d588515f125ebe968fe6a81cb6df7cfc41969e68 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d5ee5e4dc8fad9f1da43102d8322beb005a047c0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d62459bb217d3050bcd9e29a6327cf81f5ed68b9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d6acbf1cb46845618ed0d5a322c8bd4879d16422 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d6fc8cdbb0f1517159531098e900e2dcc91edba0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d7a9bbd9875a60edf9c528b298ea72a2fad7d3d7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d82e70046a544e95e81f6271dd2695f2599f0574 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d84bc8dca7c8fcd227254c06f5b88eaaf7cd5fde create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d8bcb7dd21205e7126e700323b1d58817e9d9a6d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d8e2628b4092b9bbab4f02041647f950503eeb48 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d8ee4c2b79863a237c432efe7d43d99c8d0afb9b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d8ee9724bf16ff336387723dcf27319c3be72e01 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d9379969bc956ad623e4bab8bbe47270a880a62d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/d9ccb79b0e070dcc2f5ed8e15d99bc5ef86ecff7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/db83586ca6266e03067e9a9772ea728ab770ad9a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dcc63c06ed2790d1380bdb9281fe8677f439c76d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dd509e9a4660ec34b8f9dc23441c6df4ff97c34d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dd72f8ff3a067dc7871438b6023e1ed0a4c5787b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dd75880c5ad488885260f4031a763c86a8084406 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dd962d74d04aa4aed270fd8e6b0ae9c4ac35fd19 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dd9aa9a49dd790b2ce99c5af1933232d46a7f80d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ddad7630818a1caa8054d2d7280a1d01bdb33ca3 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ddb2eaf33960ce69d579a551a7b05733adcd52aa create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/de0d98cb997c0a0f7be127a46d8a24d8a003931d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/de0ff884898c83fb880498f1b8328f78701e6534 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/de9e0ed8ae29220e5b65e5b97eb3b254ccbe7e0c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dec5e8ffb35aa707d127a11a49e47cb59954e969 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/df1b205e339e7199b5094fcf0ec3b8a8ca7a692c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/df254daba2299f3ff2367e284efc53a3296d136b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/dfdcde31231b8b3d3fd4e0ef8ea88885f488c4db create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e01962d7dc1b94e5c4424ec7adae16a7c03b9773 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e058723f2964bf1405ae043ddb99efb17d821e15 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e09e306ef596dcd0e44bd3ef3c5f7019c7343f84 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e154eb76d096c1e545dcad591a58a02c37cd71ff create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e198d2e4f2f3528c2ff46d769a9281ebb3cfb44a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e2068af1e903f4a81cd6fa5f4022e62070c259ec create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e2890330b5655cb277a581b8dd2eeba0d9061ba5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e2e0767d055a7042c24a7acd5d5b6b7c093ad065 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e394a8e21e2c43c42135daa034ad5aabb06acffb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e3b200e97ec226a197e91f12103aaa53d5c37b0e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e45b077cda64c380ae1b0910bc81d010c27e1c93 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e45e71ca01ebe01b01b0ca99b8f20a756c36b967 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e4ff4bd938c3737a02862fc0656a1859d384d066 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e5a1acb7e6f71bc1a2fedaa6173764dfd04c844c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e6081eeff4ddb76e88e87ef9e4b5f199f5f11c28 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e73c42dd266c4d9671da0c7af09e98c02fc052fd create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e7b4559a77df21b73285243a8350b844775bb380 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e7dd34a80646a8c38ae1ec3a27c1358bab13b360 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e80b344f943ff0ad9219277c4578d3b4100b71dc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e86e26200290d9d428c5e98e191ec874eb918fb6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e873a3b8f5c3b716e6446df34279b837cf8d2c30 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e8fb71319db98d8e8cd131a4eb82879bfbec14d0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e93c3f14614595a2675993438b4c1bfaafdc02d0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e93faef2d77b7c467ae280ba433928d66d63ea63 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e95401b11d974ba63270668d3c32c29e95ae85da create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e9723cebe688912f684bcd19b48e5bc8efafaf2a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e9a4389895c006d4b912e8ac1169229e6b2a66da create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e9dc3d10b47ea580404c8e80b844a9978fcf4747 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/e9e2ac24e5674e7ee424e2b270e5abe84f1a15c9 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ea2b4df24b526aad253ab175334cb934b9d80b83 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ea681d11486feeab2f080b06ddd2533575b7ace4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ebb747925360528a9f366f9a57730883c636b2c7 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ec39abab70a8e1ff072eb082caa6ca77b1ae8087 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ecdd96d6cab2dc714a0b0ada1c4fcb18c75298e4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ed008faa6c9001951f50588a1597e03931501343 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ed12e272a27a2fbdbfe5a6e78e49ed722ebd3c69 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ed799ba0608690ac68dd85c588004197b86e02bf create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/edd982c5bd3030bde8c044760e9a678c2a9306f4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ee82c97e35ec92ec3b0bbf911904a050b3aca633 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ef11f14feee00e3c198015e6bc76688e970e2d8c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/efa12e91e0d63c2353c120ca1ded7b36afbf57eb create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/efa14cba9bbaf749067b7bb8515a5d8a289fa389 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/eff9bf13cd33ea50a8eacc5f2839cc4b5d67b2de create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f0143756917f0b2e374bd03e731cd64168180054 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f0b9dcd4e1845f774bb0f42653b11040baee0765 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f1a41ceb420b6b3df50b10f27108c133d4d07508 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f39378fd978c6cdb4a8d08cdffc9034e2ca5b687 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f39707a104112d13d9d6bcfbef0efe8dfd98270c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f4341645a7d466113655d63c5aa00855904166c5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f5511a42d83f94619ff8ca6c940cacc32bdc4834 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f57a39fa918249e6941b4e770e15a8131ac16ea5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f5ac272a1dbf362e265210869aaf70ca410f1703 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f64c5ca1de57bcf323741f56754f53c642be8ab0 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f64dcdee393b4b0a3343f8e684c9db91a6eaeb6e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f69d2954da077043c6ae085e2771a702689314d5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f74e2203adb9c94ba80f7cc3214e3b3040e5675d create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f7906e7dc01323b9d3d6e298e8dc2386c8d152f6 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f825cac511f3dc38a5ecf3aab3691b4c49ca8f0e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f84c3f9e305172f2ae15dff0b4d955324b3a398e create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f87cfad97831c33610fbbe34a04369bd93862464 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f8ebd7703fd3ba1a135b243fd947dbd61907d0f4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f926f6b2337650f8b518422c2f63a8869f47c742 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f939897b9fbe865c96020927dc81de9dc255d385 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/f985f995ca7d1b691e6ae3b3ef57e8b3c7aa7129 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fa79e8ad34cabea4d3c434cc02ea1499069fcafc create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fa7a8dfdd46845ab0fd9b5b7004e37d0232941bf create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fcb3054fde86111e2c346aa71af2456a1705902c create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fce30dcdf2f23b14c580c282a39e065d7aacbfe8 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fd15b8dd6c27bc65f90e1c988e0245b1ad7d51c5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fd608012362d161cc7f3d30e1700c51f4ccef4ac create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fdce5b4f3a038ce7cfeee4deb9a4644edb78189a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fe203731ada762e02bf843b82e33daee4c2efbf5 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fe46e6ef4cd5788d89a101c77123387e3fc9d206 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fe7ac2ef276b817af3487bab5fe089186ca0484b create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/fe7ef7c0e835873b7b1cd780f248114f18adf13a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ff5274cad94d590347d6cdba7637078f82e3d44a create mode 100644 src/sys/libwebm/webm_parser/fuzzing/corpus/ffff6a92363e0e55a9688d9bc025cd8dea3b50d4 create mode 100644 src/sys/libwebm/webm_parser/fuzzing/webm.dict create mode 100644 src/sys/libwebm/webm_parser/fuzzing/webm_fuzzer.cc create mode 100644 src/sys/libwebm/webm_parser/include/webm/buffer_reader.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/callback.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/dom_types.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/element.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/file_reader.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/id.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/istream_reader.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/reader.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/status.h create mode 100644 src/sys/libwebm/webm_parser/include/webm/webm_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/ancestory.cc create mode 100644 src/sys/libwebm/webm_parser/src/ancestory.h create mode 100644 src/sys/libwebm/webm_parser/src/audio_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/bit_utils.cc create mode 100644 src/sys/libwebm/webm_parser/src/bit_utils.h create mode 100644 src/sys/libwebm/webm_parser/src/block_additions_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/block_group_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/block_header_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/block_header_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/block_more_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/block_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/block_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/bool_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/buffer_reader.cc create mode 100644 src/sys/libwebm/webm_parser/src/byte_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/callback.cc create mode 100644 src/sys/libwebm/webm_parser/src/chapter_atom_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/chapter_display_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/chapters_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/cluster_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/colour_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/content_enc_aes_settings_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/content_encoding_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/content_encodings_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/content_encryption_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/cue_point_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/cue_track_positions_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/cues_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/date_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/date_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/ebml_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/edition_entry_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/element_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/file_reader.cc create mode 100644 src/sys/libwebm/webm_parser/src/float_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/float_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/id_element_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/id_element_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/id_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/id_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/info_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/int_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/istream_reader.cc create mode 100644 src/sys/libwebm/webm_parser/src/master_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/master_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/master_value_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/mastering_metadata_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/parser.h create mode 100644 src/sys/libwebm/webm_parser/src/parser_utils.cc create mode 100644 src/sys/libwebm/webm_parser/src/parser_utils.h create mode 100644 src/sys/libwebm/webm_parser/src/projection_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/recursive_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/seek_head_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/seek_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/segment_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/segment_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/simple_tag_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/size_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/size_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/skip_callback.h create mode 100644 src/sys/libwebm/webm_parser/src/skip_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/skip_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/slices_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/tag_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/tags_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/targets_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/time_slice_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/track_entry_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/tracks_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/unknown_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/unknown_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/var_int_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/var_int_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/video_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/virtual_block_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/virtual_block_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/void_parser.cc create mode 100644 src/sys/libwebm/webm_parser/src/void_parser.h create mode 100644 src/sys/libwebm/webm_parser/src/webm_parser.cc create mode 100644 src/sys/libwebm/webm_parser/test_utils/element_parser_test.h create mode 100644 src/sys/libwebm/webm_parser/test_utils/limited_reader.cc create mode 100644 src/sys/libwebm/webm_parser/test_utils/limited_reader.h create mode 100644 src/sys/libwebm/webm_parser/test_utils/mock_callback.h create mode 100644 src/sys/libwebm/webm_parser/test_utils/parser_test.h create mode 100644 src/sys/libwebm/webm_parser/tests/audio_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/bit_utils_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/block_additions_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/block_group_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/block_header_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/block_more_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/block_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/bool_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/buffer_reader_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/byte_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/callback_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/chapter_atom_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/chapter_display_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/chapters_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/cluster_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/colour_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/content_enc_aes_settings_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/content_encoding_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/content_encodings_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/content_encryption_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/cue_point_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/cue_track_positions_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/cues_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/date_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/ebml_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/edition_entry_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/element_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/float_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/id_element_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/id_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/info_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/int_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/istream_reader_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/limited_reader_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/master_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/master_value_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/mastering_metadata_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/parser_utils_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/projection_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/recursive_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/seek_head_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/seek_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/segment_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/simple_tag_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/size_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/skip_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/slices_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/tag_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/tags_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/targets_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/time_slice_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/track_entry_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/tracks_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/unknown_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/var_int_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/video_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/virtual_block_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/void_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/webm_parser_test.cc create mode 100644 src/sys/libwebm/webm_parser/tests/webm_parser_tests.cc create mode 100644 src/sys/libwebm/webmids.hpp create mode 100644 src/sys/libwebm/webvtt/vttreader.cc create mode 100644 src/sys/libwebm/webvtt/vttreader.h create mode 100644 src/sys/libwebm/webvtt/webvttparser.cc create mode 100644 src/sys/libwebm/webvtt/webvttparser.h create mode 100644 src/sys/libwebm/webvttparser.h diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2b94e13..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "src/sys/libwebm"] - path = src/sys/libwebm - url = https://chromium.googlesource.com/webm/libwebm diff --git a/src/sys/libwebm b/src/sys/libwebm deleted file mode 160000 index d411c86..0000000 --- a/src/sys/libwebm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d411c8668dc226d9a3c7433c560dedfcc46fc69c diff --git a/src/sys/libwebm/.clang-format b/src/sys/libwebm/.clang-format new file mode 100644 index 0000000..7ce4e92 --- /dev/null +++ b/src/sys/libwebm/.clang-format @@ -0,0 +1,152 @@ +--- +Language: Cpp +# BasedOnStyle: Google +# Generated with clang-format 7.0.1 +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: true +AlignOperands: true +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: false +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^' + Priority: 2 + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 +UseTab: Never +... diff --git a/src/sys/libwebm/.cmake-format.py b/src/sys/libwebm/.cmake-format.py new file mode 100644 index 0000000..f1db75d --- /dev/null +++ b/src/sys/libwebm/.cmake-format.py @@ -0,0 +1,240 @@ +# ---------------------------------- +# Options affecting listfile parsing +# ---------------------------------- +with section("parse"): + + # Specify structure for custom cmake functions + additional_commands = { 'foo': { 'flags': ['BAR', 'BAZ'], + 'kwargs': {'DEPENDS': '*', 'HEADERS': '*', 'SOURCES': '*'}}} + + # Override configurations per-command where available + override_spec = {} + + # Specify variable tags. + vartags = [] + + # Specify property tags. + proptags = [] + +# ----------------------------- +# Options affecting formatting. +# ----------------------------- +with section("format"): + + # Disable formatting entirely, making cmake-format a no-op + disable = False + + # How wide to allow formatted cmake files + line_width = 80 + + # How many spaces to tab for indent + tab_size = 2 + + # If true, lines are indented using tab characters (utf-8 0x09) instead of + # space characters (utf-8 0x20). In cases where the layout would + # require a fractional tab character, the behavior of the fractional + # indentation is governed by + use_tabchars = False + + # If is True, then the value of this variable indicates how + # fractional indentions are handled during whitespace replacement. If set to + # 'use-space', fractional indentation is left as spaces (utf-8 0x20). If set + # to `round-up` fractional indentation is replaced with a single tab character + # (utf-8 0x09) effectively shifting the column to the next tabstop + fractional_tab_policy = 'use-space' + + # If an argument group contains more than this many sub-groups (parg or kwarg + # groups) then force it to a vertical layout. + max_subgroups_hwrap = 2 + + # If a positional argument group contains more than this many arguments, then + # force it to a vertical layout. + max_pargs_hwrap = 6 + + # If a cmdline positional group consumes more than this many lines without + # nesting, then invalidate the layout (and nest) + max_rows_cmdline = 2 + + # If true, separate flow control names from their parentheses with a space + separate_ctrl_name_with_space = False + + # If true, separate function names from parentheses with a space + separate_fn_name_with_space = False + + # If a statement is wrapped to more than one line, than dangle the closing + # parenthesis on its own line. + dangle_parens = False + + # If the trailing parenthesis must be 'dangled' on its on line, then align it + # to this reference: `prefix`: the start of the statement, `prefix-indent`: + # the start of the statement, plus one indentation level, `child`: align to + # the column of the arguments + dangle_align = 'prefix' + + # If the statement spelling length (including space and parenthesis) is + # smaller than this amount, then force reject nested layouts. + min_prefix_chars = 4 + + # If the statement spelling length (including space and parenthesis) is larger + # than the tab width by more than this amount, then force reject un-nested + # layouts. + max_prefix_chars = 10 + + # If a candidate layout is wrapped horizontally but it exceeds this many + # lines, then reject the layout. + max_lines_hwrap = 2 + + # What style line endings to use in the output. + line_ending = 'unix' + + # Format command names consistently as 'lower' or 'upper' case + command_case = 'canonical' + + # Format keywords consistently as 'lower' or 'upper' case + keyword_case = 'unchanged' + + # A list of command names which should always be wrapped + always_wrap = [] + + # If true, the argument lists which are known to be sortable will be sorted + # lexicographicall + enable_sort = True + + # If true, the parsers may infer whether or not an argument list is sortable + # (without annotation). + autosort = False + + # By default, if cmake-format cannot successfully fit everything into the + # desired linewidth it will apply the last, most agressive attempt that it + # made. If this flag is True, however, cmake-format will print error, exit + # with non-zero status code, and write-out nothing + require_valid_layout = False + + # A dictionary mapping layout nodes to a list of wrap decisions. See the + # documentation for more information. + layout_passes = {} + +# ------------------------------------------------ +# Options affecting comment reflow and formatting. +# ------------------------------------------------ +with section("markup"): + + # What character to use for bulleted lists + bullet_char = '*' + + # What character to use as punctuation after numerals in an enumerated list + enum_char = '.' + + # If comment markup is enabled, don't reflow the first comment block in each + # listfile. Use this to preserve formatting of your copyright/license + # statements. + first_comment_is_literal = True + + # If comment markup is enabled, don't reflow any comment block which matches + # this (regex) pattern. Default is `None` (disabled). + literal_comment_pattern = None + + # Regular expression to match preformat fences in comments default= + # ``r'^\s*([`~]{3}[`~]*)(.*)$'`` + fence_pattern = '^\\s*([`~]{3}[`~]*)(.*)$' + + # Regular expression to match rulers in comments default= + # ``r'^\s*[^\w\s]{3}.*[^\w\s]{3}$'`` + ruler_pattern = '^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$' + + # If a comment line matches starts with this pattern then it is explicitly a + # trailing comment for the preceeding argument. Default is '#<' + explicit_trailing_pattern = '#<' + + # If a comment line starts with at least this many consecutive hash + # characters, then don't lstrip() them off. This allows for lazy hash rulers + # where the first hash char is not separated by space + hashruler_min_length = 10 + + # If true, then insert a space between the first hash char and remaining hash + # chars in a hash ruler, and normalize its length to fill the column + canonicalize_hashrulers = True + + # enable comment markup parsing and reflow + enable_markup = True + +# ---------------------------- +# Options affecting the linter +# ---------------------------- +with section("lint"): + + # a list of lint codes to disable + disabled_codes = [] + + # regular expression pattern describing valid function names + function_pattern = '[0-9a-z_]+' + + # regular expression pattern describing valid macro names + macro_pattern = '[0-9A-Z_]+' + + # regular expression pattern describing valid names for variables with global + # (cache) scope + global_var_pattern = '[A-Z][0-9A-Z_]+' + + # regular expression pattern describing valid names for variables with global + # scope (but internal semantic) + internal_var_pattern = '_[A-Z][0-9A-Z_]+' + + # regular expression pattern describing valid names for variables with local + # scope + local_var_pattern = '[a-z][a-z0-9_]+' + + # regular expression pattern describing valid names for privatedirectory + # variables + private_var_pattern = '_[0-9a-z_]+' + + # regular expression pattern describing valid names for public directory + # variables + public_var_pattern = '[A-Z][0-9A-Z_]+' + + # regular expression pattern describing valid names for function/macro + # arguments and loop variables. + argument_var_pattern = '[a-z][a-z0-9_]+' + + # regular expression pattern describing valid names for keywords used in + # functions or macros + keyword_pattern = '[A-Z][0-9A-Z_]+' + + # In the heuristic for C0201, how many conditionals to match within a loop in + # before considering the loop a parser. + max_conditionals_custom_parser = 2 + + # Require at least this many newlines between statements + min_statement_spacing = 1 + + # Require no more than this many newlines between statements + max_statement_spacing = 2 + max_returns = 6 + max_branches = 12 + max_arguments = 5 + max_localvars = 15 + max_statements = 50 + +# ------------------------------- +# Options affecting file encoding +# ------------------------------- +with section("encode"): + + # If true, emit the unicode byte-order mark (BOM) at the start of the file + emit_byteorder_mark = False + + # Specify the encoding of the input file. Defaults to utf-8 + input_encoding = 'utf-8' + + # Specify the encoding of the output file. Defaults to utf-8. Note that cmake + # only claims to support utf-8 so be careful when using anything else + output_encoding = 'utf-8' + +# ------------------------------------- +# Miscellaneous configurations options. +# ------------------------------------- +with section("misc"): + + # A dictionary containing any per-command configuration overrides. Currently + # only `command_case` is supported. + per_command = {} diff --git a/src/sys/libwebm/.gitattributes b/src/sys/libwebm/.gitattributes new file mode 100644 index 0000000..2b5cda5 --- /dev/null +++ b/src/sys/libwebm/.gitattributes @@ -0,0 +1,6 @@ +*.sln eol=crlf +*.vcproj eol=crlf +*.vsprops eol=crlf +*.vcxproj eol=crlf +*.mkv -text -diff +*.webm -text -diff diff --git a/src/sys/libwebm/.gitignore b/src/sys/libwebm/.gitignore new file mode 100644 index 0000000..ad6fba1 --- /dev/null +++ b/src/sys/libwebm/.gitignore @@ -0,0 +1,36 @@ +*.MKV +*.a +*.cmake +*.d +*.exe +*.mkv +*.ncb +*.o +*.opensdf +*.sdf +*.so* +*.suo +*.swp +*.user +*~ +.vscode +/*.webm +CMakeCache.txt +CMakeFiles +Debug +Makefile +Release +core +dumpvtt +ipch +mkvmuxer_sample +mkvmuxer_tests +mkvparser_sample +mkvparser_tests +vp9_header_parser_tests +vp9_level_stats_tests +vttdemux +webm2pes +webm2pes_tests +webm2ts +webm_info diff --git a/src/sys/libwebm/.mailmap b/src/sys/libwebm/.mailmap new file mode 100644 index 0000000..63683a0 --- /dev/null +++ b/src/sys/libwebm/.mailmap @@ -0,0 +1,6 @@ +Hui Su +Matthew Heaney +Neil Birkbeck +Patrik Carlsson +Roberto Alanis Baez +Tom Finegan diff --git a/src/sys/libwebm/.pylintrc b/src/sys/libwebm/.pylintrc new file mode 100644 index 0000000..4658b84 --- /dev/null +++ b/src/sys/libwebm/.pylintrc @@ -0,0 +1,441 @@ +# This Pylint rcfile contains a best-effort configuration to uphold the +# best-practices and style described in the Google Python style guide: +# https://google.github.io/styleguide/pyguide.html +# +# Its canonical open-source location is: +# https://google.github.io/styleguide/pylintrc + +[MASTER] + +# Files or directories to be skipped. They should be base names, not paths. +ignore=third_party + +# Files or directories matching the regex patterns are skipped. The regex +# matches against base names, not paths. +ignore-patterns= + +# Pickle collected data for later comparisons. +persistent=no + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Use multiple processes to speed up Pylint. +jobs=4 + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=abstract-method, + apply-builtin, + arguments-differ, + attribute-defined-outside-init, + backtick, + bad-option-value, + basestring-builtin, + buffer-builtin, + c-extension-no-member, + consider-using-enumerate, + cmp-builtin, + cmp-method, + coerce-builtin, + coerce-method, + delslice-method, + div-method, + duplicate-code, + eq-without-hash, + execfile-builtin, + file-builtin, + filter-builtin-not-iterating, + fixme, + getslice-method, + global-statement, + hex-method, + idiv-method, + implicit-str-concat-in-sequence, + import-error, + import-self, + import-star-module-level, + inconsistent-return-statements, + input-builtin, + intern-builtin, + invalid-str-codec, + locally-disabled, + long-builtin, + long-suffix, + map-builtin-not-iterating, + misplaced-comparison-constant, + missing-function-docstring, + metaclass-assignment, + next-method-called, + next-method-defined, + no-absolute-import, + no-else-break, + no-else-continue, + no-else-raise, + no-else-return, + no-init, # added + no-member, + no-name-in-module, + no-self-use, + nonzero-method, + oct-method, + old-division, + old-ne-operator, + old-octal-literal, + old-raise-syntax, + parameter-unpacking, + print-statement, + raising-string, + range-builtin-not-iterating, + raw_input-builtin, + rdiv-method, + reduce-builtin, + relative-import, + reload-builtin, + round-builtin, + setslice-method, + signature-differs, + standarderror-builtin, + suppressed-message, + sys-max-int, + too-few-public-methods, + too-many-ancestors, + too-many-arguments, + too-many-boolean-expressions, + too-many-branches, + too-many-instance-attributes, + too-many-locals, + too-many-nested-blocks, + too-many-public-methods, + too-many-return-statements, + too-many-statements, + trailing-newlines, + unichr-builtin, + unicode-builtin, + unnecessary-pass, + unpacking-in-except, + useless-else-on-loop, + useless-object-inheritance, + useless-suppression, + using-cmp-argument, + wrong-import-order, + xrange-builtin, + zip-builtin-not-iterating, + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". This option is deprecated +# and it will be removed in Pylint 2.0. +files-output=no + +# Tells whether to display a full report or only the messages +reports=no + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + + +[BASIC] + +# Good variable names which should always be accepted, separated by a comma +good-names=main,_,PRESUBMIT + +# Bad variable names which should always be refused, separated by a comma +bad-names= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl + +# Regular expression matching correct function names +function-rgx=^(?:(?PsetUp|tearDown|setUpModule|tearDownModule)|(?P_?[A-Z][a-zA-Z0-9]*)|(?P_?[a-z][a-z0-9_]*))$ + +# Regular expression matching correct variable names +variable-rgx=^[a-z][a-z0-9_]*$ + +# Regular expression matching correct constant names +const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ + +# Regular expression matching correct attribute names +attr-rgx=^_{0,2}[a-z][a-z0-9_]*$ + +# Regular expression matching correct argument names +argument-rgx=^[a-z][a-z0-9_]*$ + +# Regular expression matching correct class attribute names +class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ + +# Regular expression matching correct inline iteration names +inlinevar-rgx=^[a-z][a-z0-9_]*$ + +# Regular expression matching correct class names +class-rgx=^_?[A-Z][a-zA-Z0-9]*$ + +# Regular expression matching correct module names +module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$ + +# Regular expression matching correct method names +method-rgx=(?x)^(?:(?P_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P_{0,2}[a-z][a-z0-9_]*))$ + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$ + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=10 + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=80 + +# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt +# lines made too long by directives to pytype. + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=(?x)( + ^\s*(\#\ )??$| + ^\s*(from\s+\S+\s+)?import\s+.+$) + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=yes + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check= + +# Maximum number of lines in a module +max-module-lines=99999 + +# String used as indentation unit. The internal Google style guide mandates 2 +# spaces. Google's externaly-published style guide says 4, consistent with +# PEP 8. Here, we use 2 spaces, for conformity with many open-sourced Google +# projects (like TensorFlow). +indent-string=' ' + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=TODO + + +[STRING] + +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=yes + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_) + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_,_cb + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging,absl.logging,tensorflow.io.logging + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + + +[SPELLING] + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub, + TERMIOS, + Bastion, + rexec, + sets + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant, absl + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls, + class_ + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=StandardError, + Exception, + BaseException diff --git a/src/sys/libwebm/.style.yapf b/src/sys/libwebm/.style.yapf new file mode 100644 index 0000000..47ca4cc --- /dev/null +++ b/src/sys/libwebm/.style.yapf @@ -0,0 +1,2 @@ +[style] +based_on_style = chromium \ No newline at end of file diff --git a/src/sys/libwebm/AUTHORS.TXT b/src/sys/libwebm/AUTHORS.TXT new file mode 100644 index 0000000..59b648c --- /dev/null +++ b/src/sys/libwebm/AUTHORS.TXT @@ -0,0 +1,5 @@ +# Names should be added to this file like so: +# Name or Organization + +Google Inc. +Elijah Cirioli diff --git a/src/sys/libwebm/Android.mk b/src/sys/libwebm/Android.mk new file mode 100644 index 0000000..e6c17df --- /dev/null +++ b/src/sys/libwebm/Android.mk @@ -0,0 +1,23 @@ +# Ignore this file during non-NDK builds. +ifdef NDK_ROOT +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE:= libwebm +LOCAL_CPPFLAGS:=-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS +LOCAL_CPPFLAGS+=-D__STDC_LIMIT_MACROS -std=c++11 +LOCAL_C_INCLUDES:= $(LOCAL_PATH) +LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH) + +LOCAL_SRC_FILES:= common/file_util.cc \ + common/hdr_util.cc \ + mkvparser/mkvparser.cc \ + mkvparser/mkvreader.cc \ + mkvmuxer/mkvmuxer.cc \ + mkvmuxer/mkvmuxerutil.cc \ + mkvmuxer/mkvwriter.cc +LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD +LOCAL_LICENSE_CONDITIONS := notice +LOCAL_NOTICE_FILE := $(LOCAL_PATH)/LICENSE.TXT $(LOCAL_PATH)/PATENTS.TXT +include $(BUILD_STATIC_LIBRARY) +endif # NDK_ROOT diff --git a/src/sys/libwebm/CMakeLists.txt b/src/sys/libwebm/CMakeLists.txt new file mode 100644 index 0000000..85b2603 --- /dev/null +++ b/src/sys/libwebm/CMakeLists.txt @@ -0,0 +1,474 @@ +# Copyright (c) 2015 The WebM project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. +cmake_minimum_required(VERSION 3.2) +project(LIBWEBM CXX) + +include(GNUInstallDirs) +include("${CMAKE_CURRENT_SOURCE_DIR}/build/cxx_flags.cmake") + +if(BUILD_SHARED_LIBS) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +else() + include("${CMAKE_CURRENT_SOURCE_DIR}/build/msvc_runtime.cmake") +endif() + +set(LIBWEBM_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + +# Build/test configuration flags. +option(ENABLE_WEBMTS "Enables WebM PES/TS support." ON) +option(ENABLE_WEBMINFO "Enables building webm_info." ON) +option(ENABLE_TESTS "Enables tests." OFF) +option(ENABLE_IWYU "Enables include-what-you-use support." OFF) +option(ENABLE_WERROR "Enable warnings as errors." OFF) +option(ENABLE_WEBM_PARSER "Enables new parser API." OFF) +option(ENABLE_SAMPLE_PROGRAMS "Enables building sample programs." ON) + +if(WIN32 + OR CYGWIN + OR MSYS) + # Allow use of rand_r() / fdopen() and other POSIX functions. + require_cxx_flag_nomsvc("-std=gnu++11") +else() + require_cxx_flag_nomsvc("-std=c++11") +endif() + +add_cxx_preproc_definition("__STDC_CONSTANT_MACROS") +add_cxx_preproc_definition("__STDC_FORMAT_MACROS") +add_cxx_preproc_definition("__STDC_LIMIT_MACROS") + +# Set up compiler flags and build properties. +include_directories("${LIBWEBM_SRC_DIR}") + +if(MSVC) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + add_cxx_flag_if_supported("/W4") + # Disable MSVC warnings that suggest making code non-portable. + add_cxx_flag_if_supported("/wd4996") + if(ENABLE_WERROR) + add_cxx_flag_if_supported("/WX") + endif() +else() + add_cxx_flag_if_supported("-Wall") + add_cxx_flag_if_supported("-Wc++14-compat") + add_cxx_flag_if_supported("-Wc++17-compat") + add_cxx_flag_if_supported("-Wc++20-compat") + add_cxx_flag_if_supported("-Wextra") + add_cxx_flag_if_supported("-Wnarrowing") + add_cxx_flag_if_supported("-Wno-deprecated") + add_cxx_flag_if_supported("-Wshorten-64-to-32") + if(ENABLE_WERROR) + add_cxx_flag_if_supported("-Werror") + endif() +endif() + +# Source list variables. +set(dumpvtt_sources "${LIBWEBM_SRC_DIR}/dumpvtt.cc") + +set(libwebm_common_public_headers "${LIBWEBM_SRC_DIR}/common/webmids.h") + +set(libwebm_common_sources + ${libwebm_common_public_headers} + "${LIBWEBM_SRC_DIR}/common/file_util.cc" + "${LIBWEBM_SRC_DIR}/common/file_util.h" + "${LIBWEBM_SRC_DIR}/common/hdr_util.cc" + "${LIBWEBM_SRC_DIR}/common/hdr_util.h") + +set(mkvmuxer_public_headers + "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxer.h" + "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxertypes.h" + "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxerutil.h" + "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvwriter.h") + +set(mkvmuxer_sources + ${mkvmuxer_public_headers} + "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxer.cc" + "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvmuxerutil.cc" + "${LIBWEBM_SRC_DIR}/mkvmuxer/mkvwriter.cc" + "${LIBWEBM_SRC_DIR}/common/webmids.h") + +set(mkvmuxer_sample_sources + "${LIBWEBM_SRC_DIR}/mkvmuxer_sample.cc" + "${LIBWEBM_SRC_DIR}/sample_muxer_metadata.cc" + "${LIBWEBM_SRC_DIR}/sample_muxer_metadata.h") + +set(mkvmuxer_tests_sources + "${LIBWEBM_SRC_DIR}/testing/mkvmuxer_tests.cc" + "${LIBWEBM_SRC_DIR}/testing/test_util.cc" + "${LIBWEBM_SRC_DIR}/testing/test_util.h") + +set(mkvparser_public_headers "${LIBWEBM_SRC_DIR}/mkvparser/mkvparser.h" + "${LIBWEBM_SRC_DIR}/mkvparser/mkvreader.h") + +set(mkvparser_sources + ${mkvparser_public_headers} "${LIBWEBM_SRC_DIR}/mkvparser/mkvparser.cc" + "${LIBWEBM_SRC_DIR}/mkvparser/mkvreader.cc" + "${LIBWEBM_SRC_DIR}/common/webmids.h") + +set(mkvparser_sample_sources "${LIBWEBM_SRC_DIR}/mkvparser_sample.cc") +set(mkvparser_tests_sources + "${LIBWEBM_SRC_DIR}/testing/mkvparser_tests.cc" + "${LIBWEBM_SRC_DIR}/testing/test_util.cc" + "${LIBWEBM_SRC_DIR}/testing/test_util.h") + +set(vp9_header_parser_tests_sources + "${LIBWEBM_SRC_DIR}/common/vp9_header_parser_tests.cc" + "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc" + "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h" + "${LIBWEBM_SRC_DIR}/testing/test_util.cc" + "${LIBWEBM_SRC_DIR}/testing/test_util.h") + +set(vp9_level_stats_tests_sources + "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc" + "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h" + "${LIBWEBM_SRC_DIR}/common/vp9_level_stats_tests.cc" + "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.cc" + "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.h" + "${LIBWEBM_SRC_DIR}/testing/test_util.cc" + "${LIBWEBM_SRC_DIR}/testing/test_util.h") + +set(webm_parser_public_headers + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/buffer_reader.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/callback.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/dom_types.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/element.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/file_reader.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/id.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/istream_reader.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/reader.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/status.h" + "${LIBWEBM_SRC_DIR}/webm_parser/include/webm/webm_parser.h") + +set(webm_parser_sources + ${webm_parser_public_headers} + "${LIBWEBM_SRC_DIR}/webm_parser/src/ancestory.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/ancestory.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/audio_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/bit_utils.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/bit_utils.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/block_additions_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/block_group_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/block_header_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/block_header_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/block_more_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/block_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/block_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/bool_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/buffer_reader.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/byte_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/callback.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/chapter_atom_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/chapter_display_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/chapters_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/cluster_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/colour_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/content_enc_aes_settings_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encoding_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encodings_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/content_encryption_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/cue_point_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/cue_track_positions_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/cues_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/date_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/date_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/ebml_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/edition_entry_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/element_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/file_reader.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/float_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/float_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/id_element_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/id_element_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/id_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/id_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/info_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/int_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/istream_reader.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/master_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/master_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/master_value_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/mastering_metadata_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/parser_utils.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/projection_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/recursive_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_head_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/seek_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/segment_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/segment_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/simple_tag_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/size_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/size_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_callback.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/skip_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/slices_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/tag_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/tags_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/targets_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/time_slice_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/track_entry_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/tracks_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/unknown_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/unknown_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/var_int_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/var_int_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/video_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/virtual_block_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/virtual_block_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/void_parser.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/src/void_parser.h" + "${LIBWEBM_SRC_DIR}/webm_parser/src/webm_parser.cc") + +set(webm_parser_demo_sources "${LIBWEBM_SRC_DIR}/webm_parser/demo/demo.cc") +set(webm_parser_tests_sources + "${LIBWEBM_SRC_DIR}/webm_parser/tests/audio_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/bit_utils_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_additions_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_group_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_header_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_more_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/block_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/bool_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/buffer_reader_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/byte_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/callback_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapter_atom_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapter_display_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/chapters_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/cluster_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/colour_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_enc_aes_settings_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encoding_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encodings_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/content_encryption_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/cue_point_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/cue_track_positions_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/cues_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/date_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/ebml_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/edition_entry_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/element_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/float_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/id_element_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/id_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/info_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/int_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/istream_reader_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/limited_reader_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/master_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/master_value_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/mastering_metadata_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/parser_utils_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/projection_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/recursive_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_head_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/seek_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/segment_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/simple_tag_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/size_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/skip_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/slices_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/tag_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/tags_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/targets_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/time_slice_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/track_entry_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/tracks_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/unknown_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/var_int_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/video_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/virtual_block_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/void_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/webm_parser_test.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/element_parser_test.h" + "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/limited_reader.cc" + "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/limited_reader.h" + "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/mock_callback.h" + "${LIBWEBM_SRC_DIR}/webm_parser/test_utils/parser_test.h" + "${LIBWEBM_SRC_DIR}/webm_parser/tests/webm_parser_tests.cc") + +set(webm_info_sources + "${LIBWEBM_SRC_DIR}/common/indent.cc" + "${LIBWEBM_SRC_DIR}/common/indent.h" + "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.cc" + "${LIBWEBM_SRC_DIR}/common/vp9_header_parser.h" + "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.cc" + "${LIBWEBM_SRC_DIR}/common/vp9_level_stats.h" + "${LIBWEBM_SRC_DIR}/common/webm_constants.h" + "${LIBWEBM_SRC_DIR}/common/webm_endian.cc" + "${LIBWEBM_SRC_DIR}/common/webm_endian.h" + "${LIBWEBM_SRC_DIR}/webm_info.cc") + +set(webmts_sources + "${LIBWEBM_SRC_DIR}/common/libwebm_util.cc" + "${LIBWEBM_SRC_DIR}/common/libwebm_util.h" + "${LIBWEBM_SRC_DIR}/common/video_frame.cc" + "${LIBWEBM_SRC_DIR}/common/video_frame.h" + "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts.cc" + "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts.h" + "${LIBWEBM_SRC_DIR}/m2ts/vpxpes_parser.cc" + "${LIBWEBM_SRC_DIR}/m2ts/vpxpes_parser.h" + "${LIBWEBM_SRC_DIR}/m2ts/webm2pes.cc" + "${LIBWEBM_SRC_DIR}/m2ts/webm2pes.h") + +set(webm2pes_sources "${LIBWEBM_SRC_DIR}/m2ts/webm2pes_main.cc") +set(webm2pes_tests_sources + "${LIBWEBM_SRC_DIR}/testing/test_util.cc" + "${LIBWEBM_SRC_DIR}/testing/test_util.h" + "${LIBWEBM_SRC_DIR}/testing/video_frame_tests.cc" + "${LIBWEBM_SRC_DIR}/m2ts/tests/webm2pes_tests.cc") +set(webm2ts_sources "${LIBWEBM_SRC_DIR}/m2ts/vpxpes2ts_main.cc") + +set(webvtt_common_headers "${LIBWEBM_SRC_DIR}/webvtt/vttreader.h" + "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.h") + +set(webvtt_common_sources + ${webvtt_common_headers} "${LIBWEBM_SRC_DIR}/webvtt/vttreader.cc" + "${LIBWEBM_SRC_DIR}/webvtt/webvttparser.cc") + +set(vttdemux_sources ${webvtt_common_sources} "${LIBWEBM_SRC_DIR}/vttdemux.cc") + +# Targets. +add_library(mkvmuxer OBJECT ${mkvmuxer_sources}) +add_library(mkvparser OBJECT ${mkvparser_sources}) +add_library(webvtt_common OBJECT ${webvtt_common_sources}) + +add_library(webm ${libwebm_common_sources} $ + $) + +if(ENABLE_SAMPLE_PROGRAMS) + add_executable(mkvparser_sample ${mkvparser_sample_sources}) + target_link_libraries(mkvparser_sample LINK_PUBLIC webm) + + add_executable(mkvmuxer_sample ${mkvmuxer_sample_sources} + $) + target_link_libraries(mkvmuxer_sample LINK_PUBLIC webm) + + add_executable(dumpvtt ${dumpvtt_sources} $) + target_link_libraries(dumpvtt LINK_PUBLIC webm) + + add_executable(vttdemux ${vttdemux_sources}) + target_link_libraries(vttdemux LINK_PUBLIC webm) +endif() + +if(ENABLE_WEBMINFO) + add_executable(webm_info ${webm_info_sources}) + target_link_libraries(webm_info LINK_PUBLIC webm) +endif() + +if(ENABLE_WEBM_PARSER) + include_directories(webm_parser webm_parser/include) + add_library(webm_parser OBJECT ${webm_parser_sources}) + target_sources(webm PUBLIC $) + + add_executable(webm_parser_demo ${webm_parser_demo_sources}) + target_link_libraries(webm_parser_demo LINK_PUBLIC webm) +endif() + +if(ENABLE_WEBMTS) + add_library(webmts OBJECT ${webmts_sources}) + + add_executable(webm2pes ${webm2pes_sources} $) + target_link_libraries(webm2pes LINK_PUBLIC webm) + + add_executable(webm2ts ${webm2ts_sources} $) + target_link_libraries(webm2ts LINK_PUBLIC webm) +endif() + +if(ENABLE_TESTS) + set(GTEST_SRC_DIR + "${LIBWEBM_SRC_DIR}/../googletest" + CACHE PATH "Path to Googletest git repository.") + # This directory is where libwebm will build googletest dependencies. + set(GTEST_BUILD_DIR "${CMAKE_BINARY_DIR}/googletest_build") + + if(LIBWEBM_DISABLE_GTEST_CMAKE) + add_library(gtest STATIC "${GTEST_SRC_DIR}/googletest/src/gtest-all.cc") + include_directories("${GTEST_SRC_DIR}/googletest") + else() + add_subdirectory("${GTEST_SRC_DIR}" "${GTEST_BUILD_DIR}") + endif() + include_directories("${GTEST_SRC_DIR}/googletest/include") + + add_executable(mkvmuxer_tests ${mkvmuxer_tests_sources}) + target_link_libraries(mkvmuxer_tests LINK_PUBLIC gtest webm) + + add_executable(mkvparser_tests ${mkvparser_tests_sources}) + target_link_libraries(mkvparser_tests LINK_PUBLIC gtest webm) + + add_executable(vp9_header_parser_tests ${vp9_header_parser_tests_sources}) + target_link_libraries(vp9_header_parser_tests LINK_PUBLIC gtest webm) + + add_executable(vp9_level_stats_tests ${vp9_level_stats_tests_sources}) + target_link_libraries(vp9_level_stats_tests LINK_PUBLIC gtest webm) + + if(ENABLE_WEBMTS) + add_executable(webm2pes_tests ${webm2pes_tests_sources} + $) + target_link_libraries(webm2pes_tests LINK_PUBLIC gtest webm) + endif() + + if(ENABLE_WEBM_PARSER) + include_directories("${GTEST_SRC_DIR}/googlemock/include") + add_executable(webm_parser_tests ${webm_parser_tests_sources}) + target_link_libraries(webm_parser_tests LINK_PUBLIC gmock gtest webm) + endif() +endif() + +# Include-what-you-use. +if(ENABLE_IWYU) + # Make sure all the tools necessary for IWYU are present. + find_program(iwyu_path NAMES include-what-you-use) + find_program(iwyu_tool_path NAMES iwyu_tool.py) + + # Some odd behavior on cmake's part: PYTHON_EXECUTABLE and PYTHON_VERSION_* + # are set by cmake when it does its internal python check, but + # PYTHONINTERP_FOUND is empty without explicitly looking for it. + find_package(PythonInterp) + + if(iwyu_path + AND iwyu_tool_path + AND PYTHONINTERP_FOUND) + # Enable compilation command export (needed for iwyu_tool.py) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + + # Add a custom target to run iwyu across all targets. + add_custom_target( + iwyu ALL + COMMAND "${PYTHON_EXECUTABLE}" "${iwyu_tool_path}" -p + "${CMAKE_BINARY_DIR}" + COMMENT "Running include-what-you-use..." + VERBATIM) + else() + message(STATUS "Ignoring ENABLE_IWYU because reasons:") + message(STATUS " iwyu_path=" ${iwyu_path}) + message(STATUS " iwyu_tool_path=" ${iwyu_tool_path}) + message(STATUS " PYTHONINTERP_FOUND=" ${PYTHONINTERP_FOUND}) + message(STATUS " See README.libwebm for more information.") + endif() +endif() + +# webm_parser headers are rooted at webm/. +set_target_properties(webm PROPERTIES PUBLIC_HEADER + "${webm_parser_public_headers}") +install( + TARGETS webm + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webm) + +# Install common headers into a subdirectory to avoid breaking nested includes. +install(FILES ${libwebm_common_public_headers} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webm/common) +# mkvmuxer and mkvparser headers are referenced with their prefix. +install(FILES ${mkvmuxer_public_headers} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webm/mkvmuxer) +install(FILES ${mkvparser_public_headers} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/webm/mkvparser) diff --git a/src/sys/libwebm/CONTRIBUTING.md b/src/sys/libwebm/CONTRIBUTING.md new file mode 100644 index 0000000..a30c512 --- /dev/null +++ b/src/sys/libwebm/CONTRIBUTING.md @@ -0,0 +1,41 @@ +# How to Contribute + +We'd love to accept your patches and contributions to this project. There are +just a few small guidelines you need to follow. + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution; +this simply gives us permission to use and redistribute your contributions as +part of the project. Head over to to see +your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + +## Code reviews + +All submissions, including submissions by project members, require review. We +use a [Gerrit](https://www.gerritcodereview.com) instance hosted at +https://chromium-review.googlesource.com for this purpose. See the +[WebM Project page](https://www.webmproject.org/code/contribute/submitting-patches/) +for additional details. + +## Code Style + +The C++ code style is based on the +[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) and +`clang-format --style=Google`. `clang-format -i --style=file` can be used to +format individual files, it will use the settings from `.clang-format`. + +CMake files are formatted with +[cmake-format](https://cmake-format.readthedocs.io/en/latest/). `cmake-format +-i` can be used to format individual files, it will use the settings from +`.cmake-format.py`. + +## Community Guidelines + +This project follows +[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). diff --git a/src/sys/libwebm/LICENSE.TXT b/src/sys/libwebm/LICENSE.TXT new file mode 100644 index 0000000..7a6f995 --- /dev/null +++ b/src/sys/libwebm/LICENSE.TXT @@ -0,0 +1,30 @@ +Copyright (c) 2010, Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Google nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/src/sys/libwebm/Makefile.unix b/src/sys/libwebm/Makefile.unix new file mode 100644 index 0000000..0430d17 --- /dev/null +++ b/src/sys/libwebm/Makefile.unix @@ -0,0 +1,57 @@ +CXX := g++ +DEFINES := -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS +DEFINES += -D__STDC_LIMIT_MACROS +INCLUDES := -I. +CXXFLAGS := -W -Wall -g -std=c++11 +ALL_CXXFLAGS := -MMD -MP $(DEFINES) $(INCLUDES) $(CXXFLAGS) +LIBWEBMA := libwebm.a +LIBWEBMSO := libwebm.so +WEBMOBJS := mkvmuxer/mkvmuxer.o mkvmuxer/mkvmuxerutil.o mkvmuxer/mkvwriter.o +WEBMOBJS += mkvparser/mkvparser.o mkvparser/mkvreader.o +WEBMOBJS += common/file_util.o common/hdr_util.o +OBJSA := $(WEBMOBJS:.o=_a.o) +OBJSSO := $(WEBMOBJS:.o=_so.o) +VTTOBJS := webvtt/vttreader.o webvtt/webvttparser.o sample_muxer_metadata.o +EXEOBJS := mkvmuxer_sample.o mkvparser_sample.o dumpvtt.o vttdemux.o +EXES := mkvparser_sample mkvmuxer_sample dumpvtt vttdemux +DEPS := $(WEBMOBJS:.o=.d) $(OBJECTS1:.o=.d) $(OBJECTS2:.o=.d) +DEPS += $(OBJECTS3:.o=.d) $(OBJECTS4:.o=.d) $(OBJSA:.o=.d) $(OBJSSO:.o=.d) +DEPS += $(VTTOBJS:.o=.d) $(EXEOBJS:.o=.d) +CLEAN := $(EXEOBJS) $(VTTOBJS) $(WEBMOBJS) $(OBJSA) $(OBJSSO) $(LIBWEBMA) +CLEAN += $(LIBWEBMSO) $(EXES) $(DEPS) $(INFOOBJS) + +all: $(EXES) + +mkvparser_sample: mkvparser_sample.o $(LIBWEBMA) + $(CXX) $^ -o $@ + +mkvmuxer_sample: mkvmuxer_sample.o $(VTTOBJS) $(LIBWEBMA) + $(CXX) $^ -o $@ + +dumpvtt: dumpvtt.o $(VTTOBJS) $(WEBMOBJS) + $(CXX) $^ -o $@ + +vttdemux: vttdemux.o $(VTTOBJS) $(LIBWEBMA) + $(CXX) $^ -o $@ + +shared: $(LIBWEBMSO) + +libwebm.a: $(OBJSA) + $(AR) rcs $@ $^ + +libwebm.so: $(OBJSSO) + $(CXX) $(ALL_CXXFLAGS) -shared $(OBJSSO) -o $(LIBWEBMSO) + +%.o: %.cc + $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ +%_a.o: %.cc + $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ +%_so.o: %.cc + $(CXX) -c $(ALL_CXXFLAGS) -fPIC $< -o $@ + +clean: + $(RM) -f $(CLEAN) Makefile.bak + +ifneq ($(MAKECMDGOALS), clean) + -include $(DEPS) +endif diff --git a/src/sys/libwebm/PATENTS.TXT b/src/sys/libwebm/PATENTS.TXT new file mode 100644 index 0000000..caedf60 --- /dev/null +++ b/src/sys/libwebm/PATENTS.TXT @@ -0,0 +1,23 @@ +Additional IP Rights Grant (Patents) +------------------------------------ + +"These implementations" means the copyrightable works that implement the WebM +codecs distributed by Google as part of the WebM Project. + +Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, +royalty-free, irrevocable (except as stated in this section) patent license to +make, have made, use, offer to sell, sell, import, transfer, and otherwise +run, modify and propagate the contents of these implementations of WebM, where +such license applies only to those patent claims, both currently owned by +Google and acquired in the future, licensable by Google that are necessarily +infringed by these implementations of WebM. This grant does not include claims +that would be infringed only as a consequence of further modification of these +implementations. If you or your agent or exclusive licensee institute or order +or agree to the institution of patent litigation or any other patent +enforcement activity against any entity (including a cross-claim or +counterclaim in a lawsuit) alleging that any of these implementations of WebM +or any code incorporated within any of these implementations of WebM +constitute direct or contributory patent infringement, or inducement of +patent infringement, then any patent rights granted to you under this License +for these implementations of WebM shall terminate as of the date such +litigation is filed. diff --git a/src/sys/libwebm/PRESUBMIT.py b/src/sys/libwebm/PRESUBMIT.py new file mode 100644 index 0000000..58be26d --- /dev/null +++ b/src/sys/libwebm/PRESUBMIT.py @@ -0,0 +1,202 @@ +# Copyright (c) 2021, Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of Google nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +"""Top-level presubmit script for libwebm. + +See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for +details on the presubmit API built into depot_tools. +""" +import re +import subprocess2 + +USE_PYTHON3 = True +_BASH_INDENTATION = "2" +_GIT_COMMIT_SUBJECT_LENGTH = 65 +_INCLUDE_BASH_FILES_ONLY = [r".*\.sh$"] +_INCLUDE_SOURCE_FILES_ONLY = [r".*\.(c|cc|[hc]pp|h)$"] +_LIBWEBM_MAX_LINE_LENGTH = 80 + + +def _CheckCommitSubjectLength(input_api, output_api): + """Ensures commit's subject length is no longer than 65 chars.""" + name = "git-commit subject" + cmd = ["git", "log", "-1", "--pretty=%s"] + start = input_api.time.time() + proc = subprocess2.Popen( + cmd, + stderr=subprocess2.PIPE, + stdout=subprocess2.PIPE, + universal_newlines=True) + + stdout, _ = proc.communicate() + duration = input_api.time.time() - start + + if not re.match(r"^Revert", + stdout) and (len(stdout) - 1) > _GIT_COMMIT_SUBJECT_LENGTH: + failure_msg = ( + "The commit subject: %s is too long (%d chars)\n" + "Try to keep this to 50 or less (up to 65 is permitted for " + "non-reverts).\n" + "https://www.git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-" + "Project#_commit_guidelines") % (stdout, len(stdout) - 1) + return output_api.PresubmitError("%s\n (%4.2fs) failed\n%s" % + (name, duration, failure_msg)) + + return output_api.PresubmitResult("%s\n (%4.2fs) success" % (name, duration)) + + +def _GetFilesToSkip(input_api): + """Skips libwebm-specific files.""" + return list(input_api.DEFAULT_FILES_TO_SKIP) + [ + r"\.pylintrc$", + ] + + +def _CheckChangeLintsClean(input_api, output_api): + """Makes sure that libwebm/ code is cpplint clean.""" + sources = lambda x: input_api.FilterSourceFile( + x, files_to_check=_INCLUDE_SOURCE_FILES_ONLY, files_to_skip=None) + return input_api.canned_checks.CheckChangeLintsClean(input_api, output_api, + sources) + + +def _RunShellCheckCmd(input_api, output_api, bash_file): + """shellcheck command wrapper.""" + cmd = ["shellcheck", "-x", "-oall", "-sbash", bash_file] + name = "Check %s file." % bash_file + start = input_api.time.time() + output, rc = subprocess2.communicate( + cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True) + duration = input_api.time.time() - start + if rc == 0: + return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" % + (name, " ".join(cmd), duration)) + return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" % + (name, " ".join(cmd), duration, output[1])) + + +def _RunShfmtCheckCmd(input_api, output_api, bash_file): + """shfmt command wrapper.""" + cmd = [ + "shfmt", "-i", _BASH_INDENTATION, "-bn", "-ci", "-sr", "-kp", "-d", + bash_file + ] + name = "Check %s file." % bash_file + start = input_api.time.time() + output, rc = subprocess2.communicate( + cmd, stdout=None, stderr=subprocess2.PIPE, universal_newlines=True) + duration = input_api.time.time() - start + if rc == 0: + return output_api.PresubmitResult("%s\n%s (%4.2fs)\n" % + (name, " ".join(cmd), duration)) + return output_api.PresubmitError("%s\n%s (%4.2fs) failed\n%s" % + (name, " ".join(cmd), duration, output[1])) + + +def _RunCmdOnCheckedFiles(input_api, output_api, run_cmd, files_to_check): + """Ensure that libwebm/ files are clean.""" + file_filter = lambda x: input_api.FilterSourceFile( + x, files_to_check=files_to_check, files_to_skip=None) + + affected_files = input_api.change.AffectedFiles(file_filter=file_filter) + results = [ + run_cmd(input_api, output_api, f.AbsoluteLocalPath()) + for f in affected_files + ] + return results + + +def _CommonChecks(input_api, output_api): + results = [] + results.extend( + input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol( + input_api, output_api)) + results.extend( + input_api.canned_checks.CheckChangeHasNoTabs(input_api, output_api)) + results.extend( + input_api.canned_checks.CheckChangeHasNoStrayWhitespace( + input_api, output_api)) + results.append(_CheckCommitSubjectLength(input_api, output_api)) + + source_file_filter = lambda x: input_api.FilterSourceFile( + x, files_to_skip=_GetFilesToSkip(input_api)) + results.extend( + input_api.canned_checks.CheckLongLines( + input_api, + output_api, + maxlen=_LIBWEBM_MAX_LINE_LENGTH, + source_file_filter=source_file_filter)) + + results.extend( + input_api.canned_checks.CheckPatchFormatted( + input_api, + output_api, + check_clang_format=True, + check_python=True, + result_factory=output_api.PresubmitError)) + results.extend(_CheckChangeLintsClean(input_api, output_api)) + + # Run pylint. + results.extend( + input_api.canned_checks.RunPylint( + input_api, + output_api, + files_to_skip=_GetFilesToSkip(input_api), + pylintrc=".pylintrc", + version="2.7")) + + # Binaries shellcheck and shfmt are not installed in depot_tools. + # Installation is needed + try: + subprocess2.communicate(["shellcheck", "--version"]) + results.extend( + _RunCmdOnCheckedFiles(input_api, output_api, _RunShellCheckCmd, + _INCLUDE_BASH_FILES_ONLY)) + print("shfmt") + subprocess2.communicate(["shfmt", "-version"]) + results.extend( + _RunCmdOnCheckedFiles(input_api, output_api, _RunShfmtCheckCmd, + _INCLUDE_BASH_FILES_ONLY)) + except OSError as os_error: + results.append( + output_api.PresubmitPromptWarning( + "%s\nPlease install missing binaries locally." % os_error.args[0])) + return results + + +def CheckChangeOnUpload(input_api, output_api): + results = [] + results.extend(_CommonChecks(input_api, output_api)) + return results + + +def CheckChangeOnCommit(input_api, output_api): + results = [] + results.extend(_CommonChecks(input_api, output_api)) + return results diff --git a/src/sys/libwebm/README.libwebm b/src/sys/libwebm/README.libwebm new file mode 100644 index 0000000..3406f80 --- /dev/null +++ b/src/sys/libwebm/README.libwebm @@ -0,0 +1,143 @@ +Building Libwebm + +To build libwebm you must first create project files. To do this run cmake +and pass it the path to your libwebm repo. + +Makefile.unix can be used as a fallback on systems that cmake does not +support. + + +CMake Basics + +To generate project/make files for the default toolchain on your system simply +run cmake with the path to the libwebm repo: + +$ cmake path/to/libwebm + +On Windows the above command will produce Visual Studio project files for the +newest Visual Studio detected on the system. On Mac OS X and Linux systems, the +above command will produce a makefile. + +To control what types of projects are generated the -G parameter is added to +the cmake command line. This argument must be followed by the name of a +generator. Running cmake with the --help argument will list the available +generators for your system. + +On Mac OS X you would run the following command to generate Xcode projects: + +$ cmake path/to/libwebm -G Xcode + +On a Windows box you would run the following command to generate Visual Studio +2013 projects: + +$ cmake path/to/libwebm -G "Visual Studio 12" + +To generate 64-bit Windows Visual Studio 2013 projects: + +$ cmake path/to/libwebm "Visual Studio 12 Win64" + + +CMake Makefiles: Debugging and Optimization + +Unlike Visual Studio and Xcode projects, the build configuration for make builds +is controlled when you run cmake. The following examples demonstrate various +build configurations. + +Omitting the build type produces makefiles that use build flags containing +neither optimization nor debug flags: +$ cmake path/to/libwebm + +A makefile using release (optimized) flags is produced like this: +$ cmake path/to/libwebm -DCMAKE_BUILD_TYPE=release + +A release build with debug info can be produced as well: +$ cmake path/to/libwebm -DCMAKE_BUILD_TYPE=relwithdebinfo + +And your standard debug build will be produced using: +$ cmake path/to/libwebm -DCMAKE_BUILD_TYPE=debug + + +Tests + +To enable libwebm tests add -DENABLE_TESTS=ON CMake generation command line. For +example: + +$ cmake path/to/libwebm -G Xcode -DENABLE_TESTS=ON + +Libwebm tests depend on googletest. By default googletest is expected to be a +sibling directory of the Libwebm repository. To change that, update your CMake +command to be similar to the following: + +$ cmake path/to/libwebm -G Xcode -DENABLE_TESTS=ON \ + -DGTEST_SRC_DIR=/path/to/googletest + +The tests rely upon the LIBWEBM_TEST_DATA_PATH environment variable to locate +test input. The following example demonstrates running the muxer tests from the +build directory: + +$ LIBWEBM_TEST_DATA_PATH=path/to/libwebm/testing/testdata ./mkvmuxer_tests + +Note: Libwebm Googletest integration was built with googletest from + https://github.com/google/googletest.git at git revision + ddb8012eb48bc203aa93dcc2b22c1db516302b29. + + +CMake Include-what-you-use integration + +Include-what-you-use is an analysis tool that helps ensure libwebm includes the +C/C++ header files actually in use. To enable the integration support +ENABLE_IWYU must be turned on at cmake run time: + +$ cmake path/to/libwebm -G "Unix Makefiles" -DENABLE_IWYU=ON + +This adds the iwyu target to the build. To run include-what-you-use: + +$ make iwyu + +The following requirements must be met for ENABLE_IWYU to enable the iwyu +target: + +1. include-what-you-use and iwyu_tool.py must be in your PATH. +2. A python interpreter must be on the system and available to CMake. + +The values of the following variables are used to determine if the requirements +have been met. Values to the right of the equals sign are what a successful run +might look like: + iwyu_path=/path/to/iwyu_tool.py + iwyu_tool_path=/path/to/include-what-you-use + PYTHONINTERP_FOUND=TRUE + +An empty PYTHONINTERP_FOUND, or iwyu_path/iwyu_tool_path suffixed with NOTFOUND +are failures. + +For Include-what-you-use setup instructions, see: +https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/InstructionsForUsers.md + +If, when building the iwyu target, compile errors reporting failures loading +standard include files occur, one solution can be found here: +https://github.com/include-what-you-use/include-what-you-use/issues/100 + + +CMake cross compile +To cross compile libwebm for Windows using mingw-w64 run cmake with the +following arguments: + +$ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/libwebm/build/mingw-w64_toolchain.cmake \ + path/to/libwebm + +Note1: As of this writing googletest will not build via mingw-w64 without +disabling pthreads. +googletest hash: d225acc90bc3a8c420a9bcd1f033033c1ccd7fe0 + +To build with tests when using mingw-w64 use the following arguments when +running CMake: + +$ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/libwebm/build/mingw-w64_toolchain.cmake \ + -DENABLE_TESTS=ON -Dgtest_disable_pthreads=ON path/to/libwebm + +Note2: i686-w64-mingw32 is the default compiler. This can be controlled using +the MINGW_PREFIX variable: + +$ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/libwebm/build/mingw-w64_toolchain.cmake \ + -DMINGW_PREFIX=x86_64-w64-mingw32 path/to/libwebm + diff --git a/src/sys/libwebm/codereview.settings b/src/sys/libwebm/codereview.settings new file mode 100644 index 0000000..ccba2ee --- /dev/null +++ b/src/sys/libwebm/codereview.settings @@ -0,0 +1,4 @@ +# This file is used by git cl to get repository specific information. +GERRIT_HOST: True +CODE_REVIEW_SERVER: chromium-review.googlesource.com +GERRIT_SQUASH_UPLOADS: False diff --git a/src/sys/libwebm/common/common.sh b/src/sys/libwebm/common/common.sh new file mode 100644 index 0000000..49fec79 --- /dev/null +++ b/src/sys/libwebm/common/common.sh @@ -0,0 +1,62 @@ +#!/bin/sh +## +## Copyright (c) 2015 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## +set -e +devnull='> /dev/null 2>&1' + +readonly ORIG_PWD="$(pwd)" + +elog() { + echo "${0##*/} failed because: $@" 1>&2 +} + +vlog() { + if [ "${VERBOSE}" = "yes" ]; then + echo "$@" + fi +} + +# Terminates script when name of current directory does not match $1. +check_dir() { + current_dir="$(pwd)" + required_dir="$1" + if [ "${current_dir##*/}" != "${required_dir}" ]; then + elog "This script must be run from the ${required_dir} directory." + exit 1 + fi +} + +# Terminates the script when $1 is not in $PATH. Any arguments required for +# the tool being tested to return a successful exit code can be passed as +# additional arguments. +check_tool() { + tool="$1" + shift + tool_args="$@" + if ! eval "${tool}" ${tool_args} > /dev/null 2>&1; then + elog "${tool} must be in your path." + exit 1 + fi +} + +# Echoes git describe output for the directory specified by $1 to stdout. +git_describe() { + git_dir="$1" + check_git + echo $(git -C "${git_dir}" describe) +} + +# Echoes current git revision for the directory specifed by $1 to stdout. +git_revision() { + git_dir="$1" + check_git + echo $(git -C "${git_dir}" rev-parse HEAD) +} + diff --git a/src/sys/libwebm/common/file_util.cc b/src/sys/libwebm/common/file_util.cc new file mode 100644 index 0000000..6eb6428 --- /dev/null +++ b/src/sys/libwebm/common/file_util.cc @@ -0,0 +1,93 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "common/file_util.h" + +#include +#ifndef _MSC_VER +#include // close() +#endif + +#include +#include +#include +#include +#include +#include + +namespace libwebm { + +std::string GetTempFileName() { +#if !defined _MSC_VER && !defined __MINGW32__ + std::string temp_file_name_template_str = + std::string(std::getenv("TEST_TMPDIR") ? std::getenv("TEST_TMPDIR") + : ".") + + "/libwebm_temp.XXXXXX"; + char* temp_file_name_template = + new char[temp_file_name_template_str.length() + 1]; + memset(temp_file_name_template, 0, temp_file_name_template_str.length() + 1); + temp_file_name_template_str.copy(temp_file_name_template, + temp_file_name_template_str.length(), 0); + int fd = mkstemp(temp_file_name_template); + std::string temp_file_name = + (fd != -1) ? std::string(temp_file_name_template) : std::string(); + delete[] temp_file_name_template; + if (fd != -1) { + close(fd); + } + return temp_file_name; +#else + char tmp_file_name[_MAX_PATH]; +#if defined _MSC_VER || defined MINGW_HAS_SECURE_API + errno_t err = tmpnam_s(tmp_file_name); +#else + char* fname_pointer = tmpnam(tmp_file_name); + int err = (fname_pointer == &tmp_file_name[0]) ? 0 : -1; +#endif + if (err == 0) { + return std::string(tmp_file_name); + } + return std::string(); +#endif +} + +uint64_t GetFileSize(const std::string& file_name) { + uint64_t file_size = 0; +#ifndef _MSC_VER + struct stat st; + st.st_size = 0; + if (stat(file_name.c_str(), &st) == 0) { +#else + struct _stat st; + st.st_size = 0; + if (_stat(file_name.c_str(), &st) == 0) { +#endif + file_size = st.st_size; + } + return file_size; +} + +bool GetFileContents(const std::string& file_name, std::string* contents) { + std::ifstream file(file_name.c_str()); + *contents = std::string(static_cast(GetFileSize(file_name)), 0); + if (file.good() && contents->size()) { + file.read(&(*contents)[0], contents->size()); + } + return !file.fail(); +} + +TempFileDeleter::TempFileDeleter() { file_name_ = GetTempFileName(); } + +TempFileDeleter::~TempFileDeleter() { + std::ifstream file(file_name_.c_str()); + if (file.good()) { + file.close(); + std::remove(file_name_.c_str()); + } +} + +} // namespace libwebm diff --git a/src/sys/libwebm/common/file_util.h b/src/sys/libwebm/common/file_util.h new file mode 100644 index 0000000..a873734 --- /dev/null +++ b/src/sys/libwebm/common/file_util.h @@ -0,0 +1,44 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_COMMON_FILE_UTIL_H_ +#define LIBWEBM_COMMON_FILE_UTIL_H_ + +#include + +#include + +#include "mkvmuxer/mkvmuxertypes.h" // LIBWEBM_DISALLOW_COPY_AND_ASSIGN() + +namespace libwebm { + +// Returns a temporary file name. +std::string GetTempFileName(); + +// Returns size of file specified by |file_name|, or 0 upon failure. +uint64_t GetFileSize(const std::string& file_name); + +// Gets the contents file_name as a string. Returns false on error. +bool GetFileContents(const std::string& file_name, std::string* contents); + +// Manages life of temporary file specified at time of construction. Deletes +// file upon destruction. +class TempFileDeleter { + public: + TempFileDeleter(); + explicit TempFileDeleter(std::string file_name) : file_name_(file_name) {} + ~TempFileDeleter(); + const std::string& name() const { return file_name_; } + + private: + std::string file_name_; + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(TempFileDeleter); +}; + +} // namespace libwebm + +#endif // LIBWEBM_COMMON_FILE_UTIL_H_ diff --git a/src/sys/libwebm/common/hdr_util.cc b/src/sys/libwebm/common/hdr_util.cc new file mode 100644 index 0000000..916f717 --- /dev/null +++ b/src/sys/libwebm/common/hdr_util.cc @@ -0,0 +1,220 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "hdr_util.h" + +#include +#include +#include + +#include "mkvparser/mkvparser.h" + +namespace libwebm { +const int Vp9CodecFeatures::kValueNotPresent = INT_MAX; + +bool CopyPrimaryChromaticity(const mkvparser::PrimaryChromaticity& parser_pc, + PrimaryChromaticityPtr* muxer_pc) { + muxer_pc->reset(new (std::nothrow) + mkvmuxer::PrimaryChromaticity(parser_pc.x, parser_pc.y)); + if (!muxer_pc->get()) + return false; + return true; +} + +bool MasteringMetadataValuePresent(double value) { + return value != mkvparser::MasteringMetadata::kValueNotPresent; +} + +bool CopyMasteringMetadata(const mkvparser::MasteringMetadata& parser_mm, + mkvmuxer::MasteringMetadata* muxer_mm) { + if (MasteringMetadataValuePresent(parser_mm.luminance_max)) + muxer_mm->set_luminance_max(parser_mm.luminance_max); + if (MasteringMetadataValuePresent(parser_mm.luminance_min)) + muxer_mm->set_luminance_min(parser_mm.luminance_min); + + PrimaryChromaticityPtr r_ptr(nullptr); + PrimaryChromaticityPtr g_ptr(nullptr); + PrimaryChromaticityPtr b_ptr(nullptr); + PrimaryChromaticityPtr wp_ptr(nullptr); + + if (parser_mm.r) { + if (!CopyPrimaryChromaticity(*parser_mm.r, &r_ptr)) + return false; + } + if (parser_mm.g) { + if (!CopyPrimaryChromaticity(*parser_mm.g, &g_ptr)) + return false; + } + if (parser_mm.b) { + if (!CopyPrimaryChromaticity(*parser_mm.b, &b_ptr)) + return false; + } + if (parser_mm.white_point) { + if (!CopyPrimaryChromaticity(*parser_mm.white_point, &wp_ptr)) + return false; + } + + if (!muxer_mm->SetChromaticity(r_ptr.get(), g_ptr.get(), b_ptr.get(), + wp_ptr.get())) { + return false; + } + + return true; +} + +bool ColourValuePresent(long long value) { + return value != mkvparser::Colour::kValueNotPresent; +} + +bool CopyColour(const mkvparser::Colour& parser_colour, + mkvmuxer::Colour* muxer_colour) { + if (!muxer_colour) + return false; + + if (ColourValuePresent(parser_colour.matrix_coefficients)) + muxer_colour->set_matrix_coefficients(parser_colour.matrix_coefficients); + if (ColourValuePresent(parser_colour.bits_per_channel)) + muxer_colour->set_bits_per_channel(parser_colour.bits_per_channel); + if (ColourValuePresent(parser_colour.chroma_subsampling_horz)) { + muxer_colour->set_chroma_subsampling_horz( + parser_colour.chroma_subsampling_horz); + } + if (ColourValuePresent(parser_colour.chroma_subsampling_vert)) { + muxer_colour->set_chroma_subsampling_vert( + parser_colour.chroma_subsampling_vert); + } + if (ColourValuePresent(parser_colour.cb_subsampling_horz)) + muxer_colour->set_cb_subsampling_horz(parser_colour.cb_subsampling_horz); + if (ColourValuePresent(parser_colour.cb_subsampling_vert)) + muxer_colour->set_cb_subsampling_vert(parser_colour.cb_subsampling_vert); + if (ColourValuePresent(parser_colour.chroma_siting_horz)) + muxer_colour->set_chroma_siting_horz(parser_colour.chroma_siting_horz); + if (ColourValuePresent(parser_colour.chroma_siting_vert)) + muxer_colour->set_chroma_siting_vert(parser_colour.chroma_siting_vert); + if (ColourValuePresent(parser_colour.range)) + muxer_colour->set_range(parser_colour.range); + if (ColourValuePresent(parser_colour.transfer_characteristics)) { + muxer_colour->set_transfer_characteristics( + parser_colour.transfer_characteristics); + } + if (ColourValuePresent(parser_colour.primaries)) + muxer_colour->set_primaries(parser_colour.primaries); + if (ColourValuePresent(parser_colour.max_cll)) + muxer_colour->set_max_cll(parser_colour.max_cll); + if (ColourValuePresent(parser_colour.max_fall)) + muxer_colour->set_max_fall(parser_colour.max_fall); + + if (parser_colour.mastering_metadata) { + mkvmuxer::MasteringMetadata muxer_mm; + if (!CopyMasteringMetadata(*parser_colour.mastering_metadata, &muxer_mm)) + return false; + if (!muxer_colour->SetMasteringMetadata(muxer_mm)) + return false; + } + return true; +} + +// Format of VPx private data: +// +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | ID Byte | Length | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | +// | | +// : Bytes 1..Length of Codec Feature : +// | | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// ID Byte Format +// ID byte is an unsigned byte. +// 0 1 2 3 4 5 6 7 +// +-+-+-+-+-+-+-+-+ +// |X| ID | +// +-+-+-+-+-+-+-+-+ +// +// The X bit is reserved. +// +// See the following link for more information: +// http://www.webmproject.org/vp9/profiles/ +bool ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length, + Vp9CodecFeatures* features) { + const int kVpxCodecPrivateMinLength = 3; + if (!private_data || !features || length < kVpxCodecPrivateMinLength) + return false; + + const uint8_t kVp9ProfileId = 1; + const uint8_t kVp9LevelId = 2; + const uint8_t kVp9BitDepthId = 3; + const uint8_t kVp9ChromaSubsamplingId = 4; + const int kVpxFeatureLength = 1; + int offset = 0; + + // Set features to not set. + features->profile = Vp9CodecFeatures::kValueNotPresent; + features->level = Vp9CodecFeatures::kValueNotPresent; + features->bit_depth = Vp9CodecFeatures::kValueNotPresent; + features->chroma_subsampling = Vp9CodecFeatures::kValueNotPresent; + do { + const uint8_t id_byte = private_data[offset++]; + const uint8_t length_byte = private_data[offset++]; + if (length_byte != kVpxFeatureLength) + return false; + if (id_byte == kVp9ProfileId) { + const int priv_profile = static_cast(private_data[offset++]); + if (priv_profile < 0 || priv_profile > 3) + return false; + if (features->profile != Vp9CodecFeatures::kValueNotPresent && + features->profile != priv_profile) { + return false; + } + features->profile = priv_profile; + } else if (id_byte == kVp9LevelId) { + const int priv_level = static_cast(private_data[offset++]); + + const int kNumLevels = 14; + const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40, + 41, 50, 51, 52, 60, 61, 62}; + + for (int i = 0; i < kNumLevels; ++i) { + if (priv_level == levels[i]) { + if (features->level != Vp9CodecFeatures::kValueNotPresent && + features->level != priv_level) { + return false; + } + features->level = priv_level; + break; + } + } + if (features->level == Vp9CodecFeatures::kValueNotPresent) + return false; + } else if (id_byte == kVp9BitDepthId) { + const int priv_profile = static_cast(private_data[offset++]); + if (priv_profile != 8 && priv_profile != 10 && priv_profile != 12) + return false; + if (features->bit_depth != Vp9CodecFeatures::kValueNotPresent && + features->bit_depth != priv_profile) { + return false; + } + features->bit_depth = priv_profile; + } else if (id_byte == kVp9ChromaSubsamplingId) { + const int priv_profile = static_cast(private_data[offset++]); + if (priv_profile != 0 && priv_profile != 2 && priv_profile != 3) + return false; + if (features->chroma_subsampling != Vp9CodecFeatures::kValueNotPresent && + features->chroma_subsampling != priv_profile) { + return false; + } + features->chroma_subsampling = priv_profile; + } else { + // Invalid ID. + return false; + } + } while (offset + kVpxCodecPrivateMinLength <= length); + + return true; +} +} // namespace libwebm diff --git a/src/sys/libwebm/common/hdr_util.h b/src/sys/libwebm/common/hdr_util.h new file mode 100644 index 0000000..78e2eeb --- /dev/null +++ b/src/sys/libwebm/common/hdr_util.h @@ -0,0 +1,71 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_COMMON_HDR_UTIL_H_ +#define LIBWEBM_COMMON_HDR_UTIL_H_ + +#include + +#include + +#include "mkvmuxer/mkvmuxer.h" + +namespace mkvparser { +struct Colour; +struct MasteringMetadata; +struct PrimaryChromaticity; +} // namespace mkvparser + +namespace libwebm { +// Utility types and functions for working with the Colour element and its +// children. Copiers return true upon success. Presence functions return true +// when the specified element is present. + +// TODO(tomfinegan): These should be moved to libwebm_utils once c++11 is +// required by libwebm. + +// Features of the VP9 codec that may be set in the CodecPrivate of a VP9 video +// stream. A value of kValueNotPresent represents that the value was not set in +// the CodecPrivate. +struct Vp9CodecFeatures { + static const int kValueNotPresent; + + Vp9CodecFeatures() + : profile(kValueNotPresent), + level(kValueNotPresent), + bit_depth(kValueNotPresent), + chroma_subsampling(kValueNotPresent) {} + ~Vp9CodecFeatures() {} + + int profile; + int level; + int bit_depth; + int chroma_subsampling; +}; + +typedef std::unique_ptr PrimaryChromaticityPtr; + +bool CopyPrimaryChromaticity(const mkvparser::PrimaryChromaticity& parser_pc, + PrimaryChromaticityPtr* muxer_pc); + +bool MasteringMetadataValuePresent(double value); + +bool CopyMasteringMetadata(const mkvparser::MasteringMetadata& parser_mm, + mkvmuxer::MasteringMetadata* muxer_mm); + +bool ColourValuePresent(long long value); + +bool CopyColour(const mkvparser::Colour& parser_colour, + mkvmuxer::Colour* muxer_colour); + +// Returns true if |features| is set to one or more valid values. +bool ParseVpxCodecPrivate(const uint8_t* private_data, int32_t length, + Vp9CodecFeatures* features); + +} // namespace libwebm + +#endif // LIBWEBM_COMMON_HDR_UTIL_H_ diff --git a/src/sys/libwebm/common/indent.cc b/src/sys/libwebm/common/indent.cc new file mode 100644 index 0000000..87d656c --- /dev/null +++ b/src/sys/libwebm/common/indent.cc @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "common/indent.h" + +#include + +namespace libwebm { + +Indent::Indent(int indent) : indent_(indent), indent_str_() { Update(); } + +void Indent::Adjust(int indent) { + indent_ += indent; + if (indent_ < 0) + indent_ = 0; + + Update(); +} + +void Indent::Update() { indent_str_ = std::string(indent_, ' '); } + +} // namespace libwebm diff --git a/src/sys/libwebm/common/indent.h b/src/sys/libwebm/common/indent.h new file mode 100644 index 0000000..22d3d26 --- /dev/null +++ b/src/sys/libwebm/common/indent.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef LIBWEBM_COMMON_INDENT_H_ +#define LIBWEBM_COMMON_INDENT_H_ + +#include + +#include "mkvmuxer/mkvmuxertypes.h" + +namespace libwebm { + +const int kIncreaseIndent = 2; +const int kDecreaseIndent = -2; + +// Used for formatting output so objects only have to keep track of spacing +// within their scope. +class Indent { + public: + explicit Indent(int indent); + + // Changes the number of spaces output. The value adjusted is relative to + // |indent_|. + void Adjust(int indent); + + std::string indent_str() const { return indent_str_; } + + private: + // Called after |indent_| is changed. This will set |indent_str_| to the + // proper number of spaces. + void Update(); + + int indent_; + std::string indent_str_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Indent); +}; + +} // namespace libwebm + +#endif // LIBWEBM_COMMON_INDENT_H_ diff --git a/src/sys/libwebm/common/libwebm_util.cc b/src/sys/libwebm/common/libwebm_util.cc new file mode 100644 index 0000000..d158250 --- /dev/null +++ b/src/sys/libwebm/common/libwebm_util.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2015 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "common/libwebm_util.h" + +#include +#include +#include +#include + +namespace libwebm { + +std::int64_t NanosecondsTo90KhzTicks(std::int64_t nanoseconds) { + const double pts_seconds = nanoseconds / kNanosecondsPerSecond; + return static_cast(pts_seconds * 90000); +} + +std::int64_t Khz90TicksToNanoseconds(std::int64_t ticks) { + const double seconds = ticks / 90000.0; + return static_cast(seconds * kNanosecondsPerSecond); +} + +bool ParseVP9SuperFrameIndex(const std::uint8_t* frame, + std::size_t frame_length, Ranges* frame_ranges, + bool* error) { + if (frame == nullptr || frame_length == 0 || frame_ranges == nullptr || + error == nullptr) { + return false; + } + + bool parse_ok = false; + const std::uint8_t marker = frame[frame_length - 1]; + const std::uint32_t kHasSuperFrameIndexMask = 0xe0; + const std::uint32_t kSuperFrameMarker = 0xc0; + const std::uint32_t kLengthFieldSizeMask = 0x3; + + if ((marker & kHasSuperFrameIndexMask) == kSuperFrameMarker) { + const std::uint32_t kFrameCountMask = 0x7; + const int num_frames = (marker & kFrameCountMask) + 1; + const int length_field_size = ((marker >> 3) & kLengthFieldSizeMask) + 1; + const std::size_t index_length = 2 + length_field_size * num_frames; + + if (frame_length < index_length) { + std::fprintf(stderr, + "VP9ParseSuperFrameIndex: Invalid superframe index size.\n"); + *error = true; + return false; + } + + // Consume the super frame index. Note: it's at the end of the super frame. + const std::size_t length = frame_length - index_length; + + if (length >= index_length && + frame[frame_length - index_length] == marker) { + // Found a valid superframe index. + const std::uint8_t* byte = frame + length + 1; + + std::size_t frame_offset = 0; + + for (int i = 0; i < num_frames; ++i) { + std::uint32_t child_frame_length = 0; + + for (int j = 0; j < length_field_size; ++j) { + child_frame_length |= (*byte++) << (j * 8); + } + + if (length - frame_offset < child_frame_length) { + std::fprintf(stderr, + "ParseVP9SuperFrameIndex: Invalid superframe, sub frame " + "larger than entire frame.\n"); + *error = true; + return false; + } + + frame_ranges->push_back(Range(frame_offset, child_frame_length)); + frame_offset += child_frame_length; + } + + if (static_cast(frame_ranges->size()) != num_frames) { + std::fprintf(stderr, "VP9Parse: superframe index parse failed.\n"); + *error = true; + return false; + } + + parse_ok = true; + } else { + std::fprintf(stderr, "VP9Parse: Invalid superframe index.\n"); + *error = true; + } + } + return parse_ok; +} + +bool WriteUint8(std::uint8_t val, std::FILE* fileptr) { + if (fileptr == nullptr) + return false; + return (std::fputc(val, fileptr) == val); +} + +std::uint16_t ReadUint16(const std::uint8_t* buf) { + if (buf == nullptr) + return 0; + return ((buf[0] << 8) | buf[1]); +} + +} // namespace libwebm diff --git a/src/sys/libwebm/common/libwebm_util.h b/src/sys/libwebm/common/libwebm_util.h new file mode 100644 index 0000000..71d805f --- /dev/null +++ b/src/sys/libwebm/common/libwebm_util.h @@ -0,0 +1,65 @@ +// Copyright (c) 2015 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_COMMON_LIBWEBM_UTIL_H_ +#define LIBWEBM_COMMON_LIBWEBM_UTIL_H_ + +#include +#include +#include +#include +#include + +namespace libwebm { + +const double kNanosecondsPerSecond = 1000000000.0; + +// fclose functor for wrapping FILE in std::unique_ptr. +// TODO(tomfinegan): Move this to file_util once c++11 restrictions are +// relaxed. +struct FILEDeleter { + int operator()(std::FILE* f) { + if (f != nullptr) + return fclose(f); + return 0; + } +}; +typedef std::unique_ptr FilePtr; + +struct Range { + Range(std::size_t off, std::size_t len) : offset(off), length(len) {} + Range() = delete; + Range(const Range&) = default; + Range(Range&&) = default; + ~Range() = default; + const std::size_t offset; + const std::size_t length; +}; +typedef std::vector Ranges; + +// Converts |nanoseconds| to 90000 Hz clock ticks and vice versa. Each return +// the converted value. +std::int64_t NanosecondsTo90KhzTicks(std::int64_t nanoseconds); +std::int64_t Khz90TicksToNanoseconds(std::int64_t khz90_ticks); + +// Returns true and stores frame offsets and lengths in |frame_ranges| when +// |frame| has a valid VP9 super frame index. Sets |error| to true when parsing +// fails for any reason. +bool ParseVP9SuperFrameIndex(const std::uint8_t* frame, + std::size_t frame_length, Ranges* frame_ranges, + bool* error); + +// Writes |val| to |fileptr| and returns true upon success. +bool WriteUint8(std::uint8_t val, std::FILE* fileptr); + +// Reads 2 bytes from |buf| and returns them as a uint16_t. Returns 0 when |buf| +// is a nullptr. +std::uint16_t ReadUint16(const std::uint8_t* buf); + +} // namespace libwebm + +#endif // LIBWEBM_COMMON_LIBWEBM_UTIL_H_ diff --git a/src/sys/libwebm/common/video_frame.cc b/src/sys/libwebm/common/video_frame.cc new file mode 100644 index 0000000..00aa8da --- /dev/null +++ b/src/sys/libwebm/common/video_frame.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "common/video_frame.h" + +#include + +namespace libwebm { + +bool VideoFrame::Buffer::Init(std::size_t new_length) { + capacity = 0; + length = 0; + data.reset(new std::uint8_t[new_length]); + + if (data.get() == nullptr) { + fprintf(stderr, "VideoFrame: Out of memory."); + return false; + } + + capacity = new_length; + length = 0; + return true; +} + +bool VideoFrame::Init(std::size_t length) { return buffer_.Init(length); } + +bool VideoFrame::Init(std::size_t length, std::int64_t nano_pts, Codec codec) { + nanosecond_pts_ = nano_pts; + codec_ = codec; + return Init(length); +} + +bool VideoFrame::SetBufferLength(std::size_t length) { + if (length > buffer_.capacity || buffer_.data.get() == nullptr) + return false; + + buffer_.length = length; + return true; +} + +} // namespace libwebm diff --git a/src/sys/libwebm/common/video_frame.h b/src/sys/libwebm/common/video_frame.h new file mode 100644 index 0000000..3031ef2 --- /dev/null +++ b/src/sys/libwebm/common/video_frame.h @@ -0,0 +1,68 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_COMMON_VIDEO_FRAME_H_ +#define LIBWEBM_COMMON_VIDEO_FRAME_H_ + +#include +#include + +namespace libwebm { + +// VideoFrame is a storage class for compressed video frames. +class VideoFrame { + public: + enum Codec { kVP8, kVP9 }; + struct Buffer { + Buffer() = default; + ~Buffer() = default; + + // Resets |data| to be of size |new_length| bytes, sets |capacity| to + // |new_length|, sets |length| to 0 (aka empty). Returns true for success. + bool Init(std::size_t new_length); + + std::unique_ptr data; + std::size_t length = 0; + std::size_t capacity = 0; + }; + + VideoFrame() = default; + ~VideoFrame() = default; + VideoFrame(std::int64_t pts_in_nanoseconds, Codec vpx_codec) + : nanosecond_pts_(pts_in_nanoseconds), codec_(vpx_codec) {} + VideoFrame(bool keyframe, std::int64_t pts_in_nanoseconds, Codec vpx_codec) + : keyframe_(keyframe), + nanosecond_pts_(pts_in_nanoseconds), + codec_(vpx_codec) {} + bool Init(std::size_t length); + bool Init(std::size_t length, std::int64_t nano_pts, Codec codec); + + // Updates actual length of data stored in |buffer_.data| when it's been + // written via the raw pointer returned from buffer_.data.get(). + // Returns false when buffer_.data.get() return nullptr and/or when + // |length| > |buffer_.length|. Returns true otherwise. + bool SetBufferLength(std::size_t length); + + // Accessors. + const Buffer& buffer() const { return buffer_; } + bool keyframe() const { return keyframe_; } + std::int64_t nanosecond_pts() const { return nanosecond_pts_; } + Codec codec() const { return codec_; } + + // Mutators. + void set_nanosecond_pts(std::int64_t nano_pts) { nanosecond_pts_ = nano_pts; } + + private: + Buffer buffer_; + bool keyframe_ = false; + std::int64_t nanosecond_pts_ = 0; + Codec codec_ = kVP9; +}; + +} // namespace libwebm + +#endif // LIBWEBM_COMMON_VIDEO_FRAME_H_ \ No newline at end of file diff --git a/src/sys/libwebm/common/vp9_header_parser.cc b/src/sys/libwebm/common/vp9_header_parser.cc new file mode 100644 index 0000000..c017d7f --- /dev/null +++ b/src/sys/libwebm/common/vp9_header_parser.cc @@ -0,0 +1,269 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "common/vp9_header_parser.h" + +#include + +namespace vp9_parser { + +bool Vp9HeaderParser::SetFrame(const uint8_t* frame, size_t length) { + if (!frame || length == 0) + return false; + + frame_ = frame; + frame_size_ = length; + bit_offset_ = 0; + profile_ = -1; + show_existing_frame_ = 0; + key_ = 0; + altref_ = 0; + error_resilient_mode_ = 0; + intra_only_ = 0; + reset_frame_context_ = 0; + color_space_ = 0; + color_range_ = 0; + subsampling_x_ = 0; + subsampling_y_ = 0; + refresh_frame_flags_ = 0; + return true; +} + +bool Vp9HeaderParser::ParseUncompressedHeader(const uint8_t* frame, + size_t length) { + if (!SetFrame(frame, length)) + return false; + const int frame_marker = VpxReadLiteral(2); + if (frame_marker != kVp9FrameMarker) { + fprintf(stderr, "Invalid VP9 frame_marker:%d\n", frame_marker); + return false; + } + + profile_ = ReadBit(); + profile_ |= ReadBit() << 1; + if (profile_ > 2) + profile_ += ReadBit(); + + // TODO(fgalligan): Decide how to handle show existing frames. + show_existing_frame_ = ReadBit(); + if (show_existing_frame_) + return true; + + key_ = !ReadBit(); + altref_ = !ReadBit(); + error_resilient_mode_ = ReadBit(); + if (key_) { + if (!ValidateVp9SyncCode()) { + fprintf(stderr, "Invalid Sync code!\n"); + return false; + } + + ParseColorSpace(); + ParseFrameResolution(); + ParseFrameParallelMode(); + ParseTileInfo(); + } else { + intra_only_ = altref_ ? ReadBit() : 0; + reset_frame_context_ = error_resilient_mode_ ? 0 : VpxReadLiteral(2); + if (intra_only_) { + if (!ValidateVp9SyncCode()) { + fprintf(stderr, "Invalid Sync code!\n"); + return false; + } + + if (profile_ > 0) { + ParseColorSpace(); + } else { + // NOTE: The intra-only frame header does not include the specification + // of either the color format or color sub-sampling in profile 0. VP9 + // specifies that the default color format should be YUV 4:2:0 in this + // case (normative). + color_space_ = kVpxCsBt601; + color_range_ = kVpxCrStudioRange; + subsampling_y_ = subsampling_x_ = 1; + bit_depth_ = 8; + } + + refresh_frame_flags_ = VpxReadLiteral(kRefFrames); + ParseFrameResolution(); + } else { + refresh_frame_flags_ = VpxReadLiteral(kRefFrames); + for (int i = 0; i < kRefsPerFrame; ++i) { + VpxReadLiteral(kRefFrames_LOG2); // Consume ref. + ReadBit(); // Consume ref sign bias. + } + + bool found = false; + for (int i = 0; i < kRefsPerFrame; ++i) { + if (ReadBit()) { + // Found previous reference, width and height did not change since + // last frame. + found = true; + break; + } + } + + if (!found) + ParseFrameResolution(); + } + } + return true; +} + +int Vp9HeaderParser::ReadBit() { + const size_t off = bit_offset_; + const size_t byte_offset = off >> 3; + const int bit_shift = 7 - static_cast(off & 0x7); + if (byte_offset < frame_size_) { + const int bit = (frame_[byte_offset] >> bit_shift) & 1; + bit_offset_++; + return bit; + } else { + return 0; + } +} + +int Vp9HeaderParser::VpxReadLiteral(int bits) { + int value = 0; + for (int bit = bits - 1; bit >= 0; --bit) + value |= ReadBit() << bit; + return value; +} + +bool Vp9HeaderParser::ValidateVp9SyncCode() { + const int sync_code_0 = VpxReadLiteral(8); + const int sync_code_1 = VpxReadLiteral(8); + const int sync_code_2 = VpxReadLiteral(8); + return (sync_code_0 == 0x49 && sync_code_1 == 0x83 && sync_code_2 == 0x42); +} + +void Vp9HeaderParser::ParseColorSpace() { + bit_depth_ = 0; + if (profile_ >= 2) + bit_depth_ = ReadBit() ? 12 : 10; + else + bit_depth_ = 8; + color_space_ = VpxReadLiteral(3); + if (color_space_ != kVpxCsSrgb) { + color_range_ = ReadBit(); + if (profile_ == 1 || profile_ == 3) { + subsampling_x_ = ReadBit(); + subsampling_y_ = ReadBit(); + ReadBit(); + } else { + subsampling_y_ = subsampling_x_ = 1; + } + } else { + color_range_ = kVpxCrFullRange; + if (profile_ == 1 || profile_ == 3) { + subsampling_y_ = subsampling_x_ = 0; + ReadBit(); + } + } +} + +void Vp9HeaderParser::ParseFrameResolution() { + width_ = VpxReadLiteral(16) + 1; + height_ = VpxReadLiteral(16) + 1; + if (ReadBit()) { + display_width_ = VpxReadLiteral(16) + 1; + display_height_ = VpxReadLiteral(16) + 1; + } else { + display_width_ = width_; + display_height_ = height_; + } +} + +void Vp9HeaderParser::ParseFrameParallelMode() { + if (!error_resilient_mode_) { + ReadBit(); // Consume refresh frame context + frame_parallel_mode_ = ReadBit(); + } else { + frame_parallel_mode_ = 1; + } +} + +void Vp9HeaderParser::ParseTileInfo() { + VpxReadLiteral(2); // Consume frame context index + + // loopfilter + VpxReadLiteral(6); // Consume filter level + VpxReadLiteral(3); // Consume sharpness level + + const bool mode_ref_delta_enabled = ReadBit(); + if (mode_ref_delta_enabled) { + const bool mode_ref_delta_update = ReadBit(); + if (mode_ref_delta_update) { + const int kMaxRefLFDeltas = 4; + for (int i = 0; i < kMaxRefLFDeltas; ++i) { + if (ReadBit()) + VpxReadLiteral(7); // Consume ref_deltas + sign + } + + const int kMaxModeDeltas = 2; + for (int i = 0; i < kMaxModeDeltas; ++i) { + if (ReadBit()) + VpxReadLiteral(7); // Consume mode_delta + sign + } + } + } + + // quantization + VpxReadLiteral(8); // Consume base_q + SkipDeltaQ(); // y dc + SkipDeltaQ(); // uv ac + SkipDeltaQ(); // uv dc + + // segmentation + const bool segmentation_enabled = ReadBit(); + if (!segmentation_enabled) { + const int aligned_width = AlignPowerOfTwo(width_, kMiSizeLog2); + const int mi_cols = aligned_width >> kMiSizeLog2; + const int aligned_mi_cols = AlignPowerOfTwo(mi_cols, kMiSizeLog2); + const int sb_cols = aligned_mi_cols >> 3; // to_sbs(mi_cols); + int min_log2_n_tiles, max_log2_n_tiles; + + for (max_log2_n_tiles = 0; + (sb_cols >> max_log2_n_tiles) >= kMinTileWidthB64; + max_log2_n_tiles++) { + } + max_log2_n_tiles--; + if (max_log2_n_tiles < 0) + max_log2_n_tiles = 0; + + for (min_log2_n_tiles = 0; (kMaxTileWidthB64 << min_log2_n_tiles) < sb_cols; + min_log2_n_tiles++) { + } + + // columns + const int max_log2_tile_cols = max_log2_n_tiles; + const int min_log2_tile_cols = min_log2_n_tiles; + int max_ones = max_log2_tile_cols - min_log2_tile_cols; + int log2_tile_cols = min_log2_tile_cols; + while (max_ones-- && ReadBit()) + log2_tile_cols++; + + // rows + int log2_tile_rows = ReadBit(); + if (log2_tile_rows) + log2_tile_rows += ReadBit(); + + row_tiles_ = 1 << log2_tile_rows; + column_tiles_ = 1 << log2_tile_cols; + } +} + +void Vp9HeaderParser::SkipDeltaQ() { + if (ReadBit()) + VpxReadLiteral(4); +} + +int Vp9HeaderParser::AlignPowerOfTwo(int value, int n) { + return (((value) + ((1 << (n)) - 1)) & ~((1 << (n)) - 1)); +} + +} // namespace vp9_parser diff --git a/src/sys/libwebm/common/vp9_header_parser.h b/src/sys/libwebm/common/vp9_header_parser.h new file mode 100644 index 0000000..3e57514 --- /dev/null +++ b/src/sys/libwebm/common/vp9_header_parser.h @@ -0,0 +1,129 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_COMMON_VP9_HEADER_PARSER_H_ +#define LIBWEBM_COMMON_VP9_HEADER_PARSER_H_ + +#include +#include + +namespace vp9_parser { + +const int kVp9FrameMarker = 2; +const int kMinTileWidthB64 = 4; +const int kMaxTileWidthB64 = 64; +const int kRefFrames = 8; +const int kRefsPerFrame = 3; +const int kRefFrames_LOG2 = 3; +const int kVpxCsBt601 = 1; +const int kVpxCsSrgb = 7; +const int kVpxCrStudioRange = 0; +const int kVpxCrFullRange = 1; +const int kMiSizeLog2 = 3; + +// Class to parse the header of a VP9 frame. +class Vp9HeaderParser { + public: + Vp9HeaderParser() + : frame_(NULL), + frame_size_(0), + bit_offset_(0), + profile_(-1), + show_existing_frame_(0), + key_(0), + altref_(0), + error_resilient_mode_(0), + intra_only_(0), + reset_frame_context_(0), + bit_depth_(0), + color_space_(0), + color_range_(0), + subsampling_x_(0), + subsampling_y_(0), + refresh_frame_flags_(0), + width_(0), + height_(0), + row_tiles_(0), + column_tiles_(0), + frame_parallel_mode_(0) {} + + // Parse the VP9 uncompressed header. The return values of the remaining + // functions are only valid on success. + bool ParseUncompressedHeader(const uint8_t* frame, size_t length); + + size_t frame_size() const { return frame_size_; } + int profile() const { return profile_; } + int key() const { return key_; } + int altref() const { return altref_; } + int error_resilient_mode() const { return error_resilient_mode_; } + int bit_depth() const { return bit_depth_; } + int color_space() const { return color_space_; } + int width() const { return width_; } + int height() const { return height_; } + int display_width() const { return display_width_; } + int display_height() const { return display_height_; } + int refresh_frame_flags() const { return refresh_frame_flags_; } + int row_tiles() const { return row_tiles_; } + int column_tiles() const { return column_tiles_; } + int frame_parallel_mode() const { return frame_parallel_mode_; } + + private: + // Set the compressed VP9 frame. + bool SetFrame(const uint8_t* frame, size_t length); + + // Returns the next bit of the frame. + int ReadBit(); + + // Returns the next |bits| of the frame. + int VpxReadLiteral(int bits); + + // Returns true if the vp9 sync code is valid. + bool ValidateVp9SyncCode(); + + // Parses bit_depth_, color_space_, subsampling_x_, subsampling_y_, and + // color_range_. + void ParseColorSpace(); + + // Parses width and height of the frame. + void ParseFrameResolution(); + + // Parses frame_parallel_mode_. This function skips over some features. + void ParseFrameParallelMode(); + + // Parses row and column tiles. This function skips over some features. + void ParseTileInfo(); + void SkipDeltaQ(); + int AlignPowerOfTwo(int value, int n); + + const uint8_t* frame_; + size_t frame_size_; + size_t bit_offset_; + int profile_; + int show_existing_frame_; + int key_; + int altref_; + int error_resilient_mode_; + int intra_only_; + int reset_frame_context_; + int bit_depth_; + int color_space_; + int color_range_; + int subsampling_x_; + int subsampling_y_; + int refresh_frame_flags_; + int width_; + int height_; + int display_width_; + int display_height_; + int row_tiles_; + int column_tiles_; + int frame_parallel_mode_; +}; + +} // namespace vp9_parser + +#endif // LIBWEBM_COMMON_VP9_HEADER_PARSER_H_ diff --git a/src/sys/libwebm/common/vp9_header_parser_tests.cc b/src/sys/libwebm/common/vp9_header_parser_tests.cc new file mode 100644 index 0000000..d13bff2 --- /dev/null +++ b/src/sys/libwebm/common/vp9_header_parser_tests.cc @@ -0,0 +1,181 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "common/vp9_header_parser.h" + +#include + +#include "gtest/gtest.h" + +#include "common/hdr_util.h" +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" +#include "testing/test_util.h" + +namespace { + +class Vp9HeaderParserTests : public ::testing::Test { + public: + Vp9HeaderParserTests() : is_reader_open_(false), segment_(NULL) {} + + ~Vp9HeaderParserTests() override { + CloseReader(); + if (segment_ != NULL) { + delete segment_; + segment_ = NULL; + } + } + + void CloseReader() { + if (is_reader_open_) { + reader_.Close(); + } + is_reader_open_ = false; + } + + void CreateAndLoadSegment(const std::string& filename, + int expected_doc_type_ver) { + filename_ = test::GetTestFilePath(filename); + ASSERT_EQ(0, reader_.Open(filename_.c_str())); + is_reader_open_ = true; + pos_ = 0; + mkvparser::EBMLHeader ebml_header; + ebml_header.Parse(&reader_, pos_); + ASSERT_EQ(1, ebml_header.m_version); + ASSERT_EQ(1, ebml_header.m_readVersion); + ASSERT_STREQ("webm", ebml_header.m_docType); + ASSERT_EQ(expected_doc_type_ver, ebml_header.m_docTypeVersion); + ASSERT_EQ(2, ebml_header.m_docTypeReadVersion); + ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, segment_)); + ASSERT_FALSE(HasFailure()); + ASSERT_GE(0, segment_->Load()); + } + + void CreateAndLoadSegment(const std::string& filename) { + CreateAndLoadSegment(filename, 4); + } + + // Load a corrupted segment with no expectation of correctness. + void CreateAndLoadInvalidSegment(const std::string& filename) { + filename_ = test::GetTestFilePath(filename); + ASSERT_EQ(0, reader_.Open(filename_.c_str())); + is_reader_open_ = true; + pos_ = 0; + mkvparser::EBMLHeader ebml_header; + ebml_header.Parse(&reader_, pos_); + ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, segment_)); + ASSERT_GE(0, segment_->Load()); + } + + void ProcessTheFrames(bool invalid_bitstream) { + unsigned char* data = NULL; + size_t data_len = 0; + const mkvparser::Tracks* const parser_tracks = segment_->GetTracks(); + ASSERT_TRUE(parser_tracks != NULL); + const mkvparser::Cluster* cluster = segment_->GetFirst(); + ASSERT_TRUE(cluster != NULL); + + while ((cluster != NULL) && !cluster->EOS()) { + const mkvparser::BlockEntry* block_entry; + long status = cluster->GetFirst(block_entry); // NOLINT + ASSERT_EQ(0, status); + + while ((block_entry != NULL) && !block_entry->EOS()) { + const mkvparser::Block* const block = block_entry->GetBlock(); + ASSERT_TRUE(block != NULL); + const long long trackNum = block->GetTrackNumber(); // NOLINT + const mkvparser::Track* const parser_track = + parser_tracks->GetTrackByNumber( + static_cast(trackNum)); // NOLINT + ASSERT_TRUE(parser_track != NULL); + const long long track_type = parser_track->GetType(); // NOLINT + + if (track_type == mkvparser::Track::kVideo) { + const int frame_count = block->GetFrameCount(); + + for (int i = 0; i < frame_count; ++i) { + const mkvparser::Block::Frame& frame = block->GetFrame(i); + + if (static_cast(frame.len) > data_len) { + delete[] data; + data = new unsigned char[frame.len]; + ASSERT_TRUE(data != NULL); + data_len = static_cast(frame.len); + } + ASSERT_FALSE(frame.Read(&reader_, data)); + ASSERT_EQ(parser_.ParseUncompressedHeader(data, data_len), + !invalid_bitstream); + } + } + + status = cluster->GetNext(block_entry, block_entry); + ASSERT_EQ(0, status); + } + + cluster = segment_->GetNext(cluster); + } + delete[] data; + } + + protected: + mkvparser::MkvReader reader_; + bool is_reader_open_; + mkvparser::Segment* segment_; + std::string filename_; + long long pos_; // NOLINT + vp9_parser::Vp9HeaderParser parser_; +}; + +TEST_F(Vp9HeaderParserTests, VideoOnlyFile) { + ASSERT_NO_FATAL_FAILURE(CreateAndLoadSegment("test_stereo_left_right.webm")); + ProcessTheFrames(false); + EXPECT_EQ(256, parser_.width()); + EXPECT_EQ(144, parser_.height()); + EXPECT_EQ(1, parser_.column_tiles()); + EXPECT_EQ(0, parser_.frame_parallel_mode()); +} + +TEST_F(Vp9HeaderParserTests, Muxed) { + ASSERT_NO_FATAL_FAILURE( + CreateAndLoadSegment("bbb_480p_vp9_opus_1second.webm", 4)); + ProcessTheFrames(false); + EXPECT_EQ(854, parser_.width()); + EXPECT_EQ(480, parser_.height()); + EXPECT_EQ(2, parser_.column_tiles()); + EXPECT_EQ(1, parser_.frame_parallel_mode()); +} + +TEST_F(Vp9HeaderParserTests, Invalid) { + const char* files[] = { + "invalid/invalid_vp9_bitstream-bug_1416.webm", + "invalid/invalid_vp9_bitstream-bug_1417.webm", + }; + + for (int i = 0; i < static_cast(sizeof(files) / sizeof(files[0])); ++i) { + SCOPED_TRACE(files[i]); + ASSERT_NO_FATAL_FAILURE(CreateAndLoadInvalidSegment(files[i])); + ProcessTheFrames(true); + CloseReader(); + delete segment_; + segment_ = NULL; + } +} + +TEST_F(Vp9HeaderParserTests, API) { + vp9_parser::Vp9HeaderParser parser; + uint8_t data; + EXPECT_FALSE(parser.ParseUncompressedHeader(NULL, 0)); + EXPECT_FALSE(parser.ParseUncompressedHeader(NULL, 10)); + EXPECT_FALSE(parser.ParseUncompressedHeader(&data, 0)); +} + +} // namespace + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/sys/libwebm/common/vp9_level_stats.cc b/src/sys/libwebm/common/vp9_level_stats.cc new file mode 100644 index 0000000..96a4bcc --- /dev/null +++ b/src/sys/libwebm/common/vp9_level_stats.cc @@ -0,0 +1,269 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "common/vp9_level_stats.h" + +#include + +#include +#include + +#include "common/webm_constants.h" + +namespace vp9_parser { + +const Vp9LevelRow Vp9LevelStats::Vp9LevelTable[kNumVp9Levels] = { + {LEVEL_1, 829440, 36864, 512, 200, 400, 2, 1, 4, 8}, + {LEVEL_1_1, 2764800, 73728, 768, 800, 1000, 2, 1, 4, 8}, + {LEVEL_2, 4608000, 122880, 960, 1800, 1500, 2, 1, 4, 8}, + {LEVEL_2_1, 9216000, 245760, 1344, 3600, 2800, 2, 2, 4, 8}, + {LEVEL_3, 20736000, 552960, 2048, 7200, 6000, 2, 4, 4, 8}, + {LEVEL_3_1, 36864000, 983040, 2752, 12000, 10000, 2, 4, 4, 8}, + {LEVEL_4, 83558400, 2228224, 4160, 18000, 16000, 4, 4, 4, 8}, + {LEVEL_4_1, 160432128, 2228224, 4160, 30000, 18000, 4, 4, 5, 6}, + {LEVEL_5, 311951360, 8912896, 8384, 60000, 36000, 6, 8, 6, 4}, + {LEVEL_5_1, 588251136, 8912896, 8384, 120000, 46000, 8, 8, 10, 4}, + // CPB Size = 0 for levels 5_2 to 6_2 + {LEVEL_5_2, 1176502272, 8912896, 8384, 180000, 0, 8, 8, 10, 4}, + {LEVEL_6, 1176502272, 35651584, 16832, 180000, 0, 8, 16, 10, 4}, + {LEVEL_6_1, 2353004544, 35651584, 16832, 240000, 0, 8, 16, 10, 4}, + {LEVEL_6_2, 4706009088, 35651584, 16832, 480000, 0, 8, 16, 10, 4}}; + +void Vp9LevelStats::AddFrame(const Vp9HeaderParser& parser, int64_t time_ns) { + ++frames; + if (start_ns_ == -1) + start_ns_ = time_ns; + end_ns_ = time_ns; + + const int width = parser.width(); + const int height = parser.height(); + const int64_t luma_picture_size = width * height; + const int64_t luma_picture_breadth = (width > height) ? width : height; + if (luma_picture_size > max_luma_picture_size_) + max_luma_picture_size_ = luma_picture_size; + if (luma_picture_breadth > max_luma_picture_breadth_) + max_luma_picture_breadth_ = luma_picture_breadth; + + total_compressed_size_ += parser.frame_size(); + + while (!luma_window_.empty() && + luma_window_.front().first < + (time_ns - (libwebm::kNanosecondsPerSecondi - 1))) { + current_luma_size_ -= luma_window_.front().second; + luma_window_.pop(); + } + current_luma_size_ += luma_picture_size; + luma_window_.push(std::make_pair(time_ns, luma_picture_size)); + if (current_luma_size_ > max_luma_size_) { + max_luma_size_ = current_luma_size_; + max_luma_end_ns_ = luma_window_.back().first; + } + + // Record CPB stats. + // Remove all frames that are less than window size. + while (cpb_window_.size() > 3) { + current_cpb_size_ -= cpb_window_.front().second; + cpb_window_.pop(); + } + cpb_window_.push(std::make_pair(time_ns, parser.frame_size())); + + current_cpb_size_ += parser.frame_size(); + if (current_cpb_size_ > max_cpb_size_) { + max_cpb_size_ = current_cpb_size_; + max_cpb_start_ns_ = cpb_window_.front().first; + max_cpb_end_ns_ = cpb_window_.back().first; + } + + if (max_cpb_window_size_ < static_cast(cpb_window_.size())) { + max_cpb_window_size_ = cpb_window_.size(); + max_cpb_window_end_ns_ = time_ns; + } + + // Record altref stats. + if (parser.altref()) { + const int delta_altref = frames_since_last_altref; + if (first_altref) { + first_altref = false; + } else if (delta_altref < minimum_altref_distance) { + minimum_altref_distance = delta_altref; + min_altref_end_ns = time_ns; + } + frames_since_last_altref = 0; + } else { + ++frames_since_last_altref; + ++displayed_frames; + // TODO(fgalligan): Add support for other color formats. Currently assuming + // 420. + total_uncompressed_bits_ += + (luma_picture_size * parser.bit_depth() * 3) / 2; + } + + // Count max reference frames. + if (parser.key() == 1) { + frames_refreshed_ = 0; + } else { + frames_refreshed_ |= parser.refresh_frame_flags(); + + int ref_frame_count = frames_refreshed_ & 1; + for (int i = 1; i < kMaxVp9RefFrames; ++i) { + ref_frame_count += (frames_refreshed_ >> i) & 1; + } + + if (ref_frame_count > max_frames_refreshed_) + max_frames_refreshed_ = ref_frame_count; + } + + // Count max tiles. + const int tiles = parser.column_tiles(); + if (tiles > max_column_tiles_) + max_column_tiles_ = tiles; +} + +Vp9Level Vp9LevelStats::GetLevel() const { + const int64_t max_luma_sample_rate = GetMaxLumaSampleRate(); + const int64_t max_luma_picture_size = GetMaxLumaPictureSize(); + const int64_t max_luma_picture_breadth = GetMaxLumaPictureBreadth(); + const double average_bitrate = GetAverageBitRate(); + const double max_cpb_size = GetMaxCpbSize(); + const double compression_ratio = GetCompressionRatio(); + const int max_column_tiles = GetMaxColumnTiles(); + const int min_altref_distance = GetMinimumAltrefDistance(); + const int max_ref_frames = GetMaxReferenceFrames(); + + int level_index = 0; + Vp9Level max_level = LEVEL_UNKNOWN; + const double grace_multiplier = + max_luma_sample_rate_grace_percent_ / 100.0 + 1.0; + for (int i = 0; i < kNumVp9Levels; ++i) { + if (max_luma_sample_rate <= + Vp9LevelTable[i].max_luma_sample_rate * grace_multiplier) { + if (max_level < Vp9LevelTable[i].level) { + max_level = Vp9LevelTable[i].level; + level_index = i; + } + break; + } + } + for (int i = 0; i < kNumVp9Levels; ++i) { + if (max_luma_picture_size <= Vp9LevelTable[i].max_luma_picture_size) { + if (max_level < Vp9LevelTable[i].level) { + max_level = Vp9LevelTable[i].level; + level_index = i; + } + break; + } + } + for (int i = 0; i < kNumVp9Levels; ++i) { + if (max_luma_picture_breadth <= Vp9LevelTable[i].max_luma_picture_breadth) { + if (max_level < Vp9LevelTable[i].level) { + max_level = Vp9LevelTable[i].level; + level_index = i; + } + break; + } + } + for (int i = 0; i < kNumVp9Levels; ++i) { + if (average_bitrate <= Vp9LevelTable[i].average_bitrate) { + if (max_level < Vp9LevelTable[i].level) { + max_level = Vp9LevelTable[i].level; + level_index = i; + } + break; + } + } + for (int i = 0; i < kNumVp9Levels; ++i) { + // Only check CPB size for levels that are defined. + if (Vp9LevelTable[i].max_cpb_size > 0 && + max_cpb_size <= Vp9LevelTable[i].max_cpb_size) { + if (max_level < Vp9LevelTable[i].level) { + max_level = Vp9LevelTable[i].level; + level_index = i; + } + break; + } + } + for (int i = 0; i < kNumVp9Levels; ++i) { + if (max_column_tiles <= Vp9LevelTable[i].max_tiles) { + if (max_level < Vp9LevelTable[i].level) { + max_level = Vp9LevelTable[i].level; + level_index = i; + } + break; + } + } + + for (int i = 0; i < kNumVp9Levels; ++i) { + if (max_ref_frames <= Vp9LevelTable[i].max_ref_frames) { + if (max_level < Vp9LevelTable[i].level) { + max_level = Vp9LevelTable[i].level; + level_index = i; + } + break; + } + } + + // Check if the current level meets the minimum altref distance requirement. + // If not, set to unknown level as we can't move up a level as the minimum + // altref distance get farther apart and we can't move down a level as we are + // already at the minimum level for all the other requirements. + if (min_altref_distance < Vp9LevelTable[level_index].min_altref_distance) + max_level = LEVEL_UNKNOWN; + + // The minimum compression ratio has the same behavior as minimum altref + // distance. + if (compression_ratio < Vp9LevelTable[level_index].compression_ratio) + max_level = LEVEL_UNKNOWN; + return max_level; +} + +int64_t Vp9LevelStats::GetMaxLumaSampleRate() const { return max_luma_size_; } + +int64_t Vp9LevelStats::GetMaxLumaPictureSize() const { + return max_luma_picture_size_; +} + +int64_t Vp9LevelStats::GetMaxLumaPictureBreadth() const { + return max_luma_picture_breadth_; +} + +double Vp9LevelStats::GetAverageBitRate() const { + const int64_t frame_duration_ns = end_ns_ - start_ns_; + double duration_seconds = + ((duration_ns_ == -1) ? frame_duration_ns : duration_ns_) / + libwebm::kNanosecondsPerSecond; + if (estimate_last_frame_duration_ && + (duration_ns_ == -1 || duration_ns_ <= frame_duration_ns)) { + const double sec_per_frame = frame_duration_ns / + libwebm::kNanosecondsPerSecond / + (displayed_frames - 1); + duration_seconds += sec_per_frame; + } + + return total_compressed_size_ / duration_seconds / 125.0; +} + +double Vp9LevelStats::GetMaxCpbSize() const { return max_cpb_size_ / 125.0; } + +double Vp9LevelStats::GetCompressionRatio() const { + return total_uncompressed_bits_ / + static_cast(total_compressed_size_ * 8); +} + +int Vp9LevelStats::GetMaxColumnTiles() const { return max_column_tiles_; } + +int Vp9LevelStats::GetMinimumAltrefDistance() const { + if (minimum_altref_distance != std::numeric_limits::max()) + return minimum_altref_distance; + else + return -1; +} + +int Vp9LevelStats::GetMaxReferenceFrames() const { + return max_frames_refreshed_; +} + +} // namespace vp9_parser diff --git a/src/sys/libwebm/common/vp9_level_stats.h b/src/sys/libwebm/common/vp9_level_stats.h new file mode 100644 index 0000000..4230385 --- /dev/null +++ b/src/sys/libwebm/common/vp9_level_stats.h @@ -0,0 +1,208 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_COMMON_VP9_LEVEL_STATS_H_ +#define LIBWEBM_COMMON_VP9_LEVEL_STATS_H_ + +#include +#include +#include + +#include "common/vp9_header_parser.h" + +namespace vp9_parser { + +const int kMaxVp9RefFrames = 8; + +// Defined VP9 levels. See http://www.webmproject.org/vp9/profiles/ for +// detailed information on VP9 levels. +const int kNumVp9Levels = 14; +enum Vp9Level { + LEVEL_UNKNOWN = 0, + LEVEL_1 = 10, + LEVEL_1_1 = 11, + LEVEL_2 = 20, + LEVEL_2_1 = 21, + LEVEL_3 = 30, + LEVEL_3_1 = 31, + LEVEL_4 = 40, + LEVEL_4_1 = 41, + LEVEL_5 = 50, + LEVEL_5_1 = 51, + LEVEL_5_2 = 52, + LEVEL_6 = 60, + LEVEL_6_1 = 61, + LEVEL_6_2 = 62 +}; + +struct Vp9LevelRow { + Vp9Level level; + int64_t max_luma_sample_rate; + int64_t max_luma_picture_size; + int64_t max_luma_picture_breadth; + double average_bitrate; + double max_cpb_size; + double compression_ratio; + int max_tiles; + int min_altref_distance; + int max_ref_frames; +}; + +// Class to determine the VP9 level of a VP9 bitstream. +class Vp9LevelStats { + public: + static const Vp9LevelRow Vp9LevelTable[kNumVp9Levels]; + + Vp9LevelStats() + : frames(0), + displayed_frames(0), + start_ns_(-1), + end_ns_(-1), + duration_ns_(-1), + max_luma_picture_size_(0), + max_luma_picture_breadth_(0), + current_luma_size_(0), + max_luma_size_(0), + max_luma_end_ns_(0), + max_luma_sample_rate_grace_percent_(1.5), + first_altref(true), + frames_since_last_altref(0), + minimum_altref_distance(std::numeric_limits::max()), + min_altref_end_ns(0), + max_cpb_window_size_(0), + max_cpb_window_end_ns_(0), + current_cpb_size_(0), + max_cpb_size_(0), + max_cpb_start_ns_(0), + max_cpb_end_ns_(0), + total_compressed_size_(0), + total_uncompressed_bits_(0), + frames_refreshed_(0), + max_frames_refreshed_(0), + max_column_tiles_(0), + estimate_last_frame_duration_(true) {} + + ~Vp9LevelStats() = default; + Vp9LevelStats(Vp9LevelStats&& other) = delete; + Vp9LevelStats(const Vp9LevelStats& other) = delete; + Vp9LevelStats& operator=(Vp9LevelStats&& other) = delete; + Vp9LevelStats& operator=(const Vp9LevelStats& other) = delete; + + // Collects stats on a VP9 frame. The frame must already be parsed by + // |parser|. |time_ns| is the start time of the frame in nanoseconds. + void AddFrame(const Vp9HeaderParser& parser, int64_t time_ns); + + // Returns the current VP9 level. All of the video frames should have been + // processed with AddFrame before calling this function. + Vp9Level GetLevel() const; + + // Returns the maximum luma samples (pixels) per second. The Alt-Ref frames + // are taken into account, therefore this number may be larger than the + // display luma samples per second + int64_t GetMaxLumaSampleRate() const; + + // The maximum frame size (width * height) in samples. + int64_t GetMaxLumaPictureSize() const; + + // The maximum frame breadth (max of width and height) in samples. + int64_t GetMaxLumaPictureBreadth() const; + + // The average bitrate of the video in kbps. + double GetAverageBitRate() const; + + // The largest data size for any 4 consecutive frames in kilobits. + double GetMaxCpbSize() const; + + // The ratio of total bytes decompressed over total bytes compressed. + double GetCompressionRatio() const; + + // The maximum number of VP9 column tiles. + int GetMaxColumnTiles() const; + + // The minimum distance in frames between two consecutive alternate reference + // frames. + int GetMinimumAltrefDistance() const; + + // The maximum number of reference frames that had to be stored. + int GetMaxReferenceFrames() const; + + // Sets the duration of the video stream in nanoseconds. If the duration is + // not explictly set by this function then this class will use end - start + // as the duration. + void set_duration(int64_t time_ns) { duration_ns_ = time_ns; } + double max_luma_sample_rate_grace_percent() const { + return max_luma_sample_rate_grace_percent_; + } + void set_max_luma_sample_rate_grace_percent(double percent) { + max_luma_sample_rate_grace_percent_ = percent; + } + bool estimate_last_frame_duration() const { + return estimate_last_frame_duration_; + } + + // If true try to estimate the last frame's duration if the stream's duration + // is not set or the stream's duration equals the last frame's timestamp. + void set_estimate_last_frame_duration(bool flag) { + estimate_last_frame_duration_ = flag; + } + + private: + int frames; + int displayed_frames; + + int64_t start_ns_; + int64_t end_ns_; + int64_t duration_ns_; + + int64_t max_luma_picture_size_; + int64_t max_luma_picture_breadth_; + + // This is used to calculate the maximum number of luma samples per second. + // The first value is the luma picture size and the second value is the time + // in nanoseconds of one frame. + std::queue> luma_window_; + int64_t current_luma_size_; + int64_t max_luma_size_; + int64_t max_luma_end_ns_; + + // MaxLumaSampleRate = (ExampleFrameRate + ExampleFrameRate / + // MinimumAltrefDistance) * MaxLumaPictureSize. For levels 1-4 + // ExampleFrameRate / MinimumAltrefDistance is non-integer, so using a sliding + // window of one frame to calculate MaxLumaSampleRate may have frames > + // (ExampleFrameRate + ExampleFrameRate / MinimumAltrefDistance) in the + // window. In order to address this issue, a grace percent of 1.5 was added. + double max_luma_sample_rate_grace_percent_; + + bool first_altref; + int frames_since_last_altref; + int minimum_altref_distance; + int64_t min_altref_end_ns; + + // This is used to calculate the maximum number of compressed bytes for four + // consecutive frames. The first value is the compressed frame size and the + // second value is the time in nanoseconds of one frame. + std::queue> cpb_window_; + int64_t max_cpb_window_size_; + int64_t max_cpb_window_end_ns_; + int64_t current_cpb_size_; + int64_t max_cpb_size_; + int64_t max_cpb_start_ns_; + int64_t max_cpb_end_ns_; + + int64_t total_compressed_size_; + int64_t total_uncompressed_bits_; + int frames_refreshed_; + int max_frames_refreshed_; + + int max_column_tiles_; + + bool estimate_last_frame_duration_; +}; + +} // namespace vp9_parser + +#endif // LIBWEBM_COMMON_VP9_LEVEL_STATS_H_ diff --git a/src/sys/libwebm/common/vp9_level_stats_tests.cc b/src/sys/libwebm/common/vp9_level_stats_tests.cc new file mode 100644 index 0000000..a39cf37 --- /dev/null +++ b/src/sys/libwebm/common/vp9_level_stats_tests.cc @@ -0,0 +1,192 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "common/vp9_level_stats.h" + +#include +#include +#include + +#include "gtest/gtest.h" + +#include "common/hdr_util.h" +#include "common/vp9_header_parser.h" +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" +#include "testing/test_util.h" + +namespace { + +// TODO(fgalligan): Refactor this test with other test files in this directory. +class Vp9LevelStatsTests : public ::testing::Test { + public: + Vp9LevelStatsTests() : is_reader_open_(false) {} + + ~Vp9LevelStatsTests() override { CloseReader(); } + + void CloseReader() { + if (is_reader_open_) { + reader_.Close(); + } + is_reader_open_ = false; + } + + void CreateAndLoadSegment(const std::string& filename, + int expected_doc_type_ver) { + ASSERT_NE(0u, filename.length()); + filename_ = test::GetTestFilePath(filename); + ASSERT_EQ(0, reader_.Open(filename_.c_str())); + is_reader_open_ = true; + pos_ = 0; + mkvparser::EBMLHeader ebml_header; + ebml_header.Parse(&reader_, pos_); + ASSERT_EQ(1, ebml_header.m_version); + ASSERT_EQ(1, ebml_header.m_readVersion); + ASSERT_STREQ("webm", ebml_header.m_docType); + ASSERT_EQ(expected_doc_type_ver, ebml_header.m_docTypeVersion); + ASSERT_EQ(2, ebml_header.m_docTypeReadVersion); + mkvparser::Segment* temp; + ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, temp)); + segment_.reset(temp); + ASSERT_FALSE(HasFailure()); + ASSERT_GE(0, segment_->Load()); + } + + void CreateAndLoadSegment(const std::string& filename) { + CreateAndLoadSegment(filename, 4); + } + + void ProcessTheFrames() { + std::vector data; + size_t data_len = 0; + const mkvparser::Tracks* const parser_tracks = segment_->GetTracks(); + ASSERT_TRUE(parser_tracks != NULL); + const mkvparser::Cluster* cluster = segment_->GetFirst(); + ASSERT_TRUE(cluster); + + while ((cluster != NULL) && !cluster->EOS()) { + const mkvparser::BlockEntry* block_entry; + long status = cluster->GetFirst(block_entry); // NOLINT + ASSERT_EQ(0, status); + + while ((block_entry != NULL) && !block_entry->EOS()) { + const mkvparser::Block* const block = block_entry->GetBlock(); + ASSERT_TRUE(block != NULL); + const long long trackNum = block->GetTrackNumber(); // NOLINT + const mkvparser::Track* const parser_track = + parser_tracks->GetTrackByNumber( + static_cast(trackNum)); // NOLINT + ASSERT_TRUE(parser_track != NULL); + const long long track_type = parser_track->GetType(); // NOLINT + + if (track_type == mkvparser::Track::kVideo) { + const int frame_count = block->GetFrameCount(); + const long long time_ns = block->GetTime(cluster); // NOLINT + + for (int i = 0; i < frame_count; ++i) { + const mkvparser::Block::Frame& frame = block->GetFrame(i); + if (static_cast(frame.len) > data.size()) { + data.resize(frame.len); + data_len = static_cast(frame.len); + } + ASSERT_FALSE(frame.Read(&reader_, &data[0])); + parser_.ParseUncompressedHeader(&data[0], data_len); + stats_.AddFrame(parser_, time_ns); + } + } + + status = cluster->GetNext(block_entry, block_entry); + ASSERT_EQ(0, status); + } + + cluster = segment_->GetNext(cluster); + } + } + + protected: + mkvparser::MkvReader reader_; + bool is_reader_open_; + std::unique_ptr segment_; + std::string filename_; + long long pos_; // NOLINT + vp9_parser::Vp9HeaderParser parser_; + vp9_parser::Vp9LevelStats stats_; +}; + +TEST_F(Vp9LevelStatsTests, VideoOnlyFile) { + ASSERT_NO_FATAL_FAILURE(CreateAndLoadSegment("test_stereo_left_right.webm")); + ProcessTheFrames(); + EXPECT_EQ(256, parser_.width()); + EXPECT_EQ(144, parser_.height()); + EXPECT_EQ(1, parser_.column_tiles()); + EXPECT_EQ(0, parser_.frame_parallel_mode()); + + EXPECT_EQ(11, stats_.GetLevel()); + EXPECT_EQ(479232, stats_.GetMaxLumaSampleRate()); + EXPECT_EQ(36864, stats_.GetMaxLumaPictureSize()); + EXPECT_DOUBLE_EQ(264.03233333333333, stats_.GetAverageBitRate()); + EXPECT_DOUBLE_EQ(147.136, stats_.GetMaxCpbSize()); + EXPECT_DOUBLE_EQ(19.267458404715583, stats_.GetCompressionRatio()); + EXPECT_EQ(1, stats_.GetMaxColumnTiles()); + EXPECT_EQ(11, stats_.GetMinimumAltrefDistance()); + EXPECT_EQ(3, stats_.GetMaxReferenceFrames()); + + EXPECT_TRUE(stats_.estimate_last_frame_duration()); + stats_.set_estimate_last_frame_duration(false); + EXPECT_DOUBLE_EQ(275.512, stats_.GetAverageBitRate()); +} + +TEST_F(Vp9LevelStatsTests, Muxed) { + ASSERT_NO_FATAL_FAILURE( + CreateAndLoadSegment("bbb_480p_vp9_opus_1second.webm", 4)); + ProcessTheFrames(); + EXPECT_EQ(854, parser_.width()); + EXPECT_EQ(480, parser_.height()); + EXPECT_EQ(2, parser_.column_tiles()); + EXPECT_EQ(1, parser_.frame_parallel_mode()); + + EXPECT_EQ(30, stats_.GetLevel()); + EXPECT_EQ(9838080, stats_.GetMaxLumaSampleRate()); + EXPECT_EQ(409920, stats_.GetMaxLumaPictureSize()); + EXPECT_DOUBLE_EQ(447.09394572025053, stats_.GetAverageBitRate()); + EXPECT_DOUBLE_EQ(118.464, stats_.GetMaxCpbSize()); + EXPECT_DOUBLE_EQ(241.17670131398313, stats_.GetCompressionRatio()); + EXPECT_EQ(2, stats_.GetMaxColumnTiles()); + EXPECT_EQ(9, stats_.GetMinimumAltrefDistance()); + EXPECT_EQ(3, stats_.GetMaxReferenceFrames()); + + stats_.set_estimate_last_frame_duration(false); + EXPECT_DOUBLE_EQ(468.38413361169108, stats_.GetAverageBitRate()); +} + +TEST_F(Vp9LevelStatsTests, SetDuration) { + ASSERT_NO_FATAL_FAILURE(CreateAndLoadSegment("test_stereo_left_right.webm")); + ProcessTheFrames(); + const int64_t kDurationNano = 2080000000; // 2.08 seconds + stats_.set_duration(kDurationNano); + EXPECT_EQ(256, parser_.width()); + EXPECT_EQ(144, parser_.height()); + EXPECT_EQ(1, parser_.column_tiles()); + EXPECT_EQ(0, parser_.frame_parallel_mode()); + + EXPECT_EQ(11, stats_.GetLevel()); + EXPECT_EQ(479232, stats_.GetMaxLumaSampleRate()); + EXPECT_EQ(36864, stats_.GetMaxLumaPictureSize()); + EXPECT_DOUBLE_EQ(264.9153846153846, stats_.GetAverageBitRate()); + EXPECT_DOUBLE_EQ(147.136, stats_.GetMaxCpbSize()); + EXPECT_DOUBLE_EQ(19.267458404715583, stats_.GetCompressionRatio()); + EXPECT_EQ(1, stats_.GetMaxColumnTiles()); + EXPECT_EQ(11, stats_.GetMinimumAltrefDistance()); + EXPECT_EQ(3, stats_.GetMaxReferenceFrames()); +} + +} // namespace + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/sys/libwebm/common/webm_constants.h b/src/sys/libwebm/common/webm_constants.h new file mode 100644 index 0000000..a082ce8 --- /dev/null +++ b/src/sys/libwebm/common/webm_constants.h @@ -0,0 +1,20 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#ifndef LIBWEBM_COMMON_WEBM_CONSTANTS_H_ +#define LIBWEBM_COMMON_WEBM_CONSTANTS_H_ + +namespace libwebm { + +const double kNanosecondsPerSecond = 1000000000.0; +const int kNanosecondsPerSecondi = 1000000000; +const int kNanosecondsPerMillisecond = 1000000; + +} // namespace libwebm + +#endif // LIBWEBM_COMMON_WEBM_CONSTANTS_H_ diff --git a/src/sys/libwebm/common/webm_endian.cc b/src/sys/libwebm/common/webm_endian.cc new file mode 100644 index 0000000..b1ef7ca --- /dev/null +++ b/src/sys/libwebm/common/webm_endian.cc @@ -0,0 +1,85 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#include "common/webm_endian.h" + +#include + +namespace { + +// Swaps unsigned 32 bit values to big endian if needed. Returns |value| +// unmodified if architecture is big endian. Returns swapped bytes of |value| +// if architecture is little endian. Returns 0 otherwise. +uint32_t swap32_check_little_endian(uint32_t value) { + // Check endianness. + union { + uint32_t val32; + uint8_t c[4]; + } check; + check.val32 = 0x01234567U; + + // Check for big endian. + if (check.c[3] == 0x67) + return value; + + // Check for not little endian. + if (check.c[0] != 0x67) + return 0; + + return value << 24 | ((value << 8) & 0x0000FF00U) | + ((value >> 8) & 0x00FF0000U) | value >> 24; +} + +// Swaps unsigned 64 bit values to big endian if needed. Returns |value| +// unmodified if architecture is big endian. Returns swapped bytes of |value| +// if architecture is little endian. Returns 0 otherwise. +uint64_t swap64_check_little_endian(uint64_t value) { + // Check endianness. + union { + uint64_t val64; + uint8_t c[8]; + } check; + check.val64 = 0x0123456789ABCDEFULL; + + // Check for big endian. + if (check.c[7] == 0xEF) + return value; + + // Check for not little endian. + if (check.c[0] != 0xEF) + return 0; + + return value << 56 | ((value << 40) & 0x00FF000000000000ULL) | + ((value << 24) & 0x0000FF0000000000ULL) | + ((value << 8) & 0x000000FF00000000ULL) | + ((value >> 8) & 0x00000000FF000000ULL) | + ((value >> 24) & 0x0000000000FF0000ULL) | + ((value >> 40) & 0x000000000000FF00ULL) | value >> 56; +} + +} // namespace + +namespace libwebm { + +uint32_t host_to_bigendian(uint32_t value) { + return swap32_check_little_endian(value); +} + +uint32_t bigendian_to_host(uint32_t value) { + return swap32_check_little_endian(value); +} + +uint64_t host_to_bigendian(uint64_t value) { + return swap64_check_little_endian(value); +} + +uint64_t bigendian_to_host(uint64_t value) { + return swap64_check_little_endian(value); +} + +} // namespace libwebm diff --git a/src/sys/libwebm/common/webm_endian.h b/src/sys/libwebm/common/webm_endian.h new file mode 100644 index 0000000..351778b --- /dev/null +++ b/src/sys/libwebm/common/webm_endian.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#ifndef LIBWEBM_COMMON_WEBM_ENDIAN_H_ +#define LIBWEBM_COMMON_WEBM_ENDIAN_H_ + +#include + +namespace libwebm { + +// Swaps unsigned 32 bit values to big endian if needed. Returns |value| if +// architecture is big endian. Returns big endian value if architecture is +// little endian. Returns 0 otherwise. +uint32_t host_to_bigendian(uint32_t value); + +// Swaps unsigned 32 bit values to little endian if needed. Returns |value| if +// architecture is big endian. Returns little endian value if architecture is +// little endian. Returns 0 otherwise. +uint32_t bigendian_to_host(uint32_t value); + +// Swaps unsigned 64 bit values to big endian if needed. Returns |value| if +// architecture is big endian. Returns big endian value if architecture is +// little endian. Returns 0 otherwise. +uint64_t host_to_bigendian(uint64_t value); + +// Swaps unsigned 64 bit values to little endian if needed. Returns |value| if +// architecture is big endian. Returns little endian value if architecture is +// little endian. Returns 0 otherwise. +uint64_t bigendian_to_host(uint64_t value); + +} // namespace libwebm + +#endif // LIBWEBM_COMMON_WEBM_ENDIAN_H_ diff --git a/src/sys/libwebm/common/webmids.h b/src/sys/libwebm/common/webmids.h new file mode 100644 index 0000000..fc0c208 --- /dev/null +++ b/src/sys/libwebm/common/webmids.h @@ -0,0 +1,193 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#ifndef COMMON_WEBMIDS_H_ +#define COMMON_WEBMIDS_H_ + +namespace libwebm { + +enum MkvId { + kMkvEBML = 0x1A45DFA3, + kMkvEBMLVersion = 0x4286, + kMkvEBMLReadVersion = 0x42F7, + kMkvEBMLMaxIDLength = 0x42F2, + kMkvEBMLMaxSizeLength = 0x42F3, + kMkvDocType = 0x4282, + kMkvDocTypeVersion = 0x4287, + kMkvDocTypeReadVersion = 0x4285, + kMkvVoid = 0xEC, + kMkvSignatureSlot = 0x1B538667, + kMkvSignatureAlgo = 0x7E8A, + kMkvSignatureHash = 0x7E9A, + kMkvSignaturePublicKey = 0x7EA5, + kMkvSignature = 0x7EB5, + kMkvSignatureElements = 0x7E5B, + kMkvSignatureElementList = 0x7E7B, + kMkvSignedElement = 0x6532, + // segment + kMkvSegment = 0x18538067, + // Meta Seek Information + kMkvSeekHead = 0x114D9B74, + kMkvSeek = 0x4DBB, + kMkvSeekID = 0x53AB, + kMkvSeekPosition = 0x53AC, + // Segment Information + kMkvInfo = 0x1549A966, + kMkvTimecodeScale = 0x2AD7B1, + kMkvDuration = 0x4489, + kMkvDateUTC = 0x4461, + kMkvTitle = 0x7BA9, + kMkvMuxingApp = 0x4D80, + kMkvWritingApp = 0x5741, + // Cluster + kMkvCluster = 0x1F43B675, + kMkvTimecode = 0xE7, + kMkvPrevSize = 0xAB, + kMkvBlockGroup = 0xA0, + kMkvBlock = 0xA1, + kMkvBlockDuration = 0x9B, + kMkvReferenceBlock = 0xFB, + kMkvLaceNumber = 0xCC, + kMkvSimpleBlock = 0xA3, + kMkvBlockAdditions = 0x75A1, + kMkvBlockMore = 0xA6, + kMkvBlockAddID = 0xEE, + kMkvBlockAdditional = 0xA5, + kMkvDiscardPadding = 0x75A2, + // Track + kMkvTracks = 0x1654AE6B, + kMkvTrackEntry = 0xAE, + kMkvTrackNumber = 0xD7, + kMkvTrackUID = 0x73C5, + kMkvTrackType = 0x83, + kMkvFlagEnabled = 0xB9, + kMkvFlagDefault = 0x88, + kMkvFlagForced = 0x55AA, + kMkvFlagLacing = 0x9C, + kMkvDefaultDuration = 0x23E383, + kMkvMaxBlockAdditionID = 0x55EE, + kMkvName = 0x536E, + kMkvLanguage = 0x22B59C, + kMkvCodecID = 0x86, + kMkvCodecPrivate = 0x63A2, + kMkvCodecName = 0x258688, + kMkvCodecDelay = 0x56AA, + kMkvSeekPreRoll = 0x56BB, + // video + kMkvVideo = 0xE0, + kMkvFlagInterlaced = 0x9A, + kMkvStereoMode = 0x53B8, + kMkvAlphaMode = 0x53C0, + kMkvPixelWidth = 0xB0, + kMkvPixelHeight = 0xBA, + kMkvPixelCropBottom = 0x54AA, + kMkvPixelCropTop = 0x54BB, + kMkvPixelCropLeft = 0x54CC, + kMkvPixelCropRight = 0x54DD, + kMkvDisplayWidth = 0x54B0, + kMkvDisplayHeight = 0x54BA, + kMkvDisplayUnit = 0x54B2, + kMkvAspectRatioType = 0x54B3, + kMkvColourSpace = 0x2EB524, + kMkvFrameRate = 0x2383E3, + // end video + // colour + kMkvColour = 0x55B0, + kMkvMatrixCoefficients = 0x55B1, + kMkvBitsPerChannel = 0x55B2, + kMkvChromaSubsamplingHorz = 0x55B3, + kMkvChromaSubsamplingVert = 0x55B4, + kMkvCbSubsamplingHorz = 0x55B5, + kMkvCbSubsamplingVert = 0x55B6, + kMkvChromaSitingHorz = 0x55B7, + kMkvChromaSitingVert = 0x55B8, + kMkvRange = 0x55B9, + kMkvTransferCharacteristics = 0x55BA, + kMkvPrimaries = 0x55BB, + kMkvMaxCLL = 0x55BC, + kMkvMaxFALL = 0x55BD, + // mastering metadata + kMkvMasteringMetadata = 0x55D0, + kMkvPrimaryRChromaticityX = 0x55D1, + kMkvPrimaryRChromaticityY = 0x55D2, + kMkvPrimaryGChromaticityX = 0x55D3, + kMkvPrimaryGChromaticityY = 0x55D4, + kMkvPrimaryBChromaticityX = 0x55D5, + kMkvPrimaryBChromaticityY = 0x55D6, + kMkvWhitePointChromaticityX = 0x55D7, + kMkvWhitePointChromaticityY = 0x55D8, + kMkvLuminanceMax = 0x55D9, + kMkvLuminanceMin = 0x55DA, + // end mastering metadata + // end colour + // projection + kMkvProjection = 0x7670, + kMkvProjectionType = 0x7671, + kMkvProjectionPrivate = 0x7672, + kMkvProjectionPoseYaw = 0x7673, + kMkvProjectionPosePitch = 0x7674, + kMkvProjectionPoseRoll = 0x7675, + // end projection + // audio + kMkvAudio = 0xE1, + kMkvSamplingFrequency = 0xB5, + kMkvOutputSamplingFrequency = 0x78B5, + kMkvChannels = 0x9F, + kMkvBitDepth = 0x6264, + // end audio + // ContentEncodings + kMkvContentEncodings = 0x6D80, + kMkvContentEncoding = 0x6240, + kMkvContentEncodingOrder = 0x5031, + kMkvContentEncodingScope = 0x5032, + kMkvContentEncodingType = 0x5033, + kMkvContentCompression = 0x5034, + kMkvContentCompAlgo = 0x4254, + kMkvContentCompSettings = 0x4255, + kMkvContentEncryption = 0x5035, + kMkvContentEncAlgo = 0x47E1, + kMkvContentEncKeyID = 0x47E2, + kMkvContentSignature = 0x47E3, + kMkvContentSigKeyID = 0x47E4, + kMkvContentSigAlgo = 0x47E5, + kMkvContentSigHashAlgo = 0x47E6, + kMkvContentEncAESSettings = 0x47E7, + kMkvAESSettingsCipherMode = 0x47E8, + kMkvAESSettingsCipherInitData = 0x47E9, + // end ContentEncodings + // Cueing Data + kMkvCues = 0x1C53BB6B, + kMkvCuePoint = 0xBB, + kMkvCueTime = 0xB3, + kMkvCueTrackPositions = 0xB7, + kMkvCueTrack = 0xF7, + kMkvCueClusterPosition = 0xF1, + kMkvCueBlockNumber = 0x5378, + // Chapters + kMkvChapters = 0x1043A770, + kMkvEditionEntry = 0x45B9, + kMkvChapterAtom = 0xB6, + kMkvChapterUID = 0x73C4, + kMkvChapterStringUID = 0x5654, + kMkvChapterTimeStart = 0x91, + kMkvChapterTimeEnd = 0x92, + kMkvChapterDisplay = 0x80, + kMkvChapString = 0x85, + kMkvChapLanguage = 0x437C, + kMkvChapCountry = 0x437E, + // Tags + kMkvTags = 0x1254C367, + kMkvTag = 0x7373, + kMkvSimpleTag = 0x67C8, + kMkvTagName = 0x45A3, + kMkvTagString = 0x4487 +}; + +} // namespace libwebm + +#endif // COMMON_WEBMIDS_H_ diff --git a/src/sys/libwebm/dumpvtt.cc b/src/sys/libwebm/dumpvtt.cc new file mode 100644 index 0000000..472da52 --- /dev/null +++ b/src/sys/libwebm/dumpvtt.cc @@ -0,0 +1,91 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#include +#include +#include "webvtt/vttreader.h" +#include "webvtt/webvttparser.h" + +int main(int argc, const char* argv[]) { + if (argc != 2) { + fprintf(stdout, "usage: dumpvtt \n"); + return EXIT_SUCCESS; + } + + libwebvtt::VttReader reader; + const char* const filename = argv[1]; + + if (int e = reader.Open(filename)) { + (void)e; + fprintf(stderr, "open failed\n"); + return EXIT_FAILURE; + } + + libwebvtt::Parser parser(&reader); + + if (int e = parser.Init()) { + (void)e; + fprintf(stderr, "parser init failed\n"); + return EXIT_FAILURE; + } + + for (libwebvtt::Cue cue;;) { + const int e = parser.Parse(&cue); + + if (e < 0) { // error + fprintf(stderr, "error parsing cue\n"); + return EXIT_FAILURE; + } + + if (e > 0) // EOF + return EXIT_SUCCESS; + + fprintf(stdout, "cue identifier: \"%s\"\n", cue.identifier.c_str()); + + const libwebvtt::Time& st = cue.start_time; + fprintf(stdout, "cue start time: \"HH=%i MM=%i SS=%i SSS=%i\"\n", st.hours, + st.minutes, st.seconds, st.milliseconds); + + const libwebvtt::Time& sp = cue.stop_time; + fprintf(stdout, "cue stop time: \"HH=%i MM=%i SS=%i SSS=%i\"\n", sp.hours, + sp.minutes, sp.seconds, sp.milliseconds); + + { + typedef libwebvtt::Cue::settings_t::const_iterator iter_t; + iter_t i = cue.settings.begin(); + const iter_t j = cue.settings.end(); + + if (i == j) { + fprintf(stdout, "cue setting: \n"); + } else { + while (i != j) { + const libwebvtt::Setting& setting = *i++; + fprintf(stdout, "cue setting: name=%s value=%s\n", + setting.name.c_str(), setting.value.c_str()); + } + } + } + + { + typedef libwebvtt::Cue::payload_t::const_iterator iter_t; + iter_t i = cue.payload.begin(); + const iter_t j = cue.payload.end(); + + int idx = 1; + while (i != j) { + const std::string& payload = *i++; + const char* const payload_str = payload.c_str(); + fprintf(stdout, "cue payload[%i]: \"%s\"\n", idx, payload_str); + ++idx; + } + } + + fprintf(stdout, "\n"); + fflush(stdout); + } +} diff --git a/src/sys/libwebm/hdr_util.hpp b/src/sys/libwebm/hdr_util.hpp new file mode 100644 index 0000000..7abcb3a --- /dev/null +++ b/src/sys/libwebm/hdr_util.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_HDR_UTIL_HPP_ +#define LIBWEBM_HDR_UTIL_HPP_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "common/hdr_util.h" + +#endif // LIBWEBM_HDR_UTIL_HPP_ diff --git a/src/sys/libwebm/infra/README.md b/src/sys/libwebm/infra/README.md new file mode 100644 index 0000000..ce75d2d --- /dev/null +++ b/src/sys/libwebm/infra/README.md @@ -0,0 +1,23 @@ +# Infra Build Scripts + +This directory contains scripts to build libwebm in various configurations. +These scripts were created to support Jenkins integration pipelines but these +scripts can also be run locally. + +## Environment + +Most of these scripts were ported from Jenkins, so in order to be run locally +some environment variables must be set prior to invocation. + +**WORKSPACE** Traditionally, the Jenkins `WORKSPACE` path. If not defined, a +temporary directory will be used. + +## LUCI Integration + +[Builder Dashboard](https://ci.chromium/p/open-codecs) \ +The new builders run these scripts on each CL. The current configuration +supports the `refs/head/main` branch. + +## Scripts + +**compile.sh** Builds libwebm with supported configuration and host toolchains. diff --git a/src/sys/libwebm/infra/common.sh b/src/sys/libwebm/infra/common.sh new file mode 100644 index 0000000..5d9c8e5 --- /dev/null +++ b/src/sys/libwebm/infra/common.sh @@ -0,0 +1,65 @@ +# Copyright (c) 2021, Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of Google nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +log_err() { + echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2 +} + +####################################### +# Create build directory. Build directory will be deleted if it exists. +# Outputs: +# build dir path +# Returns: +# mkdir result +####################################### +make_build_dir() { + if [[ "$#" -ne 1 ]]; then + return 1 + fi + + local build_dir + build_dir="$1" + [[ -d "${build_dir}" ]] && rm -rf "${build_dir}" + mkdir -p "${build_dir}" +} + +####################################### +# Cleanup files from the backup directory. +# Globals: +# BUILD_DIR build directory +# LIBWEBM_ROOT repository's root path +####################################### +cleanup() { + # BUILD_DIR is not completely removed to allow for binary artifacts to be + # extracted. + find "${BUILD_DIR:?}" \( -name "*.[ao]" -o -name "*.l[ao]" \) -exec rm \ + -f {} + + make -C "${LIBWEBM_ROOT:?}" -f Makefile.unix clean +} diff --git a/src/sys/libwebm/infra/compile.sh b/src/sys/libwebm/infra/compile.sh new file mode 100644 index 0000000..b4f81f9 --- /dev/null +++ b/src/sys/libwebm/infra/compile.sh @@ -0,0 +1,128 @@ +#!/bin/bash +# Copyright (c) 2021, Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of Google nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -e +shopt -s inherit_errexit + +LIBWEBM_ROOT="$(realpath "$(dirname "$0")/..")" +readonly LIBWEBM_ROOT +readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webm.XXX)"} + +# shellcheck source=infra/common.sh +source "${LIBWEBM_ROOT}/infra/common.sh" + +usage() { + cat << EOF +Usage: compile.sh BUILD_TYPE TARGET +Options: +BUILD_TYPE supported build type (static, static-debug) +TARGET supported target platform compilation: (native, native-clang, + clang-i686, i686-w64-mingw32, x86_64-w64-mingw32, + native-Makefile.unix) +Environment variables: +WORKSPACE directory where the build is done +EOF +} + +####################################### +# Setup ccache for toolchain. +####################################### +setup_ccache() { + if command -v ccache 2> /dev/null; then + export CCACHE_CPP2=yes + export PATH="/usr/lib/ccache:${PATH}" + fi +} + +################################################################################ +echo "Building libwebm in ${WORKSPACE}" + +if [[ ! -d "${WORKSPACE}" ]]; then + log_err "${WORKSPACE} directory does not exist" + exit 1 +fi + +BUILD_TYPE=${1:?"Build type not defined.$( + echo + usage +)"} +TARGET=${2:?"Target not defined.$( + echo + usage +)"} +BUILD_DIR="${WORKSPACE}/build-${BUILD_TYPE}" + +trap cleanup EXIT +setup_ccache +make_build_dir "${BUILD_DIR}" + +case "${TARGET}" in + native-Makefile.unix) + make -C "${LIBWEBM_ROOT}" -f Makefile.unix + ;; + *) + opts=() + case "${BUILD_TYPE}" in + static) opts+=("-DCMAKE_BUILD_TYPE=Release") ;; + *debug) opts+=("-DCMAKE_BUILD_TYPE=Debug") ;; + *) + log_err "${BUILD_TYPE} build type not supported" + usage + exit 1 + ;; + esac + + TOOLCHAIN_FILE_FLAG="-DCMAKE_TOOLCHAIN_FILE=${LIBWEBM_ROOT}/build" + case "${TARGET}" in + native-clang) opts+=("-DCMAKE_CXX_COMPILER=clang++") ;; + clang-i686) + opts+=("-DCMAKE_CXX_COMPILER=clang++") + opts+=("-DCMAKE_CXX_FLAGS=-m32") + ;; + native) ;; # No additional flags needed. + i686-w64-mingw32) + opts+=("${TOOLCHAIN_FILE_FLAG}/x86-mingw-gcc.cmake") + ;; + x86_64-w64-mingw32) + opts+=("${TOOLCHAIN_FILE_FLAG}/x86_64-mingw-gcc.cmake") + ;; + *) + log_err "${TARGET} TARGET not supported" + usage + exit 1 + ;; + esac + pushd "${BUILD_DIR}" + cmake "${LIBWEBM_ROOT}" "${opts[@]}" + make -j4 VERBOSE=1 + popd + ;; +esac diff --git a/src/sys/libwebm/infra/compile_android.sh b/src/sys/libwebm/infra/compile_android.sh new file mode 100644 index 0000000..df0d39c --- /dev/null +++ b/src/sys/libwebm/infra/compile_android.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# Copyright (c) 2021, Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of Google nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -e +shopt -s inherit_errexit + +LIBWEBM_ROOT="$(realpath "$(dirname "$0")/..")" +readonly LIBWEBM_ROOT +readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d)"} + +# shellcheck source=infra/common.sh +source "${LIBWEBM_ROOT}/infra/common.sh" + +usage() { + cat << EOF +Usage: $(basename "$0") APP_OPTIM APP_ABI +Options: +APP_OPTIM supported build type (release, debug) +APP_ABI supported application binary interface compilation: (armeabi-v7a, + arm64-v8a, x86, x86_64) +Environment variables: +WORKSPACE directory where the build is done +EOF +} + +################################################################################ +echo "Building libwebm for Android in ${WORKSPACE}" + +if [[ ! -d "${WORKSPACE}" ]]; then + log_err "${WORKSPACE} directory does not exist" + exit 1 +fi + +APP_OPTIM=${1:?"not defined.$( + echo + usage +)"} +APP_ABI=${2:?"Application Binary Interface not defined.$( + echo + usage +)"} +BUILD_DIR="${WORKSPACE}/build-${APP_OPTIM}" + +if ! command -v ndk-build 2> /dev/null; then + log_err "unable to find ndk-build in PATH" + exit 1 +fi + +make_build_dir "${BUILD_DIR}" +ndk-build -j2 NDK_PROJECT_PATH="${BUILD_DIR}" APP_OPTIM="${APP_OPTIM}" \ + APP_ABI="${APP_ABI}" APP_BUILD_SCRIPT="${LIBWEBM_ROOT}/Android.mk" \ + APP_STL="c++_static" diff --git a/src/sys/libwebm/infra/run_unit_tests.sh b/src/sys/libwebm/infra/run_unit_tests.sh new file mode 100644 index 0000000..abcae55 --- /dev/null +++ b/src/sys/libwebm/infra/run_unit_tests.sh @@ -0,0 +1,200 @@ +#!/bin/bash +# Copyright (c) 2021, Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# * Neither the name of Google nor the names of its contributors may +# be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -xeo pipefail +shopt -s inherit_errexit + +readonly GOOGLETEST_REPO="https://github.com/google/googletest.git" +LIBWEBM_ROOT="$(realpath "$(dirname "$0")/..")" +readonly LIBWEBM_ROOT +readonly WORKSPACE=${WORKSPACE:-"$(mktemp -d -t webm.XXX)"} + +# shellcheck source=infra/common.sh +source "${LIBWEBM_ROOT}/infra/common.sh" + +usage() { + cat << EOF +Usage: $(basename "$0") TARGET +Options: +TARGET supported targets: (x86-asan, x86-ubsan, x86_64-asan, x86_64-ubsan, + x86_64-valgrind) +Global variables: +WORKSPACE directory where the build is done +EOF +} + +####################################### +# Run valgrind +####################################### +run_valgrind() { + valgrind \ + --leak-check=full \ + --show-reachable=yes \ + --track-origins=yes \ + --error-exitcode=1 \ + "$@" +} + +####################################### +# Ensure GoogleTest repository is setup +# +# Globals: +# GOOGLETEST_REPO googletest repository url +# WORKSPACE directory where the build is done +####################################### +ensure_googletest() { + local googletest_dir + googletest_dir="${WORKSPACE}/googletest" + + if [[ ! -d "${googletest_dir}" ]] || ! git -C "${googletest_dir}" pull; then + rm -rf "${googletest_dir}" + git clone --depth 1 "${GOOGLETEST_REPO}" "${googletest_dir}" + fi + + opts+=("-DGTEST_SRC_DIR=${googletest_dir}") +} + +####################################### +# Symbolizes and dumps warnings in the address sanitizer log +# Globals: +# BUILD_DIR directory where the build is done +# SANITIZER_LOG path to sanitizer log file +####################################### +dump_sanitizer_log() { + if [[ "$#" -ne 1 ]]; then + return 1 + fi + + if command -v asan_symbolize; then + asan_symbolize_tool="asan_symbolize" + else + asan_symbolize_tool="asan_symbolize.py" + fi + + local target + target="$1" + case "${target}" in + *-asan) + asanlog_symbolized="${BUILD_DIR}/asan_log.asanlog_symbolized" + grep -v 'Invalid VP9' "${SANITIZER_LOG}" > "${SANITIZER_LOG}.2" || true + "${asan_symbolize_tool}" "${BUILD_DIR}" < "${SANITIZER_LOG}.2" \ + | c++filt > "${asanlog_symbolized}" + if [[ -s "${asanlog_symbolized}" ]]; then + cat "${asanlog_symbolized}" + return 1 + fi + ;; + *) ;; # No other sanitizer options are required + # TODO(b/185520494): Handle ubsan warning output inspection + esac +} + +################################################################################ +echo "Unit testing libwebm in ${WORKSPACE}" + +if [[ ! -d "${WORKSPACE}" ]]; then + log_err "${WORKSPACE} directory does not exist" + exit 1 +fi + +TARGET=${1:? "$( + echo + usage +)"} +readonly BUILD_DIR="${WORKSPACE}/tests-${TARGET}" +readonly SANITIZER_LOG="${BUILD_DIR}/sanitizer_log" + +# Create a fresh build directory. +trap 'dump_sanitizer_log ${TARGET}; cleanup' EXIT +make_build_dir "${BUILD_DIR}" + +case "${TARGET}" in + x86-*) CXX='clang++ -m32' ;; + x86_64-*) CXX=clang++ ;; + *) + log_err "${TARGET} should have x86 or x86_64 prefix." + usage + exit 1 + ;; +esac +# cmake (3.4.3) will only accept the -m32 variants when used via the CXX env +# var. +export CXX +opts+=("-DCMAKE_BUILD_TYPE=Debug" "-DENABLE_TESTS=ON") +case "${TARGET}" in + *-asan) opts+=("-DCMAKE_CXX_FLAGS=-fsanitize=address") ;; + *-ubsan) + opts+=("-DCMAKE_CXX_FLAGS=-fsanitize=integer") + if [[ "${TARGET}" == "x86-ubsan" ]]; then + # clang fails to find symbols when -fsanitize=integer is set in x86 arch. + # https://bugs.llvm.org/show_bug.cgi?id=17693 + opts+=("-DCMAKE_CXX_FLAGS=-rtlib=compiler-rt") + opts+=("-DCMAKE_EXE_LINKER_FLAGS=-lgcc_s") + fi + ;; + *) ;; # No additional flags needed. +esac + +ensure_googletest +# Using pushd instead of -S/-B for backward compatibility with CMake < 3.13.x +pushd "${BUILD_DIR}" +cmake "${LIBWEBM_ROOT}" "${opts[@]}" +make -j 4 +popd + +find_tests="$(find "${BUILD_DIR}" -name '*_tests')" +UNIT_TESTS=() +while IFS='' read -r line; do + UNIT_TESTS+=("${line}") +done < <(echo "${find_tests}") + +export LIBWEBM_TEST_DATA_PATH="${LIBWEBM_ROOT}/testing/testdata" +case "${TARGET}" in + *-asan | *-ubsan) + rm -f "${SANITIZER_LOG}" + for test in "${UNIT_TESTS[@]}"; do + "${test}" \ + --gtest_output="xml:${BUILD_DIR}/$(basename "${test}")_detail.xml" \ + 3<&1 1>&2 2>&3 | tee -a "${SANITIZER_LOG}" + done + ;; + *-valgrind) + for test in "${UNIT_TESTS[@]}"; do + run_valgrind --error-exitcode=1 "${test}" \ + --gtest_output="xml:${BUILD_DIR}/$(basename "${test}")_detail.xml" + done + ;; + *) + log_err "Unrecognized TARGET:${TARGET}." + usage + exit 1 + ;; +esac diff --git a/src/sys/libwebm/iosbuild.sh b/src/sys/libwebm/iosbuild.sh new file mode 100644 index 0000000..a183af3 --- /dev/null +++ b/src/sys/libwebm/iosbuild.sh @@ -0,0 +1,207 @@ +#!/bin/sh +## +## Copyright (c) 2015 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## +## This script generates 'WebM.framework'. An iOS app can mux/demux WebM +## container files by including 'WebM.framework'. +## +## Run ./iosbuild.sh to generate 'WebM.framework'. By default the framework +## bundle will be created in a directory called framework. Use --out-dir to +## change the output directory. +## +## This script is based on iosbuild.sh from the libwebp project. +. $(dirname $0)/common/common.sh + +# Trap function. Cleans up build output. +cleanup() { + local readonly res=$? + cd "${ORIG_PWD}" + + for dir in ${LIBDIRS}; do + if [ -d "${dir}" ]; then + rm -rf "${dir}" + fi + done + + if [ $res -ne 0 ]; then + elog "build exited with error ($res)" + fi +} + +trap cleanup EXIT + +check_dir libwebm + +iosbuild_usage() { +cat << EOF + Usage: ${0##*/} [arguments] + --help: Display this message and exit. + --out-dir: Override output directory (default is ${OUTDIR}). + --show-build-output: Show output from each library build. + --verbose: Output information about the environment and each stage of the + build. +EOF +} + +# Extract the latest SDK version from the final field of the form: iphoneosX.Y +readonly SDK=$(xcodebuild -showsdks \ + | grep iphoneos | sort | tail -n 1 | awk '{print substr($NF, 9)}' +) + +# Extract Xcode version. +readonly XCODE=$(xcodebuild -version | grep Xcode | cut -d " " -f2) +if [ -z "${XCODE}" ]; then + echo "Xcode not available" + exit 1 +fi + +# Add iPhoneOS-V6 to the list of platforms below if you need armv6 support. +# Note that iPhoneOS-V6 support is not available with the iOS6 SDK. +readonly INCLUDES="common/file_util.h + common/hdr_util.h + common/webmids.h + mkvmuxer/mkvmuxer.h + mkvmuxer/mkvmuxertypes.h + mkvmuxer/mkvmuxerutil.h + mkvmuxer/mkvwriter.h + mkvparser/mkvparser.h + mkvparser/mkvreader.h" +readonly PLATFORMS="iPhoneSimulator + iPhoneSimulator64 + iPhoneOS-V7 + iPhoneOS-V7s + iPhoneOS-V7-arm64" +readonly TARGETDIR="WebM.framework" +readonly DEVELOPER="$(xcode-select --print-path)" +readonly PLATFORMSROOT="${DEVELOPER}/Platforms" +readonly LIPO="$(xcrun -sdk iphoneos${SDK} -find lipo)" +LIBLIST="" +OPT_FLAGS="-DNDEBUG -O3" +readonly SDK_MAJOR_VERSION="$(echo ${SDK} | awk -F '.' '{ print $1 }')" + +if [ -z "${SDK_MAJOR_VERSION}" ]; then + elog "iOS SDK not available" + exit 1 +elif [ "${SDK_MAJOR_VERSION}" -lt "6" ]; then + elog "You need iOS SDK version 6 or above" + exit 1 +else + vlog "iOS SDK Version ${SDK}" +fi + + +# Parse the command line. +while [ -n "$1" ]; do + case "$1" in + --help) + iosbuild_usage + exit + ;; + --out-dir) + OUTDIR="$2" + shift + ;; + --enable-debug) + OPT_FLAGS="-g" + ;; + --show-build-output) + devnull= + ;; + --verbose) + VERBOSE=yes + ;; + *) + iosbuild_usage + exit 1 + ;; + esac + shift +done + +readonly OPT_FLAGS="${OPT_FLAGS}" +readonly OUTDIR="${OUTDIR:-framework}" + +if [ "${VERBOSE}" = "yes" ]; then +cat << EOF + OUTDIR=${OUTDIR} + INCLUDES=${INCLUDES} + PLATFORMS=${PLATFORMS} + TARGETDIR=${TARGETDIR} + DEVELOPER=${DEVELOPER} + LIPO=${LIPO} + OPT_FLAGS=${OPT_FLAGS} + ORIG_PWD=${ORIG_PWD} +EOF +fi + +rm -rf "${OUTDIR}/${TARGETDIR}" +mkdir -p "${OUTDIR}/${TARGETDIR}/Headers/" + +for PLATFORM in ${PLATFORMS}; do + ARCH2="" + if [ "${PLATFORM}" = "iPhoneOS-V7-arm64" ]; then + PLATFORM="iPhoneOS" + ARCH="aarch64" + ARCH2="arm64" + elif [ "${PLATFORM}" = "iPhoneOS-V7s" ]; then + PLATFORM="iPhoneOS" + ARCH="armv7s" + elif [ "${PLATFORM}" = "iPhoneOS-V7" ]; then + PLATFORM="iPhoneOS" + ARCH="armv7" + elif [ "${PLATFORM}" = "iPhoneOS-V6" ]; then + PLATFORM="iPhoneOS" + ARCH="armv6" + elif [ "${PLATFORM}" = "iPhoneSimulator64" ]; then + PLATFORM="iPhoneSimulator" + ARCH="x86_64" + else + ARCH="i386" + fi + + LIBDIR="${OUTDIR}/${PLATFORM}-${SDK}-${ARCH}" + LIBDIRS="${LIBDIRS} ${LIBDIR}" + LIBFILE="${LIBDIR}/libwebm.a" + eval mkdir -p "${LIBDIR}" ${devnull} + + DEVROOT="${DEVELOPER}/Toolchains/XcodeDefault.xctoolchain" + SDKROOT="${PLATFORMSROOT}/" + SDKROOT="${SDKROOT}${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDK}.sdk/" + CXXFLAGS="-arch ${ARCH2:-${ARCH}} -isysroot ${SDKROOT} ${OPT_FLAGS} + -miphoneos-version-min=6.0" + + # enable bitcode if available + if [ "${SDK_MAJOR_VERSION}" -gt 8 ]; then + CXXFLAGS="${CXXFLAGS} -fembed-bitcode" + fi + + # Build using the legacy makefile (instead of generating via cmake). + eval make -f Makefile.unix libwebm.a CXXFLAGS=\"${CXXFLAGS}\" ${devnull} + + # copy lib and add it to LIBLIST. + eval cp libwebm.a "${LIBFILE}" ${devnull} + LIBLIST="${LIBLIST} ${LIBFILE}" + + # clean build so we can go again. + eval make -f Makefile.unix clean ${devnull} +done + +# create include sub dirs in framework dir. +readonly framework_header_dir="${OUTDIR}/${TARGETDIR}/Headers" +readonly framework_header_sub_dirs="common mkvmuxer mkvparser" +for dir in ${framework_header_sub_dirs}; do + mkdir "${framework_header_dir}/${dir}" +done + +for header_file in ${INCLUDES}; do + eval cp -p ${header_file} "${framework_header_dir}/${header_file}" ${devnull} +done + +eval ${LIPO} -create ${LIBLIST} -output "${OUTDIR}/${TARGETDIR}/WebM" ${devnull} +echo "Succesfully built ${TARGETDIR} in ${OUTDIR}." diff --git a/src/sys/libwebm/m2ts/tests/webm2pes_tests.cc b/src/sys/libwebm/m2ts/tests/webm2pes_tests.cc new file mode 100644 index 0000000..664856f --- /dev/null +++ b/src/sys/libwebm/m2ts/tests/webm2pes_tests.cc @@ -0,0 +1,158 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "m2ts/webm2pes.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" + +#include "common/file_util.h" +#include "common/libwebm_util.h" +#include "m2ts/vpxpes_parser.h" +#include "testing/test_util.h" + +namespace { + +class Webm2PesTests : public ::testing::Test { + public: + // Constants for validating known values from input data. + const std::uint8_t kMinVideoStreamId = 0xE0; + const std::uint8_t kMaxVideoStreamId = 0xEF; + const int kPesHeaderSize = 6; + const int kPesOptionalHeaderStartOffset = kPesHeaderSize; + const int kPesOptionalHeaderSize = 9; + const int kPesOptionalHeaderMarkerValue = 0x2; + const int kWebm2PesOptHeaderRemainingSize = 6; + const int kBcmvHeaderSize = 10; + + Webm2PesTests() = default; + ~Webm2PesTests() = default; + + void CreateAndLoadTestInput() { + libwebm::Webm2Pes converter(input_file_name_, temp_file_name_.name()); + ASSERT_TRUE(converter.ConvertToFile()); + ASSERT_TRUE(parser_.Open(pes_file_name())); + } + + bool VerifyPacketStartCode(const libwebm::VpxPesParser::PesHeader& header) { + // PES packets all start with the byte sequence 0x0 0x0 0x1. + if (header.start_code[0] != 0 || header.start_code[1] != 0 || + header.start_code[2] != 1) { + return false; + } + return true; + } + + const std::string& pes_file_name() const { return temp_file_name_.name(); } + libwebm::VpxPesParser* parser() { return &parser_; } + + private: + const libwebm::TempFileDeleter temp_file_name_; + const std::string input_file_name_ = + test::GetTestFilePath("bbb_480p_vp9_opus_1second.webm"); + libwebm::VpxPesParser parser_; +}; + +TEST_F(Webm2PesTests, CreatePesFile) { CreateAndLoadTestInput(); } + +TEST_F(Webm2PesTests, CanParseFirstPacket) { + CreateAndLoadTestInput(); + libwebm::VpxPesParser::PesHeader header; + libwebm::VideoFrame frame; + ASSERT_TRUE(parser()->ParseNextPacket(&header, &frame)); + EXPECT_TRUE(VerifyPacketStartCode(header)); + + // 9 bytes: PES optional header + // 10 bytes: BCMV Header + // 83 bytes: frame + // 102 bytes total in packet length field: + const std::size_t kPesPayloadLength = 102; + EXPECT_EQ(kPesPayloadLength, header.packet_length); + + EXPECT_GE(header.stream_id, kMinVideoStreamId); + EXPECT_LE(header.stream_id, kMaxVideoStreamId); + + // Test PesOptionalHeader values. + EXPECT_EQ(kPesOptionalHeaderMarkerValue, header.opt_header.marker); + EXPECT_EQ(kWebm2PesOptHeaderRemainingSize, header.opt_header.remaining_size); + EXPECT_EQ(0, header.opt_header.scrambling); + EXPECT_EQ(0, header.opt_header.priority); + EXPECT_EQ(0, header.opt_header.data_alignment); + EXPECT_EQ(0, header.opt_header.copyright); + EXPECT_EQ(0, header.opt_header.original); + EXPECT_EQ(1, header.opt_header.has_pts); + EXPECT_EQ(0, header.opt_header.has_dts); + EXPECT_EQ(0, header.opt_header.unused_fields); + + // Test the BCMV header. + // Note: The length field of the BCMV header includes its own length. + const std::size_t kBcmvBaseLength = 10; + const std::size_t kFirstFrameLength = 83; + const libwebm::VpxPesParser::BcmvHeader kFirstBcmvHeader(kFirstFrameLength + + kBcmvBaseLength); + EXPECT_TRUE(header.bcmv_header.Valid()); + EXPECT_EQ(kFirstBcmvHeader, header.bcmv_header); + + // Parse the next packet to confirm correct parse and consumption of payload. + EXPECT_TRUE(parser()->ParseNextPacket(&header, &frame)); +} + +TEST_F(Webm2PesTests, CanMuxLargeBuffers) { + const std::size_t kBufferSize = 100 * 1024; + const std::int64_t kFakeTimestamp = libwebm::kNanosecondsPerSecond; + libwebm::VideoFrame fake_frame(kFakeTimestamp, libwebm::VideoFrame::kVP9); + ASSERT_TRUE(fake_frame.Init(kBufferSize)); + std::memset(fake_frame.buffer().data.get(), 0x80, kBufferSize); + ASSERT_TRUE(fake_frame.SetBufferLength(kBufferSize)); + libwebm::PacketDataBuffer pes_packet_buffer; + ASSERT_TRUE( + libwebm::Webm2Pes::WritePesPacket(fake_frame, &pes_packet_buffer)); + + // TODO(tomfinegan): Change VpxPesParser so it can read from a buffer, and get + // rid of this extra step. + libwebm::FilePtr pes_file(std::fopen(pes_file_name().c_str(), "wb"), + libwebm::FILEDeleter()); + ASSERT_EQ(pes_packet_buffer.size(), + fwrite(&pes_packet_buffer[0], 1, pes_packet_buffer.size(), + pes_file.get())); + fclose(pes_file.get()); + pes_file.release(); + + libwebm::VpxPesParser parser; + ASSERT_TRUE(parser.Open(pes_file_name())); + libwebm::VpxPesParser::PesHeader header; + libwebm::VideoFrame parsed_frame; + ASSERT_TRUE(parser.ParseNextPacket(&header, &parsed_frame)); + EXPECT_EQ(fake_frame.nanosecond_pts(), parsed_frame.nanosecond_pts()); + EXPECT_EQ(fake_frame.buffer().length, parsed_frame.buffer().length); + EXPECT_EQ(0, std::memcmp(fake_frame.buffer().data.get(), + parsed_frame.buffer().data.get(), kBufferSize)); +} + +TEST_F(Webm2PesTests, ParserConsumesAllInput) { + CreateAndLoadTestInput(); + libwebm::VpxPesParser::PesHeader header; + libwebm::VideoFrame frame; + while (parser()->ParseNextPacket(&header, &frame) == true) { + EXPECT_TRUE(VerifyPacketStartCode(header)); + } + EXPECT_EQ(0, parser()->BytesAvailable()); +} + +} // namespace + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/sys/libwebm/m2ts/vpxpes2ts.cc b/src/sys/libwebm/m2ts/vpxpes2ts.cc new file mode 100644 index 0000000..7684b56 --- /dev/null +++ b/src/sys/libwebm/m2ts/vpxpes2ts.cc @@ -0,0 +1,217 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "m2ts/vpxpes2ts.h" + +#include +#include +#include +#include + +namespace libwebm { +// TODO(tomfinegan): Dedupe this and PesHeaderField. +// Stores a value and its size in bits for writing into a MPEG2 TS Header. +// Maximum size is 64 bits. Users may call the Check() method to perform minimal +// validation (size > 0 and <= 64). +struct TsHeaderField { + TsHeaderField(std::uint64_t value, std::uint32_t size_in_bits, + std::uint8_t byte_index, std::uint8_t bits_to_shift) + : bits(value), + num_bits(size_in_bits), + index(byte_index), + shift(bits_to_shift) {} + TsHeaderField() = delete; + TsHeaderField(const TsHeaderField&) = default; + TsHeaderField(TsHeaderField&&) = default; + ~TsHeaderField() = default; + bool Check() const { + return num_bits > 0 && num_bits <= 64 && shift >= 0 && shift < 64; + } + + // Value to be stored in the field. + std::uint64_t bits; + + // Number of bits in the value. + const int num_bits; + + // Index into the header for the byte in which |bits| will be written. + const std::uint8_t index; + + // Number of bits to left shift value before or'ing. Ignored for whole bytes. + const int shift; +}; + +// Data storage for MPEG2 Transport Stream headers. +// https://en.wikipedia.org/wiki/MPEG_transport_stream#Packet +struct TsHeader { + TsHeader(bool payload_start, bool adaptation_flag, std::uint8_t counter) + : is_payload_start(payload_start), + has_adaptation(adaptation_flag), + counter_value(counter) {} + TsHeader() = delete; + TsHeader(const TsHeader&) = default; + TsHeader(TsHeader&&) = default; + ~TsHeader() = default; + + void Write(PacketDataBuffer* buffer) const; + + // Indicates the packet is the beginning of a new fragmented payload. + const bool is_payload_start; + + // Indicates the packet contains an adaptation field. + const bool has_adaptation; + + // The sync byte is the bit pattern of 0x47 (ASCII char 'G'). + const std::uint8_t kTsHeaderSyncByte = 0x47; + const std::uint8_t sync_byte = kTsHeaderSyncByte; + + // Value for |continuity_counter|. Used to detect gaps when demuxing. + const std::uint8_t counter_value; + + // Set when FEC is impossible. Always 0. + const TsHeaderField transport_error_indicator = TsHeaderField(0, 1, 1, 7); + + // This MPEG2 TS header is the start of a new payload (aka PES packet). + const TsHeaderField payload_unit_start_indicator = + TsHeaderField(is_payload_start ? 1 : 0, 1, 1, 6); + + // Set when the current packet has a higher priority than other packets with + // the same PID. Always 0 for VPX. + const TsHeaderField transport_priority = TsHeaderField(0, 1, 1, 5); + + // https://en.wikipedia.org/wiki/MPEG_transport_stream#Packet_Identifier_.28PID.29 + // 0x0020-0x1FFA May be assigned as needed to Program Map Tables, elementary + // streams and other data tables. + // Note: Though we hard code to 0x20, this value is actually 13 bits-- the + // buffer for the header is always set to 0, so it doesn't matter in practice. + const TsHeaderField pid = TsHeaderField(0x20, 8, 2, 0); + + // Indicates scrambling key. Unused; always 0. + const TsHeaderField scrambling_control = TsHeaderField(0, 2, 3, 6); + + // Adaptation field flag. Unused; always 0. + // TODO(tomfinegan): Not sure this is OK. Might need to add support for + // writing the Adaptation Field. + const TsHeaderField adaptation_field_flag = + TsHeaderField(has_adaptation ? 1 : 0, 1, 3, 5); + + // Payload flag. All output packets created here have payloads. Always 1. + const TsHeaderField payload_flag = TsHeaderField(1, 1, 3, 4); + + // Continuity counter. Two bit field that is incremented for every packet. + const TsHeaderField continuity_counter = + TsHeaderField(counter_value, 4, 3, 3); +}; + +void TsHeader::Write(PacketDataBuffer* buffer) const { + std::uint8_t* byte = &(*buffer)[0]; + *byte = sync_byte; + + *++byte = 0; + *byte |= transport_error_indicator.bits << transport_error_indicator.shift; + *byte |= payload_unit_start_indicator.bits + << payload_unit_start_indicator.shift; + *byte |= transport_priority.bits << transport_priority.shift; + + *++byte = pid.bits & 0xff; + + *++byte = 0; + *byte |= scrambling_control.bits << scrambling_control.shift; + *byte |= adaptation_field_flag.bits << adaptation_field_flag.shift; + *byte |= payload_flag.bits << payload_flag.shift; + *byte |= continuity_counter.bits; // last 4 bits. +} + +bool VpxPes2Ts::ConvertToFile() { + output_file_ = FilePtr(fopen(output_file_name_.c_str(), "wb"), FILEDeleter()); + if (output_file_ == nullptr) { + std::fprintf(stderr, "VpxPes2Ts: Cannot open %s for output.\n", + output_file_name_.c_str()); + return false; + } + pes_converter_.reset(new Webm2Pes(input_file_name_, this)); + if (pes_converter_ == nullptr) { + std::fprintf(stderr, "VpxPes2Ts: Out of memory.\n"); + return false; + } + return pes_converter_->ConvertToPacketReceiver(); +} + +bool VpxPes2Ts::ReceivePacket(const PacketDataBuffer& packet_data) { + const int kTsHeaderSize = 4; + const int kTsPayloadSize = 184; + const int kTsPacketSize = kTsHeaderSize + kTsPayloadSize; + int bytes_to_packetize = static_cast(packet_data.size()); + std::uint8_t continuity_counter = 0; + std::size_t read_pos = 0; + + ts_buffer_.reserve(kTsPacketSize); + + while (bytes_to_packetize > 0) { + if (continuity_counter > 0xf) + continuity_counter = 0; + + // Calculate payload size (need to know if we'll have to pad with an empty + // adaptation field). + int payload_size = std::min(bytes_to_packetize, kTsPayloadSize); + + // Write the TS header. + const TsHeader header( + bytes_to_packetize == static_cast(packet_data.size()), + payload_size != kTsPayloadSize, continuity_counter); + header.Write(&ts_buffer_); + int write_pos = kTsHeaderSize; + + // (pre)Pad payload with an empty adaptation field. All packets must be + // |kTsPacketSize| (188). + if (payload_size < kTsPayloadSize) { + // We need at least 2 bytes to write an empty adaptation field. + if (payload_size == (kTsPayloadSize - 1)) { + payload_size--; + } + + // Padding adaptation field: + // 8 bits: number of adaptation field bytes following this byte. + // 8 bits: unused (in this program) flags. + // This is followed by a run of 0xff to reach |kTsPayloadSize| (184) + // bytes. + const int pad_size = kTsPayloadSize - payload_size - 1 - 1; + ts_buffer_[write_pos++] = pad_size + 1; + ts_buffer_[write_pos++] = 0; + + const std::uint8_t kStuffingByte = 0xff; + for (int i = 0; i < pad_size; ++i) { + ts_buffer_[write_pos++] = kStuffingByte; + } + } + + for (int i = 0; i < payload_size; ++i) { + ts_buffer_[write_pos++] = packet_data[read_pos++]; + } + + bytes_to_packetize -= payload_size; + continuity_counter++; + + if (write_pos != kTsPacketSize) { + fprintf(stderr, "VpxPes2Ts: Invalid packet length.\n"); + return false; + } + + // Write contents of |ts_buffer_| to |output_file_|. + // TODO(tomfinegan): Writing 188 bytes at a time isn't exactly efficient... + // Fix me. + if (static_cast(std::fwrite(&ts_buffer_[0], 1, kTsPacketSize, + output_file_.get())) != kTsPacketSize) { + std::fprintf(stderr, "VpxPes2Ts: TS packet write failed.\n"); + return false; + } + } + + return true; +} + +} // namespace libwebm diff --git a/src/sys/libwebm/m2ts/vpxpes2ts.h b/src/sys/libwebm/m2ts/vpxpes2ts.h new file mode 100644 index 0000000..2609a1f --- /dev/null +++ b/src/sys/libwebm/m2ts/vpxpes2ts.h @@ -0,0 +1,45 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_M2TS_VPXPES2TS_H_ +#define LIBWEBM_M2TS_VPXPES2TS_H_ + +#include +#include + +#include "common/libwebm_util.h" +#include "m2ts/webm2pes.h" + +namespace libwebm { + +class VpxPes2Ts : public PacketReceiverInterface { + public: + VpxPes2Ts(const std::string& input_file_name, + const std::string& output_file_name) + : input_file_name_(input_file_name), + output_file_name_(output_file_name) {} + virtual ~VpxPes2Ts() = default; + VpxPes2Ts() = delete; + VpxPes2Ts(const VpxPes2Ts&) = delete; + VpxPes2Ts(VpxPes2Ts&&) = delete; + + bool ConvertToFile(); + + private: + bool ReceivePacket(const PacketDataBuffer& packet_data) override; + + const std::string input_file_name_; + const std::string output_file_name_; + + FilePtr output_file_; + std::unique_ptr pes_converter_; + PacketDataBuffer ts_buffer_; +}; + +} // namespace libwebm + +#endif // LIBWEBM_M2TS_VPXPES2TS_H_ diff --git a/src/sys/libwebm/m2ts/vpxpes2ts_main.cc b/src/sys/libwebm/m2ts/vpxpes2ts_main.cc new file mode 100644 index 0000000..435d805 --- /dev/null +++ b/src/sys/libwebm/m2ts/vpxpes2ts_main.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "m2ts/vpxpes2ts.h" + +#include +#include +#include + +namespace { + +void Usage(const char* argv[]) { + printf("Usage: %s ", argv[0]); +} + +} // namespace + +int main(int argc, const char* argv[]) { + if (argc < 3) { + Usage(argv); + return EXIT_FAILURE; + } + + const std::string input_path = argv[1]; + const std::string output_path = argv[2]; + + libwebm::VpxPes2Ts converter(input_path, output_path); + return converter.ConvertToFile() == true ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/sys/libwebm/m2ts/vpxpes_parser.cc b/src/sys/libwebm/m2ts/vpxpes_parser.cc new file mode 100644 index 0000000..4f6fe5c --- /dev/null +++ b/src/sys/libwebm/m2ts/vpxpes_parser.cc @@ -0,0 +1,409 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "vpxpes_parser.h" + +#include +#include +#include +#include +#include + +#include "common/file_util.h" + +namespace libwebm { + +VpxPesParser::BcmvHeader::BcmvHeader(std::uint32_t len) : length(len) { + id[0] = 'B'; + id[1] = 'C'; + id[2] = 'M'; + id[3] = 'V'; +} + +bool VpxPesParser::BcmvHeader::operator==(const BcmvHeader& other) const { + return (other.length == length && other.id[0] == id[0] && + other.id[1] == id[1] && other.id[2] == id[2] && other.id[3] == id[3]); +} + +bool VpxPesParser::BcmvHeader::Valid() const { + return (length > 0 && id[0] == 'B' && id[1] == 'C' && id[2] == 'M' && + id[3] == 'V'); +} + +// TODO(tomfinegan): Break Open() into separate functions. One that opens the +// file, and one that reads one packet at a time. As things are files larger +// than the maximum availble memory for the current process cannot be loaded. +bool VpxPesParser::Open(const std::string& pes_file) { + pes_file_size_ = static_cast(libwebm::GetFileSize(pes_file)); + if (pes_file_size_ <= 0) + return false; + pes_file_data_.reserve(static_cast(pes_file_size_)); + libwebm::FilePtr file = libwebm::FilePtr(std::fopen(pes_file.c_str(), "rb"), + libwebm::FILEDeleter()); + int byte; + while ((byte = fgetc(file.get())) != EOF) { + pes_file_data_.push_back(static_cast(byte)); + } + + if (!feof(file.get()) || ferror(file.get()) || + pes_file_size_ != pes_file_data_.size()) { + return false; + } + + read_pos_ = 0; + parse_state_ = kFindStartCode; + return true; +} + +bool VpxPesParser::VerifyPacketStartCode() const { + if (read_pos_ + 2 > pes_file_data_.size()) + return false; + + // PES packets all start with the byte sequence 0x0 0x0 0x1. + if (pes_file_data_[read_pos_] != 0 || pes_file_data_[read_pos_ + 1] != 0 || + pes_file_data_[read_pos_ + 2] != 1) { + return false; + } + + return true; +} + +bool VpxPesParser::ReadStreamId(std::uint8_t* stream_id) const { + if (!stream_id || BytesAvailable() < 4) + return false; + + *stream_id = pes_file_data_[read_pos_ + 3]; + return true; +} + +bool VpxPesParser::ReadPacketLength(std::uint16_t* packet_length) const { + if (!packet_length || BytesAvailable() < 6) + return false; + + // Read and byte swap 16 bit big endian length. + *packet_length = + (pes_file_data_[read_pos_ + 4] << 8) | pes_file_data_[read_pos_ + 5]; + + return true; +} + +bool VpxPesParser::ParsePesHeader(PesHeader* header) { + if (!header || parse_state_ != kParsePesHeader) + return false; + + if (!VerifyPacketStartCode()) + return false; + + std::size_t pos = read_pos_; + for (auto& a : header->start_code) { + a = pes_file_data_[pos++]; + } + + // PES Video stream IDs start at E0. + if (!ReadStreamId(&header->stream_id)) + return false; + + if (header->stream_id < kMinVideoStreamId || + header->stream_id > kMaxVideoStreamId) + return false; + + if (!ReadPacketLength(&header->packet_length)) + return false; + + read_pos_ += kPesHeaderSize; + parse_state_ = kParsePesOptionalHeader; + return true; +} + +// TODO(tomfinegan): Make these masks constants. +bool VpxPesParser::ParsePesOptionalHeader(PesOptionalHeader* header) { + if (!header || parse_state_ != kParsePesOptionalHeader || + read_pos_ >= pes_file_size_) { + return false; + } + + std::size_t consumed = 0; + PacketData poh_buffer; + if (!RemoveStartCodeEmulationPreventionBytes(&pes_file_data_[read_pos_], + kPesOptionalHeaderSize, + &poh_buffer, &consumed)) { + return false; + } + + std::size_t offset = 0; + header->marker = (poh_buffer[offset] & 0x80) >> 6; + header->scrambling = (poh_buffer[offset] & 0x30) >> 4; + header->priority = (poh_buffer[offset] & 0x8) >> 3; + header->data_alignment = (poh_buffer[offset] & 0xc) >> 2; + header->copyright = (poh_buffer[offset] & 0x2) >> 1; + header->original = poh_buffer[offset] & 0x1; + offset++; + + header->has_pts = (poh_buffer[offset] & 0x80) >> 7; + header->has_dts = (poh_buffer[offset] & 0x40) >> 6; + header->unused_fields = poh_buffer[offset] & 0x3f; + offset++; + + header->remaining_size = poh_buffer[offset]; + if (header->remaining_size != + static_cast(kWebm2PesOptHeaderRemainingSize)) + return false; + + size_t bytes_left = header->remaining_size; + offset++; + + if (header->has_pts) { + // Read PTS markers. Format: + // PTS: 5 bytes + // 4 bits (flag: PTS present, but no DTS): 0x2 ('0010') + // 36 bits (90khz PTS): + // top 3 bits + // marker ('1') + // middle 15 bits + // marker ('1') + // bottom 15 bits + // marker ('1') + // TODO(tomfinegan): read/store the timestamp. + header->pts_dts_flag = (poh_buffer[offset] & 0x20) >> 4; + // Check the marker bits. + if ((poh_buffer[offset + 0] & 1) != 1 || + (poh_buffer[offset + 2] & 1) != 1 || + (poh_buffer[offset + 4] & 1) != 1) { + return false; + } + + header->pts = (poh_buffer[offset] & 0xe) << 29 | + ((ReadUint16(&poh_buffer[offset + 1]) & ~1) << 14) | + (ReadUint16(&poh_buffer[offset + 3]) >> 1); + offset += 5; + bytes_left -= 5; + } + + // Validate stuffing byte(s). + for (size_t i = 0; i < bytes_left; ++i) { + if (poh_buffer[offset + i] != 0xff) + return false; + } + + read_pos_ += consumed; + parse_state_ = kParseBcmvHeader; + + return true; +} + +// Parses and validates a BCMV header. +bool VpxPesParser::ParseBcmvHeader(BcmvHeader* header) { + if (!header || parse_state_ != kParseBcmvHeader) + return false; + + PacketData bcmv_buffer; + std::size_t consumed = 0; + if (!RemoveStartCodeEmulationPreventionBytes(&pes_file_data_[read_pos_], + kBcmvHeaderSize, &bcmv_buffer, + &consumed)) { + return false; + } + + std::size_t offset = 0; + header->id[0] = bcmv_buffer[offset++]; + header->id[1] = bcmv_buffer[offset++]; + header->id[2] = bcmv_buffer[offset++]; + header->id[3] = bcmv_buffer[offset++]; + + header->length = 0; + header->length |= bcmv_buffer[offset++] << 24; + header->length |= bcmv_buffer[offset++] << 16; + header->length |= bcmv_buffer[offset++] << 8; + header->length |= bcmv_buffer[offset++]; + + // Length stored in the BCMV header is followed by 2 bytes of 0 padding. + if (bcmv_buffer[offset++] != 0 || bcmv_buffer[offset++] != 0) + return false; + + if (!header->Valid()) + return false; + + parse_state_ = kFindStartCode; + read_pos_ += consumed; + + return true; +} + +bool VpxPesParser::FindStartCode(std::size_t origin, + std::size_t* offset) const { + if (read_pos_ + 2 >= pes_file_size_) + return false; + + const std::size_t length = pes_file_size_ - origin; + if (length < 3) + return false; + + const uint8_t* const data = &pes_file_data_[origin]; + for (std::size_t i = 0; i < length - 3; ++i) { + if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 1) { + *offset = origin + i; + return true; + } + } + + return false; +} + +bool VpxPesParser::IsPayloadFragmented(const PesHeader& header) const { + return (header.packet_length != 0 && + (header.packet_length - kPesOptionalHeaderSize) != + header.bcmv_header.length); +} + +bool VpxPesParser::AccumulateFragmentedPayload(std::size_t pes_packet_length, + std::size_t payload_length) { + const std::size_t first_fragment_length = + pes_packet_length - kPesOptionalHeaderSize - kBcmvHeaderSize; + for (std::size_t i = 0; i < first_fragment_length; ++i) { + payload_.push_back(pes_file_data_[read_pos_ + i]); + } + read_pos_ += first_fragment_length; + parse_state_ = kFindStartCode; + + while (payload_.size() < payload_length) { + PesHeader header; + std::size_t packet_start_pos = read_pos_; + if (!FindStartCode(read_pos_, &packet_start_pos)) { + return false; + } + parse_state_ = kParsePesHeader; + read_pos_ = packet_start_pos; + + if (!ParsePesHeader(&header)) { + return false; + } + if (!ParsePesOptionalHeader(&header.opt_header)) { + return false; + } + + const std::size_t fragment_length = + header.packet_length - kPesOptionalHeaderSize; + std::size_t consumed = 0; + if (!RemoveStartCodeEmulationPreventionBytes(&pes_file_data_[read_pos_], + fragment_length, &payload_, + &consumed)) { + return false; + } + read_pos_ += consumed; + } + return true; +} + +bool VpxPesParser::RemoveStartCodeEmulationPreventionBytes( + const std::uint8_t* raw_data, std::size_t bytes_required, + PacketData* processed_data, std::size_t* bytes_consumed) const { + if (bytes_required == 0 || !processed_data) + return false; + + std::size_t num_zeros = 0; + std::size_t bytes_copied = 0; + const std::uint8_t* const end_of_input = + &pes_file_data_[0] + pes_file_data_.size(); + std::size_t i; + for (i = 0; bytes_copied < bytes_required; ++i) { + if (raw_data + i > end_of_input) + return false; + + bool skip = false; + + const std::uint8_t byte = raw_data[i]; + if (byte == 0) { + ++num_zeros; + } else if (byte == 0x3 && num_zeros == 2) { + skip = true; + num_zeros = 0; + } else { + num_zeros = 0; + } + + if (skip == false) { + processed_data->push_back(byte); + ++bytes_copied; + } + } + *bytes_consumed = i; + return true; +} + +int VpxPesParser::BytesAvailable() const { + return static_cast(pes_file_data_.size() - read_pos_); +} + +bool VpxPesParser::ParseNextPacket(PesHeader* header, VideoFrame* frame) { + if (!header || !frame || parse_state_ != kFindStartCode || + BytesAvailable() == 0) { + return false; + } + + std::size_t packet_start_pos = read_pos_; + if (!FindStartCode(read_pos_, &packet_start_pos)) { + return false; + } + parse_state_ = kParsePesHeader; + read_pos_ = packet_start_pos; + + if (!ParsePesHeader(header)) { + return false; + } + if (!ParsePesOptionalHeader(&header->opt_header)) { + return false; + } + if (!ParseBcmvHeader(&header->bcmv_header)) { + return false; + } + + // BCMV header length includes the length of the BCMVHeader itself. Adjust: + const std::size_t payload_length = + header->bcmv_header.length - BcmvHeader::size(); + + // Make sure there's enough input data to read the entire frame. + if (read_pos_ + payload_length > pes_file_data_.size()) { + // Need more data. + printf("VpxPesParser: Not enough data. Required: %u Available: %u\n", + static_cast(payload_length), + static_cast(pes_file_data_.size() - read_pos_)); + parse_state_ = kFindStartCode; + read_pos_ = packet_start_pos; + return false; + } + + if (IsPayloadFragmented(*header)) { + if (!AccumulateFragmentedPayload(header->packet_length, payload_length)) { + fprintf(stderr, "VpxPesParser: Failed parsing fragmented payload!\n"); + return false; + } + } else { + std::size_t consumed = 0; + if (!RemoveStartCodeEmulationPreventionBytes( + &pes_file_data_[read_pos_], payload_length, &payload_, &consumed)) { + return false; + } + read_pos_ += consumed; + } + + if (frame->buffer().capacity < payload_.size()) { + if (frame->Init(payload_.size()) == false) { + fprintf(stderr, "VpxPesParser: Out of memory.\n"); + return false; + } + } + frame->set_nanosecond_pts(Khz90TicksToNanoseconds(header->opt_header.pts)); + std::memcpy(frame->buffer().data.get(), &payload_[0], payload_.size()); + frame->SetBufferLength(payload_.size()); + + payload_.clear(); + parse_state_ = kFindStartCode; + + return true; +} + +} // namespace libwebm diff --git a/src/sys/libwebm/m2ts/vpxpes_parser.h b/src/sys/libwebm/m2ts/vpxpes_parser.h new file mode 100644 index 0000000..d18b4b7 --- /dev/null +++ b/src/sys/libwebm/m2ts/vpxpes_parser.h @@ -0,0 +1,177 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_M2TS_VPXPES_PARSER_H_ +#define LIBWEBM_M2TS_VPXPES_PARSER_H_ + +#include +#include +#include + +#include "common/libwebm_util.h" +#include "common/video_frame.h" + +namespace libwebm { + +// Parser for VPx PES. Requires that the _entire_ PES stream can be stored in +// a std::vector and read into memory when Open() is called. +// TODO(tomfinegan): Support incremental parse. +class VpxPesParser { + public: + typedef std::vector PesFileData; + typedef std::vector PacketData; + + enum ParseState { + kFindStartCode, + kParsePesHeader, + kParsePesOptionalHeader, + kParseBcmvHeader, + }; + + struct PesOptionalHeader { + int marker = 0; + int scrambling = 0; + int priority = 0; + int data_alignment = 0; + int copyright = 0; + int original = 0; + int has_pts = 0; + int has_dts = 0; + int unused_fields = 0; + int remaining_size = 0; + int pts_dts_flag = 0; + std::uint64_t pts = 0; + int stuffing_byte = 0; + }; + + struct BcmvHeader { + BcmvHeader() = default; + ~BcmvHeader() = default; + BcmvHeader(const BcmvHeader&) = delete; + BcmvHeader(BcmvHeader&&) = delete; + + // Convenience ctor for quick validation of expected values via operator== + // after parsing input. + explicit BcmvHeader(std::uint32_t len); + + bool operator==(const BcmvHeader& other) const; + + void Reset(); + bool Valid() const; + static std::size_t size() { return 10; } + + char id[4] = {0}; + std::uint32_t length = 0; + }; + + struct PesHeader { + std::uint8_t start_code[4] = {0}; + std::uint16_t packet_length = 0; + std::uint8_t stream_id = 0; + PesOptionalHeader opt_header; + BcmvHeader bcmv_header; + }; + + // Constants for validating known values from input data. + const std::uint8_t kMinVideoStreamId = 0xE0; + const std::uint8_t kMaxVideoStreamId = 0xEF; + const std::size_t kPesHeaderSize = 6; + const std::size_t kPesOptionalHeaderStartOffset = kPesHeaderSize; + const std::size_t kPesOptionalHeaderSize = 9; + const std::size_t kPesOptionalHeaderMarkerValue = 0x2; + const std::size_t kWebm2PesOptHeaderRemainingSize = 6; + const std::size_t kBcmvHeaderSize = 10; + + VpxPesParser() = default; + ~VpxPesParser() = default; + + // Opens file specified by |pes_file_path| and reads its contents. Returns + // true after successful read of input file. + bool Open(const std::string& pes_file_path); + + // Parses the next packet in the PES. PES header information is stored in + // |header|, and the frame payload is stored in |frame|. Returns true when + // a full frame has been consumed from the PES. + bool ParseNextPacket(PesHeader* header, VideoFrame* frame); + + // PES Header parsing utility functions. + // PES Header structure: + // Start code Stream ID Packet length (16 bits) + // / / ____/ + // | | / + // Byte0 Byte1 Byte2 Byte3 Byte4 Byte5 + // 0 0 1 X Y + bool VerifyPacketStartCode() const; + bool ReadStreamId(std::uint8_t* stream_id) const; + bool ReadPacketLength(std::uint16_t* packet_length) const; + + std::uint64_t pes_file_size() const { return pes_file_size_; } + const PesFileData& pes_file_data() const { return pes_file_data_; } + + // Returns number of unparsed bytes remaining. + int BytesAvailable() const; + + private: + // Parses and verifies the static 6 byte portion that begins every PES packet. + bool ParsePesHeader(PesHeader* header); + + // Parses a PES optional header, the optional header following the static + // header that begins the VPX PES packet. + // https://en.wikipedia.org/wiki/Packetized_elementary_stream + bool ParsePesOptionalHeader(PesOptionalHeader* header); + + // Parses and validates the BCMV header. This immediately follows the optional + // header. + bool ParseBcmvHeader(BcmvHeader* header); + + // Returns true when a start code is found and sets |offset| to the position + // of the start code relative to |pes_file_data_[read_pos_]|. + // Does not set |offset| value if the end of |pes_file_data_| is reached + // without locating a start code. + // Note: A start code is the byte sequence 0x00 0x00 0x01. + bool FindStartCode(std::size_t origin, std::size_t* offset) const; + + // Returns true when a PES packet containing a BCMV header contains only a + // portion of the frame payload length reported by the BCMV header. + bool IsPayloadFragmented(const PesHeader& header) const; + + // Parses PES and PES Optional header while accumulating payload data in + // |payload_|. + // Returns true once all payload fragments have been stored in |payload_|. + // Returns false if unable to accumulate full payload. + bool AccumulateFragmentedPayload(std::size_t pes_packet_length, + std::size_t payload_length); + + // The byte sequence 0x0 0x0 0x1 is a start code in PES. When PES muxers + // encounter 0x0 0x0 0x1 or 0x0 0x0 0x3, an additional 0x3 is inserted into + // the PES. The following change occurs: + // 0x0 0x0 0x1 => 0x0 0x0 0x3 0x1 + // 0x0 0x0 0x3 => 0x0 0x0 0x3 0x3 + // PES demuxers must reverse the change: + // 0x0 0x0 0x3 0x1 => 0x0 0x0 0x1 + // 0x0 0x0 0x3 0x3 => 0x0 0x0 0x3 + // PES optional header, BCMV header, and payload data must be preprocessed to + // avoid potentially invalid data due to the presence of inserted bytes. + // + // Removes start code emulation prevention bytes while copying data from + // |raw_data| to |processed_data|. Returns true when |bytes_required| bytes + // have been written to |processed_data|. Reports bytes consumed during the + // operation via |bytes_consumed|. + bool RemoveStartCodeEmulationPreventionBytes( + const std::uint8_t* raw_data, std::size_t bytes_required, + PacketData* processed_data, std::size_t* bytes_consumed) const; + + std::size_t pes_file_size_ = 0; + PacketData payload_; + PesFileData pes_file_data_; + std::size_t read_pos_ = 0; + ParseState parse_state_ = kFindStartCode; +}; + +} // namespace libwebm + +#endif // LIBWEBM_M2TS_VPXPES_PARSER_H_ diff --git a/src/sys/libwebm/m2ts/webm2pes.cc b/src/sys/libwebm/m2ts/webm2pes.cc new file mode 100644 index 0000000..a4169c0 --- /dev/null +++ b/src/sys/libwebm/m2ts/webm2pes.cc @@ -0,0 +1,552 @@ +// Copyright (c) 2015 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "m2ts/webm2pes.h" + +#include +#include +#include +#include +#include +#include + +#include "common/libwebm_util.h" + +namespace libwebm { + +const std::size_t Webm2Pes::kMaxPayloadSize = 32768; + +namespace { + +std::string ToString(const char* str) { + return std::string((str == nullptr) ? "" : str); +} + +} // namespace + +// +// PesOptionalHeader methods. +// + +void PesOptionalHeader::SetPtsBits(std::int64_t pts_90khz) { + // PTS is broken up and stored in 40 bits as shown: + // + // PES PTS Only flag + // / Marker Marker Marker + // | / / / + // | | | | + // 7654 321 0 765432107654321 0 765432107654321 0 + // 0010 PTS 32-30 1 PTS 29-15 1 PTS 14-0 1 + const std::uint32_t pts1 = (pts_90khz >> 30) & 0x7; + const std::uint32_t pts2 = (pts_90khz >> 15) & 0x7FFF; + const std::uint32_t pts3 = pts_90khz & 0x7FFF; + + pts.bits = 0; + + // bottom 7 bits of second PTS chunk. + pts.bits |= (pts3 << 1) & 0xff; + // Marker. + pts.bits |= 1; + + // Last 15 bits of pts and 1 bit marker. + // Top 8 bits of second PTS chunk. + pts.bits <<= 8; + pts.bits |= (pts3 >> 7) & 0xff; + + // bottom 7 bits of second PTS chunk. + pts.bits <<= 8; + pts.bits |= (pts2 << 1); + // Marker. + pts.bits |= 1; + + // Next 15 bits of pts and 1 bit marker. + // Top 8 bits of second PTS chunk. + pts.bits <<= 8; + pts.bits |= (pts2 >> 7) & 0xff; + + // PTS only flag. + pts.bits <<= 8; + pts.bits |= 1 << 5; + // Top 3 bits of PTS and 1 bit marker. + pts.bits |= pts1 << 1; + // Marker. + pts.bits |= 1; +} + +// Writes fields to |buffer| and returns true. Returns false when write or +// field value validation fails. +bool PesOptionalHeader::Write(bool write_pts, PacketDataBuffer* buffer) const { + if (buffer == nullptr) { + std::fprintf(stderr, "Webm2Pes: nullptr in opt header writer.\n"); + return false; + } + + const int kHeaderSize = 9; + std::uint8_t header[kHeaderSize] = {0}; + std::uint8_t* byte = header; + + if (marker.Check() != true || scrambling.Check() != true || + priority.Check() != true || data_alignment.Check() != true || + copyright.Check() != true || original.Check() != true || + has_pts.Check() != true || has_dts.Check() != true || + pts.Check() != true || stuffing_byte.Check() != true) { + std::fprintf(stderr, "Webm2Pes: Invalid PES Optional Header field.\n"); + return false; + } + + // TODO(tomfinegan): As noted in above, the PesHeaderFields should be an + // array (or some data structure) that can be iterated over. + + // First byte of header, fields: marker, scrambling, priority, alignment, + // copyright, original. + *byte = 0; + *byte |= marker.bits << marker.shift; + *byte |= scrambling.bits << scrambling.shift; + *byte |= priority.bits << priority.shift; + *byte |= data_alignment.bits << data_alignment.shift; + *byte |= copyright.bits << copyright.shift; + *byte |= original.bits << original.shift; + + // Second byte of header, fields: has_pts, has_dts, unused fields. + *++byte = 0; + if (write_pts == true) + *byte |= has_pts.bits << has_pts.shift; + + *byte |= has_dts.bits << has_dts.shift; + + // Third byte of header, fields: remaining size of header. + *++byte = remaining_size.bits & 0xff; // Field is 8 bits wide. + + int num_stuffing_bytes = + (pts.num_bits + 7) / 8 + 1 /* always 1 stuffing byte */; + if (write_pts == true) { + // Write the PTS value as big endian and adjust stuffing byte count + // accordingly. + *++byte = pts.bits & 0xff; + *++byte = (pts.bits >> 8) & 0xff; + *++byte = (pts.bits >> 16) & 0xff; + *++byte = (pts.bits >> 24) & 0xff; + *++byte = (pts.bits >> 32) & 0xff; + num_stuffing_bytes = 1; + } + + // Add the stuffing byte(s). + for (int i = 0; i < num_stuffing_bytes; ++i) + *++byte = stuffing_byte.bits & 0xff; + + return CopyAndEscapeStartCodes(&header[0], kHeaderSize, buffer); +} + +// +// BCMVHeader methods. +// + +bool BCMVHeader::Write(PacketDataBuffer* buffer) const { + if (buffer == nullptr) { + std::fprintf(stderr, "Webm2Pes: nullptr for buffer in BCMV Write.\n"); + return false; + } + const int kBcmvSize = 4; + for (int i = 0; i < kBcmvSize; ++i) + buffer->push_back(bcmv[i]); + + // Note: The 4 byte length field must include the size of the BCMV header. + const int kRemainingBytes = 6; + const uint32_t bcmv_total_length = length + static_cast(size()); + const uint8_t bcmv_buffer[kRemainingBytes] = { + static_cast((bcmv_total_length >> 24) & 0xff), + static_cast((bcmv_total_length >> 16) & 0xff), + static_cast((bcmv_total_length >> 8) & 0xff), + static_cast(bcmv_total_length & 0xff), + 0, + 0 /* 2 bytes 0 padding */}; + + return CopyAndEscapeStartCodes(bcmv_buffer, kRemainingBytes, buffer); +} + +// +// PesHeader methods. +// + +// Writes out the header to |buffer|. Calls PesOptionalHeader::Write() to write +// |optional_header| contents. Returns true when successful, false otherwise. +bool PesHeader::Write(bool write_pts, PacketDataBuffer* buffer) const { + if (buffer == nullptr) { + std::fprintf(stderr, "Webm2Pes: nullptr in header writer.\n"); + return false; + } + + // Write |start_code|. + const int kStartCodeLength = 4; + for (int i = 0; i < kStartCodeLength; ++i) + buffer->push_back(start_code[i]); + + // The length field here reports number of bytes following the field. The + // length of the optional header must be added to the payload length set by + // the user. + const std::size_t header_length = + packet_length + optional_header.size_in_bytes(); + if (header_length > UINT16_MAX) + return false; + + // Write |header_length| as big endian. + std::uint8_t byte = (header_length >> 8) & 0xff; + buffer->push_back(byte); + byte = header_length & 0xff; + buffer->push_back(byte); + + // Write the (not really) optional header. + if (optional_header.Write(write_pts, buffer) != true) { + std::fprintf(stderr, "Webm2Pes: PES optional header write failed."); + return false; + } + return true; +} + +// +// Webm2Pes methods. +// + +bool Webm2Pes::ConvertToFile() { + if (input_file_name_.empty() || output_file_name_.empty()) { + std::fprintf(stderr, "Webm2Pes: input and/or output file name(s) empty.\n"); + return false; + } + + output_file_ = FilePtr(fopen(output_file_name_.c_str(), "wb"), FILEDeleter()); + if (output_file_ == nullptr) { + std::fprintf(stderr, "Webm2Pes: Cannot open %s for output.\n", + output_file_name_.c_str()); + return false; + } + + if (InitWebmParser() != true) { + std::fprintf(stderr, "Webm2Pes: Cannot initialize WebM parser.\n"); + return false; + } + + // Walk clusters in segment. + const mkvparser::Cluster* cluster = webm_parser_->GetFirst(); + while (cluster != nullptr && cluster->EOS() == false) { + const mkvparser::BlockEntry* block_entry = nullptr; + std::int64_t block_status = cluster->GetFirst(block_entry); + if (block_status < 0) { + std::fprintf(stderr, "Webm2Pes: Cannot parse first block in %s.\n", + input_file_name_.c_str()); + return false; + } + + // Walk blocks in cluster. + while (block_entry != nullptr && block_entry->EOS() == false) { + const mkvparser::Block* block = block_entry->GetBlock(); + if (block->GetTrackNumber() == video_track_num_) { + const int frame_count = block->GetFrameCount(); + + // Walk frames in block. + for (int frame_num = 0; frame_num < frame_count; ++frame_num) { + const mkvparser::Block::Frame& mkvparser_frame = + block->GetFrame(frame_num); + + // Read the frame. + VideoFrame vpx_frame(block->GetTime(cluster), codec_); + if (ReadVideoFrame(mkvparser_frame, &vpx_frame) == false) { + fprintf(stderr, "Webm2Pes: frame read failed.\n"); + return false; + } + + // Write frame out as PES packet(s). + if (WritePesPacket(vpx_frame, &packet_data_) == false) { + std::fprintf(stderr, "Webm2Pes: WritePesPacket failed.\n"); + return false; + } + + // Write contents of |packet_data_| to |output_file_|. + if (std::fwrite(&packet_data_[0], 1, packet_data_.size(), + output_file_.get()) != packet_data_.size()) { + std::fprintf(stderr, "Webm2Pes: packet payload write failed.\n"); + return false; + } + bytes_written_ += packet_data_.size(); + } + } + block_status = cluster->GetNext(block_entry, block_entry); + if (block_status < 0) { + std::fprintf(stderr, "Webm2Pes: Cannot parse block in %s.\n", + input_file_name_.c_str()); + return false; + } + } + + cluster = webm_parser_->GetNext(cluster); + } + + std::fflush(output_file_.get()); + return true; +} + +bool Webm2Pes::ConvertToPacketReceiver() { + if (input_file_name_.empty() || packet_sink_ == nullptr) { + std::fprintf(stderr, "Webm2Pes: input file name empty or null sink.\n"); + return false; + } + + if (InitWebmParser() != true) { + std::fprintf(stderr, "Webm2Pes: Cannot initialize WebM parser.\n"); + return false; + } + + // Walk clusters in segment. + const mkvparser::Cluster* cluster = webm_parser_->GetFirst(); + while (cluster != nullptr && cluster->EOS() == false) { + const mkvparser::BlockEntry* block_entry = nullptr; + std::int64_t block_status = cluster->GetFirst(block_entry); + if (block_status < 0) { + std::fprintf(stderr, "Webm2Pes: Cannot parse first block in %s.\n", + input_file_name_.c_str()); + return false; + } + + // Walk blocks in cluster. + while (block_entry != nullptr && block_entry->EOS() == false) { + const mkvparser::Block* block = block_entry->GetBlock(); + if (block->GetTrackNumber() == video_track_num_) { + const int frame_count = block->GetFrameCount(); + + // Walk frames in block. + for (int frame_num = 0; frame_num < frame_count; ++frame_num) { + const mkvparser::Block::Frame& mkvparser_frame = + block->GetFrame(frame_num); + + // Read the frame. + VideoFrame frame(block->GetTime(cluster), codec_); + if (ReadVideoFrame(mkvparser_frame, &frame) == false) { + fprintf(stderr, "Webm2Pes: frame read failed.\n"); + return false; + } + + // Write frame out as PES packet(s). + if (WritePesPacket(frame, &packet_data_) == false) { + std::fprintf(stderr, "Webm2Pes: WritePesPacket failed.\n"); + return false; + } + if (packet_sink_->ReceivePacket(packet_data_) != true) { + std::fprintf(stderr, "Webm2Pes: ReceivePacket failed.\n"); + return false; + } + bytes_written_ += packet_data_.size(); + } + } + block_status = cluster->GetNext(block_entry, block_entry); + if (block_status < 0) { + std::fprintf(stderr, "Webm2Pes: Cannot parse block in %s.\n", + input_file_name_.c_str()); + return false; + } + } + + cluster = webm_parser_->GetNext(cluster); + } + + return true; +} + +bool Webm2Pes::InitWebmParser() { + if (webm_reader_.Open(input_file_name_.c_str()) != 0) { + std::fprintf(stderr, "Webm2Pes: Cannot open %s as input.\n", + input_file_name_.c_str()); + return false; + } + + using mkvparser::Segment; + Segment* webm_parser = nullptr; + if (Segment::CreateInstance(&webm_reader_, 0 /* pos */, + webm_parser /* Segment*& */) != 0) { + std::fprintf(stderr, "Webm2Pes: Cannot create WebM parser.\n"); + return false; + } + webm_parser_.reset(webm_parser); + + if (webm_parser_->Load() != 0) { + std::fprintf(stderr, "Webm2Pes: Cannot parse %s.\n", + input_file_name_.c_str()); + return false; + } + + // Make sure there's a video track. + const mkvparser::Tracks* tracks = webm_parser_->GetTracks(); + if (tracks == nullptr) { + std::fprintf(stderr, "Webm2Pes: %s has no tracks.\n", + input_file_name_.c_str()); + return false; + } + + timecode_scale_ = webm_parser_->GetInfo()->GetTimeCodeScale(); + + for (int track_index = 0; + track_index < static_cast(tracks->GetTracksCount()); + ++track_index) { + const mkvparser::Track* track = tracks->GetTrackByIndex(track_index); + if (track && track->GetType() == mkvparser::Track::kVideo) { + const std::string codec_id = ToString(track->GetCodecId()); + if (codec_id == std::string("V_VP8")) { + codec_ = VideoFrame::kVP8; + } else if (codec_id == std::string("V_VP9")) { + codec_ = VideoFrame::kVP9; + } else { + fprintf(stderr, "Webm2Pes: Codec must be VP8 or VP9.\n"); + return false; + } + video_track_num_ = track_index + 1; + break; + } + } + if (video_track_num_ < 1) { + std::fprintf(stderr, "Webm2Pes: No video track found in %s.\n", + input_file_name_.c_str()); + return false; + } + return true; +} + +bool Webm2Pes::ReadVideoFrame(const mkvparser::Block::Frame& mkvparser_frame, + VideoFrame* frame) { + if (mkvparser_frame.len < 1 || frame == nullptr) + return false; + + const std::size_t mkv_len = static_cast(mkvparser_frame.len); + if (mkv_len > frame->buffer().capacity) { + const std::size_t new_size = 2 * mkv_len; + if (frame->Init(new_size) == false) { + std::fprintf(stderr, "Webm2Pes: Out of memory.\n"); + return false; + } + } + if (mkvparser_frame.Read(&webm_reader_, frame->buffer().data.get()) != 0) { + std::fprintf(stderr, "Webm2Pes: Error reading VPx frame!\n"); + return false; + } + return frame->SetBufferLength(mkv_len); +} + +bool Webm2Pes::WritePesPacket(const VideoFrame& frame, + PacketDataBuffer* packet_data) { + if (frame.buffer().data.get() == nullptr || frame.buffer().length < 1) + return false; + + Ranges frame_ranges; + if (frame.codec() == VideoFrame::kVP9) { + bool error = false; + const bool has_superframe_index = + ParseVP9SuperFrameIndex(frame.buffer().data.get(), + frame.buffer().length, &frame_ranges, &error); + if (error) { + std::fprintf(stderr, "Webm2Pes: Superframe index parse failed.\n"); + return false; + } + if (has_superframe_index == false) { + frame_ranges.push_back(Range(0, frame.buffer().length)); + } + } else { + frame_ranges.push_back(Range(0, frame.buffer().length)); + } + + const std::int64_t khz90_pts = + NanosecondsTo90KhzTicks(frame.nanosecond_pts()); + PesHeader header; + header.optional_header.SetPtsBits(khz90_pts); + + packet_data->clear(); + + for (const Range& packet_payload_range : frame_ranges) { + std::size_t extra_bytes = 0; + if (packet_payload_range.length > kMaxPayloadSize) { + extra_bytes = packet_payload_range.length - kMaxPayloadSize; + } + if (packet_payload_range.length + packet_payload_range.offset > + frame.buffer().length) { + std::fprintf(stderr, "Webm2Pes: Invalid frame length.\n"); + return false; + } + + // First packet of new frame. Always include PTS and BCMV header. + header.packet_length = + packet_payload_range.length - extra_bytes + BCMVHeader::size(); + if (header.Write(true, packet_data) != true) { + std::fprintf(stderr, "Webm2Pes: packet header write failed.\n"); + return false; + } + + BCMVHeader bcmv_header(static_cast(packet_payload_range.length)); + if (bcmv_header.Write(packet_data) != true) { + std::fprintf(stderr, "Webm2Pes: BCMV write failed.\n"); + return false; + } + + // Insert the payload at the end of |packet_data|. + const std::uint8_t* const payload_start = + frame.buffer().data.get() + packet_payload_range.offset; + + const std::size_t bytes_to_copy = packet_payload_range.length - extra_bytes; + if (CopyAndEscapeStartCodes(payload_start, bytes_to_copy, packet_data) == + false) { + fprintf(stderr, "Webm2Pes: Payload write failed.\n"); + return false; + } + + std::size_t bytes_copied = bytes_to_copy; + while (extra_bytes) { + // Write PES packets for the remaining data, but omit the PTS and BCMV + // header. + const std::size_t extra_bytes_to_copy = + std::min(kMaxPayloadSize, extra_bytes); + extra_bytes -= extra_bytes_to_copy; + header.packet_length = extra_bytes_to_copy; + if (header.Write(false, packet_data) != true) { + fprintf(stderr, "Webm2pes: fragment write failed.\n"); + return false; + } + + const std::uint8_t* fragment_start = payload_start + bytes_copied; + if (CopyAndEscapeStartCodes(fragment_start, extra_bytes_to_copy, + packet_data) == false) { + fprintf(stderr, "Webm2Pes: Payload write failed.\n"); + return false; + } + + bytes_copied += extra_bytes_to_copy; + } + } + + return true; +} + +bool CopyAndEscapeStartCodes(const std::uint8_t* raw_input, + std::size_t raw_input_length, + PacketDataBuffer* packet_buffer) { + if (raw_input == nullptr || raw_input_length < 1 || packet_buffer == nullptr) + return false; + + int num_zeros = 0; + for (std::size_t i = 0; i < raw_input_length; ++i) { + const uint8_t byte = raw_input[i]; + + if (byte == 0) { + ++num_zeros; + } else if (num_zeros >= 2 && (byte == 0x1 || byte == 0x3)) { + packet_buffer->push_back(0x3); + num_zeros = 0; + } else { + num_zeros = 0; + } + + packet_buffer->push_back(byte); + } + + return true; +} + +} // namespace libwebm diff --git a/src/sys/libwebm/m2ts/webm2pes.h b/src/sys/libwebm/m2ts/webm2pes.h new file mode 100644 index 0000000..6dcb0fd --- /dev/null +++ b/src/sys/libwebm/m2ts/webm2pes.h @@ -0,0 +1,274 @@ +// Copyright (c) 2015 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_M2TS_WEBM2PES_H_ +#define LIBWEBM_M2TS_WEBM2PES_H_ + +#include +#include +#include +#include +#include + +#include "common/libwebm_util.h" +#include "common/video_frame.h" +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" + +// Webm2pes +// +// Webm2pes consumes a WebM file containing a VP8 or VP9 video stream and +// outputs a PES stream suitable for inclusion in a MPEG2 Transport Stream. +// +// In the simplest case the PES stream output by Webm2pes consists of a sequence +// of PES packets with the following structure: +// | PES Header w/PTS | BCMV Header | Payload (VPx frame) | +// +// More typically the output will look like the following due to the PES +// payload size limitations caused by the format of the PES header. +// The PES header contains only 2 bytes of storage for expressing payload size. +// VPx PES streams containing fragmented packets look like this: +// +// | PH PTS | BCMV | Payload fragment 1 | PH | Payload fragment 2 | ... +// +// PH = PES Header +// PH PTS = PES Header with PTS +// BCMV = BCMV Header +// +// Note that start codes are properly escaped by Webm2pes, and start code +// emulation prevention bytes must be stripped from the output stream before +// it can be parsed. + +namespace libwebm { + +// Stores a value and its size in bits for writing into a PES Optional Header. +// Maximum size is 64 bits. Users may call the Check() method to perform minimal +// validation (size > 0 and <= 64). +struct PesHeaderField { + PesHeaderField(std::uint64_t value, std::uint32_t size_in_bits, + std::uint8_t byte_index, std::uint8_t bits_to_shift) + : bits(value), + num_bits(size_in_bits), + index(byte_index), + shift(bits_to_shift) {} + PesHeaderField() = delete; + PesHeaderField(const PesHeaderField&) = default; + PesHeaderField(PesHeaderField&&) = default; + ~PesHeaderField() = default; + bool Check() const { + return num_bits > 0 && num_bits <= 64 && shift >= 0 && shift < 64; + } + + // Value to be stored in the field. + std::uint64_t bits; + + // Number of bits in the value. + const int num_bits; + + // Index into the header for the byte in which |bits| will be written. + const std::uint8_t index; + + // Number of bits to shift value before or'ing. + const int shift; +}; + +// Data is stored in buffers before being written to output files. +typedef std::vector PacketDataBuffer; + +// Storage for PES Optional Header values. Fields written in order using sizes +// specified. +struct PesOptionalHeader { + // TODO(tomfinegan): The fields could be in an array, which would allow the + // code writing the optional header to iterate over the fields instead of + // having code for dealing with each one. + + // 2 bits (marker): 2 ('10') + const PesHeaderField marker = PesHeaderField(2, 2, 0, 6); + + // 2 bits (no scrambling): 0x0 ('00') + const PesHeaderField scrambling = PesHeaderField(0, 2, 0, 4); + + // 1 bit (priority): 0x0 ('0') + const PesHeaderField priority = PesHeaderField(0, 1, 0, 3); + + // TODO(tomfinegan): The BCMV header could be considered a sync word, and this + // field should be 1 when a sync word follows the packet. Clarify. + // 1 bit (data alignment): 0x0 ('0') + const PesHeaderField data_alignment = PesHeaderField(0, 1, 0, 2); + + // 1 bit (copyright): 0x0 ('0') + const PesHeaderField copyright = PesHeaderField(0, 1, 0, 1); + + // 1 bit (original/copy): 0x0 ('0') + const PesHeaderField original = PesHeaderField(0, 1, 0, 0); + + // 1 bit (has_pts): 0x1 ('1') + const PesHeaderField has_pts = PesHeaderField(1, 1, 1, 7); + + // 1 bit (has_dts): 0x0 ('0') + const PesHeaderField has_dts = PesHeaderField(0, 1, 1, 6); + + // 6 bits (unused fields): 0x0 ('000000') + const PesHeaderField unused = PesHeaderField(0, 6, 1, 0); + + // 8 bits (size of remaining data in the Header). + const PesHeaderField remaining_size = PesHeaderField(6, 8, 2, 0); + + // PTS: 5 bytes + // 4 bits (flag: PTS present, but no DTS): 0x2 ('0010') + // 36 bits (90khz PTS): + // top 3 bits + // marker ('1') + // middle 15 bits + // marker ('1') + // bottom 15 bits + // marker ('1') + PesHeaderField pts = PesHeaderField(0, 40, 3, 0); + + PesHeaderField stuffing_byte = PesHeaderField(0xFF, 8, 8, 0); + + // PTS omitted in fragments. Size remains unchanged: More stuffing bytes. + bool fragment = false; + + static std::size_t size_in_bytes() { return 9; } + + // Writes |pts_90khz| to |pts| per format described at its declaration above. + void SetPtsBits(std::int64_t pts_90khz); + + // Writes fields to |buffer| and returns true. Returns false when write or + // field value validation fails. + bool Write(bool write_pts, PacketDataBuffer* buffer) const; +}; + +// Describes custom 10 byte header that immediately follows the PES Optional +// Header in each PES packet output by Webm2Pes: +// 4 byte 'B' 'C' 'M' 'V' +// 4 byte big-endian length of frame +// 2 bytes 0 padding +struct BCMVHeader { + explicit BCMVHeader(std::uint32_t frame_length) : length(frame_length) {} + BCMVHeader() = delete; + BCMVHeader(const BCMVHeader&) = delete; + BCMVHeader(BCMVHeader&&) = delete; + ~BCMVHeader() = default; + const std::uint8_t bcmv[4] = {'B', 'C', 'M', 'V'}; + const std::uint32_t length; + + static std::size_t size() { return 10; } + + // Write the BCMV Header into |buffer|. Caller responsible for ensuring + // destination buffer is of size >= BCMVHeader::size(). + bool Write(PacketDataBuffer* buffer) const; + bool Write(uint8_t* buffer); +}; + +struct PesHeader { + const std::uint8_t start_code[4] = { + 0x00, 0x00, + 0x01, // 0x000001 is the PES packet start code prefix. + 0xE0}; // 0xE0 is the minimum video stream ID. + std::uint16_t packet_length = 0; // Number of bytes _after_ this field. + PesOptionalHeader optional_header; + std::size_t size() const { + return optional_header.size_in_bytes() + + 6 /* start_code + packet_length */ + packet_length; + } + + // Writes out the header to |buffer|. Calls PesOptionalHeader::Write() to + // write |optional_header| contents. Returns true when successful, false + // otherwise. + bool Write(bool write_pts, PacketDataBuffer* buffer) const; +}; + +class PacketReceiverInterface { + public: + virtual ~PacketReceiverInterface() {} + virtual bool ReceivePacket(const PacketDataBuffer& packet) = 0; +}; + +// Converts the VP9 track of a WebM file to a Packetized Elementary Stream +// suitable for use in a MPEG2TS. +// https://en.wikipedia.org/wiki/Packetized_elementary_stream +// https://en.wikipedia.org/wiki/MPEG_transport_stream +class Webm2Pes { + public: + static const std::size_t kMaxPayloadSize; + + Webm2Pes(const std::string& input_file, const std::string& output_file) + : input_file_name_(input_file), output_file_name_(output_file) {} + Webm2Pes(const std::string& input_file, PacketReceiverInterface* packet_sink) + : input_file_name_(input_file), packet_sink_(packet_sink) {} + + Webm2Pes() = delete; + Webm2Pes(const Webm2Pes&) = delete; + Webm2Pes(Webm2Pes&&) = delete; + ~Webm2Pes() = default; + + // Converts the VPx video stream to a PES file and returns true. Returns false + // to report failure. + bool ConvertToFile(); + + // Converts the VPx video stream to a sequence of PES packets, and calls the + // PacketReceiverInterface::ReceivePacket() once for each VPx frame. The + // packet sent to the receiver may contain multiple PES packets. Returns only + // after full conversion or error. Returns true for success, and false when + // an error occurs. + bool ConvertToPacketReceiver(); + + // Writes |vpx_frame| out as PES packet[s] and stores output in |packet_data|. + // Returns true for success, false for failure. + static bool WritePesPacket(const VideoFrame& frame, + PacketDataBuffer* packet_data); + + uint64_t bytes_written() const { return bytes_written_; } + + private: + bool InitWebmParser(); + bool ReadVideoFrame(const mkvparser::Block::Frame& mkvparser_frame, + VideoFrame* frame); + + const std::string input_file_name_; + const std::string output_file_name_; + std::unique_ptr webm_parser_; + mkvparser::MkvReader webm_reader_; + FilePtr output_file_; + + // Video track num in the WebM file. + int video_track_num_ = 0; + + // Video codec reported by CodecName from Video TrackEntry. + VideoFrame::Codec codec_; + + // Input timecode scale. + std::int64_t timecode_scale_ = 1000000; + + // Packet sink; when constructed with a PacketReceiverInterface*, packet and + // type of packet are sent to |packet_sink_| instead of written to an output + // file. + PacketReceiverInterface* packet_sink_ = nullptr; + + PacketDataBuffer packet_data_; + + std::uint64_t bytes_written_ = 0; +}; + +// Copies |raw_input_length| bytes from |raw_input| to |packet_buffer| while +// escaping start codes. Returns true when bytes are successfully copied. +// A start code is the 3 byte sequence 0x00 0x00 0x01. When +// the sequence is encountered, the value 0x03 is inserted. To avoid +// any ambiguity at reassembly time, the same is done for the sequence +// 0x00 0x00 0x03. So, the following transformation occurs for when either +// of the noted sequences is encountered: +// +// 0x00 0x00 0x01 => 0x00 0x00 0x03 0x01 +// 0x00 0x00 0x03 => 0x00 0x00 0x03 0x03 +bool CopyAndEscapeStartCodes(const std::uint8_t* raw_input, + std::size_t raw_input_length, + PacketDataBuffer* packet_buffer); +} // namespace libwebm + +#endif // LIBWEBM_M2TS_WEBM2PES_H_ diff --git a/src/sys/libwebm/m2ts/webm2pes_main.cc b/src/sys/libwebm/m2ts/webm2pes_main.cc new file mode 100644 index 0000000..075e55c --- /dev/null +++ b/src/sys/libwebm/m2ts/webm2pes_main.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2015 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "m2ts/webm2pes.h" + +#include +#include +#include + +namespace { + +void Usage(const char* argv[]) { + printf("Usage: %s ", argv[0]); +} + +} // namespace + +int main(int argc, const char* argv[]) { + if (argc < 3) { + Usage(argv); + return EXIT_FAILURE; + } + + const std::string input_path = argv[1]; + const std::string output_path = argv[2]; + + libwebm::Webm2Pes converter(input_path, output_path); + return converter.ConvertToFile() == true ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/sys/libwebm/mkvmuxer.hpp b/src/sys/libwebm/mkvmuxer.hpp new file mode 100644 index 0000000..092592b --- /dev/null +++ b/src/sys/libwebm/mkvmuxer.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_MKVMUXER_HPP_ +#define LIBWEBM_MKVMUXER_HPP_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "mkvmuxer/mkvmuxer.h" + +#endif // LIBWEBM_MKVMUXER_HPP_ diff --git a/src/sys/libwebm/mkvmuxer/mkvmuxer.cc b/src/sys/libwebm/mkvmuxer/mkvmuxer.cc new file mode 100644 index 0000000..21e51be --- /dev/null +++ b/src/sys/libwebm/mkvmuxer/mkvmuxer.cc @@ -0,0 +1,4204 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#include "mkvmuxer/mkvmuxer.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/webmids.h" +#include "mkvmuxer/mkvmuxerutil.h" +#include "mkvmuxer/mkvwriter.h" +#include "mkvparser/mkvparser.h" + +namespace mkvmuxer { + +const float PrimaryChromaticity::kChromaticityMin = 0.0f; +const float PrimaryChromaticity::kChromaticityMax = 1.0f; +const float MasteringMetadata::kMinLuminance = 0.0f; +const float MasteringMetadata::kMinLuminanceMax = 999.99f; +const float MasteringMetadata::kMaxLuminanceMax = 9999.99f; +const float MasteringMetadata::kValueNotPresent = FLT_MAX; +const uint64_t Colour::kValueNotPresent = UINT64_MAX; + +namespace { + +const char kDocTypeWebm[] = "webm"; +const char kDocTypeMatroska[] = "matroska"; + +// Deallocate the string designated by |dst|, and then copy the |src| +// string to |dst|. The caller owns both the |src| string and the +// |dst| copy (hence the caller is responsible for eventually +// deallocating the strings, either directly, or indirectly via +// StrCpy). Returns true if the source string was successfully copied +// to the destination. +bool StrCpy(const char* src, char** dst_ptr) { + if (dst_ptr == NULL) + return false; + + char*& dst = *dst_ptr; + + delete[] dst; + dst = NULL; + + if (src == NULL) + return true; + + const size_t size = strlen(src) + 1; + + dst = new (std::nothrow) char[size]; // NOLINT + if (dst == NULL) + return false; + + memcpy(dst, src, size - 1); + dst[size - 1] = '\0'; + return true; +} + +typedef std::unique_ptr PrimaryChromaticityPtr; +bool CopyChromaticity(const PrimaryChromaticity* src, + PrimaryChromaticityPtr* dst) { + if (!dst) + return false; + + dst->reset(new (std::nothrow) PrimaryChromaticity(src->x(), src->y())); + if (!dst->get()) + return false; + + return true; +} + +} // namespace + +/////////////////////////////////////////////////////////////// +// +// IMkvWriter Class + +IMkvWriter::IMkvWriter() {} + +IMkvWriter::~IMkvWriter() {} + +bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version, + const char* const doc_type) { + // Level 0 + uint64_t size = + EbmlElementSize(libwebm::kMkvEBMLVersion, static_cast(1)); + size += EbmlElementSize(libwebm::kMkvEBMLReadVersion, static_cast(1)); + size += EbmlElementSize(libwebm::kMkvEBMLMaxIDLength, static_cast(4)); + size += + EbmlElementSize(libwebm::kMkvEBMLMaxSizeLength, static_cast(8)); + size += EbmlElementSize(libwebm::kMkvDocType, doc_type); + size += EbmlElementSize(libwebm::kMkvDocTypeVersion, + static_cast(doc_type_version)); + size += + EbmlElementSize(libwebm::kMkvDocTypeReadVersion, static_cast(2)); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvEBML, size)) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvEBMLVersion, + static_cast(1))) { + return false; + } + if (!WriteEbmlElement(writer, libwebm::kMkvEBMLReadVersion, + static_cast(1))) { + return false; + } + if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxIDLength, + static_cast(4))) { + return false; + } + if (!WriteEbmlElement(writer, libwebm::kMkvEBMLMaxSizeLength, + static_cast(8))) { + return false; + } + if (!WriteEbmlElement(writer, libwebm::kMkvDocType, doc_type)) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeVersion, + static_cast(doc_type_version))) { + return false; + } + if (!WriteEbmlElement(writer, libwebm::kMkvDocTypeReadVersion, + static_cast(2))) { + return false; + } + + return true; +} + +bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version) { + return WriteEbmlHeader(writer, doc_type_version, kDocTypeWebm); +} + +bool WriteEbmlHeader(IMkvWriter* writer) { + return WriteEbmlHeader(writer, mkvmuxer::Segment::kDefaultDocTypeVersion); +} + +bool ChunkedCopy(mkvparser::IMkvReader* source, mkvmuxer::IMkvWriter* dst, + int64_t start, int64_t size) { + // TODO(vigneshv): Check if this is a reasonable value. + const uint32_t kBufSize = 2048; + uint8_t* buf = new uint8_t[kBufSize]; + int64_t offset = start; + while (size > 0) { + const int64_t read_len = (size > kBufSize) ? kBufSize : size; + if (source->Read(offset, static_cast(read_len), buf)) + return false; + dst->Write(buf, static_cast(read_len)); + offset += read_len; + size -= read_len; + } + delete[] buf; + return true; +} + +/////////////////////////////////////////////////////////////// +// +// Frame Class + +Frame::Frame() + : add_id_(0), + additional_(NULL), + additional_length_(0), + duration_(0), + duration_set_(false), + frame_(NULL), + is_key_(false), + length_(0), + track_number_(0), + timestamp_(0), + discard_padding_(0), + reference_block_timestamp_(0), + reference_block_timestamp_set_(false) {} + +Frame::~Frame() { + delete[] frame_; + delete[] additional_; +} + +bool Frame::CopyFrom(const Frame& frame) { + delete[] frame_; + frame_ = NULL; + length_ = 0; + if (frame.length() > 0 && frame.frame() != NULL && + !Init(frame.frame(), frame.length())) { + return false; + } + add_id_ = 0; + delete[] additional_; + additional_ = NULL; + additional_length_ = 0; + if (frame.additional_length() > 0 && frame.additional() != NULL && + !AddAdditionalData(frame.additional(), frame.additional_length(), + frame.add_id())) { + return false; + } + duration_ = frame.duration(); + duration_set_ = frame.duration_set(); + is_key_ = frame.is_key(); + track_number_ = frame.track_number(); + timestamp_ = frame.timestamp(); + discard_padding_ = frame.discard_padding(); + reference_block_timestamp_ = frame.reference_block_timestamp(); + reference_block_timestamp_set_ = frame.reference_block_timestamp_set(); + return true; +} + +bool Frame::Init(const uint8_t* frame, uint64_t length) { + uint8_t* const data = + new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT + if (!data) + return false; + + delete[] frame_; + frame_ = data; + length_ = length; + + memcpy(frame_, frame, static_cast(length_)); + return true; +} + +bool Frame::AddAdditionalData(const uint8_t* additional, uint64_t length, + uint64_t add_id) { + uint8_t* const data = + new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT + if (!data) + return false; + + delete[] additional_; + additional_ = data; + additional_length_ = length; + add_id_ = add_id; + + memcpy(additional_, additional, static_cast(additional_length_)); + return true; +} + +bool Frame::IsValid() const { + if (length_ == 0 || !frame_) { + return false; + } + if ((additional_length_ != 0 && !additional_) || + (additional_ != NULL && additional_length_ == 0)) { + return false; + } + if (track_number_ == 0 || track_number_ > kMaxTrackNumber) { + return false; + } + if (!CanBeSimpleBlock() && !is_key_ && !reference_block_timestamp_set_) { + return false; + } + return true; +} + +bool Frame::CanBeSimpleBlock() const { + return additional_ == NULL && discard_padding_ == 0 && duration_ == 0; +} + +void Frame::set_duration(uint64_t duration) { + duration_ = duration; + duration_set_ = true; +} + +void Frame::set_reference_block_timestamp(int64_t reference_block_timestamp) { + reference_block_timestamp_ = reference_block_timestamp; + reference_block_timestamp_set_ = true; +} + +/////////////////////////////////////////////////////////////// +// +// CuePoint Class + +CuePoint::CuePoint() + : time_(0), + track_(0), + cluster_pos_(0), + block_number_(1), + output_block_number_(true) {} + +CuePoint::~CuePoint() {} + +bool CuePoint::Write(IMkvWriter* writer) const { + if (!writer || track_ < 1 || cluster_pos_ < 1) + return false; + + uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition, + static_cast(cluster_pos_)); + size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast(track_)); + if (output_block_number_ && block_number_ > 1) + size += EbmlElementSize(libwebm::kMkvCueBlockNumber, + static_cast(block_number_)); + const uint64_t track_pos_size = + EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size; + const uint64_t payload_size = + EbmlElementSize(libwebm::kMkvCueTime, static_cast(time_)) + + track_pos_size; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvCuePoint, payload_size)) + return false; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvCueTime, + static_cast(time_))) { + return false; + } + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvCueTrackPositions, size)) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvCueTrack, + static_cast(track_))) { + return false; + } + if (!WriteEbmlElement(writer, libwebm::kMkvCueClusterPosition, + static_cast(cluster_pos_))) { + return false; + } + if (output_block_number_ && block_number_ > 1) { + if (!WriteEbmlElement(writer, libwebm::kMkvCueBlockNumber, + static_cast(block_number_))) { + return false; + } + } + + const int64_t stop_position = writer->Position(); + if (stop_position < 0) + return false; + + if (stop_position - payload_position != static_cast(payload_size)) + return false; + + return true; +} + +uint64_t CuePoint::PayloadSize() const { + uint64_t size = EbmlElementSize(libwebm::kMkvCueClusterPosition, + static_cast(cluster_pos_)); + size += EbmlElementSize(libwebm::kMkvCueTrack, static_cast(track_)); + if (output_block_number_ && block_number_ > 1) + size += EbmlElementSize(libwebm::kMkvCueBlockNumber, + static_cast(block_number_)); + const uint64_t track_pos_size = + EbmlMasterElementSize(libwebm::kMkvCueTrackPositions, size) + size; + const uint64_t payload_size = + EbmlElementSize(libwebm::kMkvCueTime, static_cast(time_)) + + track_pos_size; + + return payload_size; +} + +uint64_t CuePoint::Size() const { + const uint64_t payload_size = PayloadSize(); + return EbmlMasterElementSize(libwebm::kMkvCuePoint, payload_size) + + payload_size; +} + +/////////////////////////////////////////////////////////////// +// +// Cues Class + +Cues::Cues() + : cue_entries_capacity_(0), + cue_entries_size_(0), + cue_entries_(NULL), + output_block_number_(true) {} + +Cues::~Cues() { + if (cue_entries_) { + for (int32_t i = 0; i < cue_entries_size_; ++i) { + CuePoint* const cue = cue_entries_[i]; + delete cue; + } + delete[] cue_entries_; + } +} + +bool Cues::AddCue(CuePoint* cue) { + if (!cue) + return false; + + if ((cue_entries_size_ + 1) > cue_entries_capacity_) { + // Add more CuePoints. + const int32_t new_capacity = + (!cue_entries_capacity_) ? 2 : cue_entries_capacity_ * 2; + + if (new_capacity < 1) + return false; + + CuePoint** const cues = + new (std::nothrow) CuePoint*[new_capacity]; // NOLINT + if (!cues) + return false; + + for (int32_t i = 0; i < cue_entries_size_; ++i) { + cues[i] = cue_entries_[i]; + } + + delete[] cue_entries_; + + cue_entries_ = cues; + cue_entries_capacity_ = new_capacity; + } + + cue->set_output_block_number(output_block_number_); + cue_entries_[cue_entries_size_++] = cue; + return true; +} + +CuePoint* Cues::GetCueByIndex(int32_t index) const { + if (cue_entries_ == NULL) + return NULL; + + if (index >= cue_entries_size_) + return NULL; + + return cue_entries_[index]; +} + +uint64_t Cues::Size() { + uint64_t size = 0; + for (int32_t i = 0; i < cue_entries_size_; ++i) + size += GetCueByIndex(i)->Size(); + size += EbmlMasterElementSize(libwebm::kMkvCues, size); + return size; +} + +bool Cues::Write(IMkvWriter* writer) const { + if (!writer) + return false; + + uint64_t size = 0; + for (int32_t i = 0; i < cue_entries_size_; ++i) { + const CuePoint* const cue = GetCueByIndex(i); + + if (!cue) + return false; + + size += cue->Size(); + } + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvCues, size)) + return false; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + for (int32_t i = 0; i < cue_entries_size_; ++i) { + const CuePoint* const cue = GetCueByIndex(i); + + if (!cue->Write(writer)) + return false; + } + + const int64_t stop_position = writer->Position(); + if (stop_position < 0) + return false; + + if (stop_position - payload_position != static_cast(size)) + return false; + + return true; +} + +/////////////////////////////////////////////////////////////// +// +// ContentEncAESSettings Class + +ContentEncAESSettings::ContentEncAESSettings() : cipher_mode_(kCTR) {} + +uint64_t ContentEncAESSettings::Size() const { + const uint64_t payload = PayloadSize(); + const uint64_t size = + EbmlMasterElementSize(libwebm::kMkvContentEncAESSettings, payload) + + payload; + return size; +} + +bool ContentEncAESSettings::Write(IMkvWriter* writer) const { + const uint64_t payload = PayloadSize(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncAESSettings, + payload)) + return false; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvAESSettingsCipherMode, + static_cast(cipher_mode_))) { + return false; + } + + const int64_t stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(payload)) + return false; + + return true; +} + +uint64_t ContentEncAESSettings::PayloadSize() const { + uint64_t size = EbmlElementSize(libwebm::kMkvAESSettingsCipherMode, + static_cast(cipher_mode_)); + return size; +} + +/////////////////////////////////////////////////////////////// +// +// ContentEncoding Class + +ContentEncoding::ContentEncoding() + : enc_algo_(5), + enc_key_id_(NULL), + encoding_order_(0), + encoding_scope_(1), + encoding_type_(1), + enc_key_id_length_(0) {} + +ContentEncoding::~ContentEncoding() { delete[] enc_key_id_; } + +bool ContentEncoding::SetEncryptionID(const uint8_t* id, uint64_t length) { + if (!id || length < 1) + return false; + + delete[] enc_key_id_; + + enc_key_id_ = + new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT + if (!enc_key_id_) + return false; + + memcpy(enc_key_id_, id, static_cast(length)); + enc_key_id_length_ = length; + + return true; +} + +uint64_t ContentEncoding::Size() const { + const uint64_t encryption_size = EncryptionSize(); + const uint64_t encoding_size = EncodingSize(0, encryption_size); + const uint64_t encodings_size = + EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) + + encoding_size; + + return encodings_size; +} + +bool ContentEncoding::Write(IMkvWriter* writer) const { + const uint64_t encryption_size = EncryptionSize(); + const uint64_t encoding_size = EncodingSize(0, encryption_size); + const uint64_t size = + EbmlMasterElementSize(libwebm::kMkvContentEncoding, encoding_size) + + encoding_size; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncoding, + encoding_size)) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingOrder, + static_cast(encoding_order_))) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingScope, + static_cast(encoding_scope_))) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvContentEncodingType, + static_cast(encoding_type_))) + return false; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncryption, + encryption_size)) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvContentEncAlgo, + static_cast(enc_algo_))) { + return false; + } + if (!WriteEbmlElement(writer, libwebm::kMkvContentEncKeyID, enc_key_id_, + enc_key_id_length_)) + return false; + + if (!enc_aes_settings_.Write(writer)) + return false; + + const int64_t stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(size)) + return false; + + return true; +} + +uint64_t ContentEncoding::EncodingSize(uint64_t compression_size, + uint64_t encryption_size) const { + // TODO(fgalligan): Add support for compression settings. + if (compression_size != 0) + return 0; + + uint64_t encoding_size = 0; + + if (encryption_size > 0) { + encoding_size += + EbmlMasterElementSize(libwebm::kMkvContentEncryption, encryption_size) + + encryption_size; + } + encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingType, + static_cast(encoding_type_)); + encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingScope, + static_cast(encoding_scope_)); + encoding_size += EbmlElementSize(libwebm::kMkvContentEncodingOrder, + static_cast(encoding_order_)); + + return encoding_size; +} + +uint64_t ContentEncoding::EncryptionSize() const { + const uint64_t aes_size = enc_aes_settings_.Size(); + + uint64_t encryption_size = EbmlElementSize(libwebm::kMkvContentEncKeyID, + enc_key_id_, enc_key_id_length_); + encryption_size += EbmlElementSize(libwebm::kMkvContentEncAlgo, + static_cast(enc_algo_)); + + return encryption_size + aes_size; +} + +/////////////////////////////////////////////////////////////// +// +// Track Class + +Track::Track(unsigned int* seed) + : codec_id_(NULL), + codec_private_(NULL), + language_(NULL), + max_block_additional_id_(0), + name_(NULL), + number_(0), + type_(0), + uid_(MakeUID(seed)), + codec_delay_(0), + seek_pre_roll_(0), + default_duration_(0), + codec_private_length_(0), + content_encoding_entries_(NULL), + content_encoding_entries_size_(0) {} + +Track::~Track() { + delete[] codec_id_; + delete[] codec_private_; + delete[] language_; + delete[] name_; + + if (content_encoding_entries_) { + for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { + ContentEncoding* const encoding = content_encoding_entries_[i]; + delete encoding; + } + delete[] content_encoding_entries_; + } +} + +bool Track::AddContentEncoding() { + const uint32_t count = content_encoding_entries_size_ + 1; + + ContentEncoding** const content_encoding_entries = + new (std::nothrow) ContentEncoding*[count]; // NOLINT + if (!content_encoding_entries) + return false; + + ContentEncoding* const content_encoding = + new (std::nothrow) ContentEncoding(); // NOLINT + if (!content_encoding) { + delete[] content_encoding_entries; + return false; + } + + for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { + content_encoding_entries[i] = content_encoding_entries_[i]; + } + + delete[] content_encoding_entries_; + + content_encoding_entries_ = content_encoding_entries; + content_encoding_entries_[content_encoding_entries_size_] = content_encoding; + content_encoding_entries_size_ = count; + return true; +} + +ContentEncoding* Track::GetContentEncodingByIndex(uint32_t index) const { + if (content_encoding_entries_ == NULL) + return NULL; + + if (index >= content_encoding_entries_size_) + return NULL; + + return content_encoding_entries_[index]; +} + +uint64_t Track::PayloadSize() const { + uint64_t size = + EbmlElementSize(libwebm::kMkvTrackNumber, static_cast(number_)); + size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast(uid_)); + size += EbmlElementSize(libwebm::kMkvTrackType, static_cast(type_)); + if (codec_id_) + size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_); + if (codec_private_) + size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_, + codec_private_length_); + if (language_) + size += EbmlElementSize(libwebm::kMkvLanguage, language_); + if (name_) + size += EbmlElementSize(libwebm::kMkvName, name_); + if (max_block_additional_id_) { + size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID, + static_cast(max_block_additional_id_)); + } + if (codec_delay_) { + size += EbmlElementSize(libwebm::kMkvCodecDelay, + static_cast(codec_delay_)); + } + if (seek_pre_roll_) { + size += EbmlElementSize(libwebm::kMkvSeekPreRoll, + static_cast(seek_pre_roll_)); + } + if (default_duration_) { + size += EbmlElementSize(libwebm::kMkvDefaultDuration, + static_cast(default_duration_)); + } + + if (content_encoding_entries_size_ > 0) { + uint64_t content_encodings_size = 0; + for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { + ContentEncoding* const encoding = content_encoding_entries_[i]; + content_encodings_size += encoding->Size(); + } + + size += EbmlMasterElementSize(libwebm::kMkvContentEncodings, + content_encodings_size) + + content_encodings_size; + } + + return size; +} + +uint64_t Track::Size() const { + uint64_t size = PayloadSize(); + size += EbmlMasterElementSize(libwebm::kMkvTrackEntry, size); + return size; +} + +bool Track::Write(IMkvWriter* writer) const { + if (!writer) + return false; + + // mandatory elements without a default value. + if (!type_ || !codec_id_) + return false; + + // AV1 tracks require a CodecPrivate. See + // https://github.com/ietf-wg-cellar/matroska-specification/blob/HEAD/codec/av1.md + // TODO(tomfinegan): Update the above link to the AV1 Matroska mappings to + // point to a stable version once it is finalized, or our own WebM mappings + // page on webmproject.org should we decide to release them. + if (!strcmp(codec_id_, Tracks::kAv1CodecId) && !codec_private_) + return false; + + // |size| may be bigger than what is written out in this function because + // derived classes may write out more data in the Track element. + const uint64_t payload_size = PayloadSize(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvTrackEntry, payload_size)) + return false; + + uint64_t size = + EbmlElementSize(libwebm::kMkvTrackNumber, static_cast(number_)); + size += EbmlElementSize(libwebm::kMkvTrackUID, static_cast(uid_)); + size += EbmlElementSize(libwebm::kMkvTrackType, static_cast(type_)); + if (codec_id_) + size += EbmlElementSize(libwebm::kMkvCodecID, codec_id_); + if (codec_private_) + size += EbmlElementSize(libwebm::kMkvCodecPrivate, codec_private_, + static_cast(codec_private_length_)); + if (language_) + size += EbmlElementSize(libwebm::kMkvLanguage, language_); + if (name_) + size += EbmlElementSize(libwebm::kMkvName, name_); + if (max_block_additional_id_) + size += EbmlElementSize(libwebm::kMkvMaxBlockAdditionID, + static_cast(max_block_additional_id_)); + if (codec_delay_) + size += EbmlElementSize(libwebm::kMkvCodecDelay, + static_cast(codec_delay_)); + if (seek_pre_roll_) + size += EbmlElementSize(libwebm::kMkvSeekPreRoll, + static_cast(seek_pre_roll_)); + if (default_duration_) + size += EbmlElementSize(libwebm::kMkvDefaultDuration, + static_cast(default_duration_)); + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvTrackNumber, + static_cast(number_))) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvTrackUID, + static_cast(uid_))) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvTrackType, + static_cast(type_))) + return false; + if (max_block_additional_id_) { + if (!WriteEbmlElement(writer, libwebm::kMkvMaxBlockAdditionID, + static_cast(max_block_additional_id_))) { + return false; + } + } + if (codec_delay_) { + if (!WriteEbmlElement(writer, libwebm::kMkvCodecDelay, + static_cast(codec_delay_))) + return false; + } + if (seek_pre_roll_) { + if (!WriteEbmlElement(writer, libwebm::kMkvSeekPreRoll, + static_cast(seek_pre_roll_))) + return false; + } + if (default_duration_) { + if (!WriteEbmlElement(writer, libwebm::kMkvDefaultDuration, + static_cast(default_duration_))) + return false; + } + if (codec_id_) { + if (!WriteEbmlElement(writer, libwebm::kMkvCodecID, codec_id_)) + return false; + } + if (codec_private_) { + if (!WriteEbmlElement(writer, libwebm::kMkvCodecPrivate, codec_private_, + static_cast(codec_private_length_))) + return false; + } + if (language_) { + if (!WriteEbmlElement(writer, libwebm::kMkvLanguage, language_)) + return false; + } + if (name_) { + if (!WriteEbmlElement(writer, libwebm::kMkvName, name_)) + return false; + } + + int64_t stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(size)) + return false; + + if (content_encoding_entries_size_ > 0) { + uint64_t content_encodings_size = 0; + for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { + ContentEncoding* const encoding = content_encoding_entries_[i]; + content_encodings_size += encoding->Size(); + } + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvContentEncodings, + content_encodings_size)) + return false; + + for (uint32_t i = 0; i < content_encoding_entries_size_; ++i) { + ContentEncoding* const encoding = content_encoding_entries_[i]; + if (!encoding->Write(writer)) + return false; + } + } + + stop_position = writer->Position(); + if (stop_position < 0) + return false; + return true; +} + +bool Track::SetCodecPrivate(const uint8_t* codec_private, uint64_t length) { + if (!codec_private || length < 1) + return false; + + delete[] codec_private_; + + codec_private_ = + new (std::nothrow) uint8_t[static_cast(length)]; // NOLINT + if (!codec_private_) + return false; + + memcpy(codec_private_, codec_private, static_cast(length)); + codec_private_length_ = length; + + return true; +} + +void Track::set_codec_id(const char* codec_id) { + if (codec_id) { + delete[] codec_id_; + + const size_t length = strlen(codec_id) + 1; + codec_id_ = new (std::nothrow) char[length]; // NOLINT + if (codec_id_) { + memcpy(codec_id_, codec_id, length - 1); + codec_id_[length - 1] = '\0'; + } + } +} + +// TODO(fgalligan): Vet the language parameter. +void Track::set_language(const char* language) { + if (language) { + delete[] language_; + + const size_t length = strlen(language) + 1; + language_ = new (std::nothrow) char[length]; // NOLINT + if (language_) { + memcpy(language_, language, length - 1); + language_[length - 1] = '\0'; + } + } +} + +void Track::set_name(const char* name) { + if (name) { + delete[] name_; + + const size_t length = strlen(name) + 1; + name_ = new (std::nothrow) char[length]; // NOLINT + if (name_) { + memcpy(name_, name, length - 1); + name_[length - 1] = '\0'; + } + } +} + +/////////////////////////////////////////////////////////////// +// +// Colour and its child elements + +uint64_t PrimaryChromaticity::PrimaryChromaticitySize( + libwebm::MkvId x_id, libwebm::MkvId y_id) const { + return EbmlElementSize(x_id, x_) + EbmlElementSize(y_id, y_); +} + +bool PrimaryChromaticity::Write(IMkvWriter* writer, libwebm::MkvId x_id, + libwebm::MkvId y_id) const { + if (!Valid()) { + return false; + } + return WriteEbmlElement(writer, x_id, x_) && + WriteEbmlElement(writer, y_id, y_); +} + +bool PrimaryChromaticity::Valid() const { + return (x_ >= kChromaticityMin && x_ <= kChromaticityMax && + y_ >= kChromaticityMin && y_ <= kChromaticityMax); +} + +uint64_t MasteringMetadata::MasteringMetadataSize() const { + uint64_t size = PayloadSize(); + + if (size > 0) + size += EbmlMasterElementSize(libwebm::kMkvMasteringMetadata, size); + + return size; +} + +bool MasteringMetadata::Valid() const { + if (luminance_min_ != kValueNotPresent) { + if (luminance_min_ < kMinLuminance || luminance_min_ > kMinLuminanceMax || + luminance_min_ > luminance_max_) { + return false; + } + } + if (luminance_max_ != kValueNotPresent) { + if (luminance_max_ < kMinLuminance || luminance_max_ > kMaxLuminanceMax || + luminance_max_ < luminance_min_) { + return false; + } + } + if (r_ && !r_->Valid()) + return false; + if (g_ && !g_->Valid()) + return false; + if (b_ && !b_->Valid()) + return false; + if (white_point_ && !white_point_->Valid()) + return false; + + return true; +} + +bool MasteringMetadata::Write(IMkvWriter* writer) const { + const uint64_t size = PayloadSize(); + + // Don't write an empty element. + if (size == 0) + return true; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvMasteringMetadata, size)) + return false; + if (luminance_max_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvLuminanceMax, luminance_max_)) { + return false; + } + if (luminance_min_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvLuminanceMin, luminance_min_)) { + return false; + } + if (r_ && !r_->Write(writer, libwebm::kMkvPrimaryRChromaticityX, + libwebm::kMkvPrimaryRChromaticityY)) { + return false; + } + if (g_ && !g_->Write(writer, libwebm::kMkvPrimaryGChromaticityX, + libwebm::kMkvPrimaryGChromaticityY)) { + return false; + } + if (b_ && !b_->Write(writer, libwebm::kMkvPrimaryBChromaticityX, + libwebm::kMkvPrimaryBChromaticityY)) { + return false; + } + if (white_point_ && + !white_point_->Write(writer, libwebm::kMkvWhitePointChromaticityX, + libwebm::kMkvWhitePointChromaticityY)) { + return false; + } + + return true; +} + +bool MasteringMetadata::SetChromaticity( + const PrimaryChromaticity* r, const PrimaryChromaticity* g, + const PrimaryChromaticity* b, const PrimaryChromaticity* white_point) { + PrimaryChromaticityPtr r_ptr(nullptr); + if (r) { + if (!CopyChromaticity(r, &r_ptr)) + return false; + } + PrimaryChromaticityPtr g_ptr(nullptr); + if (g) { + if (!CopyChromaticity(g, &g_ptr)) + return false; + } + PrimaryChromaticityPtr b_ptr(nullptr); + if (b) { + if (!CopyChromaticity(b, &b_ptr)) + return false; + } + PrimaryChromaticityPtr wp_ptr(nullptr); + if (white_point) { + if (!CopyChromaticity(white_point, &wp_ptr)) + return false; + } + + r_ = r_ptr.release(); + g_ = g_ptr.release(); + b_ = b_ptr.release(); + white_point_ = wp_ptr.release(); + return true; +} + +uint64_t MasteringMetadata::PayloadSize() const { + uint64_t size = 0; + + if (luminance_max_ != kValueNotPresent) + size += EbmlElementSize(libwebm::kMkvLuminanceMax, luminance_max_); + if (luminance_min_ != kValueNotPresent) + size += EbmlElementSize(libwebm::kMkvLuminanceMin, luminance_min_); + + if (r_) { + size += r_->PrimaryChromaticitySize(libwebm::kMkvPrimaryRChromaticityX, + libwebm::kMkvPrimaryRChromaticityY); + } + if (g_) { + size += g_->PrimaryChromaticitySize(libwebm::kMkvPrimaryGChromaticityX, + libwebm::kMkvPrimaryGChromaticityY); + } + if (b_) { + size += b_->PrimaryChromaticitySize(libwebm::kMkvPrimaryBChromaticityX, + libwebm::kMkvPrimaryBChromaticityY); + } + if (white_point_) { + size += white_point_->PrimaryChromaticitySize( + libwebm::kMkvWhitePointChromaticityX, + libwebm::kMkvWhitePointChromaticityY); + } + + return size; +} + +uint64_t Colour::ColourSize() const { + uint64_t size = PayloadSize(); + + if (size > 0) + size += EbmlMasterElementSize(libwebm::kMkvColour, size); + + return size; +} + +bool Colour::Valid() const { + if (mastering_metadata_ && !mastering_metadata_->Valid()) + return false; + if (matrix_coefficients_ != kValueNotPresent && + !IsMatrixCoefficientsValueValid(matrix_coefficients_)) { + return false; + } + if (chroma_siting_horz_ != kValueNotPresent && + !IsChromaSitingHorzValueValid(chroma_siting_horz_)) { + return false; + } + if (chroma_siting_vert_ != kValueNotPresent && + !IsChromaSitingVertValueValid(chroma_siting_vert_)) { + return false; + } + if (range_ != kValueNotPresent && !IsColourRangeValueValid(range_)) + return false; + if (transfer_characteristics_ != kValueNotPresent && + !IsTransferCharacteristicsValueValid(transfer_characteristics_)) { + return false; + } + if (primaries_ != kValueNotPresent && !IsPrimariesValueValid(primaries_)) + return false; + + return true; +} + +bool Colour::Write(IMkvWriter* writer) const { + const uint64_t size = PayloadSize(); + + // Don't write an empty element. + if (size == 0) + return true; + + // Don't write an invalid element. + if (!Valid()) + return false; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvColour, size)) + return false; + + if (matrix_coefficients_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvMatrixCoefficients, + static_cast(matrix_coefficients_))) { + return false; + } + if (bits_per_channel_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvBitsPerChannel, + static_cast(bits_per_channel_))) { + return false; + } + if (chroma_subsampling_horz_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingHorz, + static_cast(chroma_subsampling_horz_))) { + return false; + } + if (chroma_subsampling_vert_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvChromaSubsamplingVert, + static_cast(chroma_subsampling_vert_))) { + return false; + } + + if (cb_subsampling_horz_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingHorz, + static_cast(cb_subsampling_horz_))) { + return false; + } + if (cb_subsampling_vert_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvCbSubsamplingVert, + static_cast(cb_subsampling_vert_))) { + return false; + } + if (chroma_siting_horz_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvChromaSitingHorz, + static_cast(chroma_siting_horz_))) { + return false; + } + if (chroma_siting_vert_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvChromaSitingVert, + static_cast(chroma_siting_vert_))) { + return false; + } + if (range_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvRange, + static_cast(range_))) { + return false; + } + if (transfer_characteristics_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvTransferCharacteristics, + static_cast(transfer_characteristics_))) { + return false; + } + if (primaries_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvPrimaries, + static_cast(primaries_))) { + return false; + } + if (max_cll_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvMaxCLL, + static_cast(max_cll_))) { + return false; + } + if (max_fall_ != kValueNotPresent && + !WriteEbmlElement(writer, libwebm::kMkvMaxFALL, + static_cast(max_fall_))) { + return false; + } + + if (mastering_metadata_ && !mastering_metadata_->Write(writer)) + return false; + + return true; +} + +bool Colour::SetMasteringMetadata(const MasteringMetadata& mastering_metadata) { + std::unique_ptr mm_ptr(new MasteringMetadata()); + if (!mm_ptr.get()) + return false; + + mm_ptr->set_luminance_max(mastering_metadata.luminance_max()); + mm_ptr->set_luminance_min(mastering_metadata.luminance_min()); + + if (!mm_ptr->SetChromaticity(mastering_metadata.r(), mastering_metadata.g(), + mastering_metadata.b(), + mastering_metadata.white_point())) { + return false; + } + + delete mastering_metadata_; + mastering_metadata_ = mm_ptr.release(); + return true; +} + +uint64_t Colour::PayloadSize() const { + uint64_t size = 0; + + if (matrix_coefficients_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvMatrixCoefficients, + static_cast(matrix_coefficients_)); + } + if (bits_per_channel_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvBitsPerChannel, + static_cast(bits_per_channel_)); + } + if (chroma_subsampling_horz_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvChromaSubsamplingHorz, + static_cast(chroma_subsampling_horz_)); + } + if (chroma_subsampling_vert_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvChromaSubsamplingVert, + static_cast(chroma_subsampling_vert_)); + } + if (cb_subsampling_horz_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvCbSubsamplingHorz, + static_cast(cb_subsampling_horz_)); + } + if (cb_subsampling_vert_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvCbSubsamplingVert, + static_cast(cb_subsampling_vert_)); + } + if (chroma_siting_horz_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvChromaSitingHorz, + static_cast(chroma_siting_horz_)); + } + if (chroma_siting_vert_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvChromaSitingVert, + static_cast(chroma_siting_vert_)); + } + if (range_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvRange, static_cast(range_)); + } + if (transfer_characteristics_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvTransferCharacteristics, + static_cast(transfer_characteristics_)); + } + if (primaries_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvPrimaries, + static_cast(primaries_)); + } + if (max_cll_ != kValueNotPresent) { + size += EbmlElementSize(libwebm::kMkvMaxCLL, static_cast(max_cll_)); + } + if (max_fall_ != kValueNotPresent) { + size += + EbmlElementSize(libwebm::kMkvMaxFALL, static_cast(max_fall_)); + } + + if (mastering_metadata_) + size += mastering_metadata_->MasteringMetadataSize(); + + return size; +} + +/////////////////////////////////////////////////////////////// +// +// Projection element + +uint64_t Projection::ProjectionSize() const { + uint64_t size = PayloadSize(); + + if (size > 0) + size += EbmlMasterElementSize(libwebm::kMkvProjection, size); + + return size; +} + +bool Projection::Write(IMkvWriter* writer) const { + const uint64_t size = PayloadSize(); + + // Don't write an empty element. + if (size == 0) + return true; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvProjection, size)) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvProjectionType, + static_cast(type_))) { + return false; + } + + if (private_data_length_ > 0 && private_data_ != NULL && + !WriteEbmlElement(writer, libwebm::kMkvProjectionPrivate, private_data_, + private_data_length_)) { + return false; + } + + if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseYaw, pose_yaw_)) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPosePitch, + pose_pitch_)) { + return false; + } + + if (!WriteEbmlElement(writer, libwebm::kMkvProjectionPoseRoll, pose_roll_)) { + return false; + } + + return true; +} + +bool Projection::SetProjectionPrivate(const uint8_t* data, + uint64_t data_length) { + if (data == NULL || data_length == 0) { + return false; + } + + if (data_length != static_cast(data_length)) { + return false; + } + + uint8_t* new_private_data = + new (std::nothrow) uint8_t[static_cast(data_length)]; + if (new_private_data == NULL) { + return false; + } + + delete[] private_data_; + private_data_ = new_private_data; + private_data_length_ = data_length; + memcpy(private_data_, data, static_cast(data_length)); + + return true; +} + +uint64_t Projection::PayloadSize() const { + uint64_t size = + EbmlElementSize(libwebm::kMkvProjection, static_cast(type_)); + + if (private_data_length_ > 0 && private_data_ != NULL) { + size += EbmlElementSize(libwebm::kMkvProjectionPrivate, private_data_, + private_data_length_); + } + + size += EbmlElementSize(libwebm::kMkvProjectionPoseYaw, pose_yaw_); + size += EbmlElementSize(libwebm::kMkvProjectionPosePitch, pose_pitch_); + size += EbmlElementSize(libwebm::kMkvProjectionPoseRoll, pose_roll_); + + return size; +} + +/////////////////////////////////////////////////////////////// +// +// VideoTrack Class + +VideoTrack::VideoTrack(unsigned int* seed) + : Track(seed), + display_height_(0), + display_width_(0), + pixel_height_(0), + pixel_width_(0), + crop_left_(0), + crop_right_(0), + crop_top_(0), + crop_bottom_(0), + frame_rate_(0.0), + height_(0), + stereo_mode_(0), + alpha_mode_(0), + width_(0), + colour_space_(NULL), + colour_(NULL), + projection_(NULL) {} + +VideoTrack::~VideoTrack() { + delete colour_; + delete projection_; +} + +bool VideoTrack::SetStereoMode(uint64_t stereo_mode) { + if (stereo_mode != kMono && stereo_mode != kSideBySideLeftIsFirst && + stereo_mode != kTopBottomRightIsFirst && + stereo_mode != kTopBottomLeftIsFirst && + stereo_mode != kSideBySideRightIsFirst) + return false; + + stereo_mode_ = stereo_mode; + return true; +} + +bool VideoTrack::SetAlphaMode(uint64_t alpha_mode) { + if (alpha_mode != kNoAlpha && alpha_mode != kAlpha) + return false; + + alpha_mode_ = alpha_mode; + return true; +} + +uint64_t VideoTrack::PayloadSize() const { + const uint64_t parent_size = Track::PayloadSize(); + + uint64_t size = VideoPayloadSize(); + size += EbmlMasterElementSize(libwebm::kMkvVideo, size); + + return parent_size + size; +} + +bool VideoTrack::Write(IMkvWriter* writer) const { + if (!Track::Write(writer)) + return false; + + const uint64_t size = VideoPayloadSize(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvVideo, size)) + return false; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + if (!WriteEbmlElement( + writer, libwebm::kMkvPixelWidth, + static_cast((pixel_width_ > 0) ? pixel_width_ : width_))) + return false; + if (!WriteEbmlElement( + writer, libwebm::kMkvPixelHeight, + static_cast((pixel_height_ > 0) ? pixel_height_ : height_))) + return false; + if (display_width_ > 0) { + if (!WriteEbmlElement(writer, libwebm::kMkvDisplayWidth, + static_cast(display_width_))) + return false; + } + if (display_height_ > 0) { + if (!WriteEbmlElement(writer, libwebm::kMkvDisplayHeight, + static_cast(display_height_))) + return false; + } + if (crop_left_ > 0) { + if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropLeft, + static_cast(crop_left_))) + return false; + } + if (crop_right_ > 0) { + if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropRight, + static_cast(crop_right_))) + return false; + } + if (crop_top_ > 0) { + if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropTop, + static_cast(crop_top_))) + return false; + } + if (crop_bottom_ > 0) { + if (!WriteEbmlElement(writer, libwebm::kMkvPixelCropBottom, + static_cast(crop_bottom_))) + return false; + } + if (stereo_mode_ > kMono) { + if (!WriteEbmlElement(writer, libwebm::kMkvStereoMode, + static_cast(stereo_mode_))) + return false; + } + if (alpha_mode_ > kNoAlpha) { + if (!WriteEbmlElement(writer, libwebm::kMkvAlphaMode, + static_cast(alpha_mode_))) + return false; + } + if (colour_space_) { + if (!WriteEbmlElement(writer, libwebm::kMkvColourSpace, colour_space_)) + return false; + } + if (frame_rate_ > 0.0) { + if (!WriteEbmlElement(writer, libwebm::kMkvFrameRate, + static_cast(frame_rate_))) { + return false; + } + } + if (colour_) { + if (!colour_->Write(writer)) + return false; + } + if (projection_) { + if (!projection_->Write(writer)) + return false; + } + + const int64_t stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(size)) { + return false; + } + + return true; +} + +void VideoTrack::set_colour_space(const char* colour_space) { + if (colour_space) { + delete[] colour_space_; + + const size_t length = strlen(colour_space) + 1; + colour_space_ = new (std::nothrow) char[length]; // NOLINT + if (colour_space_) { + memcpy(colour_space_, colour_space, length - 1); + colour_space_[length - 1] = '\0'; + } + } +} + +bool VideoTrack::SetColour(const Colour& colour) { + std::unique_ptr colour_ptr(new Colour()); + if (!colour_ptr.get()) + return false; + + if (colour.mastering_metadata()) { + if (!colour_ptr->SetMasteringMetadata(*colour.mastering_metadata())) + return false; + } + + colour_ptr->set_matrix_coefficients(colour.matrix_coefficients()); + colour_ptr->set_bits_per_channel(colour.bits_per_channel()); + colour_ptr->set_chroma_subsampling_horz(colour.chroma_subsampling_horz()); + colour_ptr->set_chroma_subsampling_vert(colour.chroma_subsampling_vert()); + colour_ptr->set_cb_subsampling_horz(colour.cb_subsampling_horz()); + colour_ptr->set_cb_subsampling_vert(colour.cb_subsampling_vert()); + colour_ptr->set_chroma_siting_horz(colour.chroma_siting_horz()); + colour_ptr->set_chroma_siting_vert(colour.chroma_siting_vert()); + colour_ptr->set_range(colour.range()); + colour_ptr->set_transfer_characteristics(colour.transfer_characteristics()); + colour_ptr->set_primaries(colour.primaries()); + colour_ptr->set_max_cll(colour.max_cll()); + colour_ptr->set_max_fall(colour.max_fall()); + delete colour_; + colour_ = colour_ptr.release(); + return true; +} + +bool VideoTrack::SetProjection(const Projection& projection) { + std::unique_ptr projection_ptr(new Projection()); + if (!projection_ptr.get()) + return false; + + if (projection.private_data()) { + if (!projection_ptr->SetProjectionPrivate( + projection.private_data(), projection.private_data_length())) { + return false; + } + } + + projection_ptr->set_type(projection.type()); + projection_ptr->set_pose_yaw(projection.pose_yaw()); + projection_ptr->set_pose_pitch(projection.pose_pitch()); + projection_ptr->set_pose_roll(projection.pose_roll()); + delete projection_; + projection_ = projection_ptr.release(); + return true; +} + +uint64_t VideoTrack::VideoPayloadSize() const { + uint64_t size = EbmlElementSize( + libwebm::kMkvPixelWidth, + static_cast((pixel_width_ > 0) ? pixel_width_ : width_)); + size += EbmlElementSize( + libwebm::kMkvPixelHeight, + static_cast((pixel_height_ > 0) ? pixel_height_ : height_)); + if (display_width_ > 0) + size += EbmlElementSize(libwebm::kMkvDisplayWidth, + static_cast(display_width_)); + if (display_height_ > 0) + size += EbmlElementSize(libwebm::kMkvDisplayHeight, + static_cast(display_height_)); + if (crop_left_ > 0) + size += EbmlElementSize(libwebm::kMkvPixelCropLeft, + static_cast(crop_left_)); + if (crop_right_ > 0) + size += EbmlElementSize(libwebm::kMkvPixelCropRight, + static_cast(crop_right_)); + if (crop_top_ > 0) + size += EbmlElementSize(libwebm::kMkvPixelCropTop, + static_cast(crop_top_)); + if (crop_bottom_ > 0) + size += EbmlElementSize(libwebm::kMkvPixelCropBottom, + static_cast(crop_bottom_)); + if (stereo_mode_ > kMono) + size += EbmlElementSize(libwebm::kMkvStereoMode, + static_cast(stereo_mode_)); + if (alpha_mode_ > kNoAlpha) + size += EbmlElementSize(libwebm::kMkvAlphaMode, + static_cast(alpha_mode_)); + if (frame_rate_ > 0.0) + size += EbmlElementSize(libwebm::kMkvFrameRate, + static_cast(frame_rate_)); + if (colour_space_) + size += EbmlElementSize(libwebm::kMkvColourSpace, colour_space_); + if (colour_) + size += colour_->ColourSize(); + if (projection_) + size += projection_->ProjectionSize(); + + return size; +} + +/////////////////////////////////////////////////////////////// +// +// AudioTrack Class + +AudioTrack::AudioTrack(unsigned int* seed) + : Track(seed), bit_depth_(0), channels_(1), sample_rate_(0.0) {} + +AudioTrack::~AudioTrack() {} + +uint64_t AudioTrack::PayloadSize() const { + const uint64_t parent_size = Track::PayloadSize(); + + uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency, + static_cast(sample_rate_)); + size += + EbmlElementSize(libwebm::kMkvChannels, static_cast(channels_)); + if (bit_depth_ > 0) + size += + EbmlElementSize(libwebm::kMkvBitDepth, static_cast(bit_depth_)); + size += EbmlMasterElementSize(libwebm::kMkvAudio, size); + + return parent_size + size; +} + +bool AudioTrack::Write(IMkvWriter* writer) const { + if (!Track::Write(writer)) + return false; + + // Calculate AudioSettings size. + uint64_t size = EbmlElementSize(libwebm::kMkvSamplingFrequency, + static_cast(sample_rate_)); + size += + EbmlElementSize(libwebm::kMkvChannels, static_cast(channels_)); + if (bit_depth_ > 0) + size += + EbmlElementSize(libwebm::kMkvBitDepth, static_cast(bit_depth_)); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvAudio, size)) + return false; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvSamplingFrequency, + static_cast(sample_rate_))) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvChannels, + static_cast(channels_))) + return false; + if (bit_depth_ > 0) + if (!WriteEbmlElement(writer, libwebm::kMkvBitDepth, + static_cast(bit_depth_))) + return false; + + const int64_t stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(size)) + return false; + + return true; +} + +/////////////////////////////////////////////////////////////// +// +// Tracks Class + +const char Tracks::kOpusCodecId[] = "A_OPUS"; +const char Tracks::kVorbisCodecId[] = "A_VORBIS"; +const char Tracks::kAv1CodecId[] = "V_AV1"; +const char Tracks::kVp8CodecId[] = "V_VP8"; +const char Tracks::kVp9CodecId[] = "V_VP9"; +const char Tracks::kWebVttCaptionsId[] = "D_WEBVTT/CAPTIONS"; +const char Tracks::kWebVttDescriptionsId[] = "D_WEBVTT/DESCRIPTIONS"; +const char Tracks::kWebVttMetadataId[] = "D_WEBVTT/METADATA"; +const char Tracks::kWebVttSubtitlesId[] = "D_WEBVTT/SUBTITLES"; + +Tracks::Tracks() + : track_entries_(NULL), track_entries_size_(0), wrote_tracks_(false) {} + +Tracks::~Tracks() { + if (track_entries_) { + for (uint32_t i = 0; i < track_entries_size_; ++i) { + Track* const track = track_entries_[i]; + delete track; + } + delete[] track_entries_; + } +} + +bool Tracks::AddTrack(Track* track, int32_t number) { + if (number < 0 || wrote_tracks_) + return false; + + // This muxer only supports track numbers in the range [1, 126], in + // order to be able (to use Matroska integer representation) to + // serialize the block header (of which the track number is a part) + // for a frame using exactly 4 bytes. + + if (number > 0x7E) + return false; + + uint32_t track_num = number; + + if (track_num > 0) { + // Check to make sure a track does not already have |track_num|. + for (uint32_t i = 0; i < track_entries_size_; ++i) { + if (track_entries_[i]->number() == track_num) + return false; + } + } + + const uint32_t count = track_entries_size_ + 1; + + Track** const track_entries = new (std::nothrow) Track*[count]; // NOLINT + if (!track_entries) + return false; + + for (uint32_t i = 0; i < track_entries_size_; ++i) { + track_entries[i] = track_entries_[i]; + } + + delete[] track_entries_; + + // Find the lowest availible track number > 0. + if (track_num == 0) { + track_num = count; + + // Check to make sure a track does not already have |track_num|. + bool exit = false; + do { + exit = true; + for (uint32_t i = 0; i < track_entries_size_; ++i) { + if (track_entries[i]->number() == track_num) { + track_num++; + exit = false; + break; + } + } + } while (!exit); + } + track->set_number(track_num); + + track_entries_ = track_entries; + track_entries_[track_entries_size_] = track; + track_entries_size_ = count; + return true; +} + +const Track* Tracks::GetTrackByIndex(uint32_t index) const { + if (track_entries_ == NULL) + return NULL; + + if (index >= track_entries_size_) + return NULL; + + return track_entries_[index]; +} + +Track* Tracks::GetTrackByNumber(uint64_t track_number) const { + const int32_t count = track_entries_size(); + for (int32_t i = 0; i < count; ++i) { + if (track_entries_[i]->number() == track_number) + return track_entries_[i]; + } + + return NULL; +} + +bool Tracks::TrackIsAudio(uint64_t track_number) const { + const Track* const track = GetTrackByNumber(track_number); + + if (track->type() == kAudio) + return true; + + return false; +} + +bool Tracks::TrackIsVideo(uint64_t track_number) const { + const Track* const track = GetTrackByNumber(track_number); + + if (track->type() == kVideo) + return true; + + return false; +} + +bool Tracks::Write(IMkvWriter* writer) const { + uint64_t size = 0; + const int32_t count = track_entries_size(); + for (int32_t i = 0; i < count; ++i) { + const Track* const track = GetTrackByIndex(i); + + if (!track) + return false; + + size += track->Size(); + } + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvTracks, size)) + return false; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + for (int32_t i = 0; i < count; ++i) { + const Track* const track = GetTrackByIndex(i); + if (!track->Write(writer)) + return false; + } + + const int64_t stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(size)) + return false; + + wrote_tracks_ = true; + return true; +} + +/////////////////////////////////////////////////////////////// +// +// Chapter Class + +bool Chapter::set_id(const char* id) { return StrCpy(id, &id_); } + +void Chapter::set_time(const Segment& segment, uint64_t start_ns, + uint64_t end_ns) { + const SegmentInfo* const info = segment.GetSegmentInfo(); + const uint64_t timecode_scale = info->timecode_scale(); + start_timecode_ = start_ns / timecode_scale; + end_timecode_ = end_ns / timecode_scale; +} + +bool Chapter::add_string(const char* title, const char* language, + const char* country) { + if (!ExpandDisplaysArray()) + return false; + + Display& d = displays_[displays_count_++]; + d.Init(); + + if (!d.set_title(title)) + return false; + + if (!d.set_language(language)) + return false; + + if (!d.set_country(country)) + return false; + + return true; +} + +Chapter::Chapter() { + // This ctor only constructs the object. Proper initialization is + // done in Init() (called in Chapters::AddChapter()). The only + // reason we bother implementing this ctor is because we had to + // declare it as private (along with the dtor), in order to prevent + // clients from creating Chapter instances (a privelege we grant + // only to the Chapters class). Doing no initialization here also + // means that creating arrays of chapter objects is more efficient, + // because we only initialize each new chapter object as it becomes + // active on the array. +} + +Chapter::~Chapter() {} + +void Chapter::Init(unsigned int* seed) { + id_ = NULL; + start_timecode_ = 0; + end_timecode_ = 0; + displays_ = NULL; + displays_size_ = 0; + displays_count_ = 0; + uid_ = MakeUID(seed); +} + +void Chapter::ShallowCopy(Chapter* dst) const { + dst->id_ = id_; + dst->start_timecode_ = start_timecode_; + dst->end_timecode_ = end_timecode_; + dst->uid_ = uid_; + dst->displays_ = displays_; + dst->displays_size_ = displays_size_; + dst->displays_count_ = displays_count_; +} + +void Chapter::Clear() { + StrCpy(NULL, &id_); + + while (displays_count_ > 0) { + Display& d = displays_[--displays_count_]; + d.Clear(); + } + + delete[] displays_; + displays_ = NULL; + + displays_size_ = 0; +} + +bool Chapter::ExpandDisplaysArray() { + if (displays_size_ > displays_count_) + return true; // nothing to do yet + + const int size = (displays_size_ == 0) ? 1 : 2 * displays_size_; + + Display* const displays = new (std::nothrow) Display[size]; // NOLINT + if (displays == NULL) + return false; + + for (int idx = 0; idx < displays_count_; ++idx) { + displays[idx] = displays_[idx]; // shallow copy + } + + delete[] displays_; + + displays_ = displays; + displays_size_ = size; + + return true; +} + +uint64_t Chapter::WriteAtom(IMkvWriter* writer) const { + uint64_t payload_size = + EbmlElementSize(libwebm::kMkvChapterStringUID, id_) + + EbmlElementSize(libwebm::kMkvChapterUID, static_cast(uid_)) + + EbmlElementSize(libwebm::kMkvChapterTimeStart, + static_cast(start_timecode_)) + + EbmlElementSize(libwebm::kMkvChapterTimeEnd, + static_cast(end_timecode_)); + + for (int idx = 0; idx < displays_count_; ++idx) { + const Display& d = displays_[idx]; + payload_size += d.WriteDisplay(NULL); + } + + const uint64_t atom_size = + EbmlMasterElementSize(libwebm::kMkvChapterAtom, payload_size) + + payload_size; + + if (writer == NULL) + return atom_size; + + const int64_t start = writer->Position(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterAtom, payload_size)) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvChapterStringUID, id_)) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvChapterUID, + static_cast(uid_))) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeStart, + static_cast(start_timecode_))) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvChapterTimeEnd, + static_cast(end_timecode_))) + return 0; + + for (int idx = 0; idx < displays_count_; ++idx) { + const Display& d = displays_[idx]; + + if (!d.WriteDisplay(writer)) + return 0; + } + + const int64_t stop = writer->Position(); + + if (stop >= start && uint64_t(stop - start) != atom_size) + return 0; + + return atom_size; +} + +void Chapter::Display::Init() { + title_ = NULL; + language_ = NULL; + country_ = NULL; +} + +void Chapter::Display::Clear() { + StrCpy(NULL, &title_); + StrCpy(NULL, &language_); + StrCpy(NULL, &country_); +} + +bool Chapter::Display::set_title(const char* title) { + return StrCpy(title, &title_); +} + +bool Chapter::Display::set_language(const char* language) { + return StrCpy(language, &language_); +} + +bool Chapter::Display::set_country(const char* country) { + return StrCpy(country, &country_); +} + +uint64_t Chapter::Display::WriteDisplay(IMkvWriter* writer) const { + uint64_t payload_size = EbmlElementSize(libwebm::kMkvChapString, title_); + + if (language_) + payload_size += EbmlElementSize(libwebm::kMkvChapLanguage, language_); + + if (country_) + payload_size += EbmlElementSize(libwebm::kMkvChapCountry, country_); + + const uint64_t display_size = + EbmlMasterElementSize(libwebm::kMkvChapterDisplay, payload_size) + + payload_size; + + if (writer == NULL) + return display_size; + + const int64_t start = writer->Position(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapterDisplay, + payload_size)) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvChapString, title_)) + return 0; + + if (language_) { + if (!WriteEbmlElement(writer, libwebm::kMkvChapLanguage, language_)) + return 0; + } + + if (country_) { + if (!WriteEbmlElement(writer, libwebm::kMkvChapCountry, country_)) + return 0; + } + + const int64_t stop = writer->Position(); + + if (stop >= start && uint64_t(stop - start) != display_size) + return 0; + + return display_size; +} + +/////////////////////////////////////////////////////////////// +// +// Chapters Class + +Chapters::Chapters() : chapters_size_(0), chapters_count_(0), chapters_(NULL) {} + +Chapters::~Chapters() { + while (chapters_count_ > 0) { + Chapter& chapter = chapters_[--chapters_count_]; + chapter.Clear(); + } + + delete[] chapters_; + chapters_ = NULL; +} + +int Chapters::Count() const { return chapters_count_; } + +Chapter* Chapters::AddChapter(unsigned int* seed) { + if (!ExpandChaptersArray()) + return NULL; + + Chapter& chapter = chapters_[chapters_count_++]; + chapter.Init(seed); + + return &chapter; +} + +bool Chapters::Write(IMkvWriter* writer) const { + if (writer == NULL) + return false; + + const uint64_t payload_size = WriteEdition(NULL); // return size only + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvChapters, payload_size)) + return false; + + const int64_t start = writer->Position(); + + if (WriteEdition(writer) == 0) // error + return false; + + const int64_t stop = writer->Position(); + + if (stop >= start && uint64_t(stop - start) != payload_size) + return false; + + return true; +} + +bool Chapters::ExpandChaptersArray() { + if (chapters_size_ > chapters_count_) + return true; // nothing to do yet + + const int size = (chapters_size_ == 0) ? 1 : 2 * chapters_size_; + + Chapter* const chapters = new (std::nothrow) Chapter[size]; // NOLINT + if (chapters == NULL) + return false; + + for (int idx = 0; idx < chapters_count_; ++idx) { + const Chapter& src = chapters_[idx]; + Chapter* const dst = chapters + idx; + src.ShallowCopy(dst); + } + + delete[] chapters_; + + chapters_ = chapters; + chapters_size_ = size; + + return true; +} + +uint64_t Chapters::WriteEdition(IMkvWriter* writer) const { + uint64_t payload_size = 0; + + for (int idx = 0; idx < chapters_count_; ++idx) { + const Chapter& chapter = chapters_[idx]; + payload_size += chapter.WriteAtom(NULL); + } + + const uint64_t edition_size = + EbmlMasterElementSize(libwebm::kMkvEditionEntry, payload_size) + + payload_size; + + if (writer == NULL) // return size only + return edition_size; + + const int64_t start = writer->Position(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvEditionEntry, payload_size)) + return 0; // error + + for (int idx = 0; idx < chapters_count_; ++idx) { + const Chapter& chapter = chapters_[idx]; + + const uint64_t chapter_size = chapter.WriteAtom(writer); + if (chapter_size == 0) // error + return 0; + } + + const int64_t stop = writer->Position(); + + if (stop >= start && uint64_t(stop - start) != edition_size) + return 0; + + return edition_size; +} + +// Tag Class + +bool Tag::add_simple_tag(const char* tag_name, const char* tag_string) { + if (!ExpandSimpleTagsArray()) + return false; + + SimpleTag& st = simple_tags_[simple_tags_count_++]; + st.Init(); + + if (!st.set_tag_name(tag_name)) + return false; + + if (!st.set_tag_string(tag_string)) + return false; + + return true; +} + +Tag::Tag() { + simple_tags_ = NULL; + simple_tags_size_ = 0; + simple_tags_count_ = 0; +} + +Tag::~Tag() {} + +void Tag::ShallowCopy(Tag* dst) const { + dst->simple_tags_ = simple_tags_; + dst->simple_tags_size_ = simple_tags_size_; + dst->simple_tags_count_ = simple_tags_count_; +} + +void Tag::Clear() { + while (simple_tags_count_ > 0) { + SimpleTag& st = simple_tags_[--simple_tags_count_]; + st.Clear(); + } + + delete[] simple_tags_; + simple_tags_ = NULL; + + simple_tags_size_ = 0; +} + +bool Tag::ExpandSimpleTagsArray() { + if (simple_tags_size_ > simple_tags_count_) + return true; // nothing to do yet + + const int size = (simple_tags_size_ == 0) ? 1 : 2 * simple_tags_size_; + + SimpleTag* const simple_tags = new (std::nothrow) SimpleTag[size]; // NOLINT + if (simple_tags == NULL) + return false; + + for (int idx = 0; idx < simple_tags_count_; ++idx) { + simple_tags[idx] = simple_tags_[idx]; // shallow copy + } + + delete[] simple_tags_; + + simple_tags_ = simple_tags; + simple_tags_size_ = size; + + return true; +} + +uint64_t Tag::Write(IMkvWriter* writer) const { + uint64_t payload_size = 0; + + for (int idx = 0; idx < simple_tags_count_; ++idx) { + const SimpleTag& st = simple_tags_[idx]; + payload_size += st.Write(NULL); + } + + const uint64_t tag_size = + EbmlMasterElementSize(libwebm::kMkvTag, payload_size) + payload_size; + + if (writer == NULL) + return tag_size; + + const int64_t start = writer->Position(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvTag, payload_size)) + return 0; + + for (int idx = 0; idx < simple_tags_count_; ++idx) { + const SimpleTag& st = simple_tags_[idx]; + + if (!st.Write(writer)) + return 0; + } + + const int64_t stop = writer->Position(); + + if (stop >= start && uint64_t(stop - start) != tag_size) + return 0; + + return tag_size; +} + +// Tag::SimpleTag + +void Tag::SimpleTag::Init() { + tag_name_ = NULL; + tag_string_ = NULL; +} + +void Tag::SimpleTag::Clear() { + StrCpy(NULL, &tag_name_); + StrCpy(NULL, &tag_string_); +} + +bool Tag::SimpleTag::set_tag_name(const char* tag_name) { + return StrCpy(tag_name, &tag_name_); +} + +bool Tag::SimpleTag::set_tag_string(const char* tag_string) { + return StrCpy(tag_string, &tag_string_); +} + +uint64_t Tag::SimpleTag::Write(IMkvWriter* writer) const { + uint64_t payload_size = EbmlElementSize(libwebm::kMkvTagName, tag_name_); + + payload_size += EbmlElementSize(libwebm::kMkvTagString, tag_string_); + + const uint64_t simple_tag_size = + EbmlMasterElementSize(libwebm::kMkvSimpleTag, payload_size) + + payload_size; + + if (writer == NULL) + return simple_tag_size; + + const int64_t start = writer->Position(); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvSimpleTag, payload_size)) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvTagName, tag_name_)) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvTagString, tag_string_)) + return 0; + + const int64_t stop = writer->Position(); + + if (stop >= start && uint64_t(stop - start) != simple_tag_size) + return 0; + + return simple_tag_size; +} + +// Tags Class + +Tags::Tags() : tags_size_(0), tags_count_(0), tags_(NULL) {} + +Tags::~Tags() { + while (tags_count_ > 0) { + Tag& tag = tags_[--tags_count_]; + tag.Clear(); + } + + delete[] tags_; + tags_ = NULL; +} + +int Tags::Count() const { return tags_count_; } + +Tag* Tags::AddTag() { + if (!ExpandTagsArray()) + return NULL; + + Tag& tag = tags_[tags_count_++]; + + return &tag; +} + +bool Tags::Write(IMkvWriter* writer) const { + if (writer == NULL) + return false; + + uint64_t payload_size = 0; + + for (int idx = 0; idx < tags_count_; ++idx) { + const Tag& tag = tags_[idx]; + payload_size += tag.Write(NULL); + } + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvTags, payload_size)) + return false; + + const int64_t start = writer->Position(); + + for (int idx = 0; idx < tags_count_; ++idx) { + const Tag& tag = tags_[idx]; + + const uint64_t tag_size = tag.Write(writer); + if (tag_size == 0) // error + return 0; + } + + const int64_t stop = writer->Position(); + + if (stop >= start && uint64_t(stop - start) != payload_size) + return false; + + return true; +} + +bool Tags::ExpandTagsArray() { + if (tags_size_ > tags_count_) + return true; // nothing to do yet + + const int size = (tags_size_ == 0) ? 1 : 2 * tags_size_; + + Tag* const tags = new (std::nothrow) Tag[size]; // NOLINT + if (tags == NULL) + return false; + + for (int idx = 0; idx < tags_count_; ++idx) { + const Tag& src = tags_[idx]; + Tag* const dst = tags + idx; + src.ShallowCopy(dst); + } + + delete[] tags_; + + tags_ = tags; + tags_size_ = size; + + return true; +} + +/////////////////////////////////////////////////////////////// +// +// Cluster class + +Cluster::Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale, + bool write_last_frame_with_duration, bool fixed_size_timecode) + : blocks_added_(0), + finalized_(false), + fixed_size_timecode_(fixed_size_timecode), + header_written_(false), + payload_size_(0), + position_for_cues_(cues_pos), + size_position_(-1), + timecode_(timecode), + timecode_scale_(timecode_scale), + write_last_frame_with_duration_(write_last_frame_with_duration), + writer_(NULL) {} + +Cluster::~Cluster() { + // Delete any stored frames that are left behind. This will happen if the + // Cluster was not Finalized for whatever reason. + while (!stored_frames_.empty()) { + while (!stored_frames_.begin()->second.empty()) { + delete stored_frames_.begin()->second.front(); + stored_frames_.begin()->second.pop_front(); + } + stored_frames_.erase(stored_frames_.begin()->first); + } +} + +bool Cluster::Init(IMkvWriter* ptr_writer) { + if (!ptr_writer) { + return false; + } + writer_ = ptr_writer; + return true; +} + +bool Cluster::AddFrame(const Frame* const frame) { + return QueueOrWriteFrame(frame); +} + +bool Cluster::AddFrame(const uint8_t* data, uint64_t length, + uint64_t track_number, uint64_t abs_timecode, + bool is_key) { + Frame frame; + if (!frame.Init(data, length)) + return false; + frame.set_track_number(track_number); + frame.set_timestamp(abs_timecode); + frame.set_is_key(is_key); + return QueueOrWriteFrame(&frame); +} + +bool Cluster::AddFrameWithAdditional(const uint8_t* data, uint64_t length, + const uint8_t* additional, + uint64_t additional_length, + uint64_t add_id, uint64_t track_number, + uint64_t abs_timecode, bool is_key) { + if (!additional || additional_length == 0) { + return false; + } + Frame frame; + if (!frame.Init(data, length) || + !frame.AddAdditionalData(additional, additional_length, add_id)) { + return false; + } + frame.set_track_number(track_number); + frame.set_timestamp(abs_timecode); + frame.set_is_key(is_key); + return QueueOrWriteFrame(&frame); +} + +bool Cluster::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, + int64_t discard_padding, + uint64_t track_number, + uint64_t abs_timecode, bool is_key) { + Frame frame; + if (!frame.Init(data, length)) + return false; + frame.set_discard_padding(discard_padding); + frame.set_track_number(track_number); + frame.set_timestamp(abs_timecode); + frame.set_is_key(is_key); + return QueueOrWriteFrame(&frame); +} + +bool Cluster::AddMetadata(const uint8_t* data, uint64_t length, + uint64_t track_number, uint64_t abs_timecode, + uint64_t duration_timecode) { + Frame frame; + if (!frame.Init(data, length)) + return false; + frame.set_track_number(track_number); + frame.set_timestamp(abs_timecode); + frame.set_duration(duration_timecode); + frame.set_is_key(true); // All metadata blocks are keyframes. + return QueueOrWriteFrame(&frame); +} + +void Cluster::AddPayloadSize(uint64_t size) { payload_size_ += size; } + +bool Cluster::Finalize() { + return !write_last_frame_with_duration_ && Finalize(false, 0); +} + +bool Cluster::Finalize(bool set_last_frame_duration, uint64_t duration) { + if (!writer_ || finalized_) + return false; + + if (write_last_frame_with_duration_) { + // Write out held back Frames. This essentially performs a k-way merge + // across all tracks in the increasing order of timestamps. + while (!stored_frames_.empty()) { + Frame* frame = stored_frames_.begin()->second.front(); + + // Get the next frame to write (frame with least timestamp across all + // tracks). + for (FrameMapIterator frames_iterator = ++stored_frames_.begin(); + frames_iterator != stored_frames_.end(); ++frames_iterator) { + if (frames_iterator->second.front()->timestamp() < frame->timestamp()) { + frame = frames_iterator->second.front(); + } + } + + // Set the duration if it's the last frame for the track. + if (set_last_frame_duration && + stored_frames_[frame->track_number()].size() == 1 && + !frame->duration_set()) { + frame->set_duration(duration - frame->timestamp()); + if (!frame->is_key() && !frame->reference_block_timestamp_set()) { + frame->set_reference_block_timestamp( + last_block_timestamp_[frame->track_number()]); + } + } + + // Write the frame and remove it from |stored_frames_|. + const bool wrote_frame = DoWriteFrame(frame); + stored_frames_[frame->track_number()].pop_front(); + if (stored_frames_[frame->track_number()].empty()) { + stored_frames_.erase(frame->track_number()); + } + delete frame; + if (!wrote_frame) + return false; + } + } + + if (size_position_ == -1) + return false; + + if (writer_->Seekable()) { + const int64_t pos = writer_->Position(); + + if (writer_->Position(size_position_)) + return false; + + if (WriteUIntSize(writer_, payload_size(), 8)) + return false; + + if (writer_->Position(pos)) + return false; + } + + finalized_ = true; + + return true; +} + +uint64_t Cluster::Size() const { + const uint64_t element_size = + EbmlMasterElementSize(libwebm::kMkvCluster, 0xFFFFFFFFFFFFFFFFULL) + + payload_size_; + return element_size; +} + +bool Cluster::PreWriteBlock() { + if (finalized_) + return false; + + if (!header_written_) { + if (!WriteClusterHeader()) + return false; + } + + return true; +} + +void Cluster::PostWriteBlock(uint64_t element_size) { + AddPayloadSize(element_size); + ++blocks_added_; +} + +int64_t Cluster::GetRelativeTimecode(int64_t abs_timecode) const { + const int64_t cluster_timecode = this->Cluster::timecode(); + const int64_t rel_timecode = + static_cast(abs_timecode) - cluster_timecode; + + if (rel_timecode < 0 || rel_timecode > kMaxBlockTimecode) + return -1; + + return rel_timecode; +} + +bool Cluster::DoWriteFrame(const Frame* const frame) { + if (!frame || !frame->IsValid()) + return false; + + if (!PreWriteBlock()) + return false; + + const uint64_t element_size = WriteFrame(writer_, frame, this); + if (element_size == 0) + return false; + + PostWriteBlock(element_size); + last_block_timestamp_[frame->track_number()] = frame->timestamp(); + return true; +} + +bool Cluster::QueueOrWriteFrame(const Frame* const frame) { + if (!frame || !frame->IsValid()) + return false; + + // If |write_last_frame_with_duration_| is not set, then write the frame right + // away. + if (!write_last_frame_with_duration_) { + return DoWriteFrame(frame); + } + + // Queue the current frame. + uint64_t track_number = frame->track_number(); + Frame* const frame_to_store = new Frame(); + frame_to_store->CopyFrom(*frame); + stored_frames_[track_number].push_back(frame_to_store); + + // Iterate through all queued frames in the current track except the last one + // and write it if it is okay to do so (i.e.) no other track has an held back + // frame with timestamp <= the timestamp of the frame in question. + std::vector::iterator> frames_to_erase; + for (std::list::iterator + current_track_iterator = stored_frames_[track_number].begin(), + end = --stored_frames_[track_number].end(); + current_track_iterator != end; ++current_track_iterator) { + const Frame* const frame_to_write = *current_track_iterator; + bool okay_to_write = true; + for (FrameMapIterator track_iterator = stored_frames_.begin(); + track_iterator != stored_frames_.end(); ++track_iterator) { + if (track_iterator->first == track_number) { + continue; + } + if (track_iterator->second.front()->timestamp() < + frame_to_write->timestamp()) { + okay_to_write = false; + break; + } + } + if (okay_to_write) { + const bool wrote_frame = DoWriteFrame(frame_to_write); + delete frame_to_write; + if (!wrote_frame) + return false; + frames_to_erase.push_back(current_track_iterator); + } else { + break; + } + } + for (std::vector::iterator>::iterator iterator = + frames_to_erase.begin(); + iterator != frames_to_erase.end(); ++iterator) { + stored_frames_[track_number].erase(*iterator); + } + return true; +} + +bool Cluster::WriteClusterHeader() { + if (finalized_) + return false; + + if (WriteID(writer_, libwebm::kMkvCluster)) + return false; + + // Save for later. + size_position_ = writer_->Position(); + + // Write "unknown" (EBML coded -1) as cluster size value. We need to write 8 + // bytes because we do not know how big our cluster will be. + if (SerializeInt(writer_, kEbmlUnknownValue, 8)) + return false; + + if (!WriteEbmlElement(writer_, libwebm::kMkvTimecode, timecode(), + fixed_size_timecode_ ? 8 : 0)) { + return false; + } + AddPayloadSize(EbmlElementSize(libwebm::kMkvTimecode, timecode(), + fixed_size_timecode_ ? 8 : 0)); + header_written_ = true; + + return true; +} + +/////////////////////////////////////////////////////////////// +// +// SeekHead Class + +SeekHead::SeekHead() : start_pos_(0ULL) { + for (int32_t i = 0; i < kSeekEntryCount; ++i) { + seek_entry_id_[i] = 0; + seek_entry_pos_[i] = 0; + } +} + +SeekHead::~SeekHead() {} + +bool SeekHead::Finalize(IMkvWriter* writer) const { + if (writer->Seekable()) { + if (start_pos_ == -1) + return false; + + uint64_t payload_size = 0; + uint64_t entry_size[kSeekEntryCount]; + + for (int32_t i = 0; i < kSeekEntryCount; ++i) { + if (seek_entry_id_[i] != 0) { + entry_size[i] = EbmlElementSize(libwebm::kMkvSeekID, + static_cast(seek_entry_id_[i])); + entry_size[i] += EbmlElementSize( + libwebm::kMkvSeekPosition, static_cast(seek_entry_pos_[i])); + + payload_size += + EbmlMasterElementSize(libwebm::kMkvSeek, entry_size[i]) + + entry_size[i]; + } + } + + // No SeekHead elements + if (payload_size == 0) + return true; + + const int64_t pos = writer->Position(); + if (writer->Position(start_pos_)) + return false; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeekHead, payload_size)) + return false; + + for (int32_t i = 0; i < kSeekEntryCount; ++i) { + if (seek_entry_id_[i] != 0) { + if (!WriteEbmlMasterElement(writer, libwebm::kMkvSeek, entry_size[i])) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvSeekID, + static_cast(seek_entry_id_[i]))) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvSeekPosition, + static_cast(seek_entry_pos_[i]))) + return false; + } + } + + const uint64_t total_entry_size = kSeekEntryCount * MaxEntrySize(); + const uint64_t total_size = + EbmlMasterElementSize(libwebm::kMkvSeekHead, total_entry_size) + + total_entry_size; + const int64_t size_left = total_size - (writer->Position() - start_pos_); + + const uint64_t bytes_written = WriteVoidElement(writer, size_left); + if (!bytes_written) + return false; + + if (writer->Position(pos)) + return false; + } + + return true; +} + +bool SeekHead::Write(IMkvWriter* writer) { + const uint64_t entry_size = kSeekEntryCount * MaxEntrySize(); + const uint64_t size = + EbmlMasterElementSize(libwebm::kMkvSeekHead, entry_size); + + start_pos_ = writer->Position(); + + const uint64_t bytes_written = WriteVoidElement(writer, size + entry_size); + if (!bytes_written) + return false; + + return true; +} + +bool SeekHead::AddSeekEntry(uint32_t id, uint64_t pos) { + for (int32_t i = 0; i < kSeekEntryCount; ++i) { + if (seek_entry_id_[i] == 0) { + seek_entry_id_[i] = id; + seek_entry_pos_[i] = pos; + return true; + } + } + return false; +} + +uint32_t SeekHead::GetId(int index) const { + if (index < 0 || index >= kSeekEntryCount) + return UINT32_MAX; + return seek_entry_id_[index]; +} + +uint64_t SeekHead::GetPosition(int index) const { + if (index < 0 || index >= kSeekEntryCount) + return UINT64_MAX; + return seek_entry_pos_[index]; +} + +bool SeekHead::SetSeekEntry(int index, uint32_t id, uint64_t position) { + if (index < 0 || index >= kSeekEntryCount) + return false; + seek_entry_id_[index] = id; + seek_entry_pos_[index] = position; + return true; +} + +uint64_t SeekHead::MaxEntrySize() const { + const uint64_t max_entry_payload_size = + EbmlElementSize(libwebm::kMkvSeekID, + static_cast(UINT64_C(0xffffffff))) + + EbmlElementSize(libwebm::kMkvSeekPosition, + static_cast(UINT64_C(0xffffffffffffffff))); + const uint64_t max_entry_size = + EbmlMasterElementSize(libwebm::kMkvSeek, max_entry_payload_size) + + max_entry_payload_size; + + return max_entry_size; +} + +/////////////////////////////////////////////////////////////// +// +// SegmentInfo Class + +SegmentInfo::SegmentInfo() + : duration_(-1.0), + muxing_app_(NULL), + timecode_scale_(1000000ULL), + writing_app_(NULL), + date_utc_(INT64_MIN), + duration_pos_(-1) {} + +SegmentInfo::~SegmentInfo() { + delete[] muxing_app_; + delete[] writing_app_; +} + +bool SegmentInfo::Init() { + int32_t major; + int32_t minor; + int32_t build; + int32_t revision; + GetVersion(&major, &minor, &build, &revision); + char temp[256]; +#ifdef _MSC_VER + sprintf_s(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, + minor, build, revision); +#else + snprintf(temp, sizeof(temp) / sizeof(temp[0]), "libwebm-%d.%d.%d.%d", major, + minor, build, revision); +#endif + + const size_t app_len = strlen(temp) + 1; + + delete[] muxing_app_; + + muxing_app_ = new (std::nothrow) char[app_len]; // NOLINT + if (!muxing_app_) + return false; + + memcpy(muxing_app_, temp, app_len - 1); + muxing_app_[app_len - 1] = '\0'; + + set_writing_app(temp); + if (!writing_app_) + return false; + return true; +} + +bool SegmentInfo::Finalize(IMkvWriter* writer) const { + if (!writer) + return false; + + if (duration_ > 0.0) { + if (writer->Seekable()) { + if (duration_pos_ == -1) + return false; + + const int64_t pos = writer->Position(); + + if (writer->Position(duration_pos_)) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvDuration, + static_cast(duration_))) + return false; + + if (writer->Position(pos)) + return false; + } + } + + return true; +} + +bool SegmentInfo::Write(IMkvWriter* writer) { + if (!writer || !muxing_app_ || !writing_app_) + return false; + + uint64_t size = EbmlElementSize(libwebm::kMkvTimecodeScale, + static_cast(timecode_scale_)); + if (duration_ > 0.0) + size += + EbmlElementSize(libwebm::kMkvDuration, static_cast(duration_)); + if (date_utc_ != INT64_MIN) + size += EbmlDateElementSize(libwebm::kMkvDateUTC); + size += EbmlElementSize(libwebm::kMkvMuxingApp, muxing_app_); + size += EbmlElementSize(libwebm::kMkvWritingApp, writing_app_); + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvInfo, size)) + return false; + + const int64_t payload_position = writer->Position(); + if (payload_position < 0) + return false; + + if (!WriteEbmlElement(writer, libwebm::kMkvTimecodeScale, + static_cast(timecode_scale_))) + return false; + + if (duration_ > 0.0) { + // Save for later + duration_pos_ = writer->Position(); + + if (!WriteEbmlElement(writer, libwebm::kMkvDuration, + static_cast(duration_))) + return false; + } + + if (date_utc_ != INT64_MIN) + WriteEbmlDateElement(writer, libwebm::kMkvDateUTC, date_utc_); + + if (!WriteEbmlElement(writer, libwebm::kMkvMuxingApp, muxing_app_)) + return false; + if (!WriteEbmlElement(writer, libwebm::kMkvWritingApp, writing_app_)) + return false; + + const int64_t stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(size)) + return false; + + return true; +} + +void SegmentInfo::set_muxing_app(const char* app) { + if (app) { + const size_t length = strlen(app) + 1; + char* temp_str = new (std::nothrow) char[length]; // NOLINT + if (!temp_str) + return; + + memcpy(temp_str, app, length - 1); + temp_str[length - 1] = '\0'; + + delete[] muxing_app_; + muxing_app_ = temp_str; + } +} + +void SegmentInfo::set_writing_app(const char* app) { + if (app) { + const size_t length = strlen(app) + 1; + char* temp_str = new (std::nothrow) char[length]; // NOLINT + if (!temp_str) + return; + + memcpy(temp_str, app, length - 1); + temp_str[length - 1] = '\0'; + + delete[] writing_app_; + writing_app_ = temp_str; + } +} + +/////////////////////////////////////////////////////////////// +// +// Segment Class + +Segment::Segment() + : chunk_count_(0), + chunk_name_(NULL), + chunk_writer_cluster_(NULL), + chunk_writer_cues_(NULL), + chunk_writer_header_(NULL), + chunking_(false), + chunking_base_name_(NULL), + cluster_list_(NULL), + cluster_list_capacity_(0), + cluster_list_size_(0), + cues_position_(kAfterClusters), + cues_track_(0), + force_new_cluster_(false), + frames_(NULL), + frames_capacity_(0), + frames_size_(0), + has_video_(false), + header_written_(false), + last_block_duration_(0), + last_timestamp_(0), + max_cluster_duration_(kDefaultMaxClusterDuration), + max_cluster_size_(0), + mode_(kFile), + new_cuepoint_(false), + output_cues_(true), + accurate_cluster_duration_(false), + fixed_size_cluster_timecode_(false), + estimate_file_duration_(false), + ebml_header_size_(0), + payload_pos_(0), + size_position_(0), + doc_type_version_(kDefaultDocTypeVersion), + doc_type_version_written_(0), + duration_(0.0), + writer_cluster_(NULL), + writer_cues_(NULL), + writer_header_(NULL) { + const time_t curr_time = time(NULL); + seed_ = static_cast(curr_time); +#ifdef _WIN32 + srand(seed_); +#endif +} + +Segment::~Segment() { + if (cluster_list_) { + for (int32_t i = 0; i < cluster_list_size_; ++i) { + Cluster* const cluster = cluster_list_[i]; + delete cluster; + } + delete[] cluster_list_; + } + + if (frames_) { + for (int32_t i = 0; i < frames_size_; ++i) { + Frame* const frame = frames_[i]; + delete frame; + } + delete[] frames_; + } + + delete[] chunk_name_; + delete[] chunking_base_name_; + + if (chunk_writer_cluster_) { + chunk_writer_cluster_->Close(); + delete chunk_writer_cluster_; + } + if (chunk_writer_cues_) { + chunk_writer_cues_->Close(); + delete chunk_writer_cues_; + } + if (chunk_writer_header_) { + chunk_writer_header_->Close(); + delete chunk_writer_header_; + } +} + +void Segment::MoveCuesBeforeClustersHelper(uint64_t diff, int32_t index, + uint64_t* cues_size) { + CuePoint* const cue_point = cues_.GetCueByIndex(index); + if (cue_point == NULL) + return; + const uint64_t old_cue_point_size = cue_point->Size(); + const uint64_t cluster_pos = cue_point->cluster_pos() + diff; + cue_point->set_cluster_pos(cluster_pos); // update the new cluster position + // New size of the cue is computed as follows + // Let a = current sum of size of all CuePoints + // Let b = Increase in Cue Point's size due to this iteration + // Let c = Increase in size of Cues Element's length due to this iteration + // (This is computed as CodedSize(a + b) - CodedSize(a)) + // Let d = b + c. Now d is the |diff| passed to the next recursive call. + // Let e = a + b. Now e is the |cues_size| passed to the next recursive + // call. + const uint64_t cue_point_size_diff = cue_point->Size() - old_cue_point_size; + const uint64_t cue_size_diff = + GetCodedUIntSize(*cues_size + cue_point_size_diff) - + GetCodedUIntSize(*cues_size); + *cues_size += cue_point_size_diff; + diff = cue_size_diff + cue_point_size_diff; + if (diff > 0) { + for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) { + MoveCuesBeforeClustersHelper(diff, i, cues_size); + } + } +} + +void Segment::MoveCuesBeforeClusters() { + const uint64_t current_cue_size = cues_.Size(); + uint64_t cue_size = 0; + for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) + cue_size += cues_.GetCueByIndex(i)->Size(); + for (int32_t i = 0; i < cues_.cue_entries_size(); ++i) + MoveCuesBeforeClustersHelper(current_cue_size, i, &cue_size); + + // Adjust the Seek Entry to reflect the change in position + // of Cluster and Cues + int32_t cluster_index = 0; + int32_t cues_index = 0; + for (int32_t i = 0; i < SeekHead::kSeekEntryCount; ++i) { + if (seek_head_.GetId(i) == libwebm::kMkvCluster) + cluster_index = i; + if (seek_head_.GetId(i) == libwebm::kMkvCues) + cues_index = i; + } + seek_head_.SetSeekEntry(cues_index, libwebm::kMkvCues, + seek_head_.GetPosition(cluster_index)); + seek_head_.SetSeekEntry(cluster_index, libwebm::kMkvCluster, + cues_.Size() + seek_head_.GetPosition(cues_index)); +} + +bool Segment::Init(IMkvWriter* ptr_writer) { + if (!ptr_writer) { + return false; + } + writer_cluster_ = ptr_writer; + writer_cues_ = ptr_writer; + writer_header_ = ptr_writer; + memset(&track_frames_written_, 0, + sizeof(track_frames_written_[0]) * kMaxTrackNumber); + memset(&last_track_timestamp_, 0, + sizeof(last_track_timestamp_[0]) * kMaxTrackNumber); + return segment_info_.Init(); +} + +bool Segment::CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader, + IMkvWriter* writer) { + if (!writer->Seekable() || chunking_) + return false; + const int64_t cluster_offset = + cluster_list_[0]->size_position() - GetUIntSize(libwebm::kMkvCluster); + + // Copy the headers. + if (!ChunkedCopy(reader, writer, 0, cluster_offset)) + return false; + + // Recompute cue positions and seek entries. + MoveCuesBeforeClusters(); + + // Write cues and seek entries. + // TODO(vigneshv): As of now, it's safe to call seek_head_.Finalize() for the + // second time with a different writer object. But the name Finalize() doesn't + // indicate something we want to call more than once. So consider renaming it + // to write() or some such. + if (!cues_.Write(writer) || !seek_head_.Finalize(writer)) + return false; + + // Copy the Clusters. + if (!ChunkedCopy(reader, writer, cluster_offset, + cluster_end_offset_ - cluster_offset)) + return false; + + // Update the Segment size in case the Cues size has changed. + const int64_t pos = writer->Position(); + const int64_t segment_size = writer->Position() - payload_pos_; + if (writer->Position(size_position_) || + WriteUIntSize(writer, segment_size, 8) || writer->Position(pos)) + return false; + return true; +} + +bool Segment::Finalize() { + if (WriteFramesAll() < 0) + return false; + + // In kLive mode, call Cluster::Finalize only if |accurate_cluster_duration_| + // is set. In all other modes, always call Cluster::Finalize. + if ((mode_ == kLive ? accurate_cluster_duration_ : true) && + cluster_list_size_ > 0) { + // Update last cluster's size + Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; + + // For the last frame of the last Cluster, we don't write it as a BlockGroup + // with Duration unless the frame itself has duration set explicitly. + if (!old_cluster || !old_cluster->Finalize(false, 0)) + return false; + } + + if (mode_ == kFile) { + if (chunking_ && chunk_writer_cluster_) { + chunk_writer_cluster_->Close(); + chunk_count_++; + } + + double duration = + (static_cast(last_timestamp_) + last_block_duration_) / + segment_info_.timecode_scale(); + if (duration_ > 0.0) { + duration = duration_; + } else { + if (last_block_duration_ == 0 && estimate_file_duration_) { + const int num_tracks = static_cast(tracks_.track_entries_size()); + for (int i = 0; i < num_tracks; ++i) { + if (track_frames_written_[i] < 2) + continue; + + // Estimate the duration for the last block of a Track. + const double nano_per_frame = + static_cast(last_track_timestamp_[i]) / + (track_frames_written_[i] - 1); + const double track_duration = + (last_track_timestamp_[i] + nano_per_frame) / + segment_info_.timecode_scale(); + if (track_duration > duration) + duration = track_duration; + } + } + } + segment_info_.set_duration(duration); + if (!segment_info_.Finalize(writer_header_)) + return false; + + if (output_cues_) + if (!seek_head_.AddSeekEntry(libwebm::kMkvCues, MaxOffset())) + return false; + + if (chunking_) { + if (!chunk_writer_cues_) + return false; + + char* name = NULL; + if (!UpdateChunkName("cues", &name)) + return false; + + const bool cues_open = chunk_writer_cues_->Open(name); + delete[] name; + if (!cues_open) + return false; + } + + cluster_end_offset_ = writer_cluster_->Position(); + + // Write the seek headers and cues + if (output_cues_) + if (!cues_.Write(writer_cues_)) + return false; + + if (!seek_head_.Finalize(writer_header_)) + return false; + + if (writer_header_->Seekable()) { + if (size_position_ == -1) + return false; + + const int64_t segment_size = MaxOffset(); + if (segment_size < 1) + return false; + + const int64_t pos = writer_header_->Position(); + UpdateDocTypeVersion(); + if (doc_type_version_ != doc_type_version_written_) { + if (writer_header_->Position(0)) + return false; + + const char* const doc_type = + DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska; + if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type)) + return false; + if (writer_header_->Position() != ebml_header_size_) + return false; + + doc_type_version_written_ = doc_type_version_; + } + + if (writer_header_->Position(size_position_)) + return false; + + if (WriteUIntSize(writer_header_, segment_size, 8)) + return false; + + if (writer_header_->Position(pos)) + return false; + } + + if (chunking_) { + // Do not close any writers until the segment size has been written, + // otherwise the size may be off. + if (!chunk_writer_cues_ || !chunk_writer_header_) + return false; + + chunk_writer_cues_->Close(); + chunk_writer_header_->Close(); + } + } + + return true; +} + +Track* Segment::AddTrack(int32_t number) { + Track* const track = new (std::nothrow) Track(&seed_); // NOLINT + + if (!track) + return NULL; + + if (!tracks_.AddTrack(track, number)) { + delete track; + return NULL; + } + + return track; +} + +Chapter* Segment::AddChapter() { return chapters_.AddChapter(&seed_); } + +Tag* Segment::AddTag() { return tags_.AddTag(); } + +uint64_t Segment::AddVideoTrack(int32_t width, int32_t height, int32_t number) { + VideoTrack* const track = new (std::nothrow) VideoTrack(&seed_); // NOLINT + if (!track) + return 0; + + track->set_type(Tracks::kVideo); + track->set_codec_id(Tracks::kVp8CodecId); + track->set_width(width); + track->set_height(height); + + if (!tracks_.AddTrack(track, number)) { + delete track; + return 0; + } + has_video_ = true; + + return track->number(); +} + +bool Segment::AddCuePoint(uint64_t timestamp, uint64_t track) { + if (cluster_list_size_ < 1) + return false; + + const Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; + if (!cluster) + return false; + + CuePoint* const cue = new (std::nothrow) CuePoint(); // NOLINT + if (!cue) + return false; + + cue->set_time(timestamp / segment_info_.timecode_scale()); + cue->set_block_number(cluster->blocks_added()); + cue->set_cluster_pos(cluster->position_for_cues()); + cue->set_track(track); + if (!cues_.AddCue(cue)) { + delete cue; + return false; + } + + new_cuepoint_ = false; + return true; +} + +uint64_t Segment::AddAudioTrack(int32_t sample_rate, int32_t channels, + int32_t number) { + AudioTrack* const track = new (std::nothrow) AudioTrack(&seed_); // NOLINT + if (!track) + return 0; + + track->set_type(Tracks::kAudio); + track->set_codec_id(Tracks::kVorbisCodecId); + track->set_sample_rate(sample_rate); + track->set_channels(channels); + + if (!tracks_.AddTrack(track, number)) { + delete track; + return 0; + } + + return track->number(); +} + +bool Segment::AddFrame(const uint8_t* data, uint64_t length, + uint64_t track_number, uint64_t timestamp, bool is_key) { + if (!data) + return false; + + Frame frame; + if (!frame.Init(data, length)) + return false; + frame.set_track_number(track_number); + frame.set_timestamp(timestamp); + frame.set_is_key(is_key); + return AddGenericFrame(&frame); +} + +bool Segment::AddFrameWithAdditional(const uint8_t* data, uint64_t length, + const uint8_t* additional, + uint64_t additional_length, + uint64_t add_id, uint64_t track_number, + uint64_t timestamp, bool is_key) { + if (!data || !additional) + return false; + + Frame frame; + if (!frame.Init(data, length) || + !frame.AddAdditionalData(additional, additional_length, add_id)) { + return false; + } + frame.set_track_number(track_number); + frame.set_timestamp(timestamp); + frame.set_is_key(is_key); + return AddGenericFrame(&frame); +} + +bool Segment::AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, + int64_t discard_padding, + uint64_t track_number, + uint64_t timestamp, bool is_key) { + if (!data) + return false; + + Frame frame; + if (!frame.Init(data, length)) + return false; + frame.set_discard_padding(discard_padding); + frame.set_track_number(track_number); + frame.set_timestamp(timestamp); + frame.set_is_key(is_key); + return AddGenericFrame(&frame); +} + +bool Segment::AddMetadata(const uint8_t* data, uint64_t length, + uint64_t track_number, uint64_t timestamp_ns, + uint64_t duration_ns) { + if (!data) + return false; + + Frame frame; + if (!frame.Init(data, length)) + return false; + frame.set_track_number(track_number); + frame.set_timestamp(timestamp_ns); + frame.set_duration(duration_ns); + frame.set_is_key(true); // All metadata blocks are keyframes. + return AddGenericFrame(&frame); +} + +bool Segment::AddGenericFrame(const Frame* frame) { + if (!frame) + return false; + + if (!CheckHeaderInfo()) + return false; + + // Check for non-monotonically increasing timestamps. + if (frame->timestamp() < last_timestamp_) + return false; + + // Check if the track number is valid. + if (!tracks_.GetTrackByNumber(frame->track_number())) + return false; + + if (frame->discard_padding() != 0) + doc_type_version_ = 4; + + if (cluster_list_size_ > 0) { + const uint64_t timecode_scale = segment_info_.timecode_scale(); + const uint64_t frame_timecode = frame->timestamp() / timecode_scale; + + const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1]; + const uint64_t last_cluster_timecode = last_cluster->timecode(); + + const uint64_t rel_timecode = frame_timecode - last_cluster_timecode; + if (rel_timecode > kMaxBlockTimecode) { + force_new_cluster_ = true; + } + } + + // If the segment has a video track hold onto audio frames to make sure the + // audio that is associated with the start time of a video key-frame is + // muxed into the same cluster. + if (has_video_ && tracks_.TrackIsAudio(frame->track_number()) && + !force_new_cluster_) { + Frame* const new_frame = new (std::nothrow) Frame(); + if (!new_frame || !new_frame->CopyFrom(*frame)) { + delete new_frame; + return false; + } + if (!QueueFrame(new_frame)) { + delete new_frame; + return false; + } + track_frames_written_[frame->track_number() - 1]++; + return true; + } + + if (!DoNewClusterProcessing(frame->track_number(), frame->timestamp(), + frame->is_key())) { + return false; + } + + if (cluster_list_size_ < 1) + return false; + + Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; + if (!cluster) + return false; + + // If the Frame is not a SimpleBlock, then set the reference_block_timestamp + // if it is not set already. + bool frame_created = false; + if (!frame->CanBeSimpleBlock() && !frame->is_key() && + !frame->reference_block_timestamp_set()) { + Frame* const new_frame = new (std::nothrow) Frame(); + if (!new_frame || !new_frame->CopyFrom(*frame)) { + delete new_frame; + return false; + } + new_frame->set_reference_block_timestamp( + last_track_timestamp_[frame->track_number() - 1]); + frame = new_frame; + frame_created = true; + } + + if (!cluster->AddFrame(frame)) + return false; + + if (new_cuepoint_ && cues_track_ == frame->track_number()) { + if (!AddCuePoint(frame->timestamp(), cues_track_)) + return false; + } + + last_timestamp_ = frame->timestamp(); + last_track_timestamp_[frame->track_number() - 1] = frame->timestamp(); + last_block_duration_ = frame->duration(); + track_frames_written_[frame->track_number() - 1]++; + + if (frame_created) + delete frame; + return true; +} + +void Segment::OutputCues(bool output_cues) { output_cues_ = output_cues; } + +void Segment::AccurateClusterDuration(bool accurate_cluster_duration) { + accurate_cluster_duration_ = accurate_cluster_duration; +} + +void Segment::UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode) { + fixed_size_cluster_timecode_ = fixed_size_cluster_timecode; +} + +bool Segment::SetChunking(bool chunking, const char* filename) { + if (chunk_count_ > 0) + return false; + + if (chunking) { + if (!filename) + return false; + + // Check if we are being set to what is already set. + if (chunking_ && !strcmp(filename, chunking_base_name_)) + return true; + + const size_t filename_length = strlen(filename); + char* const temp = new (std::nothrow) char[filename_length + 1]; // NOLINT + if (!temp) + return false; + + memcpy(temp, filename, filename_length); + temp[filename_length] = '\0'; + + delete[] chunking_base_name_; + chunking_base_name_ = temp; + // From this point, strlen(chunking_base_name_) == filename_length + + if (!UpdateChunkName("chk", &chunk_name_)) + return false; + + if (!chunk_writer_cluster_) { + chunk_writer_cluster_ = new (std::nothrow) MkvWriter(); // NOLINT + if (!chunk_writer_cluster_) + return false; + } + + if (!chunk_writer_cues_) { + chunk_writer_cues_ = new (std::nothrow) MkvWriter(); // NOLINT + if (!chunk_writer_cues_) + return false; + } + + if (!chunk_writer_header_) { + chunk_writer_header_ = new (std::nothrow) MkvWriter(); // NOLINT + if (!chunk_writer_header_) + return false; + } + + if (!chunk_writer_cluster_->Open(chunk_name_)) + return false; + + const size_t hdr_length = strlen(".hdr"); + const size_t header_length = filename_length + hdr_length + 1; + char* const header = new (std::nothrow) char[header_length]; // NOLINT + if (!header) + return false; + + memcpy(header, chunking_base_name_, filename_length); + memcpy(&header[filename_length], ".hdr", hdr_length); + header[filename_length + hdr_length] = '\0'; + + if (!chunk_writer_header_->Open(header)) { + delete[] header; + return false; + } + + writer_cluster_ = chunk_writer_cluster_; + writer_cues_ = chunk_writer_cues_; + writer_header_ = chunk_writer_header_; + + delete[] header; + } + + chunking_ = chunking; + + return true; +} + +bool Segment::CuesTrack(uint64_t track_number) { + const Track* const track = GetTrackByNumber(track_number); + if (!track) + return false; + + cues_track_ = track_number; + return true; +} + +void Segment::ForceNewClusterOnNextFrame() { force_new_cluster_ = true; } + +Track* Segment::GetTrackByNumber(uint64_t track_number) const { + return tracks_.GetTrackByNumber(track_number); +} + +bool Segment::WriteSegmentHeader() { + UpdateDocTypeVersion(); + + const char* const doc_type = + DocTypeIsWebm() ? kDocTypeWebm : kDocTypeMatroska; + if (!WriteEbmlHeader(writer_header_, doc_type_version_, doc_type)) + return false; + doc_type_version_written_ = doc_type_version_; + ebml_header_size_ = static_cast(writer_header_->Position()); + + // Write "unknown" (-1) as segment size value. If mode is kFile, Segment + // will write over duration when the file is finalized. + if (WriteID(writer_header_, libwebm::kMkvSegment)) + return false; + + // Save for later. + size_position_ = writer_header_->Position(); + + // Write "unknown" (EBML coded -1) as segment size value. We need to write 8 + // bytes because if we are going to overwrite the segment size later we do + // not know how big our segment will be. + if (SerializeInt(writer_header_, kEbmlUnknownValue, 8)) + return false; + + payload_pos_ = writer_header_->Position(); + + if (mode_ == kFile && writer_header_->Seekable()) { + // Set the duration > 0.0 so SegmentInfo will write out the duration. When + // the muxer is done writing we will set the correct duration and have + // SegmentInfo upadte it. + segment_info_.set_duration(1.0); + + if (!seek_head_.Write(writer_header_)) + return false; + } + + if (!seek_head_.AddSeekEntry(libwebm::kMkvInfo, MaxOffset())) + return false; + if (!segment_info_.Write(writer_header_)) + return false; + + if (!seek_head_.AddSeekEntry(libwebm::kMkvTracks, MaxOffset())) + return false; + if (!tracks_.Write(writer_header_)) + return false; + + if (chapters_.Count() > 0) { + if (!seek_head_.AddSeekEntry(libwebm::kMkvChapters, MaxOffset())) + return false; + if (!chapters_.Write(writer_header_)) + return false; + } + + if (tags_.Count() > 0) { + if (!seek_head_.AddSeekEntry(libwebm::kMkvTags, MaxOffset())) + return false; + if (!tags_.Write(writer_header_)) + return false; + } + + if (chunking_ && (mode_ == kLive || !writer_header_->Seekable())) { + if (!chunk_writer_header_) + return false; + + chunk_writer_header_->Close(); + } + + header_written_ = true; + + return true; +} + +// Here we are testing whether to create a new cluster, given a frame +// having time frame_timestamp_ns. +// +int Segment::TestFrame(uint64_t track_number, uint64_t frame_timestamp_ns, + bool is_key) const { + if (force_new_cluster_) + return 1; + + // If no clusters have been created yet, then create a new cluster + // and write this frame immediately, in the new cluster. This path + // should only be followed once, the first time we attempt to write + // a frame. + + if (cluster_list_size_ <= 0) + return 1; + + // There exists at least one cluster. We must compare the frame to + // the last cluster, in order to determine whether the frame is + // written to the existing cluster, or that a new cluster should be + // created. + + const uint64_t timecode_scale = segment_info_.timecode_scale(); + const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale; + + const Cluster* const last_cluster = cluster_list_[cluster_list_size_ - 1]; + const uint64_t last_cluster_timecode = last_cluster->timecode(); + + // For completeness we test for the case when the frame's timecode + // is less than the cluster's timecode. Although in principle that + // is allowed, this muxer doesn't actually write clusters like that, + // so this indicates a bug somewhere in our algorithm. + + if (frame_timecode < last_cluster_timecode) // should never happen + return -1; + + // If the frame has a timestamp significantly larger than the last + // cluster (in Matroska, cluster-relative timestamps are serialized + // using a 16-bit signed integer), then we cannot write this frame + // to that cluster, and so we must create a new cluster. + + const int64_t delta_timecode = frame_timecode - last_cluster_timecode; + + if (delta_timecode > kMaxBlockTimecode) + return 2; + + // We decide to create a new cluster when we have a video keyframe. + // This will flush queued (audio) frames, and write the keyframe + // immediately, in the newly-created cluster. + + if (is_key && tracks_.TrackIsVideo(track_number)) + return 1; + + // Create a new cluster if we have accumulated too many frames + // already, where "too many" is defined as "the total time of frames + // in the cluster exceeds a threshold". + + const uint64_t delta_ns = delta_timecode * timecode_scale; + + if (max_cluster_duration_ > 0 && delta_ns >= max_cluster_duration_) + return 1; + + // This is similar to the case above, with the difference that a new + // cluster is created when the size of the current cluster exceeds a + // threshold. + + const uint64_t cluster_size = last_cluster->payload_size(); + + if (max_cluster_size_ > 0 && cluster_size >= max_cluster_size_) + return 1; + + // There's no need to create a new cluster, so emit this frame now. + + return 0; +} + +bool Segment::MakeNewCluster(uint64_t frame_timestamp_ns) { + const int32_t new_size = cluster_list_size_ + 1; + + if (new_size > cluster_list_capacity_) { + // Add more clusters. + const int32_t new_capacity = + (cluster_list_capacity_ <= 0) ? 1 : cluster_list_capacity_ * 2; + Cluster** const clusters = + new (std::nothrow) Cluster*[new_capacity]; // NOLINT + if (!clusters) + return false; + + for (int32_t i = 0; i < cluster_list_size_; ++i) { + clusters[i] = cluster_list_[i]; + } + + delete[] cluster_list_; + + cluster_list_ = clusters; + cluster_list_capacity_ = new_capacity; + } + + if (!WriteFramesLessThan(frame_timestamp_ns)) + return false; + + if (cluster_list_size_ > 0) { + // Update old cluster's size + Cluster* const old_cluster = cluster_list_[cluster_list_size_ - 1]; + + if (!old_cluster || !old_cluster->Finalize(true, frame_timestamp_ns)) + return false; + } + + if (output_cues_) + new_cuepoint_ = true; + + if (chunking_ && cluster_list_size_ > 0) { + chunk_writer_cluster_->Close(); + chunk_count_++; + + if (!UpdateChunkName("chk", &chunk_name_)) + return false; + if (!chunk_writer_cluster_->Open(chunk_name_)) + return false; + } + + const uint64_t timecode_scale = segment_info_.timecode_scale(); + const uint64_t frame_timecode = frame_timestamp_ns / timecode_scale; + + uint64_t cluster_timecode = frame_timecode; + + if (frames_size_ > 0) { + const Frame* const f = frames_[0]; // earliest queued frame + const uint64_t ns = f->timestamp(); + const uint64_t tc = ns / timecode_scale; + + if (tc < cluster_timecode) + cluster_timecode = tc; + } + + Cluster*& cluster = cluster_list_[cluster_list_size_]; + const int64_t offset = MaxOffset(); + cluster = new (std::nothrow) + Cluster(cluster_timecode, offset, segment_info_.timecode_scale(), + accurate_cluster_duration_, fixed_size_cluster_timecode_); + if (!cluster) + return false; + + if (!cluster->Init(writer_cluster_)) + return false; + + cluster_list_size_ = new_size; + return true; +} + +bool Segment::DoNewClusterProcessing(uint64_t track_number, + uint64_t frame_timestamp_ns, bool is_key) { + for (;;) { + // Based on the characteristics of the current frame and current + // cluster, decide whether to create a new cluster. + const int result = TestFrame(track_number, frame_timestamp_ns, is_key); + if (result < 0) // error + return false; + + // Always set force_new_cluster_ to false after TestFrame. + force_new_cluster_ = false; + + // A non-zero result means create a new cluster. + if (result > 0 && !MakeNewCluster(frame_timestamp_ns)) + return false; + + // Write queued (audio) frames. + const int frame_count = WriteFramesAll(); + if (frame_count < 0) // error + return false; + + // Write the current frame to the current cluster (if TestFrame + // returns 0) or to a newly created cluster (TestFrame returns 1). + if (result <= 1) + return true; + + // TestFrame returned 2, which means there was a large time + // difference between the cluster and the frame itself. Do the + // test again, comparing the frame to the new cluster. + } +} + +bool Segment::CheckHeaderInfo() { + if (!header_written_) { + if (!WriteSegmentHeader()) + return false; + + if (!seek_head_.AddSeekEntry(libwebm::kMkvCluster, MaxOffset())) + return false; + + if (output_cues_ && cues_track_ == 0) { + // Check for a video track + for (uint32_t i = 0; i < tracks_.track_entries_size(); ++i) { + const Track* const track = tracks_.GetTrackByIndex(i); + if (!track) + return false; + + if (tracks_.TrackIsVideo(track->number())) { + cues_track_ = track->number(); + break; + } + } + + // Set first track found + if (cues_track_ == 0) { + const Track* const track = tracks_.GetTrackByIndex(0); + if (!track) + return false; + + cues_track_ = track->number(); + } + } + } + return true; +} + +void Segment::UpdateDocTypeVersion() { + for (uint32_t index = 0; index < tracks_.track_entries_size(); ++index) { + const Track* track = tracks_.GetTrackByIndex(index); + if (track == NULL) + break; + if ((track->codec_delay() || track->seek_pre_roll()) && + doc_type_version_ < 4) { + doc_type_version_ = 4; + break; + } + } +} + +bool Segment::UpdateChunkName(const char* ext, char** name) const { + if (!name || !ext) + return false; + + char ext_chk[64]; +#ifdef _MSC_VER + sprintf_s(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); +#else + snprintf(ext_chk, sizeof(ext_chk), "_%06d.%s", chunk_count_, ext); +#endif + + const size_t chunking_base_name_length = strlen(chunking_base_name_); + const size_t ext_chk_length = strlen(ext_chk); + const size_t length = chunking_base_name_length + ext_chk_length + 1; + char* const str = new (std::nothrow) char[length]; // NOLINT + if (!str) + return false; + + memcpy(str, chunking_base_name_, chunking_base_name_length); + memcpy(&str[chunking_base_name_length], ext_chk, ext_chk_length); + str[chunking_base_name_length + ext_chk_length] = '\0'; + + delete[] * name; + *name = str; + + return true; +} + +int64_t Segment::MaxOffset() { + if (!writer_header_) + return -1; + + int64_t offset = writer_header_->Position() - payload_pos_; + + if (chunking_) { + for (int32_t i = 0; i < cluster_list_size_; ++i) { + Cluster* const cluster = cluster_list_[i]; + offset += cluster->Size(); + } + + if (writer_cues_) + offset += writer_cues_->Position(); + } + + return offset; +} + +bool Segment::QueueFrame(Frame* frame) { + const int32_t new_size = frames_size_ + 1; + + if (new_size > frames_capacity_) { + // Add more frames. + const int32_t new_capacity = (!frames_capacity_) ? 2 : frames_capacity_ * 2; + + if (new_capacity < 1) + return false; + + Frame** const frames = new (std::nothrow) Frame*[new_capacity]; // NOLINT + if (!frames) + return false; + + for (int32_t i = 0; i < frames_size_; ++i) { + frames[i] = frames_[i]; + } + + delete[] frames_; + frames_ = frames; + frames_capacity_ = new_capacity; + } + + frames_[frames_size_++] = frame; + + return true; +} + +int Segment::WriteFramesAll() { + if (frames_ == NULL) + return 0; + + if (cluster_list_size_ < 1) + return -1; + + Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; + + if (!cluster) + return -1; + + for (int32_t i = 0; i < frames_size_; ++i) { + Frame*& frame = frames_[i]; + // TODO(jzern/vigneshv): using Segment::AddGenericFrame here would limit the + // places where |doc_type_version_| needs to be updated. + if (frame->discard_padding() != 0) + doc_type_version_ = 4; + if (!cluster->AddFrame(frame)) { + delete frame; + continue; + } + + if (new_cuepoint_ && cues_track_ == frame->track_number()) { + if (!AddCuePoint(frame->timestamp(), cues_track_)) { + delete frame; + continue; + } + } + + if (frame->timestamp() > last_timestamp_) { + last_timestamp_ = frame->timestamp(); + last_track_timestamp_[frame->track_number() - 1] = frame->timestamp(); + } + + delete frame; + frame = NULL; + } + + const int result = frames_size_; + frames_size_ = 0; + + return result; +} + +bool Segment::WriteFramesLessThan(uint64_t timestamp) { + // Check |cluster_list_size_| to see if this is the first cluster. If it is + // the first cluster the audio frames that are less than the first video + // timesatmp will be written in a later step. + if (frames_size_ > 0 && cluster_list_size_ > 0) { + if (!frames_) + return false; + + Cluster* const cluster = cluster_list_[cluster_list_size_ - 1]; + if (!cluster) + return false; + + int32_t shift_left = 0; + + // TODO(fgalligan): Change this to use the durations of frames instead of + // the next frame's start time if the duration is accurate. + for (int32_t i = 1; i < frames_size_; ++i) { + const Frame* const frame_curr = frames_[i]; + + if (frame_curr->timestamp() > timestamp) + break; + + const Frame* const frame_prev = frames_[i - 1]; + if (frame_prev->discard_padding() != 0) + doc_type_version_ = 4; + if (!cluster->AddFrame(frame_prev)) { + delete frame_prev; + continue; + } + + if (new_cuepoint_ && cues_track_ == frame_prev->track_number()) { + if (!AddCuePoint(frame_prev->timestamp(), cues_track_)) { + delete frame_prev; + continue; + } + } + + ++shift_left; + if (frame_prev->timestamp() > last_timestamp_) { + last_timestamp_ = frame_prev->timestamp(); + last_track_timestamp_[frame_prev->track_number() - 1] = + frame_prev->timestamp(); + } + + delete frame_prev; + } + + if (shift_left > 0) { + if (shift_left >= frames_size_) + return false; + + const int32_t new_frames_size = frames_size_ - shift_left; + for (int32_t i = 0; i < new_frames_size; ++i) { + frames_[i] = frames_[i + shift_left]; + } + + frames_size_ = new_frames_size; + } + } + + return true; +} + +bool Segment::DocTypeIsWebm() const { + const int kNumCodecIds = 9; + + // TODO(vigneshv): Tweak .clang-format. + const char* kWebmCodecIds[kNumCodecIds] = { + Tracks::kOpusCodecId, Tracks::kVorbisCodecId, + Tracks::kAv1CodecId, Tracks::kVp8CodecId, + Tracks::kVp9CodecId, Tracks::kWebVttCaptionsId, + Tracks::kWebVttDescriptionsId, Tracks::kWebVttMetadataId, + Tracks::kWebVttSubtitlesId}; + + const int num_tracks = static_cast(tracks_.track_entries_size()); + for (int track_index = 0; track_index < num_tracks; ++track_index) { + const Track* const track = tracks_.GetTrackByIndex(track_index); + const std::string codec_id = track->codec_id(); + + bool id_is_webm = false; + for (int id_index = 0; id_index < kNumCodecIds; ++id_index) { + if (codec_id == kWebmCodecIds[id_index]) { + id_is_webm = true; + break; + } + } + + if (!id_is_webm) + return false; + } + + return true; +} + +} // namespace mkvmuxer diff --git a/src/sys/libwebm/mkvmuxer/mkvmuxer.h b/src/sys/libwebm/mkvmuxer/mkvmuxer.h new file mode 100644 index 0000000..2c4bb9e --- /dev/null +++ b/src/sys/libwebm/mkvmuxer/mkvmuxer.h @@ -0,0 +1,1924 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#ifndef MKVMUXER_MKVMUXER_H_ +#define MKVMUXER_MKVMUXER_H_ + +#include + +#include +#include +#include + +#include "common/webmids.h" +#include "mkvmuxer/mkvmuxertypes.h" + +// For a description of the WebM elements see +// http://www.webmproject.org/code/specs/container/. + +namespace mkvparser { +class IMkvReader; +} // namespace mkvparser + +namespace mkvmuxer { + +class MkvWriter; +class Segment; + +const uint64_t kMaxTrackNumber = 126; + +/////////////////////////////////////////////////////////////// +// Interface used by the mkvmuxer to write out the Mkv data. +class IMkvWriter { + public: + // Writes out |len| bytes of |buf|. Returns 0 on success. + virtual int32 Write(const void* buf, uint32 len) = 0; + + // Returns the offset of the output position from the beginning of the + // output. + virtual int64 Position() const = 0; + + // Set the current File position. Returns 0 on success. + virtual int32 Position(int64 position) = 0; + + // Returns true if the writer is seekable. + virtual bool Seekable() const = 0; + + // Element start notification. Called whenever an element identifier is about + // to be written to the stream. |element_id| is the element identifier, and + // |position| is the location in the WebM stream where the first octet of the + // element identifier will be written. + // Note: the |MkvId| enumeration in webmids.hpp defines element values. + virtual void ElementStartNotify(uint64 element_id, int64 position) = 0; + + protected: + IMkvWriter(); + virtual ~IMkvWriter(); + + private: + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(IMkvWriter); +}; + +// Writes out the EBML header for a WebM file, but allows caller to specify +// DocType. This function must be called before any other libwebm writing +// functions are called. +bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version, + const char* const doc_type); + +// Writes out the EBML header for a WebM file. This function must be called +// before any other libwebm writing functions are called. +bool WriteEbmlHeader(IMkvWriter* writer, uint64_t doc_type_version); + +// Deprecated. Writes out EBML header with doc_type_version as +// kDefaultDocTypeVersion. Exists for backward compatibility. +bool WriteEbmlHeader(IMkvWriter* writer); + +// Copies in Chunk from source to destination between the given byte positions +bool ChunkedCopy(mkvparser::IMkvReader* source, IMkvWriter* dst, int64_t start, + int64_t size); + +/////////////////////////////////////////////////////////////// +// Class to hold data the will be written to a block. +class Frame { + public: + Frame(); + ~Frame(); + + // Sets this frame's contents based on |frame|. Returns true on success. On + // failure, this frame's existing contents may be lost. + bool CopyFrom(const Frame& frame); + + // Copies |frame| data into |frame_|. Returns true on success. + bool Init(const uint8_t* frame, uint64_t length); + + // Copies |additional| data into |additional_|. Returns true on success. + bool AddAdditionalData(const uint8_t* additional, uint64_t length, + uint64_t add_id); + + // Returns true if the frame has valid parameters. + bool IsValid() const; + + // Returns true if the frame can be written as a SimpleBlock based on current + // parameters. + bool CanBeSimpleBlock() const; + + uint64_t add_id() const { return add_id_; } + const uint8_t* additional() const { return additional_; } + uint64_t additional_length() const { return additional_length_; } + void set_duration(uint64_t duration); + uint64_t duration() const { return duration_; } + bool duration_set() const { return duration_set_; } + const uint8_t* frame() const { return frame_; } + void set_is_key(bool key) { is_key_ = key; } + bool is_key() const { return is_key_; } + uint64_t length() const { return length_; } + void set_track_number(uint64_t track_number) { track_number_ = track_number; } + uint64_t track_number() const { return track_number_; } + void set_timestamp(uint64_t timestamp) { timestamp_ = timestamp; } + uint64_t timestamp() const { return timestamp_; } + void set_discard_padding(int64_t discard_padding) { + discard_padding_ = discard_padding; + } + int64_t discard_padding() const { return discard_padding_; } + void set_reference_block_timestamp(int64_t reference_block_timestamp); + int64_t reference_block_timestamp() const { + return reference_block_timestamp_; + } + bool reference_block_timestamp_set() const { + return reference_block_timestamp_set_; + } + + private: + // Id of the Additional data. + uint64_t add_id_; + + // Pointer to additional data. Owned by this class. + uint8_t* additional_; + + // Length of the additional data. + uint64_t additional_length_; + + // Duration of the frame in nanoseconds. + uint64_t duration_; + + // Flag indicating that |duration_| has been set. Setting duration causes the + // frame to be written out as a Block with BlockDuration instead of as a + // SimpleBlock. + bool duration_set_; + + // Pointer to the data. Owned by this class. + uint8_t* frame_; + + // Flag telling if the data should set the key flag of a block. + bool is_key_; + + // Length of the data. + uint64_t length_; + + // Mkv track number the data is associated with. + uint64_t track_number_; + + // Timestamp of the data in nanoseconds. + uint64_t timestamp_; + + // Discard padding for the frame. + int64_t discard_padding_; + + // Reference block timestamp. + int64_t reference_block_timestamp_; + + // Flag indicating if |reference_block_timestamp_| has been set. + bool reference_block_timestamp_set_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Frame); +}; + +/////////////////////////////////////////////////////////////// +// Class to hold one cue point in a Cues element. +class CuePoint { + public: + CuePoint(); + ~CuePoint(); + + // Returns the size in bytes for the entire CuePoint element. + uint64_t Size() const; + + // Output the CuePoint element to the writer. Returns true on success. + bool Write(IMkvWriter* writer) const; + + void set_time(uint64_t time) { time_ = time; } + uint64_t time() const { return time_; } + void set_track(uint64_t track) { track_ = track; } + uint64_t track() const { return track_; } + void set_cluster_pos(uint64_t cluster_pos) { cluster_pos_ = cluster_pos; } + uint64_t cluster_pos() const { return cluster_pos_; } + void set_block_number(uint64_t block_number) { block_number_ = block_number; } + uint64_t block_number() const { return block_number_; } + void set_output_block_number(bool output_block_number) { + output_block_number_ = output_block_number; + } + bool output_block_number() const { return output_block_number_; } + + private: + // Returns the size in bytes for the payload of the CuePoint element. + uint64_t PayloadSize() const; + + // Absolute timecode according to the segment time base. + uint64_t time_; + + // The Track element associated with the CuePoint. + uint64_t track_; + + // The position of the Cluster containing the Block. + uint64_t cluster_pos_; + + // Number of the Block within the Cluster, starting from 1. + uint64_t block_number_; + + // If true the muxer will write out the block number for the cue if the + // block number is different than the default of 1. Default is set to true. + bool output_block_number_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(CuePoint); +}; + +/////////////////////////////////////////////////////////////// +// Cues element. +class Cues { + public: + Cues(); + ~Cues(); + + // Adds a cue point to the Cues element. Returns true on success. + bool AddCue(CuePoint* cue); + + // Returns the cue point by index. Returns NULL if there is no cue point + // match. + CuePoint* GetCueByIndex(int32_t index) const; + + // Returns the total size of the Cues element + uint64_t Size(); + + // Output the Cues element to the writer. Returns true on success. + bool Write(IMkvWriter* writer) const; + + int32_t cue_entries_size() const { return cue_entries_size_; } + void set_output_block_number(bool output_block_number) { + output_block_number_ = output_block_number; + } + bool output_block_number() const { return output_block_number_; } + + private: + // Number of allocated elements in |cue_entries_|. + int32_t cue_entries_capacity_; + + // Number of CuePoints in |cue_entries_|. + int32_t cue_entries_size_; + + // CuePoint list. + CuePoint** cue_entries_; + + // If true the muxer will write out the block number for the cue if the + // block number is different than the default of 1. Default is set to true. + bool output_block_number_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cues); +}; + +/////////////////////////////////////////////////////////////// +// ContentEncAESSettings element +class ContentEncAESSettings { + public: + enum { kCTR = 1 }; + + ContentEncAESSettings(); + ~ContentEncAESSettings() {} + + // Returns the size in bytes for the ContentEncAESSettings element. + uint64_t Size() const; + + // Writes out the ContentEncAESSettings element to |writer|. Returns true on + // success. + bool Write(IMkvWriter* writer) const; + + uint64_t cipher_mode() const { return cipher_mode_; } + + private: + // Returns the size in bytes for the payload of the ContentEncAESSettings + // element. + uint64_t PayloadSize() const; + + // Sub elements + uint64_t cipher_mode_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncAESSettings); +}; + +/////////////////////////////////////////////////////////////// +// ContentEncoding element +// Elements used to describe if the track data has been encrypted or +// compressed with zlib or header stripping. +// Currently only whole frames can be encrypted with AES. This dictates that +// ContentEncodingOrder will be 0, ContentEncodingScope will be 1, +// ContentEncodingType will be 1, and ContentEncAlgo will be 5. +class ContentEncoding { + public: + ContentEncoding(); + ~ContentEncoding(); + + // Sets the content encryption id. Copies |length| bytes from |id| to + // |enc_key_id_|. Returns true on success. + bool SetEncryptionID(const uint8_t* id, uint64_t length); + + // Returns the size in bytes for the ContentEncoding element. + uint64_t Size() const; + + // Writes out the ContentEncoding element to |writer|. Returns true on + // success. + bool Write(IMkvWriter* writer) const; + + uint64_t enc_algo() const { return enc_algo_; } + uint64_t encoding_order() const { return encoding_order_; } + uint64_t encoding_scope() const { return encoding_scope_; } + uint64_t encoding_type() const { return encoding_type_; } + ContentEncAESSettings* enc_aes_settings() { return &enc_aes_settings_; } + + private: + // Returns the size in bytes for the encoding elements. + uint64_t EncodingSize(uint64_t compression_size, + uint64_t encryption_size) const; + + // Returns the size in bytes for the encryption elements. + uint64_t EncryptionSize() const; + + // Track element names + uint64_t enc_algo_; + uint8_t* enc_key_id_; + uint64_t encoding_order_; + uint64_t encoding_scope_; + uint64_t encoding_type_; + + // ContentEncAESSettings element. + ContentEncAESSettings enc_aes_settings_; + + // Size of the ContentEncKeyID data in bytes. + uint64_t enc_key_id_length_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding); +}; + +/////////////////////////////////////////////////////////////// +// Colour element. +class PrimaryChromaticity { + public: + static const float kChromaticityMin; + static const float kChromaticityMax; + + PrimaryChromaticity(float x_val, float y_val) : x_(x_val), y_(y_val) {} + PrimaryChromaticity() : x_(0), y_(0) {} + ~PrimaryChromaticity() {} + + // Returns sum of |x_id| and |y_id| element id sizes and payload sizes. + uint64_t PrimaryChromaticitySize(libwebm::MkvId x_id, + libwebm::MkvId y_id) const; + bool Valid() const; + bool Write(IMkvWriter* writer, libwebm::MkvId x_id, + libwebm::MkvId y_id) const; + + float x() const { return x_; } + void set_x(float new_x) { x_ = new_x; } + float y() const { return y_; } + void set_y(float new_y) { y_ = new_y; } + + private: + float x_; + float y_; +}; + +class MasteringMetadata { + public: + static const float kValueNotPresent; + static const float kMinLuminance; + static const float kMinLuminanceMax; + static const float kMaxLuminanceMax; + + MasteringMetadata() + : luminance_max_(kValueNotPresent), + luminance_min_(kValueNotPresent), + r_(NULL), + g_(NULL), + b_(NULL), + white_point_(NULL) {} + ~MasteringMetadata() { + delete r_; + delete g_; + delete b_; + delete white_point_; + } + + // Returns total size of the MasteringMetadata element. + uint64_t MasteringMetadataSize() const; + bool Valid() const; + bool Write(IMkvWriter* writer) const; + + // Copies non-null chromaticity. + bool SetChromaticity(const PrimaryChromaticity* r, + const PrimaryChromaticity* g, + const PrimaryChromaticity* b, + const PrimaryChromaticity* white_point); + const PrimaryChromaticity* r() const { return r_; } + const PrimaryChromaticity* g() const { return g_; } + const PrimaryChromaticity* b() const { return b_; } + const PrimaryChromaticity* white_point() const { return white_point_; } + + float luminance_max() const { return luminance_max_; } + void set_luminance_max(float luminance_max) { + luminance_max_ = luminance_max; + } + float luminance_min() const { return luminance_min_; } + void set_luminance_min(float luminance_min) { + luminance_min_ = luminance_min; + } + + private: + // Returns size of MasteringMetadata child elements. + uint64_t PayloadSize() const; + + float luminance_max_; + float luminance_min_; + PrimaryChromaticity* r_; + PrimaryChromaticity* g_; + PrimaryChromaticity* b_; + PrimaryChromaticity* white_point_; +}; + +class Colour { + public: + enum MatrixCoefficients { + kGbr = 0, + kBt709 = 1, + kUnspecifiedMc = 2, + kReserved = 3, + kFcc = 4, + kBt470bg = 5, + kSmpte170MMc = 6, + kSmpte240MMc = 7, + kYcocg = 8, + kBt2020NonConstantLuminance = 9, + kBt2020ConstantLuminance = 10, + }; + enum ChromaSitingHorz { + kUnspecifiedCsh = 0, + kLeftCollocated = 1, + kHalfCsh = 2, + }; + enum ChromaSitingVert { + kUnspecifiedCsv = 0, + kTopCollocated = 1, + kHalfCsv = 2, + }; + enum Range { + kUnspecifiedCr = 0, + kBroadcastRange = 1, + kFullRange = 2, + kMcTcDefined = 3, // Defined by MatrixCoefficients/TransferCharacteristics. + }; + enum TransferCharacteristics { + kIturBt709Tc = 1, + kUnspecifiedTc = 2, + kReservedTc = 3, + kGamma22Curve = 4, + kGamma28Curve = 5, + kSmpte170MTc = 6, + kSmpte240MTc = 7, + kLinear = 8, + kLog = 9, + kLogSqrt = 10, + kIec6196624 = 11, + kIturBt1361ExtendedColourGamut = 12, + kIec6196621 = 13, + kIturBt202010bit = 14, + kIturBt202012bit = 15, + kSmpteSt2084 = 16, + kSmpteSt4281Tc = 17, + kAribStdB67Hlg = 18, + }; + enum Primaries { + kReservedP0 = 0, + kIturBt709P = 1, + kUnspecifiedP = 2, + kReservedP3 = 3, + kIturBt470M = 4, + kIturBt470Bg = 5, + kSmpte170MP = 6, + kSmpte240MP = 7, + kFilm = 8, + kIturBt2020 = 9, + kSmpteSt4281P = 10, + kJedecP22Phosphors = 22, + }; + static const uint64_t kValueNotPresent; + Colour() + : matrix_coefficients_(kValueNotPresent), + bits_per_channel_(kValueNotPresent), + chroma_subsampling_horz_(kValueNotPresent), + chroma_subsampling_vert_(kValueNotPresent), + cb_subsampling_horz_(kValueNotPresent), + cb_subsampling_vert_(kValueNotPresent), + chroma_siting_horz_(kValueNotPresent), + chroma_siting_vert_(kValueNotPresent), + range_(kValueNotPresent), + transfer_characteristics_(kValueNotPresent), + primaries_(kValueNotPresent), + max_cll_(kValueNotPresent), + max_fall_(kValueNotPresent), + mastering_metadata_(NULL) {} + ~Colour() { delete mastering_metadata_; } + + // Returns total size of the Colour element. + uint64_t ColourSize() const; + bool Valid() const; + bool Write(IMkvWriter* writer) const; + + // Deep copies |mastering_metadata|. + bool SetMasteringMetadata(const MasteringMetadata& mastering_metadata); + + const MasteringMetadata* mastering_metadata() const { + return mastering_metadata_; + } + + uint64_t matrix_coefficients() const { return matrix_coefficients_; } + void set_matrix_coefficients(uint64_t matrix_coefficients) { + matrix_coefficients_ = matrix_coefficients; + } + uint64_t bits_per_channel() const { return bits_per_channel_; } + void set_bits_per_channel(uint64_t bits_per_channel) { + bits_per_channel_ = bits_per_channel; + } + uint64_t chroma_subsampling_horz() const { return chroma_subsampling_horz_; } + void set_chroma_subsampling_horz(uint64_t chroma_subsampling_horz) { + chroma_subsampling_horz_ = chroma_subsampling_horz; + } + uint64_t chroma_subsampling_vert() const { return chroma_subsampling_vert_; } + void set_chroma_subsampling_vert(uint64_t chroma_subsampling_vert) { + chroma_subsampling_vert_ = chroma_subsampling_vert; + } + uint64_t cb_subsampling_horz() const { return cb_subsampling_horz_; } + void set_cb_subsampling_horz(uint64_t cb_subsampling_horz) { + cb_subsampling_horz_ = cb_subsampling_horz; + } + uint64_t cb_subsampling_vert() const { return cb_subsampling_vert_; } + void set_cb_subsampling_vert(uint64_t cb_subsampling_vert) { + cb_subsampling_vert_ = cb_subsampling_vert; + } + uint64_t chroma_siting_horz() const { return chroma_siting_horz_; } + void set_chroma_siting_horz(uint64_t chroma_siting_horz) { + chroma_siting_horz_ = chroma_siting_horz; + } + uint64_t chroma_siting_vert() const { return chroma_siting_vert_; } + void set_chroma_siting_vert(uint64_t chroma_siting_vert) { + chroma_siting_vert_ = chroma_siting_vert; + } + uint64_t range() const { return range_; } + void set_range(uint64_t range) { range_ = range; } + uint64_t transfer_characteristics() const { + return transfer_characteristics_; + } + void set_transfer_characteristics(uint64_t transfer_characteristics) { + transfer_characteristics_ = transfer_characteristics; + } + uint64_t primaries() const { return primaries_; } + void set_primaries(uint64_t primaries) { primaries_ = primaries; } + uint64_t max_cll() const { return max_cll_; } + void set_max_cll(uint64_t max_cll) { max_cll_ = max_cll; } + uint64_t max_fall() const { return max_fall_; } + void set_max_fall(uint64_t max_fall) { max_fall_ = max_fall; } + + private: + // Returns size of Colour child elements. + uint64_t PayloadSize() const; + + uint64_t matrix_coefficients_; + uint64_t bits_per_channel_; + uint64_t chroma_subsampling_horz_; + uint64_t chroma_subsampling_vert_; + uint64_t cb_subsampling_horz_; + uint64_t cb_subsampling_vert_; + uint64_t chroma_siting_horz_; + uint64_t chroma_siting_vert_; + uint64_t range_; + uint64_t transfer_characteristics_; + uint64_t primaries_; + uint64_t max_cll_; + uint64_t max_fall_; + + MasteringMetadata* mastering_metadata_; +}; + +/////////////////////////////////////////////////////////////// +// Projection element. +class Projection { + public: + enum ProjectionType { + kTypeNotPresent = -1, + kRectangular = 0, + kEquirectangular = 1, + kCubeMap = 2, + kMesh = 3, + }; + static const uint64_t kValueNotPresent; + Projection() + : type_(kRectangular), + pose_yaw_(0.0), + pose_pitch_(0.0), + pose_roll_(0.0), + private_data_(NULL), + private_data_length_(0) {} + ~Projection() { delete[] private_data_; } + + uint64_t ProjectionSize() const; + bool Write(IMkvWriter* writer) const; + + bool SetProjectionPrivate(const uint8_t* private_data, + uint64_t private_data_length); + + ProjectionType type() const { return type_; } + void set_type(ProjectionType type) { type_ = type; } + float pose_yaw() const { return pose_yaw_; } + void set_pose_yaw(float pose_yaw) { pose_yaw_ = pose_yaw; } + float pose_pitch() const { return pose_pitch_; } + void set_pose_pitch(float pose_pitch) { pose_pitch_ = pose_pitch; } + float pose_roll() const { return pose_roll_; } + void set_pose_roll(float pose_roll) { pose_roll_ = pose_roll; } + uint8_t* private_data() const { return private_data_; } + uint64_t private_data_length() const { return private_data_length_; } + + private: + // Returns size of VideoProjection child elements. + uint64_t PayloadSize() const; + + ProjectionType type_; + float pose_yaw_; + float pose_pitch_; + float pose_roll_; + uint8_t* private_data_; + uint64_t private_data_length_; +}; + +/////////////////////////////////////////////////////////////// +// Track element. +class Track { + public: + // The |seed| parameter is used to synthesize a UID for the track. + explicit Track(unsigned int* seed); + virtual ~Track(); + + // Adds a ContentEncoding element to the Track. Returns true on success. + virtual bool AddContentEncoding(); + + // Returns the ContentEncoding by index. Returns NULL if there is no + // ContentEncoding match. + ContentEncoding* GetContentEncodingByIndex(uint32_t index) const; + + // Returns the size in bytes for the payload of the Track element. + virtual uint64_t PayloadSize() const; + + // Returns the size in bytes of the Track element. + virtual uint64_t Size() const; + + // Output the Track element to the writer. Returns true on success. + virtual bool Write(IMkvWriter* writer) const; + + // Sets the CodecPrivate element of the Track element. Copies |length| + // bytes from |codec_private| to |codec_private_|. Returns true on success. + bool SetCodecPrivate(const uint8_t* codec_private, uint64_t length); + + void set_codec_id(const char* codec_id); + const char* codec_id() const { return codec_id_; } + const uint8_t* codec_private() const { return codec_private_; } + void set_language(const char* language); + const char* language() const { return language_; } + void set_max_block_additional_id(uint64_t max_block_additional_id) { + max_block_additional_id_ = max_block_additional_id; + } + uint64_t max_block_additional_id() const { return max_block_additional_id_; } + void set_name(const char* name); + const char* name() const { return name_; } + void set_number(uint64_t number) { number_ = number; } + uint64_t number() const { return number_; } + void set_type(uint64_t type) { type_ = type; } + uint64_t type() const { return type_; } + void set_uid(uint64_t uid) { uid_ = uid; } + uint64_t uid() const { return uid_; } + void set_codec_delay(uint64_t codec_delay) { codec_delay_ = codec_delay; } + uint64_t codec_delay() const { return codec_delay_; } + void set_seek_pre_roll(uint64_t seek_pre_roll) { + seek_pre_roll_ = seek_pre_roll; + } + uint64_t seek_pre_roll() const { return seek_pre_roll_; } + void set_default_duration(uint64_t default_duration) { + default_duration_ = default_duration; + } + uint64_t default_duration() const { return default_duration_; } + + uint64_t codec_private_length() const { return codec_private_length_; } + uint32_t content_encoding_entries_size() const { + return content_encoding_entries_size_; + } + + private: + // Track element names. + char* codec_id_; + uint8_t* codec_private_; + char* language_; + uint64_t max_block_additional_id_; + char* name_; + uint64_t number_; + uint64_t type_; + uint64_t uid_; + uint64_t codec_delay_; + uint64_t seek_pre_roll_; + uint64_t default_duration_; + + // Size of the CodecPrivate data in bytes. + uint64_t codec_private_length_; + + // ContentEncoding element list. + ContentEncoding** content_encoding_entries_; + + // Number of ContentEncoding elements added. + uint32_t content_encoding_entries_size_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Track); +}; + +/////////////////////////////////////////////////////////////// +// Track that has video specific elements. +class VideoTrack : public Track { + public: + // Supported modes for stereo 3D. + enum StereoMode { + kMono = 0, + kSideBySideLeftIsFirst = 1, + kTopBottomRightIsFirst = 2, + kTopBottomLeftIsFirst = 3, + kSideBySideRightIsFirst = 11 + }; + + enum AlphaMode { kNoAlpha = 0, kAlpha = 1 }; + + // The |seed| parameter is used to synthesize a UID for the track. + explicit VideoTrack(unsigned int* seed); + virtual ~VideoTrack(); + + // Returns the size in bytes for the payload of the Track element plus the + // video specific elements. + virtual uint64_t PayloadSize() const; + + // Output the VideoTrack element to the writer. Returns true on success. + virtual bool Write(IMkvWriter* writer) const; + + // Sets the video's stereo mode. Returns true on success. + bool SetStereoMode(uint64_t stereo_mode); + + // Sets the video's alpha mode. Returns true on success. + bool SetAlphaMode(uint64_t alpha_mode); + + void set_display_height(uint64_t height) { display_height_ = height; } + uint64_t display_height() const { return display_height_; } + void set_display_width(uint64_t width) { display_width_ = width; } + uint64_t display_width() const { return display_width_; } + void set_pixel_height(uint64_t height) { pixel_height_ = height; } + uint64_t pixel_height() const { return pixel_height_; } + void set_pixel_width(uint64_t width) { pixel_width_ = width; } + uint64_t pixel_width() const { return pixel_width_; } + + void set_crop_left(uint64_t crop_left) { crop_left_ = crop_left; } + uint64_t crop_left() const { return crop_left_; } + void set_crop_right(uint64_t crop_right) { crop_right_ = crop_right; } + uint64_t crop_right() const { return crop_right_; } + void set_crop_top(uint64_t crop_top) { crop_top_ = crop_top; } + uint64_t crop_top() const { return crop_top_; } + void set_crop_bottom(uint64_t crop_bottom) { crop_bottom_ = crop_bottom; } + uint64_t crop_bottom() const { return crop_bottom_; } + + void set_frame_rate(double frame_rate) { frame_rate_ = frame_rate; } + double frame_rate() const { return frame_rate_; } + void set_height(uint64_t height) { height_ = height; } + uint64_t height() const { return height_; } + uint64_t stereo_mode() { return stereo_mode_; } + uint64_t alpha_mode() { return alpha_mode_; } + void set_width(uint64_t width) { width_ = width; } + uint64_t width() const { return width_; } + void set_colour_space(const char* colour_space); + const char* colour_space() const { return colour_space_; } + + Colour* colour() { return colour_; } + + // Deep copies |colour|. + bool SetColour(const Colour& colour); + + Projection* projection() { return projection_; } + + // Deep copies |projection|. + bool SetProjection(const Projection& projection); + + private: + // Returns the size in bytes of the Video element. + uint64_t VideoPayloadSize() const; + + // Video track element names. + uint64_t display_height_; + uint64_t display_width_; + uint64_t pixel_height_; + uint64_t pixel_width_; + uint64_t crop_left_; + uint64_t crop_right_; + uint64_t crop_top_; + uint64_t crop_bottom_; + double frame_rate_; + uint64_t height_; + uint64_t stereo_mode_; + uint64_t alpha_mode_; + uint64_t width_; + char* colour_space_; + + Colour* colour_; + Projection* projection_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack); +}; + +/////////////////////////////////////////////////////////////// +// Track that has audio specific elements. +class AudioTrack : public Track { + public: + // The |seed| parameter is used to synthesize a UID for the track. + explicit AudioTrack(unsigned int* seed); + virtual ~AudioTrack(); + + // Returns the size in bytes for the payload of the Track element plus the + // audio specific elements. + virtual uint64_t PayloadSize() const; + + // Output the AudioTrack element to the writer. Returns true on success. + virtual bool Write(IMkvWriter* writer) const; + + void set_bit_depth(uint64_t bit_depth) { bit_depth_ = bit_depth; } + uint64_t bit_depth() const { return bit_depth_; } + void set_channels(uint64_t channels) { channels_ = channels; } + uint64_t channels() const { return channels_; } + void set_sample_rate(double sample_rate) { sample_rate_ = sample_rate; } + double sample_rate() const { return sample_rate_; } + + private: + // Audio track element names. + uint64_t bit_depth_; + uint64_t channels_; + double sample_rate_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(AudioTrack); +}; + +/////////////////////////////////////////////////////////////// +// Tracks element +class Tracks { + public: + // Audio and video type defined by the Matroska specs. + enum { kVideo = 0x1, kAudio = 0x2 }; + + static const char kOpusCodecId[]; + static const char kVorbisCodecId[]; + static const char kAv1CodecId[]; + static const char kVp8CodecId[]; + static const char kVp9CodecId[]; + static const char kWebVttCaptionsId[]; + static const char kWebVttDescriptionsId[]; + static const char kWebVttMetadataId[]; + static const char kWebVttSubtitlesId[]; + + Tracks(); + ~Tracks(); + + // Adds a Track element to the Tracks object. |track| will be owned and + // deleted by the Tracks object. Returns true on success. |number| is the + // number to use for the track. |number| must be >= 0. If |number| == 0 + // then the muxer will decide on the track number. + bool AddTrack(Track* track, int32_t number); + + // Returns the track by index. Returns NULL if there is no track match. + const Track* GetTrackByIndex(uint32_t idx) const; + + // Search the Tracks and return the track that matches |tn|. Returns NULL + // if there is no track match. + Track* GetTrackByNumber(uint64_t track_number) const; + + // Returns true if the track number is an audio track. + bool TrackIsAudio(uint64_t track_number) const; + + // Returns true if the track number is a video track. + bool TrackIsVideo(uint64_t track_number) const; + + // Output the Tracks element to the writer. Returns true on success. + bool Write(IMkvWriter* writer) const; + + uint32_t track_entries_size() const { return track_entries_size_; } + + private: + // Track element list. + Track** track_entries_; + + // Number of Track elements added. + uint32_t track_entries_size_; + + // Whether or not Tracks element has already been written via IMkvWriter. + mutable bool wrote_tracks_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tracks); +}; + +/////////////////////////////////////////////////////////////// +// Chapter element +// +class Chapter { + public: + // Set the identifier for this chapter. (This corresponds to the + // Cue Identifier line in WebVTT.) + // TODO(matthewjheaney): the actual serialization of this item in + // MKV is pending. + bool set_id(const char* id); + + // Converts the nanosecond start and stop times of this chapter to + // their corresponding timecode values, and stores them that way. + void set_time(const Segment& segment, uint64_t start_time_ns, + uint64_t end_time_ns); + + // Sets the uid for this chapter. Primarily used to enable + // deterministic output from the muxer. + void set_uid(const uint64_t uid) { uid_ = uid; } + + // Add a title string to this chapter, per the semantics described + // here: + // http://www.matroska.org/technical/specs/index.html + // + // The title ("chapter string") is a UTF-8 string. + // + // The language has ISO 639-2 representation, described here: + // http://www.loc.gov/standards/iso639-2/englangn.html + // http://www.loc.gov/standards/iso639-2/php/English_list.php + // If you specify NULL as the language value, this implies + // English ("eng"). + // + // The country value corresponds to the codes listed here: + // http://www.iana.org/domains/root/db/ + // + // The function returns false if the string could not be allocated. + bool add_string(const char* title, const char* language, const char* country); + + private: + friend class Chapters; + + // For storage of chapter titles that differ by language. + class Display { + public: + // Establish representation invariant for new Display object. + void Init(); + + // Reclaim resources, in anticipation of destruction. + void Clear(); + + // Copies the title to the |title_| member. Returns false on + // error. + bool set_title(const char* title); + + // Copies the language to the |language_| member. Returns false + // on error. + bool set_language(const char* language); + + // Copies the country to the |country_| member. Returns false on + // error. + bool set_country(const char* country); + + // If |writer| is non-NULL, serialize the Display sub-element of + // the Atom into the stream. Returns the Display element size on + // success, 0 if error. + uint64_t WriteDisplay(IMkvWriter* writer) const; + + private: + char* title_; + char* language_; + char* country_; + }; + + Chapter(); + ~Chapter(); + + // Establish the representation invariant for a newly-created + // Chapter object. The |seed| parameter is used to create the UID + // for this chapter atom. + void Init(unsigned int* seed); + + // Copies this Chapter object to a different one. This is used when + // expanding a plain array of Chapter objects (see Chapters). + void ShallowCopy(Chapter* dst) const; + + // Reclaim resources used by this Chapter object, pending its + // destruction. + void Clear(); + + // If there is no storage remaining on the |displays_| array for a + // new display object, creates a new, longer array and copies the + // existing Display objects to the new array. Returns false if the + // array cannot be expanded. + bool ExpandDisplaysArray(); + + // If |writer| is non-NULL, serialize the Atom sub-element into the + // stream. Returns the total size of the element on success, 0 if + // error. + uint64_t WriteAtom(IMkvWriter* writer) const; + + // The string identifier for this chapter (corresponds to WebVTT cue + // identifier). + char* id_; + + // Start timecode of the chapter. + uint64_t start_timecode_; + + // Stop timecode of the chapter. + uint64_t end_timecode_; + + // The binary identifier for this chapter. + uint64_t uid_; + + // The Atom element can contain multiple Display sub-elements, as + // the same logical title can be rendered in different languages. + Display* displays_; + + // The physical length (total size) of the |displays_| array. + int displays_size_; + + // The logical length (number of active elements) on the |displays_| + // array. + int displays_count_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapter); +}; + +/////////////////////////////////////////////////////////////// +// Chapters element +// +class Chapters { + public: + Chapters(); + ~Chapters(); + + Chapter* AddChapter(unsigned int* seed); + + // Returns the number of chapters that have been added. + int Count() const; + + // Output the Chapters element to the writer. Returns true on success. + bool Write(IMkvWriter* writer) const; + + private: + // Expands the chapters_ array if there is not enough space to contain + // another chapter object. Returns true on success. + bool ExpandChaptersArray(); + + // If |writer| is non-NULL, serialize the Edition sub-element of the + // Chapters element into the stream. Returns the Edition element + // size on success, 0 if error. + uint64_t WriteEdition(IMkvWriter* writer) const; + + // Total length of the chapters_ array. + int chapters_size_; + + // Number of active chapters on the chapters_ array. + int chapters_count_; + + // Array for storage of chapter objects. + Chapter* chapters_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Chapters); +}; + +/////////////////////////////////////////////////////////////// +// Tag element +// +class Tag { + public: + bool add_simple_tag(const char* tag_name, const char* tag_string); + + private: + // Tags calls Clear and the destructor of Tag + friend class Tags; + + // For storage of simple tags + class SimpleTag { + public: + // Establish representation invariant for new SimpleTag object. + void Init(); + + // Reclaim resources, in anticipation of destruction. + void Clear(); + + // Copies the title to the |tag_name_| member. Returns false on + // error. + bool set_tag_name(const char* tag_name); + + // Copies the language to the |tag_string_| member. Returns false + // on error. + bool set_tag_string(const char* tag_string); + + // If |writer| is non-NULL, serialize the SimpleTag sub-element of + // the Atom into the stream. Returns the SimpleTag element size on + // success, 0 if error. + uint64_t Write(IMkvWriter* writer) const; + + private: + char* tag_name_; + char* tag_string_; + }; + + Tag(); + ~Tag(); + + // Copies this Tag object to a different one. This is used when + // expanding a plain array of Tag objects (see Tags). + void ShallowCopy(Tag* dst) const; + + // Reclaim resources used by this Tag object, pending its + // destruction. + void Clear(); + + // If there is no storage remaining on the |simple_tags_| array for a + // new display object, creates a new, longer array and copies the + // existing SimpleTag objects to the new array. Returns false if the + // array cannot be expanded. + bool ExpandSimpleTagsArray(); + + // If |writer| is non-NULL, serialize the Tag sub-element into the + // stream. Returns the total size of the element on success, 0 if + // error. + uint64_t Write(IMkvWriter* writer) const; + + // The Atom element can contain multiple SimpleTag sub-elements + SimpleTag* simple_tags_; + + // The physical length (total size) of the |simple_tags_| array. + int simple_tags_size_; + + // The logical length (number of active elements) on the |simple_tags_| + // array. + int simple_tags_count_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tag); +}; + +/////////////////////////////////////////////////////////////// +// Tags element +// +class Tags { + public: + Tags(); + ~Tags(); + + Tag* AddTag(); + + // Returns the number of tags that have been added. + int Count() const; + + // Output the Tags element to the writer. Returns true on success. + bool Write(IMkvWriter* writer) const; + + private: + // Expands the tags_ array if there is not enough space to contain + // another tag object. Returns true on success. + bool ExpandTagsArray(); + + // Total length of the tags_ array. + int tags_size_; + + // Number of active tags on the tags_ array. + int tags_count_; + + // Array for storage of tag objects. + Tag* tags_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Tags); +}; + +/////////////////////////////////////////////////////////////// +// Cluster element +// +// Notes: +// |Init| must be called before any other method in this class. +class Cluster { + public: + // |timecode| is the absolute timecode of the cluster. |cues_pos| is the + // position for the cluster within the segment that should be written in + // the cues element. |timecode_scale| is the timecode scale of the segment. + Cluster(uint64_t timecode, int64_t cues_pos, uint64_t timecode_scale, + bool write_last_frame_with_duration = false, + bool fixed_size_timecode = false); + ~Cluster(); + + bool Init(IMkvWriter* ptr_writer); + + // Adds a frame to be output in the file. The frame is written out through + // |writer_| if successful. Returns true on success. + bool AddFrame(const Frame* frame); + + // Adds a frame to be output in the file. The frame is written out through + // |writer_| if successful. Returns true on success. + // Inputs: + // data: Pointer to the data + // length: Length of the data + // track_number: Track to add the data to. Value returned by Add track + // functions. The range of allowed values is [1, 126]. + // timecode: Absolute (not relative to cluster) timestamp of the + // frame, expressed in timecode units. + // is_key: Flag telling whether or not this frame is a key frame. + bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number, + uint64_t timecode, // timecode units (absolute) + bool is_key); + + // Adds a frame to be output in the file. The frame is written out through + // |writer_| if successful. Returns true on success. + // Inputs: + // data: Pointer to the data + // length: Length of the data + // additional: Pointer to the additional data + // additional_length: Length of the additional data + // add_id: Value of BlockAddID element + // track_number: Track to add the data to. Value returned by Add track + // functions. The range of allowed values is [1, 126]. + // abs_timecode: Absolute (not relative to cluster) timestamp of the + // frame, expressed in timecode units. + // is_key: Flag telling whether or not this frame is a key frame. + bool AddFrameWithAdditional(const uint8_t* data, uint64_t length, + const uint8_t* additional, + uint64_t additional_length, uint64_t add_id, + uint64_t track_number, uint64_t abs_timecode, + bool is_key); + + // Adds a frame to be output in the file. The frame is written out through + // |writer_| if successful. Returns true on success. + // Inputs: + // data: Pointer to the data. + // length: Length of the data. + // discard_padding: DiscardPadding element value. + // track_number: Track to add the data to. Value returned by Add track + // functions. The range of allowed values is [1, 126]. + // abs_timecode: Absolute (not relative to cluster) timestamp of the + // frame, expressed in timecode units. + // is_key: Flag telling whether or not this frame is a key frame. + bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, + int64_t discard_padding, + uint64_t track_number, uint64_t abs_timecode, + bool is_key); + + // Writes a frame of metadata to the output medium; returns true on + // success. + // Inputs: + // data: Pointer to the data + // length: Length of the data + // track_number: Track to add the data to. Value returned by Add track + // functions. The range of allowed values is [1, 126]. + // timecode: Absolute (not relative to cluster) timestamp of the + // metadata frame, expressed in timecode units. + // duration: Duration of metadata frame, in timecode units. + // + // The metadata frame is written as a block group, with a duration + // sub-element but no reference time sub-elements (indicating that + // it is considered a keyframe, per Matroska semantics). + bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number, + uint64_t timecode, uint64_t duration); + + // Increments the size of the cluster's data in bytes. + void AddPayloadSize(uint64_t size); + + // Closes the cluster so no more data can be written to it. Will update the + // cluster's size if |writer_| is seekable. Returns true on success. This + // variant of Finalize() fails when |write_last_frame_with_duration_| is set + // to true. + bool Finalize(); + + // Closes the cluster so no more data can be written to it. Will update the + // cluster's size if |writer_| is seekable. Returns true on success. + // Inputs: + // set_last_frame_duration: Boolean indicating whether or not the duration + // of the last frame should be set. If set to + // false, the |duration| value is ignored and + // |write_last_frame_with_duration_| will not be + // honored. + // duration: Duration of the Cluster in timecode scale. + bool Finalize(bool set_last_frame_duration, uint64_t duration); + + // Returns the size in bytes for the entire Cluster element. + uint64_t Size() const; + + // Given |abs_timecode|, calculates timecode relative to most recent timecode. + // Returns -1 on failure, or a relative timecode. + int64_t GetRelativeTimecode(int64_t abs_timecode) const; + + int64_t size_position() const { return size_position_; } + int32_t blocks_added() const { return blocks_added_; } + uint64_t payload_size() const { return payload_size_; } + int64_t position_for_cues() const { return position_for_cues_; } + uint64_t timecode() const { return timecode_; } + uint64_t timecode_scale() const { return timecode_scale_; } + void set_write_last_frame_with_duration(bool write_last_frame_with_duration) { + write_last_frame_with_duration_ = write_last_frame_with_duration; + } + bool write_last_frame_with_duration() const { + return write_last_frame_with_duration_; + } + + private: + // Iterator type for the |stored_frames_| map. + typedef std::map >::iterator FrameMapIterator; + + // Utility method that confirms that blocks can still be added, and that the + // cluster header has been written. Used by |DoWriteFrame*|. Returns true + // when successful. + bool PreWriteBlock(); + + // Utility method used by the |DoWriteFrame*| methods that handles the book + // keeping required after each block is written. + void PostWriteBlock(uint64_t element_size); + + // Does some verification and calls WriteFrame. + bool DoWriteFrame(const Frame* const frame); + + // Either holds back the given frame, or writes it out depending on whether or + // not |write_last_frame_with_duration_| is set. + bool QueueOrWriteFrame(const Frame* const frame); + + // Outputs the Cluster header to |writer_|. Returns true on success. + bool WriteClusterHeader(); + + // Number of blocks added to the cluster. + int32_t blocks_added_; + + // Flag telling if the cluster has been closed. + bool finalized_; + + // Flag indicating whether the cluster's timecode will always be written out + // using 8 bytes. + bool fixed_size_timecode_; + + // Flag telling if the cluster's header has been written. + bool header_written_; + + // The size of the cluster elements in bytes. + uint64_t payload_size_; + + // The file position used for cue points. + const int64_t position_for_cues_; + + // The file position of the cluster's size element. + int64_t size_position_; + + // The absolute timecode of the cluster. + const uint64_t timecode_; + + // The timecode scale of the Segment containing the cluster. + const uint64_t timecode_scale_; + + // Flag indicating whether the last frame of the cluster should be written as + // a Block with Duration. If set to true, then it will result in holding back + // of frames and the parameterized version of Finalize() must be called to + // finish writing the Cluster. + bool write_last_frame_with_duration_; + + // Map used to hold back frames, if required. Track number is the key. + std::map > stored_frames_; + + // Map from track number to the timestamp of the last block written for that + // track. + std::map last_block_timestamp_; + + // Pointer to the writer object. Not owned by this class. + IMkvWriter* writer_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Cluster); +}; + +/////////////////////////////////////////////////////////////// +// SeekHead element +class SeekHead { + public: + SeekHead(); + ~SeekHead(); + + // TODO(fgalligan): Change this to reserve a certain size. Then check how + // big the seek entry to be added is as not every seek entry will be the + // maximum size it could be. + // Adds a seek entry to be written out when the element is finalized. |id| + // must be the coded mkv element id. |pos| is the file position of the + // element. Returns true on success. + bool AddSeekEntry(uint32_t id, uint64_t pos); + + // Writes out SeekHead and SeekEntry elements. Returns true on success. + bool Finalize(IMkvWriter* writer) const; + + // Returns the id of the Seek Entry at the given index. Returns -1 if index is + // out of range. + uint32_t GetId(int index) const; + + // Returns the position of the Seek Entry at the given index. Returns -1 if + // index is out of range. + uint64_t GetPosition(int index) const; + + // Sets the Seek Entry id and position at given index. + // Returns true on success. + bool SetSeekEntry(int index, uint32_t id, uint64_t position); + + // Reserves space by writing out a Void element which will be updated with + // a SeekHead element later. Returns true on success. + bool Write(IMkvWriter* writer); + + // We are going to put a cap on the number of Seek Entries. + constexpr static int32_t kSeekEntryCount = 5; + + private: + // Returns the maximum size in bytes of one seek entry. + uint64_t MaxEntrySize() const; + + // Seek entry id element list. + uint32_t seek_entry_id_[kSeekEntryCount]; + + // Seek entry pos element list. + uint64_t seek_entry_pos_[kSeekEntryCount]; + + // The file position of SeekHead element. + int64_t start_pos_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SeekHead); +}; + +/////////////////////////////////////////////////////////////// +// Segment Information element +class SegmentInfo { + public: + SegmentInfo(); + ~SegmentInfo(); + + // Will update the duration if |duration_| is > 0.0. Returns true on success. + bool Finalize(IMkvWriter* writer) const; + + // Sets |muxing_app_| and |writing_app_|. + bool Init(); + + // Output the Segment Information element to the writer. Returns true on + // success. + bool Write(IMkvWriter* writer); + + void set_duration(double duration) { duration_ = duration; } + double duration() const { return duration_; } + void set_muxing_app(const char* app); + const char* muxing_app() const { return muxing_app_; } + void set_timecode_scale(uint64_t scale) { timecode_scale_ = scale; } + uint64_t timecode_scale() const { return timecode_scale_; } + void set_writing_app(const char* app); + const char* writing_app() const { return writing_app_; } + void set_date_utc(int64_t date_utc) { date_utc_ = date_utc; } + int64_t date_utc() const { return date_utc_; } + + private: + // Segment Information element names. + // Initially set to -1 to signify that a duration has not been set and should + // not be written out. + double duration_; + // Set to libwebm-%d.%d.%d.%d, major, minor, build, revision. + char* muxing_app_; + uint64_t timecode_scale_; + // Initially set to libwebm-%d.%d.%d.%d, major, minor, build, revision. + char* writing_app_; + // INT64_MIN when DateUTC is not set. + int64_t date_utc_; + + // The file position of the duration element. + int64_t duration_pos_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(SegmentInfo); +}; + +/////////////////////////////////////////////////////////////// +// This class represents the main segment in a WebM file. Currently only +// supports one Segment element. +// +// Notes: +// |Init| must be called before any other method in this class. +class Segment { + public: + enum Mode { kLive = 0x1, kFile = 0x2 }; + + enum CuesPosition { + kAfterClusters = 0x0, // Position Cues after Clusters - Default + kBeforeClusters = 0x1 // Position Cues before Clusters + }; + + static constexpr uint32_t kDefaultDocTypeVersion = 4; + static constexpr uint64_t kDefaultMaxClusterDuration = 30000000000ULL; + + Segment(); + ~Segment(); + + // Initializes |SegmentInfo| and returns result. Always returns false when + // |ptr_writer| is NULL. + bool Init(IMkvWriter* ptr_writer); + + // Adds a generic track to the segment. Returns the newly-allocated + // track object (which is owned by the segment) on success, NULL on + // error. |number| is the number to use for the track. |number| + // must be >= 0. If |number| == 0 then the muxer will decide on the + // track number. + Track* AddTrack(int32_t number); + + // Adds a Vorbis audio track to the segment. Returns the number of the track + // on success, 0 on error. |number| is the number to use for the audio track. + // |number| must be >= 0. If |number| == 0 then the muxer will decide on + // the track number. + uint64_t AddAudioTrack(int32_t sample_rate, int32_t channels, int32_t number); + + // Adds an empty chapter to the chapters of this segment. Returns + // non-NULL on success. After adding the chapter, the caller should + // populate its fields via the Chapter member functions. + Chapter* AddChapter(); + + // Adds an empty tag to the tags of this segment. Returns + // non-NULL on success. After adding the tag, the caller should + // populate its fields via the Tag member functions. + Tag* AddTag(); + + // Adds a cue point to the Cues element. |timestamp| is the time in + // nanoseconds of the cue's time. |track| is the Track of the Cue. This + // function must be called after AddFrame to calculate the correct + // BlockNumber for the CuePoint. Returns true on success. + bool AddCuePoint(uint64_t timestamp, uint64_t track); + + // Adds a frame to be output in the file. Returns true on success. + // Inputs: + // data: Pointer to the data + // length: Length of the data + // track_number: Track to add the data to. Value returned by Add track + // functions. + // timestamp: Timestamp of the frame in nanoseconds from 0. + // is_key: Flag telling whether or not this frame is a key frame. + bool AddFrame(const uint8_t* data, uint64_t length, uint64_t track_number, + uint64_t timestamp_ns, bool is_key); + + // Writes a frame of metadata to the output medium; returns true on + // success. + // Inputs: + // data: Pointer to the data + // length: Length of the data + // track_number: Track to add the data to. Value returned by Add track + // functions. + // timecode: Absolute timestamp of the metadata frame, expressed + // in nanosecond units. + // duration: Duration of metadata frame, in nanosecond units. + // + // The metadata frame is written as a block group, with a duration + // sub-element but no reference time sub-elements (indicating that + // it is considered a keyframe, per Matroska semantics). + bool AddMetadata(const uint8_t* data, uint64_t length, uint64_t track_number, + uint64_t timestamp_ns, uint64_t duration_ns); + + // Writes a frame with additional data to the output medium; returns true on + // success. + // Inputs: + // data: Pointer to the data. + // length: Length of the data. + // additional: Pointer to additional data. + // additional_length: Length of additional data. + // add_id: Additional ID which identifies the type of additional data. + // track_number: Track to add the data to. Value returned by Add track + // functions. + // timestamp: Absolute timestamp of the frame, expressed in nanosecond + // units. + // is_key: Flag telling whether or not this frame is a key frame. + bool AddFrameWithAdditional(const uint8_t* data, uint64_t length, + const uint8_t* additional, + uint64_t additional_length, uint64_t add_id, + uint64_t track_number, uint64_t timestamp, + bool is_key); + + // Writes a frame with DiscardPadding to the output medium; returns true on + // success. + // Inputs: + // data: Pointer to the data. + // length: Length of the data. + // discard_padding: DiscardPadding element value. + // track_number: Track to add the data to. Value returned by Add track + // functions. + // timestamp: Absolute timestamp of the frame, expressed in nanosecond + // units. + // is_key: Flag telling whether or not this frame is a key frame. + bool AddFrameWithDiscardPadding(const uint8_t* data, uint64_t length, + int64_t discard_padding, + uint64_t track_number, uint64_t timestamp, + bool is_key); + + // Writes a Frame to the output medium. Chooses the correct way of writing + // the frame (Block vs SimpleBlock) based on the parameters passed. + // Inputs: + // frame: frame object + bool AddGenericFrame(const Frame* frame); + + // Adds a VP8 video track to the segment. Returns the number of the track on + // success, 0 on error. |number| is the number to use for the video track. + // |number| must be >= 0. If |number| == 0 then the muxer will decide on + // the track number. + uint64_t AddVideoTrack(int32_t width, int32_t height, int32_t number); + + // This function must be called after Finalize() if you need a copy of the + // output with Cues written before the Clusters. It will return false if the + // writer is not seekable of if chunking is set to true. + // Input parameters: + // reader - an IMkvReader object created with the same underlying file of the + // current writer object. Make sure to close the existing writer + // object before creating this so that all the data is properly + // flushed and available for reading. + // writer - an IMkvWriter object pointing to a *different* file than the one + // pointed by the current writer object. This file will contain the + // Cues element before the Clusters. + bool CopyAndMoveCuesBeforeClusters(mkvparser::IMkvReader* reader, + IMkvWriter* writer); + + // Sets which track to use for the Cues element. Must have added the track + // before calling this function. Returns true on success. |track_number| is + // returned by the Add track functions. + bool CuesTrack(uint64_t track_number); + + // This will force the muxer to create a new Cluster when the next frame is + // added. + void ForceNewClusterOnNextFrame(); + + // Writes out any frames that have not been written out. Finalizes the last + // cluster. May update the size and duration of the segment. May output the + // Cues element. May finalize the SeekHead element. Returns true on success. + bool Finalize(); + + // Returns the Cues object. + Cues* GetCues() { return &cues_; } + + // Returns the Segment Information object. + const SegmentInfo* GetSegmentInfo() const { return &segment_info_; } + SegmentInfo* GetSegmentInfo() { return &segment_info_; } + + // Search the Tracks and return the track that matches |track_number|. + // Returns NULL if there is no track match. + Track* GetTrackByNumber(uint64_t track_number) const; + + // Toggles whether to output a cues element. + void OutputCues(bool output_cues); + + // Toggles whether to write the last frame in each Cluster with Duration. + void AccurateClusterDuration(bool accurate_cluster_duration); + + // Toggles whether to write the Cluster Timecode using exactly 8 bytes. + void UseFixedSizeClusterTimecode(bool fixed_size_cluster_timecode); + + // Sets if the muxer will output files in chunks or not. |chunking| is a + // flag telling whether or not to turn on chunking. |filename| is the base + // filename for the chunk files. The header chunk file will be named + // |filename|.hdr and the data chunks will be named + // |filename|_XXXXXX.chk. Chunking implies that the muxer will be writing + // to files so the muxer will use the default MkvWriter class to control + // what data is written to what files. Returns true on success. + // TODO: Should we change the IMkvWriter Interface to add Open and Close? + // That will force the interface to be dependent on files. + bool SetChunking(bool chunking, const char* filename); + + bool chunking() const { return chunking_; } + uint64_t cues_track() const { return cues_track_; } + void set_max_cluster_duration(uint64_t max_cluster_duration) { + max_cluster_duration_ = max_cluster_duration; + } + uint64_t max_cluster_duration() const { return max_cluster_duration_; } + void set_max_cluster_size(uint64_t max_cluster_size) { + max_cluster_size_ = max_cluster_size; + } + uint64_t max_cluster_size() const { return max_cluster_size_; } + void set_mode(Mode mode) { mode_ = mode; } + Mode mode() const { return mode_; } + CuesPosition cues_position() const { return cues_position_; } + bool output_cues() const { return output_cues_; } + void set_estimate_file_duration(bool estimate_duration) { + estimate_file_duration_ = estimate_duration; + } + bool estimate_file_duration() const { return estimate_file_duration_; } + const SegmentInfo* segment_info() const { return &segment_info_; } + void set_duration(double duration) { duration_ = duration; } + double duration() const { return duration_; } + + // Returns true when codec IDs are valid for WebM. + bool DocTypeIsWebm() const; + + private: + // Checks if header information has been output and initialized. If not it + // will output the Segment element and initialize the SeekHead elment and + // Cues elements. + bool CheckHeaderInfo(); + + // Sets |doc_type_version_| based on the current element requirements. + void UpdateDocTypeVersion(); + + // Sets |name| according to how many chunks have been written. |ext| is the + // file extension. |name| must be deleted by the calling app. Returns true + // on success. + bool UpdateChunkName(const char* ext, char** name) const; + + // Returns the maximum offset within the segment's payload. When chunking + // this function is needed to determine offsets of elements within the + // chunked files. Returns -1 on error. + int64_t MaxOffset(); + + // Adds the frame to our frame array. + bool QueueFrame(Frame* frame); + + // Output all frames that are queued. Returns -1 on error, otherwise + // it returns the number of frames written. + int WriteFramesAll(); + + // Output all frames that are queued that have an end time that is less + // then |timestamp|. Returns true on success and if there are no frames + // queued. + bool WriteFramesLessThan(uint64_t timestamp); + + // Outputs the segment header, Segment Information element, SeekHead element, + // and Tracks element to |writer_|. + bool WriteSegmentHeader(); + + // Given a frame with the specified timestamp (nanosecond units) and + // keyframe status, determine whether a new cluster should be + // created, before writing enqueued frames and the frame itself. The + // function returns one of the following values: + // -1 = error: an out-of-order frame was detected + // 0 = do not create a new cluster, and write frame to the existing cluster + // 1 = create a new cluster, and write frame to that new cluster + // 2 = create a new cluster, and re-run test + int TestFrame(uint64_t track_num, uint64_t timestamp_ns, bool key) const; + + // Create a new cluster, using the earlier of the first enqueued + // frame, or the indicated time. Returns true on success. + bool MakeNewCluster(uint64_t timestamp_ns); + + // Checks whether a new cluster needs to be created, and if so + // creates a new cluster. Returns false if creation of a new cluster + // was necessary but creation was not successful. + bool DoNewClusterProcessing(uint64_t track_num, uint64_t timestamp_ns, + bool key); + + // Adjusts Cue Point values (to place Cues before Clusters) so that they + // reflect the correct offsets. + void MoveCuesBeforeClusters(); + + // This function recursively computes the correct cluster offsets (this is + // done to move the Cues before Clusters). It recursively updates the change + // in size (which indicates a change in cluster offset) until no sizes change. + // Parameters: + // diff - indicates the difference in size of the Cues element that needs to + // accounted for. + // index - index in the list of Cues which is currently being adjusted. + // cue_size - sum of size of all the CuePoint elements. + void MoveCuesBeforeClustersHelper(uint64_t diff, int index, + uint64_t* cue_size); + + // Seeds the random number generator used to make UIDs. + unsigned int seed_; + + // WebM elements + Cues cues_; + SeekHead seek_head_; + SegmentInfo segment_info_; + Tracks tracks_; + Chapters chapters_; + Tags tags_; + + // Number of chunks written. + int chunk_count_; + + // Current chunk filename. + char* chunk_name_; + + // Default MkvWriter object created by this class used for writing clusters + // out in separate files. + MkvWriter* chunk_writer_cluster_; + + // Default MkvWriter object created by this class used for writing Cues + // element out to a file. + MkvWriter* chunk_writer_cues_; + + // Default MkvWriter object created by this class used for writing the + // Matroska header out to a file. + MkvWriter* chunk_writer_header_; + + // Flag telling whether or not the muxer is chunking output to multiple + // files. + bool chunking_; + + // Base filename for the chunked files. + char* chunking_base_name_; + + // File position offset where the Clusters end. + int64_t cluster_end_offset_; + + // List of clusters. + Cluster** cluster_list_; + + // Number of cluster pointers allocated in the cluster list. + int32_t cluster_list_capacity_; + + // Number of clusters in the cluster list. + int32_t cluster_list_size_; + + // Indicates whether Cues should be written before or after Clusters + CuesPosition cues_position_; + + // Track number that is associated with the cues element for this segment. + uint64_t cues_track_; + + // Tells the muxer to force a new cluster on the next Block. + bool force_new_cluster_; + + // List of stored audio frames. These variables are used to store frames so + // the muxer can follow the guideline "Audio blocks that contain the video + // key frame's timecode should be in the same cluster as the video key frame + // block." + Frame** frames_; + + // Number of frame pointers allocated in the frame list. + int32_t frames_capacity_; + + // Number of frames in the frame list. + int32_t frames_size_; + + // Flag telling if a video track has been added to the segment. + bool has_video_; + + // Flag telling if the segment's header has been written. + bool header_written_; + + // Duration of the last block in nanoseconds. + uint64_t last_block_duration_; + + // Last timestamp in nanoseconds added to a cluster. + uint64_t last_timestamp_; + + // Last timestamp in nanoseconds by track number added to a cluster. + uint64_t last_track_timestamp_[kMaxTrackNumber]; + + // Number of frames written per track. + uint64_t track_frames_written_[kMaxTrackNumber]; + + // Maximum time in nanoseconds for a cluster duration. This variable is a + // guideline and some clusters may have a longer duration. Default is 30 + // seconds. + uint64_t max_cluster_duration_; + + // Maximum size in bytes for a cluster. This variable is a guideline and + // some clusters may have a larger size. Default is 0 which signifies that + // the muxer will decide the size. + uint64_t max_cluster_size_; + + // The mode that segment is in. If set to |kLive| the writer must not + // seek backwards. + Mode mode_; + + // Flag telling the muxer that a new cue point should be added. + bool new_cuepoint_; + + // TODO(fgalligan): Should we add support for more than one Cues element? + // Flag whether or not the muxer should output a Cues element. + bool output_cues_; + + // Flag whether or not the last frame in each Cluster will have a Duration + // element in it. + bool accurate_cluster_duration_; + + // Flag whether or not to write the Cluster Timecode using exactly 8 bytes. + bool fixed_size_cluster_timecode_; + + // Flag whether or not to estimate the file duration. + bool estimate_file_duration_; + + // The size of the EBML header, used to validate the header if + // WriteEbmlHeader() is called more than once. + int32_t ebml_header_size_; + + // The file position of the segment's payload. + int64_t payload_pos_; + + // The file position of the element's size. + int64_t size_position_; + + // Current DocTypeVersion (|doc_type_version_|) and that written in + // WriteSegmentHeader(). + // WriteEbmlHeader() will be called from Finalize() if |doc_type_version_| + // differs from |doc_type_version_written_|. + uint32_t doc_type_version_; + uint32_t doc_type_version_written_; + + // If |duration_| is > 0, then explicitly set the duration of the segment. + double duration_; + + // Pointer to the writer objects. Not owned by this class. + IMkvWriter* writer_cluster_; + IMkvWriter* writer_cues_; + IMkvWriter* writer_header_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(Segment); +}; + +} // namespace mkvmuxer + +#endif // MKVMUXER_MKVMUXER_H_ diff --git a/src/sys/libwebm/mkvmuxer/mkvmuxertypes.h b/src/sys/libwebm/mkvmuxer/mkvmuxertypes.h new file mode 100644 index 0000000..e5db121 --- /dev/null +++ b/src/sys/libwebm/mkvmuxer/mkvmuxertypes.h @@ -0,0 +1,28 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#ifndef MKVMUXER_MKVMUXERTYPES_H_ +#define MKVMUXER_MKVMUXERTYPES_H_ + +namespace mkvmuxer { +typedef unsigned char uint8; +typedef short int16; +typedef int int32; +typedef unsigned int uint32; +typedef long long int64; +typedef unsigned long long uint64; +} // namespace mkvmuxer + +// Copied from Chromium basictypes.h +// A macro to disallow the copy constructor and operator= functions +// This should be used in the private: declarations for a class +#define LIBWEBM_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +#endif // MKVMUXER_MKVMUXERTYPES_HPP_ diff --git a/src/sys/libwebm/mkvmuxer/mkvmuxerutil.cc b/src/sys/libwebm/mkvmuxer/mkvmuxerutil.cc new file mode 100644 index 0000000..4d7952f --- /dev/null +++ b/src/sys/libwebm/mkvmuxer/mkvmuxerutil.cc @@ -0,0 +1,743 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#include "mkvmuxer/mkvmuxerutil.h" + +#ifdef __ANDROID__ +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "common/webmids.h" +#include "mkvmuxer/mkvmuxer.h" +#include "mkvmuxer/mkvwriter.h" + +namespace mkvmuxer { + +namespace { + +// Date elements are always 8 octets in size. +const int kDateElementSize = 8; + +uint64 WriteBlock(IMkvWriter* writer, const Frame* const frame, int64 timecode, + uint64 timecode_scale) { + uint64 block_additional_elem_size = 0; + uint64 block_addid_elem_size = 0; + uint64 block_more_payload_size = 0; + uint64 block_more_elem_size = 0; + uint64 block_additions_payload_size = 0; + uint64 block_additions_elem_size = 0; + if (frame->additional()) { + block_additional_elem_size = + EbmlElementSize(libwebm::kMkvBlockAdditional, frame->additional(), + frame->additional_length()); + block_addid_elem_size = EbmlElementSize( + libwebm::kMkvBlockAddID, static_cast(frame->add_id())); + + block_more_payload_size = + block_addid_elem_size + block_additional_elem_size; + block_more_elem_size = + EbmlMasterElementSize(libwebm::kMkvBlockMore, block_more_payload_size) + + block_more_payload_size; + block_additions_payload_size = block_more_elem_size; + block_additions_elem_size = + EbmlMasterElementSize(libwebm::kMkvBlockAdditions, + block_additions_payload_size) + + block_additions_payload_size; + } + + uint64 discard_padding_elem_size = 0; + if (frame->discard_padding() != 0) { + discard_padding_elem_size = + EbmlElementSize(libwebm::kMkvDiscardPadding, + static_cast(frame->discard_padding())); + } + + const uint64 reference_block_timestamp = + frame->reference_block_timestamp() / timecode_scale; + uint64 reference_block_elem_size = 0; + if (!frame->is_key()) { + reference_block_elem_size = + EbmlElementSize(libwebm::kMkvReferenceBlock, reference_block_timestamp); + } + + const uint64 duration = frame->duration() / timecode_scale; + uint64 block_duration_elem_size = 0; + if (duration > 0) + block_duration_elem_size = + EbmlElementSize(libwebm::kMkvBlockDuration, duration); + + const uint64 block_payload_size = 4 + frame->length(); + const uint64 block_elem_size = + EbmlMasterElementSize(libwebm::kMkvBlock, block_payload_size) + + block_payload_size; + + const uint64 block_group_payload_size = + block_elem_size + block_additions_elem_size + block_duration_elem_size + + discard_padding_elem_size + reference_block_elem_size; + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockGroup, + block_group_payload_size)) { + return 0; + } + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlock, block_payload_size)) + return 0; + + if (WriteUInt(writer, frame->track_number())) + return 0; + + if (SerializeInt(writer, timecode, 2)) + return 0; + + // For a Block, flags is always 0. + if (SerializeInt(writer, 0, 1)) + return 0; + + if (writer->Write(frame->frame(), static_cast(frame->length()))) + return 0; + + if (frame->additional()) { + if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockAdditions, + block_additions_payload_size)) { + return 0; + } + + if (!WriteEbmlMasterElement(writer, libwebm::kMkvBlockMore, + block_more_payload_size)) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvBlockAddID, + static_cast(frame->add_id()))) + return 0; + + if (!WriteEbmlElement(writer, libwebm::kMkvBlockAdditional, + frame->additional(), frame->additional_length())) { + return 0; + } + } + + if (frame->discard_padding() != 0 && + !WriteEbmlElement(writer, libwebm::kMkvDiscardPadding, + static_cast(frame->discard_padding()))) { + return false; + } + + if (!frame->is_key() && !WriteEbmlElement(writer, libwebm::kMkvReferenceBlock, + reference_block_timestamp)) { + return false; + } + + if (duration > 0 && + !WriteEbmlElement(writer, libwebm::kMkvBlockDuration, duration)) { + return false; + } + return EbmlMasterElementSize(libwebm::kMkvBlockGroup, + block_group_payload_size) + + block_group_payload_size; +} + +uint64 WriteSimpleBlock(IMkvWriter* writer, const Frame* const frame, + int64 timecode) { + if (WriteID(writer, libwebm::kMkvSimpleBlock)) + return 0; + + const int32 size = static_cast(frame->length()) + 4; + if (WriteUInt(writer, size)) + return 0; + + if (WriteUInt(writer, static_cast(frame->track_number()))) + return 0; + + if (SerializeInt(writer, timecode, 2)) + return 0; + + uint64 flags = 0; + if (frame->is_key()) + flags |= 0x80; + + if (SerializeInt(writer, flags, 1)) + return 0; + + if (writer->Write(frame->frame(), static_cast(frame->length()))) + return 0; + + return GetUIntSize(libwebm::kMkvSimpleBlock) + GetCodedUIntSize(size) + 4 + + frame->length(); +} + +} // namespace + +int32 GetCodedUIntSize(uint64 value) { + if (value < 0x000000000000007FULL) + return 1; + else if (value < 0x0000000000003FFFULL) + return 2; + else if (value < 0x00000000001FFFFFULL) + return 3; + else if (value < 0x000000000FFFFFFFULL) + return 4; + else if (value < 0x00000007FFFFFFFFULL) + return 5; + else if (value < 0x000003FFFFFFFFFFULL) + return 6; + else if (value < 0x0001FFFFFFFFFFFFULL) + return 7; + return 8; +} + +int32 GetUIntSize(uint64 value) { + if (value < 0x0000000000000100ULL) + return 1; + else if (value < 0x0000000000010000ULL) + return 2; + else if (value < 0x0000000001000000ULL) + return 3; + else if (value < 0x0000000100000000ULL) + return 4; + else if (value < 0x0000010000000000ULL) + return 5; + else if (value < 0x0001000000000000ULL) + return 6; + else if (value < 0x0100000000000000ULL) + return 7; + return 8; +} + +int32 GetIntSize(int64 value) { + // Doubling the requested value ensures positive values with their high bit + // set are written with 0-padding to avoid flipping the signedness. + const uint64 v = (value < 0) ? value ^ -1LL : value; + return GetUIntSize(2 * v); +} + +uint64 EbmlMasterElementSize(uint64 type, uint64 value) { + // Size of EBML ID + int32 ebml_size = GetUIntSize(type); + + // Datasize + ebml_size += GetCodedUIntSize(value); + + return ebml_size; +} + +uint64 EbmlElementSize(uint64 type, int64 value) { + // Size of EBML ID + int32 ebml_size = GetUIntSize(type); + + // Datasize + ebml_size += GetIntSize(value); + + // Size of Datasize + ebml_size++; + + return ebml_size; +} + +uint64 EbmlElementSize(uint64 type, uint64 value) { + return EbmlElementSize(type, value, 0); +} + +uint64 EbmlElementSize(uint64 type, uint64 value, uint64 fixed_size) { + // Size of EBML ID + uint64 ebml_size = GetUIntSize(type); + + // Datasize + ebml_size += (fixed_size > 0) ? fixed_size : GetUIntSize(value); + + // Size of Datasize + ebml_size++; + + return ebml_size; +} + +uint64 EbmlElementSize(uint64 type, float /* value */) { + // Size of EBML ID + uint64 ebml_size = GetUIntSize(type); + + // Datasize + ebml_size += sizeof(float); + + // Size of Datasize + ebml_size++; + + return ebml_size; +} + +uint64 EbmlElementSize(uint64 type, const char* value) { + if (!value) + return 0; + + // Size of EBML ID + uint64 ebml_size = GetUIntSize(type); + + // Datasize + ebml_size += strlen(value); + + // Size of Datasize + ebml_size += GetCodedUIntSize(strlen(value)); + + return ebml_size; +} + +uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size) { + if (!value) + return 0; + + // Size of EBML ID + uint64 ebml_size = GetUIntSize(type); + + // Datasize + ebml_size += size; + + // Size of Datasize + ebml_size += GetCodedUIntSize(size); + + return ebml_size; +} + +uint64 EbmlDateElementSize(uint64 type) { + // Size of EBML ID + uint64 ebml_size = GetUIntSize(type); + + // Datasize + ebml_size += kDateElementSize; + + // Size of Datasize + ebml_size++; + + return ebml_size; +} + +int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size) { + if (!writer || size < 1 || size > 8) + return -1; + + for (int32 i = 1; i <= size; ++i) { + const int32 byte_count = size - i; + const int32 bit_count = byte_count * 8; + + const int64 bb = value >> bit_count; + const uint8 b = static_cast(bb); + + const int32 status = writer->Write(&b, 1); + + if (status < 0) + return status; + } + + return 0; +} + +int32 SerializeFloat(IMkvWriter* writer, float f) { + if (!writer) + return -1; + + assert(sizeof(uint32) == sizeof(float)); + // This union is merely used to avoid a reinterpret_cast from float& to + // uint32& which will result in violation of strict aliasing. + union U32 { + uint32 u32; + float f; + } value; + value.f = f; + + for (int32 i = 1; i <= 4; ++i) { + const int32 byte_count = 4 - i; + const int32 bit_count = byte_count * 8; + + const uint8 byte = static_cast(value.u32 >> bit_count); + + const int32 status = writer->Write(&byte, 1); + + if (status < 0) + return status; + } + + return 0; +} + +int32 WriteUInt(IMkvWriter* writer, uint64 value) { + if (!writer) + return -1; + + int32 size = GetCodedUIntSize(value); + + return WriteUIntSize(writer, value, size); +} + +int32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size) { + if (!writer || size < 0 || size > 8) + return -1; + + if (size > 0) { + const uint64 bit = 1LL << (size * 7); + + if (value > (bit - 2)) + return -1; + + value |= bit; + } else { + size = 1; + int64 bit; + + for (;;) { + bit = 1LL << (size * 7); + const uint64 max = bit - 2; + + if (value <= max) + break; + + ++size; + } + + if (size > 8) + return false; + + value |= bit; + } + + return SerializeInt(writer, value, size); +} + +int32 WriteID(IMkvWriter* writer, uint64 type) { + if (!writer) + return -1; + + writer->ElementStartNotify(type, writer->Position()); + + const int32 size = GetUIntSize(type); + + return SerializeInt(writer, type, size); +} + +bool WriteEbmlMasterElement(IMkvWriter* writer, uint64 type, uint64 size) { + if (!writer) + return false; + + if (WriteID(writer, type)) + return false; + + if (WriteUInt(writer, size)) + return false; + + return true; +} + +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value) { + return WriteEbmlElement(writer, type, value, 0); +} + +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value, + uint64 fixed_size) { + if (!writer) + return false; + + if (WriteID(writer, type)) + return false; + + uint64 size = GetUIntSize(value); + if (fixed_size > 0) { + if (size > fixed_size) + return false; + size = fixed_size; + } + if (WriteUInt(writer, size)) + return false; + + if (SerializeInt(writer, value, static_cast(size))) + return false; + + return true; +} + +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, int64 value) { + if (!writer) + return false; + + if (WriteID(writer, type)) + return 0; + + const uint64 size = GetIntSize(value); + if (WriteUInt(writer, size)) + return false; + + if (SerializeInt(writer, value, static_cast(size))) + return false; + + return true; +} + +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value) { + if (!writer) + return false; + + if (WriteID(writer, type)) + return false; + + if (WriteUInt(writer, 4)) + return false; + + if (SerializeFloat(writer, value)) + return false; + + return true; +} + +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value) { + if (!writer || !value) + return false; + + if (WriteID(writer, type)) + return false; + + const uint64 length = strlen(value); + if (WriteUInt(writer, length)) + return false; + + if (writer->Write(value, static_cast(length))) + return false; + + return true; +} + +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const uint8* value, + uint64 size) { + if (!writer || !value || size < 1) + return false; + + if (WriteID(writer, type)) + return false; + + if (WriteUInt(writer, size)) + return false; + + if (writer->Write(value, static_cast(size))) + return false; + + return true; +} + +bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value) { + if (!writer) + return false; + + if (WriteID(writer, type)) + return false; + + if (WriteUInt(writer, kDateElementSize)) + return false; + + if (SerializeInt(writer, value, kDateElementSize)) + return false; + + return true; +} + +uint64 WriteFrame(IMkvWriter* writer, const Frame* const frame, + Cluster* cluster) { + if (!writer || !frame || !frame->IsValid() || !cluster || + !cluster->timecode_scale()) + return 0; + + // Technically the timecode for a block can be less than the + // timecode for the cluster itself (remember that block timecode + // is a signed, 16-bit integer). However, as a simplification we + // only permit non-negative cluster-relative timecodes for blocks. + const int64 relative_timecode = cluster->GetRelativeTimecode( + frame->timestamp() / cluster->timecode_scale()); + if (relative_timecode < 0 || relative_timecode > kMaxBlockTimecode) + return 0; + + return frame->CanBeSimpleBlock() + ? WriteSimpleBlock(writer, frame, relative_timecode) + : WriteBlock(writer, frame, relative_timecode, + cluster->timecode_scale()); +} + +uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) { + if (!writer) + return false; + + // Subtract one for the void ID and the coded size. + uint64 void_entry_size = size - 1 - GetCodedUIntSize(size - 1); + uint64 void_size = EbmlMasterElementSize(libwebm::kMkvVoid, void_entry_size) + + void_entry_size; + + if (void_size != size) + return 0; + + const int64 payload_position = writer->Position(); + if (payload_position < 0) + return 0; + + if (WriteID(writer, libwebm::kMkvVoid)) + return 0; + + if (WriteUInt(writer, void_entry_size)) + return 0; + + const uint8 value = 0; + for (int32 i = 0; i < static_cast(void_entry_size); ++i) { + if (writer->Write(&value, 1)) + return 0; + } + + const int64 stop_position = writer->Position(); + if (stop_position < 0 || + stop_position - payload_position != static_cast(void_size)) + return 0; + + return void_size; +} + +void GetVersion(int32* major, int32* minor, int32* build, int32* revision) { + *major = 0; + *minor = 3; + *build = 2; + *revision = 0; +} + +uint64 MakeUID(unsigned int* seed) { + uint64 uid = 0; + +#ifdef __MINGW32__ + srand(*seed); +#endif + + for (int i = 0; i < 7; ++i) { // avoid problems with 8-byte values + uid <<= 8; + +// TODO(fgalligan): Move random number generation to platform specific code. +#ifdef _MSC_VER + (void)seed; + const int32 nn = rand(); +#elif __ANDROID__ + (void)seed; + int32 temp_num = 1; + int fd = open("/dev/urandom", O_RDONLY); + if (fd != -1) { + read(fd, &temp_num, sizeof(temp_num)); + close(fd); + } + const int32 nn = temp_num; +#elif defined __MINGW32__ + const int32 nn = rand(); +#else + const int32 nn = rand_r(seed); +#endif + const int32 n = 0xFF & (nn >> 4); // throw away low-order bits + + uid |= n; + } + + return uid; +} + +bool IsMatrixCoefficientsValueValid(uint64_t value) { + switch (value) { + case mkvmuxer::Colour::kGbr: + case mkvmuxer::Colour::kBt709: + case mkvmuxer::Colour::kUnspecifiedMc: + case mkvmuxer::Colour::kReserved: + case mkvmuxer::Colour::kFcc: + case mkvmuxer::Colour::kBt470bg: + case mkvmuxer::Colour::kSmpte170MMc: + case mkvmuxer::Colour::kSmpte240MMc: + case mkvmuxer::Colour::kYcocg: + case mkvmuxer::Colour::kBt2020NonConstantLuminance: + case mkvmuxer::Colour::kBt2020ConstantLuminance: + return true; + } + return false; +} + +bool IsChromaSitingHorzValueValid(uint64_t value) { + switch (value) { + case mkvmuxer::Colour::kUnspecifiedCsh: + case mkvmuxer::Colour::kLeftCollocated: + case mkvmuxer::Colour::kHalfCsh: + return true; + } + return false; +} + +bool IsChromaSitingVertValueValid(uint64_t value) { + switch (value) { + case mkvmuxer::Colour::kUnspecifiedCsv: + case mkvmuxer::Colour::kTopCollocated: + case mkvmuxer::Colour::kHalfCsv: + return true; + } + return false; +} + +bool IsColourRangeValueValid(uint64_t value) { + switch (value) { + case mkvmuxer::Colour::kUnspecifiedCr: + case mkvmuxer::Colour::kBroadcastRange: + case mkvmuxer::Colour::kFullRange: + case mkvmuxer::Colour::kMcTcDefined: + return true; + } + return false; +} + +bool IsTransferCharacteristicsValueValid(uint64_t value) { + switch (value) { + case mkvmuxer::Colour::kIturBt709Tc: + case mkvmuxer::Colour::kUnspecifiedTc: + case mkvmuxer::Colour::kReservedTc: + case mkvmuxer::Colour::kGamma22Curve: + case mkvmuxer::Colour::kGamma28Curve: + case mkvmuxer::Colour::kSmpte170MTc: + case mkvmuxer::Colour::kSmpte240MTc: + case mkvmuxer::Colour::kLinear: + case mkvmuxer::Colour::kLog: + case mkvmuxer::Colour::kLogSqrt: + case mkvmuxer::Colour::kIec6196624: + case mkvmuxer::Colour::kIturBt1361ExtendedColourGamut: + case mkvmuxer::Colour::kIec6196621: + case mkvmuxer::Colour::kIturBt202010bit: + case mkvmuxer::Colour::kIturBt202012bit: + case mkvmuxer::Colour::kSmpteSt2084: + case mkvmuxer::Colour::kSmpteSt4281Tc: + case mkvmuxer::Colour::kAribStdB67Hlg: + return true; + } + return false; +} + +bool IsPrimariesValueValid(uint64_t value) { + switch (value) { + case mkvmuxer::Colour::kReservedP0: + case mkvmuxer::Colour::kIturBt709P: + case mkvmuxer::Colour::kUnspecifiedP: + case mkvmuxer::Colour::kReservedP3: + case mkvmuxer::Colour::kIturBt470M: + case mkvmuxer::Colour::kIturBt470Bg: + case mkvmuxer::Colour::kSmpte170MP: + case mkvmuxer::Colour::kSmpte240MP: + case mkvmuxer::Colour::kFilm: + case mkvmuxer::Colour::kIturBt2020: + case mkvmuxer::Colour::kSmpteSt4281P: + case mkvmuxer::Colour::kJedecP22Phosphors: + return true; + } + return false; +} + +} // namespace mkvmuxer diff --git a/src/sys/libwebm/mkvmuxer/mkvmuxerutil.h b/src/sys/libwebm/mkvmuxer/mkvmuxerutil.h new file mode 100644 index 0000000..3355428 --- /dev/null +++ b/src/sys/libwebm/mkvmuxer/mkvmuxerutil.h @@ -0,0 +1,115 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef MKVMUXER_MKVMUXERUTIL_H_ +#define MKVMUXER_MKVMUXERUTIL_H_ + +#include "mkvmuxertypes.h" + +#include "stdint.h" + +namespace mkvmuxer { +class Cluster; +class Frame; +class IMkvWriter; + +// TODO(tomfinegan): mkvmuxer:: integer types continue to be used here because +// changing them causes pain for downstream projects. It would be nice if a +// solution that allows removal of the mkvmuxer:: integer types while avoiding +// pain for downstream users of libwebm. Considering that mkvmuxerutil.{cc,h} +// are really, for the great majority of cases, EBML size calculation and writer +// functions, perhaps a more EBML focused utility would be the way to go as a +// first step. + +const uint64 kEbmlUnknownValue = 0x01FFFFFFFFFFFFFFULL; +const int64 kMaxBlockTimecode = 0x07FFFLL; + +// Writes out |value| in Big Endian order. Returns 0 on success. +int32 SerializeInt(IMkvWriter* writer, int64 value, int32 size); + +// Writes out |f| in Big Endian order. Returns 0 on success. +int32 SerializeFloat(IMkvWriter* writer, float f); + +// Returns the size in bytes of the element. +int32 GetUIntSize(uint64 value); +int32 GetIntSize(int64 value); +int32 GetCodedUIntSize(uint64 value); +uint64 EbmlMasterElementSize(uint64 type, uint64 value); +uint64 EbmlElementSize(uint64 type, int64 value); +uint64 EbmlElementSize(uint64 type, uint64 value); +uint64 EbmlElementSize(uint64 type, float value); +uint64 EbmlElementSize(uint64 type, const char* value); +uint64 EbmlElementSize(uint64 type, const uint8* value, uint64 size); +uint64 EbmlDateElementSize(uint64 type); + +// Returns the size in bytes of the element assuming that the element was +// written using |fixed_size| bytes. If |fixed_size| is set to zero, then it +// computes the necessary number of bytes based on |value|. +uint64 EbmlElementSize(uint64 type, uint64 value, uint64 fixed_size); + +// Creates an EBML coded number from |value| and writes it out. The size of +// the coded number is determined by the value of |value|. |value| must not +// be in a coded form. Returns 0 on success. +int32 WriteUInt(IMkvWriter* writer, uint64 value); + +// Creates an EBML coded number from |value| and writes it out. The size of +// the coded number is determined by the value of |size|. |value| must not +// be in a coded form. Returns 0 on success. +int32 WriteUIntSize(IMkvWriter* writer, uint64 value, int32 size); + +// Output an Mkv master element. Returns true if the element was written. +bool WriteEbmlMasterElement(IMkvWriter* writer, uint64 value, uint64 size); + +// Outputs an Mkv ID, calls |IMkvWriter::ElementStartNotify|, and passes the +// ID to |SerializeInt|. Returns 0 on success. +int32 WriteID(IMkvWriter* writer, uint64 type); + +// Output an Mkv non-master element. Returns true if the element was written. +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value); +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, int64 value); +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, float value); +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const char* value); +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, const uint8* value, + uint64 size); +bool WriteEbmlDateElement(IMkvWriter* writer, uint64 type, int64 value); + +// Output an Mkv non-master element using fixed size. The element will be +// written out using exactly |fixed_size| bytes. If |fixed_size| is set to zero +// then it computes the necessary number of bytes based on |value|. Returns true +// if the element was written. +bool WriteEbmlElement(IMkvWriter* writer, uint64 type, uint64 value, + uint64 fixed_size); + +// Output a Mkv Frame. It decides the correct element to write (Block vs +// SimpleBlock) based on the parameters of the Frame. +uint64 WriteFrame(IMkvWriter* writer, const Frame* const frame, + Cluster* cluster); + +// Output a void element. |size| must be the entire size in bytes that will be +// void. The function will calculate the size of the void header and subtract +// it from |size|. +uint64 WriteVoidElement(IMkvWriter* writer, uint64 size); + +// Returns the version number of the muxer in |major|, |minor|, |build|, +// and |revision|. +void GetVersion(int32* major, int32* minor, int32* build, int32* revision); + +// Returns a random number to be used for UID, using |seed| to seed +// the random-number generator (see POSIX rand_r() for semantics). +uint64 MakeUID(unsigned int* seed); + +// Colour field validation helpers. All return true when |value| is valid. +bool IsMatrixCoefficientsValueValid(uint64_t value); +bool IsChromaSitingHorzValueValid(uint64_t value); +bool IsChromaSitingVertValueValid(uint64_t value); +bool IsColourRangeValueValid(uint64_t value); +bool IsTransferCharacteristicsValueValid(uint64_t value); +bool IsPrimariesValueValid(uint64_t value); + +} // namespace mkvmuxer + +#endif // MKVMUXER_MKVMUXERUTIL_H_ diff --git a/src/sys/libwebm/mkvmuxer/mkvwriter.cc b/src/sys/libwebm/mkvmuxer/mkvwriter.cc new file mode 100644 index 0000000..d668384 --- /dev/null +++ b/src/sys/libwebm/mkvmuxer/mkvwriter.cc @@ -0,0 +1,92 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#include "mkvmuxer/mkvwriter.h" + +#include + +#ifdef _MSC_VER +#include // for _SH_DENYWR +#endif + +namespace mkvmuxer { + +MkvWriter::MkvWriter() : file_(NULL), writer_owns_file_(true) {} + +MkvWriter::MkvWriter(FILE* fp) : file_(fp), writer_owns_file_(false) {} + +MkvWriter::~MkvWriter() { Close(); } + +int32 MkvWriter::Write(const void* buffer, uint32 length) { + if (!file_) + return -1; + + if (length == 0) + return 0; + + if (buffer == NULL) + return -1; + + const size_t bytes_written = fwrite(buffer, 1, length, file_); + + return (bytes_written == length) ? 0 : -1; +} + +bool MkvWriter::Open(const char* filename) { + if (filename == NULL) + return false; + + if (file_) + return false; + +#ifdef _MSC_VER + file_ = _fsopen(filename, "wb", _SH_DENYWR); +#else + file_ = fopen(filename, "wb"); +#endif + if (file_ == NULL) + return false; + return true; +} + +void MkvWriter::Close() { + if (file_ && writer_owns_file_) { + fclose(file_); + } + file_ = NULL; +} + +int64 MkvWriter::Position() const { + if (!file_) + return 0; + +#ifdef _MSC_VER + return _ftelli64(file_); +#else + return ftell(file_); +#endif +} + +int32 MkvWriter::Position(int64 position) { + if (!file_) + return -1; + +#ifdef _MSC_VER + return _fseeki64(file_, position, SEEK_SET); +#elif defined(_WIN32) + return fseeko64(file_, static_cast(position), SEEK_SET); +#else + return fseeko(file_, static_cast(position), SEEK_SET); +#endif +} + +bool MkvWriter::Seekable() const { return true; } + +void MkvWriter::ElementStartNotify(uint64, int64) {} + +} // namespace mkvmuxer diff --git a/src/sys/libwebm/mkvmuxer/mkvwriter.h b/src/sys/libwebm/mkvmuxer/mkvwriter.h new file mode 100644 index 0000000..4227c63 --- /dev/null +++ b/src/sys/libwebm/mkvmuxer/mkvwriter.h @@ -0,0 +1,51 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#ifndef MKVMUXER_MKVWRITER_H_ +#define MKVMUXER_MKVWRITER_H_ + +#include + +#include "mkvmuxer/mkvmuxer.h" +#include "mkvmuxer/mkvmuxertypes.h" + +namespace mkvmuxer { + +// Default implementation of the IMkvWriter interface on Windows. +class MkvWriter : public IMkvWriter { + public: + MkvWriter(); + explicit MkvWriter(FILE* fp); + virtual ~MkvWriter(); + + // IMkvWriter interface + virtual int64 Position() const; + virtual int32 Position(int64 position); + virtual bool Seekable() const; + virtual int32 Write(const void* buffer, uint32 length); + virtual void ElementStartNotify(uint64 element_id, int64 position); + + // Creates and opens a file for writing. |filename| is the name of the file + // to open. This function will overwrite the contents of |filename|. Returns + // true on success. + bool Open(const char* filename); + + // Closes an opened file. + void Close(); + + private: + // File handle to output file. + FILE* file_; + bool writer_owns_file_; + + LIBWEBM_DISALLOW_COPY_AND_ASSIGN(MkvWriter); +}; + +} // namespace mkvmuxer + +#endif // MKVMUXER_MKVWRITER_H_ diff --git a/src/sys/libwebm/mkvmuxer_sample.cc b/src/sys/libwebm/mkvmuxer_sample.cc new file mode 100644 index 0000000..0b84d72 --- /dev/null +++ b/src/sys/libwebm/mkvmuxer_sample.cc @@ -0,0 +1,802 @@ +// Copyright (c) 2011 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include + +#include +#include +#include +#include +#include +#include + +// libwebm common includes. +#include "common/file_util.h" +#include "common/hdr_util.h" + +// libwebm mkvparser includes +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" + +// libwebm mkvmuxer includes +#include "mkvmuxer/mkvmuxer.h" +#include "mkvmuxer/mkvmuxertypes.h" +#include "mkvmuxer/mkvwriter.h" + +#include "sample_muxer_metadata.h" + +namespace { + +void Usage() { + printf("Usage: mkvmuxer_sample -i input -o output [options]\n"); + printf("\n"); + printf("Main options:\n"); + printf(" -h | -? show help\n"); + printf(" -video >0 outputs video\n"); + printf(" -audio >0 outputs audio\n"); + printf(" -live >0 puts the muxer into live mode\n"); + printf(" 0 puts the muxer into file mode\n"); + printf(" -output_cues >0 outputs cues element\n"); + printf(" -cues_on_video_track >0 outputs cues on video track\n"); + printf(" -cues_on_audio_track >0 outputs cues on audio track\n"); + printf(" -max_cluster_duration in seconds\n"); + printf(" -max_cluster_size in bytes\n"); + printf(" -switch_tracks >0 switches tracks in output\n"); + printf(" -audio_track_number >0 Changes the audio track number\n"); + printf(" -video_track_number >0 Changes the video track number\n"); + printf(" -chunking Chunk output\n"); + printf(" -copy_tags >0 Copies the tags\n"); + printf(" -accurate_cluster_duration "); + printf(">0 Writes the last frame in each cluster with Duration\n"); + printf(" -fixed_size_cluster_timecode "); + printf(">0 Writes the cluster timecode using exactly 8 bytes\n"); + printf(" -copy_input_duration >0 Copies the input duration\n"); + printf("\n"); + printf("Video options:\n"); + printf(" -display_width Display width in pixels\n"); + printf(" -display_height Display height in pixels\n"); + printf(" -pixel_width Override pixel width\n"); + printf(" -pixel_height Override pixel height\n"); + printf(" -projection_type Set/override projection type:\n"); + printf(" 0: Rectangular\n"); + printf(" 1: Equirectangular\n"); + printf(" 2: Cube map\n"); + printf(" 3: Mesh\n"); + printf(" -projection_file Override projection private data\n"); + printf(" with contents of this file\n"); + printf(" -projection_pose_yaw Projection pose yaw\n"); + printf(" -projection_pose_pitch Projection pose pitch\n"); + printf(" -projection_pose_roll Projection pose roll\n"); + printf(" -stereo_mode 3D video mode\n"); + printf("\n"); + printf("VP9 options:\n"); + printf(" -profile VP9 profile\n"); + printf(" -level VP9 level\n"); + printf("\n"); + printf("Cues options:\n"); + printf(" -output_cues_block_number >0 outputs cue block number\n"); + printf(" -cues_before_clusters >0 puts Cues before Clusters\n"); + printf("\n"); + printf("Metadata options:\n"); + printf(" -webvtt-subtitles "); + printf("add WebVTT subtitles as metadata track\n"); + printf(" -webvtt-captions "); + printf("add WebVTT captions as metadata track\n"); + printf(" -webvtt-descriptions "); + printf("add WebVTT descriptions as metadata track\n"); + printf(" -webvtt-metadata "); + printf("add WebVTT subtitles as metadata track\n"); + printf(" -webvtt-chapters "); + printf("add WebVTT chapters as MKV chapters element\n"); +} + +struct MetadataFile { + const char* name; + SampleMuxerMetadata::Kind kind; +}; + +typedef std::list metadata_files_t; + +// Cache the WebVTT filenames specified as command-line args. +bool LoadMetadataFiles(const metadata_files_t& files, + SampleMuxerMetadata* metadata) { + typedef metadata_files_t::const_iterator iter_t; + + iter_t i = files.begin(); + const iter_t j = files.end(); + + while (i != j) { + const metadata_files_t::value_type& v = *i++; + + if (!metadata->Load(v.name, v.kind)) + return false; + } + + return true; +} + +int ParseArgWebVTT(char* argv[], int* argv_index, int argc_check, + metadata_files_t* metadata_files) { + int& i = *argv_index; + + enum { kCount = 5 }; + struct Arg { + const char* name; + SampleMuxerMetadata::Kind kind; + }; + const Arg args[kCount] = { + {"-webvtt-subtitles", SampleMuxerMetadata::kSubtitles}, + {"-webvtt-captions", SampleMuxerMetadata::kCaptions}, + {"-webvtt-descriptions", SampleMuxerMetadata::kDescriptions}, + {"-webvtt-metadata", SampleMuxerMetadata::kMetadata}, + {"-webvtt-chapters", SampleMuxerMetadata::kChapters}}; + + for (int idx = 0; idx < kCount; ++idx) { + const Arg& arg = args[idx]; + + if (strcmp(arg.name, argv[i]) != 0) // no match + continue; + + ++i; // consume arg name here + + if (i > argc_check) { + printf("missing value for %s\n", arg.name); + return -1; // error + } + + MetadataFile f; + f.name = argv[i]; // arg value is consumed via caller's loop idx + f.kind = arg.kind; + + metadata_files->push_back(f); + return 1; // successfully parsed WebVTT arg + } + + return 0; // not a WebVTT arg +} + +bool CopyVideoProjection(const mkvparser::Projection& parser_projection, + mkvmuxer::Projection* muxer_projection) { + typedef mkvmuxer::Projection::ProjectionType MuxerProjType; + const int kTypeNotPresent = mkvparser::Projection::kTypeNotPresent; + if (parser_projection.type != kTypeNotPresent) { + muxer_projection->set_type( + static_cast(parser_projection.type)); + } + if (parser_projection.private_data && + parser_projection.private_data_length > 0) { + if (!muxer_projection->SetProjectionPrivate( + parser_projection.private_data, + parser_projection.private_data_length)) { + return false; + } + } + + const float kValueNotPresent = mkvparser::Projection::kValueNotPresent; + if (parser_projection.pose_yaw != kValueNotPresent) + muxer_projection->set_pose_yaw(parser_projection.pose_yaw); + if (parser_projection.pose_pitch != kValueNotPresent) + muxer_projection->set_pose_pitch(parser_projection.pose_pitch); + if (parser_projection.pose_roll != kValueNotPresent) + muxer_projection->set_pose_roll(parser_projection.pose_roll); + return true; +} +} // end namespace + +int main(int argc, char* argv[]) { + char* input = NULL; + char* output = NULL; + + // Segment variables + bool output_video = true; + bool output_audio = true; + bool live_mode = false; + bool output_cues = true; + bool cues_before_clusters = false; + bool cues_on_video_track = true; + bool cues_on_audio_track = false; + uint64_t max_cluster_duration = 0; + uint64_t max_cluster_size = 0; + bool switch_tracks = false; + int audio_track_number = 0; // 0 tells muxer to decide. + int video_track_number = 0; // 0 tells muxer to decide. + bool chunking = false; + bool copy_tags = false; + const char* chunk_name = NULL; + bool accurate_cluster_duration = false; + bool fixed_size_cluster_timecode = false; + bool copy_input_duration = false; + + bool output_cues_block_number = true; + + uint64_t display_width = 0; + uint64_t display_height = 0; + uint64_t pixel_width = 0; + uint64_t pixel_height = 0; + uint64_t stereo_mode = 0; + const char* projection_file = 0; + int64_t projection_type = mkvparser::Projection::kTypeNotPresent; + float projection_pose_roll = mkvparser::Projection::kValueNotPresent; + float projection_pose_pitch = mkvparser::Projection::kValueNotPresent; + float projection_pose_yaw = mkvparser::Projection::kValueNotPresent; + int vp9_profile = -1; // No profile set. + int vp9_level = -1; // No level set. + + metadata_files_t metadata_files; + + const int argc_check = argc - 1; + for (int i = 1; i < argc; ++i) { + char* end; + + if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) { + Usage(); + return EXIT_SUCCESS; + } else if (!strcmp("-i", argv[i]) && i < argc_check) { + input = argv[++i]; + } else if (!strcmp("-o", argv[i]) && i < argc_check) { + output = argv[++i]; + } else if (!strcmp("-video", argv[i]) && i < argc_check) { + output_video = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-audio", argv[i]) && i < argc_check) { + output_audio = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-live", argv[i]) && i < argc_check) { + live_mode = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-output_cues", argv[i]) && i < argc_check) { + output_cues = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-cues_before_clusters", argv[i]) && i < argc_check) { + cues_before_clusters = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-cues_on_video_track", argv[i]) && i < argc_check) { + cues_on_video_track = strtol(argv[++i], &end, 10) == 0 ? false : true; + if (cues_on_video_track) + cues_on_audio_track = false; + } else if (!strcmp("-cues_on_audio_track", argv[i]) && i < argc_check) { + cues_on_audio_track = strtol(argv[++i], &end, 10) == 0 ? false : true; + if (cues_on_audio_track) + cues_on_video_track = false; + } else if (!strcmp("-max_cluster_duration", argv[i]) && i < argc_check) { + const double seconds = strtod(argv[++i], &end); + max_cluster_duration = static_cast(seconds * 1000000000.0); + } else if (!strcmp("-max_cluster_size", argv[i]) && i < argc_check) { + max_cluster_size = strtol(argv[++i], &end, 10); + } else if (!strcmp("-switch_tracks", argv[i]) && i < argc_check) { + switch_tracks = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-audio_track_number", argv[i]) && i < argc_check) { + audio_track_number = static_cast(strtol(argv[++i], &end, 10)); + } else if (!strcmp("-video_track_number", argv[i]) && i < argc_check) { + video_track_number = static_cast(strtol(argv[++i], &end, 10)); + } else if (!strcmp("-chunking", argv[i]) && i < argc_check) { + chunking = true; + chunk_name = argv[++i]; + } else if (!strcmp("-copy_tags", argv[i]) && i < argc_check) { + copy_tags = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-accurate_cluster_duration", argv[i]) && + i < argc_check) { + accurate_cluster_duration = + strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-fixed_size_cluster_timecode", argv[i]) && + i < argc_check) { + fixed_size_cluster_timecode = + strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-copy_input_duration", argv[i]) && i < argc_check) { + copy_input_duration = strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (!strcmp("-display_width", argv[i]) && i < argc_check) { + display_width = strtol(argv[++i], &end, 10); + } else if (!strcmp("-display_height", argv[i]) && i < argc_check) { + display_height = strtol(argv[++i], &end, 10); + } else if (!strcmp("-pixel_width", argv[i]) && i < argc_check) { + pixel_width = strtol(argv[++i], &end, 10); + } else if (!strcmp("-pixel_height", argv[i]) && i < argc_check) { + pixel_height = strtol(argv[++i], &end, 10); + } else if (!strcmp("-stereo_mode", argv[i]) && i < argc_check) { + stereo_mode = strtol(argv[++i], &end, 10); + } else if (!strcmp("-projection_type", argv[i]) && i < argc_check) { + projection_type = strtol(argv[++i], &end, 10); + } else if (!strcmp("-projection_file", argv[i]) && i < argc_check) { + projection_file = argv[++i]; + } else if (!strcmp("-projection_pose_roll", argv[i]) && i < argc_check) { + projection_pose_roll = strtof(argv[++i], &end); + } else if (!strcmp("-projection_pose_pitch", argv[i]) && i < argc_check) { + projection_pose_pitch = strtof(argv[++i], &end); + } else if (!strcmp("-projection_pose_yaw", argv[i]) && i < argc_check) { + projection_pose_yaw = strtof(argv[++i], &end); + } else if (!strcmp("-profile", argv[i]) && i < argc_check) { + vp9_profile = static_cast(strtol(argv[++i], &end, 10)); + } else if (!strcmp("-level", argv[i]) && i < argc_check) { + vp9_level = static_cast(strtol(argv[++i], &end, 10)); + } else if (!strcmp("-output_cues_block_number", argv[i]) && + i < argc_check) { + output_cues_block_number = + strtol(argv[++i], &end, 10) == 0 ? false : true; + } else if (int e = ParseArgWebVTT(argv, &i, argc_check, &metadata_files)) { + if (e < 0) + return EXIT_FAILURE; + } + } + + if (input == NULL || output == NULL) { + Usage(); + return EXIT_FAILURE; + } + + // Get parser header info + mkvparser::MkvReader reader; + + if (reader.Open(input)) { + printf("\n Filename is invalid or error while opening.\n"); + return EXIT_FAILURE; + } + + long long pos = 0; + mkvparser::EBMLHeader ebml_header; + long long ret = ebml_header.Parse(&reader, pos); + if (ret) { + printf("\n EBMLHeader::Parse() failed."); + return EXIT_FAILURE; + } + + mkvparser::Segment* parser_segment_; + ret = mkvparser::Segment::CreateInstance(&reader, pos, parser_segment_); + if (ret) { + printf("\n Segment::CreateInstance() failed."); + return EXIT_FAILURE; + } + + const std::unique_ptr parser_segment(parser_segment_); + ret = parser_segment->Load(); + if (ret < 0) { + printf("\n Segment::Load() failed."); + return EXIT_FAILURE; + } + + const mkvparser::SegmentInfo* const segment_info = parser_segment->GetInfo(); + if (segment_info == NULL) { + printf("\n Segment::GetInfo() failed."); + return EXIT_FAILURE; + } + const long long timeCodeScale = segment_info->GetTimeCodeScale(); + + // Set muxer header info + mkvmuxer::MkvWriter writer; + + const std::string temp_file = + cues_before_clusters ? libwebm::GetTempFileName() : output; + if (!writer.Open(temp_file.c_str())) { + printf("\n Filename is invalid or error while opening.\n"); + return EXIT_FAILURE; + } + + // Set Segment element attributes + mkvmuxer::Segment muxer_segment; + + if (!muxer_segment.Init(&writer)) { + printf("\n Could not initialize muxer segment!\n"); + return EXIT_FAILURE; + } + + muxer_segment.AccurateClusterDuration(accurate_cluster_duration); + muxer_segment.UseFixedSizeClusterTimecode(fixed_size_cluster_timecode); + + if (live_mode) + muxer_segment.set_mode(mkvmuxer::Segment::kLive); + else + muxer_segment.set_mode(mkvmuxer::Segment::kFile); + + if (chunking) + muxer_segment.SetChunking(true, chunk_name); + + if (max_cluster_duration > 0) + muxer_segment.set_max_cluster_duration(max_cluster_duration); + if (max_cluster_size > 0) + muxer_segment.set_max_cluster_size(max_cluster_size); + muxer_segment.OutputCues(output_cues); + + // Set SegmentInfo element attributes + mkvmuxer::SegmentInfo* const info = muxer_segment.GetSegmentInfo(); + info->set_timecode_scale(timeCodeScale); + info->set_writing_app("mkvmuxer_sample"); + + const mkvparser::Tags* const tags = parser_segment->GetTags(); + if (copy_tags && tags) { + for (int i = 0; i < tags->GetTagCount(); i++) { + const mkvparser::Tags::Tag* const tag = tags->GetTag(i); + mkvmuxer::Tag* muxer_tag = muxer_segment.AddTag(); + + for (int j = 0; j < tag->GetSimpleTagCount(); j++) { + const mkvparser::Tags::SimpleTag* const simple_tag = + tag->GetSimpleTag(j); + muxer_tag->add_simple_tag(simple_tag->GetTagName(), + simple_tag->GetTagString()); + } + } + } + + // Set Tracks element attributes + const mkvparser::Tracks* const parser_tracks = parser_segment->GetTracks(); + unsigned long i = 0; + uint64_t vid_track = 0; // no track added + uint64_t aud_track = 0; // no track added + + using mkvparser::Track; + + while (i != parser_tracks->GetTracksCount()) { + unsigned long track_num = i++; + if (switch_tracks) + track_num = i % parser_tracks->GetTracksCount(); + + const Track* const parser_track = parser_tracks->GetTrackByIndex(track_num); + + if (parser_track == NULL) + continue; + + // TODO(fgalligan): Add support for language to parser. + const char* const track_name = parser_track->GetNameAsUTF8(); + + const long long track_type = parser_track->GetType(); + + if (track_type == Track::kVideo && output_video) { + // Get the video track from the parser + const mkvparser::VideoTrack* const pVideoTrack = + static_cast(parser_track); + const long long width = pVideoTrack->GetWidth(); + const long long height = pVideoTrack->GetHeight(); + + // Add the video track to the muxer + vid_track = muxer_segment.AddVideoTrack(static_cast(width), + static_cast(height), + video_track_number); + if (!vid_track) { + printf("\n Could not add video track.\n"); + return EXIT_FAILURE; + } + + mkvmuxer::VideoTrack* const video = static_cast( + muxer_segment.GetTrackByNumber(vid_track)); + if (!video) { + printf("\n Could not get video track.\n"); + return EXIT_FAILURE; + } + + if (pVideoTrack->GetColour()) { + mkvmuxer::Colour muxer_colour; + if (!libwebm::CopyColour(*pVideoTrack->GetColour(), &muxer_colour)) + return EXIT_FAILURE; + if (!video->SetColour(muxer_colour)) + return EXIT_FAILURE; + } + + if (pVideoTrack->GetProjection() || + projection_type != mkvparser::Projection::kTypeNotPresent) { + mkvmuxer::Projection muxer_projection; + const mkvparser::Projection* const parser_projection = + pVideoTrack->GetProjection(); + typedef mkvmuxer::Projection::ProjectionType MuxerProjType; + if (parser_projection && + !CopyVideoProjection(*parser_projection, &muxer_projection)) { + printf("\n Unable to copy video projection.\n"); + return EXIT_FAILURE; + } + // Override the values that came from parser if set on command line. + if (projection_type != mkvparser::Projection::kTypeNotPresent) { + muxer_projection.set_type( + static_cast(projection_type)); + if (projection_type == mkvparser::Projection::kRectangular && + projection_file != NULL) { + printf("\n Rectangular projection must not have private data.\n"); + return EXIT_FAILURE; + } else if ((projection_type == mkvparser::Projection::kCubeMap || + projection_type == mkvparser::Projection::kMesh) && + projection_file == NULL) { + printf("\n Mesh or CubeMap projection must have private data.\n"); + return EXIT_FAILURE; + } + if (projection_file != NULL) { + std::string contents; + if (!libwebm::GetFileContents(projection_file, &contents) || + contents.size() == 0) { + printf("\n Failed to read file \"%s\" or file is empty\n", + projection_file); + return EXIT_FAILURE; + } + if (!muxer_projection.SetProjectionPrivate( + reinterpret_cast(&contents[0]), + contents.size())) { + printf("\n Failed to SetProjectionPrivate of length %zu.\n", + contents.size()); + return EXIT_FAILURE; + } + } + } + const float kValueNotPresent = mkvparser::Projection::kValueNotPresent; + if (projection_pose_yaw != kValueNotPresent) + muxer_projection.set_pose_yaw(projection_pose_yaw); + if (projection_pose_pitch != kValueNotPresent) + muxer_projection.set_pose_pitch(projection_pose_pitch); + if (projection_pose_roll != kValueNotPresent) + muxer_projection.set_pose_roll(projection_pose_roll); + + if (!video->SetProjection(muxer_projection)) + return EXIT_FAILURE; + } + + if (track_name) + video->set_name(track_name); + + video->set_codec_id(pVideoTrack->GetCodecId()); + + if (display_width > 0) + video->set_display_width(display_width); + if (display_height > 0) + video->set_display_height(display_height); + if (pixel_width > 0) + video->set_pixel_width(pixel_width); + if (pixel_height > 0) + video->set_pixel_height(pixel_height); + if (stereo_mode > 0) + video->SetStereoMode(stereo_mode); + + const double rate = pVideoTrack->GetFrameRate(); + if (rate > 0.0) { + video->set_frame_rate(rate); + } + + size_t parser_private_size; + const unsigned char* const parser_private_data = + pVideoTrack->GetCodecPrivate(parser_private_size); + + if (!strcmp(video->codec_id(), mkvmuxer::Tracks::kAv1CodecId)) { + if (parser_private_data == NULL || parser_private_size == 0) { + printf("AV1 input track has no CodecPrivate. %s is invalid.", input); + return EXIT_FAILURE; + } + } + + if (!strcmp(video->codec_id(), mkvmuxer::Tracks::kVp9CodecId) && + (vp9_profile >= 0 || vp9_level >= 0)) { + const int kMaxVp9PrivateSize = 6; + unsigned char vp9_private_data[kMaxVp9PrivateSize]; + int vp9_private_size = 0; + if (vp9_profile >= 0) { + if (vp9_profile < 0 || vp9_profile > 3) { + printf("\n VP9 profile(%d) is not valid.\n", vp9_profile); + return EXIT_FAILURE; + } + const uint8_t kVp9ProfileId = 1; + const uint8_t kVp9ProfileIdLength = 1; + vp9_private_data[vp9_private_size++] = kVp9ProfileId; + vp9_private_data[vp9_private_size++] = kVp9ProfileIdLength; + vp9_private_data[vp9_private_size++] = vp9_profile; + } + + if (vp9_level >= 0) { + const int kNumLevels = 14; + const int levels[kNumLevels] = {10, 11, 20, 21, 30, 31, 40, + 41, 50, 51, 52, 60, 61, 62}; + bool level_is_valid = false; + for (int i = 0; i < kNumLevels; ++i) { + if (vp9_level == levels[i]) { + level_is_valid = true; + break; + } + } + if (!level_is_valid) { + printf("\n VP9 level(%d) is not valid.\n", vp9_level); + return EXIT_FAILURE; + } + const uint8_t kVp9LevelId = 2; + const uint8_t kVp9LevelIdLength = 1; + vp9_private_data[vp9_private_size++] = kVp9LevelId; + vp9_private_data[vp9_private_size++] = kVp9LevelIdLength; + vp9_private_data[vp9_private_size++] = vp9_level; + } + if (!video->SetCodecPrivate(vp9_private_data, vp9_private_size)) { + printf("\n Could not add video private data.\n"); + return EXIT_FAILURE; + } + } else if (parser_private_data && parser_private_size > 0) { + if (!video->SetCodecPrivate(parser_private_data, parser_private_size)) { + printf("\n Could not add video private data.\n"); + return EXIT_FAILURE; + } + } + } else if (track_type == Track::kAudio && output_audio) { + // Get the audio track from the parser + const mkvparser::AudioTrack* const pAudioTrack = + static_cast(parser_track); + const long long channels = pAudioTrack->GetChannels(); + const double sample_rate = pAudioTrack->GetSamplingRate(); + + // Add the audio track to the muxer + aud_track = muxer_segment.AddAudioTrack(static_cast(sample_rate), + static_cast(channels), + audio_track_number); + if (!aud_track) { + printf("\n Could not add audio track.\n"); + return EXIT_FAILURE; + } + + mkvmuxer::AudioTrack* const audio = static_cast( + muxer_segment.GetTrackByNumber(aud_track)); + if (!audio) { + printf("\n Could not get audio track.\n"); + return EXIT_FAILURE; + } + + if (track_name) + audio->set_name(track_name); + + audio->set_codec_id(pAudioTrack->GetCodecId()); + + size_t private_size; + const unsigned char* const private_data = + pAudioTrack->GetCodecPrivate(private_size); + if (private_size > 0) { + if (!audio->SetCodecPrivate(private_data, private_size)) { + printf("\n Could not add audio private data.\n"); + return EXIT_FAILURE; + } + } + + const long long bit_depth = pAudioTrack->GetBitDepth(); + if (bit_depth > 0) + audio->set_bit_depth(bit_depth); + + if (pAudioTrack->GetCodecDelay()) + audio->set_codec_delay(pAudioTrack->GetCodecDelay()); + if (pAudioTrack->GetSeekPreRoll()) + audio->set_seek_pre_roll(pAudioTrack->GetSeekPreRoll()); + } + } + + // We have created all the video and audio tracks. If any WebVTT + // files were specified as command-line args, then parse them and + // add a track to the output file corresponding to each metadata + // input file. + + SampleMuxerMetadata metadata; + + if (!metadata.Init(&muxer_segment)) { + printf("\n Could not initialize metadata cache.\n"); + return EXIT_FAILURE; + } + + if (!LoadMetadataFiles(metadata_files, &metadata)) + return EXIT_FAILURE; + + if (!metadata.AddChapters()) + return EXIT_FAILURE; + + // Set Cues element attributes + mkvmuxer::Cues* const cues = muxer_segment.GetCues(); + cues->set_output_block_number(output_cues_block_number); + if (cues_on_video_track && vid_track) + muxer_segment.CuesTrack(vid_track); + if (cues_on_audio_track && aud_track) + muxer_segment.CuesTrack(aud_track); + + // Write clusters + unsigned char* data = NULL; + long data_len = 0; + + const mkvparser::Cluster* cluster = parser_segment->GetFirst(); + + while (cluster != NULL && !cluster->EOS()) { + const mkvparser::BlockEntry* block_entry; + + long status = cluster->GetFirst(block_entry); + + if (status) { + printf("\n Could not get first block of cluster.\n"); + return EXIT_FAILURE; + } + + while (block_entry != NULL && !block_entry->EOS()) { + const mkvparser::Block* const block = block_entry->GetBlock(); + const long long trackNum = block->GetTrackNumber(); + const mkvparser::Track* const parser_track = + parser_tracks->GetTrackByNumber(static_cast(trackNum)); + + // When |parser_track| is NULL, it means that the track number in the + // Block is invalid (i.e.) the was no TrackEntry corresponding to the + // track number. So we reject the file. + if (!parser_track) { + return EXIT_FAILURE; + } + + const long long track_type = parser_track->GetType(); + const long long time_ns = block->GetTime(cluster); + + // Flush any metadata frames to the output file, before we write + // the current block. + if (!metadata.Write(time_ns)) + return EXIT_FAILURE; + + if ((track_type == Track::kAudio && output_audio) || + (track_type == Track::kVideo && output_video)) { + const int frame_count = block->GetFrameCount(); + + for (int i = 0; i < frame_count; ++i) { + const mkvparser::Block::Frame& frame = block->GetFrame(i); + + if (frame.len > data_len) { + delete[] data; + data = new unsigned char[frame.len]; + if (!data) + return EXIT_FAILURE; + data_len = frame.len; + } + + if (frame.Read(&reader, data)) + return EXIT_FAILURE; + + mkvmuxer::Frame muxer_frame; + if (!muxer_frame.Init(data, frame.len)) + return EXIT_FAILURE; + muxer_frame.set_track_number(track_type == Track::kAudio ? aud_track + : vid_track); + if (block->GetDiscardPadding()) + muxer_frame.set_discard_padding(block->GetDiscardPadding()); + muxer_frame.set_timestamp(time_ns); + muxer_frame.set_is_key(block->IsKey()); + if (!muxer_segment.AddGenericFrame(&muxer_frame)) { + printf("\n Could not add frame.\n"); + return EXIT_FAILURE; + } + } + } + + status = cluster->GetNext(block_entry, block_entry); + + if (status) { + printf("\n Could not get next block of cluster.\n"); + return EXIT_FAILURE; + } + } + + cluster = parser_segment->GetNext(cluster); + } + + // We have exhausted all video and audio frames in the input file. + // Flush any remaining metadata frames to the output file. + if (!metadata.Write(-1)) + return EXIT_FAILURE; + + if (copy_input_duration) { + const double input_duration = + static_cast(segment_info->GetDuration()) / timeCodeScale; + muxer_segment.set_duration(input_duration); + } + + if (!muxer_segment.Finalize()) { + printf("Finalization of segment failed.\n"); + return EXIT_FAILURE; + } + + reader.Close(); + writer.Close(); + + if (cues_before_clusters) { + if (reader.Open(temp_file.c_str())) { + printf("\n Filename is invalid or error while opening.\n"); + return EXIT_FAILURE; + } + if (!writer.Open(output)) { + printf("\n Filename is invalid or error while opening.\n"); + return EXIT_FAILURE; + } + if (!muxer_segment.CopyAndMoveCuesBeforeClusters(&reader, &writer)) { + printf("\n Unable to copy and move cues before clusters.\n"); + return EXIT_FAILURE; + } + reader.Close(); + writer.Close(); + remove(temp_file.c_str()); + } + + delete[] data; + + return EXIT_SUCCESS; +} diff --git a/src/sys/libwebm/mkvmuxertypes.hpp b/src/sys/libwebm/mkvmuxertypes.hpp new file mode 100644 index 0000000..78478f4 --- /dev/null +++ b/src/sys/libwebm/mkvmuxertypes.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_MKVMUXERTYPES_HPP_ +#define LIBWEBM_MKVMUXERTYPES_HPP_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "mkvmuxer/mkvmuxertypes.h" + +#endif // LIBWEBM_MKVMUXERTYPES_HPP_ diff --git a/src/sys/libwebm/mkvmuxerutil.hpp b/src/sys/libwebm/mkvmuxerutil.hpp new file mode 100644 index 0000000..a26ba18 --- /dev/null +++ b/src/sys/libwebm/mkvmuxerutil.hpp @@ -0,0 +1,18 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_MKVMUXERUTIL_HPP_ +#define LIBWEBM_MKVMUXERUTIL_HPP_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "mkvmuxer/mkvmuxerutil.h" + +using mkvmuxer::EbmlElementSize; +using mkvmuxer::EbmlMasterElementSize; + +#endif // LIBWEBM_MKVMUXERUTIL_HPP_ diff --git a/src/sys/libwebm/mkvparser.hpp b/src/sys/libwebm/mkvparser.hpp new file mode 100644 index 0000000..3f86292 --- /dev/null +++ b/src/sys/libwebm/mkvparser.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_MKVPARSER_HPP_ +#define LIBWEBM_MKVPARSER_HPP_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "mkvparser/mkvparser.h" + +#endif // LIBWEBM_MKVPARSER_HPP_ diff --git a/src/sys/libwebm/mkvparser/mkvparser.cc b/src/sys/libwebm/mkvparser/mkvparser.cc new file mode 100644 index 0000000..bd52af1 --- /dev/null +++ b/src/sys/libwebm/mkvparser/mkvparser.cc @@ -0,0 +1,8103 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "mkvparser/mkvparser.h" + +#if defined(_MSC_VER) && _MSC_VER < 1800 +#include // _isnan() / _finite() +#define MSC_COMPAT +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "common/webmids.h" + +namespace mkvparser { +const long long kStringElementSizeLimit = 20 * 1000 * 1000; +const float MasteringMetadata::kValueNotPresent = FLT_MAX; +const long long Colour::kValueNotPresent = LLONG_MAX; +const float Projection::kValueNotPresent = FLT_MAX; + +#ifdef MSC_COMPAT +inline bool isnan(double val) { return !!_isnan(val); } +inline bool isinf(double val) { return !_finite(val); } +#else +inline bool isnan(double val) { return std::isnan(val); } +inline bool isinf(double val) { return std::isinf(val); } +#endif // MSC_COMPAT + +template +Type* SafeArrayAlloc(unsigned long long num_elements, + unsigned long long element_size) { + if (num_elements == 0 || element_size == 0) + return NULL; + + const size_t kMaxAllocSize = 0x80000000; // 2GiB + const unsigned long long num_bytes = num_elements * element_size; + if (element_size > (kMaxAllocSize / num_elements)) + return NULL; + if (num_bytes != static_cast(num_bytes)) + return NULL; + + return new (std::nothrow) Type[static_cast(num_bytes)]; +} + +void GetVersion(int& major, int& minor, int& build, int& revision) { + major = 1; + minor = 1; + build = 2; + revision = 0; +} + +long long ReadUInt(IMkvReader* pReader, long long pos, long& len) { + if (!pReader || pos < 0) + return E_FILE_FORMAT_INVALID; + + len = 1; + unsigned char b; + int status = pReader->Read(pos, 1, &b); + + if (status < 0) // error or underflow + return status; + + if (status > 0) // interpreted as "underflow" + return E_BUFFER_NOT_FULL; + + if (b == 0) // we can't handle u-int values larger than 8 bytes + return E_FILE_FORMAT_INVALID; + + unsigned char m = 0x80; + + while (!(b & m)) { + m >>= 1; + ++len; + } + + long long result = b & (~m); + ++pos; + + for (int i = 1; i < len; ++i) { + status = pReader->Read(pos, 1, &b); + + if (status < 0) { + len = 1; + return status; + } + + if (status > 0) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result <<= 8; + result |= b; + + ++pos; + } + + return result; +} + +// Reads an EBML ID and returns it. +// An ID must at least 1 byte long, cannot exceed 4, and its value must be +// greater than 0. +// See known EBML values and EBMLMaxIDLength: +// http://www.matroska.org/technical/specs/index.html +// Returns the ID, or a value less than 0 to report an error while reading the +// ID. +long long ReadID(IMkvReader* pReader, long long pos, long& len) { + if (pReader == NULL || pos < 0) + return E_FILE_FORMAT_INVALID; + + // Read the first byte. The length in bytes of the ID is determined by + // finding the first set bit in the first byte of the ID. + unsigned char temp_byte = 0; + int read_status = pReader->Read(pos, 1, &temp_byte); + + if (read_status < 0) + return E_FILE_FORMAT_INVALID; + else if (read_status > 0) // No data to read. + return E_BUFFER_NOT_FULL; + + if (temp_byte == 0) // ID length > 8 bytes; invalid file. + return E_FILE_FORMAT_INVALID; + + int bit_pos = 0; + const int kMaxIdLengthInBytes = 4; + const int kCheckByte = 0x80; + + // Find the first bit that's set. + bool found_bit = false; + for (; bit_pos < kMaxIdLengthInBytes; ++bit_pos) { + if ((kCheckByte >> bit_pos) & temp_byte) { + found_bit = true; + break; + } + } + + if (!found_bit) { + // The value is too large to be a valid ID. + return E_FILE_FORMAT_INVALID; + } + + // Read the remaining bytes of the ID (if any). + const int id_length = bit_pos + 1; + long long ebml_id = temp_byte; + for (int i = 1; i < id_length; ++i) { + ebml_id <<= 8; + read_status = pReader->Read(pos + i, 1, &temp_byte); + + if (read_status < 0) + return E_FILE_FORMAT_INVALID; + else if (read_status > 0) + return E_BUFFER_NOT_FULL; + + ebml_id |= temp_byte; + } + + len = id_length; + return ebml_id; +} + +long long GetUIntLength(IMkvReader* pReader, long long pos, long& len) { + if (!pReader || pos < 0) + return E_FILE_FORMAT_INVALID; + + long long total, available; + + int status = pReader->Length(&total, &available); + if (status < 0 || (total >= 0 && available > total)) + return E_FILE_FORMAT_INVALID; + + len = 1; + + if (pos >= available) + return pos; // too few bytes available + + unsigned char b; + + status = pReader->Read(pos, 1, &b); + + if (status != 0) + return status; + + if (b == 0) // we can't handle u-int values larger than 8 bytes + return E_FILE_FORMAT_INVALID; + + unsigned char m = 0x80; + + while (!(b & m)) { + m >>= 1; + ++len; + } + + return 0; // success +} + +// TODO(vigneshv): This function assumes that unsigned values never have their +// high bit set. +long long UnserializeUInt(IMkvReader* pReader, long long pos, long long size) { + if (!pReader || pos < 0 || (size <= 0) || (size > 8)) + return E_FILE_FORMAT_INVALID; + + long long result = 0; + + for (long long i = 0; i < size; ++i) { + unsigned char b; + + const long status = pReader->Read(pos, 1, &b); + + if (status < 0) + return status; + + result <<= 8; + result |= b; + + ++pos; + } + + return result; +} + +long UnserializeFloat(IMkvReader* pReader, long long pos, long long size_, + double& result) { + if (!pReader || pos < 0 || ((size_ != 4) && (size_ != 8))) + return E_FILE_FORMAT_INVALID; + + const long size = static_cast(size_); + + unsigned char buf[8]; + + const int status = pReader->Read(pos, size, buf); + + if (status < 0) // error + return status; + + if (size == 4) { + union { + float f; + uint32_t ff; + static_assert(sizeof(float) == sizeof(uint32_t), ""); + }; + + ff = 0; + + for (int i = 0;;) { + ff |= buf[i]; + + if (++i >= 4) + break; + + ff <<= 8; + } + + result = f; + } else { + union { + double d; + uint64_t dd; + static_assert(sizeof(double) == sizeof(uint64_t), ""); + }; + + dd = 0; + + for (int i = 0;;) { + dd |= buf[i]; + + if (++i >= 8) + break; + + dd <<= 8; + } + + result = d; + } + + if (mkvparser::isinf(result) || mkvparser::isnan(result)) + return E_FILE_FORMAT_INVALID; + + return 0; +} + +long UnserializeInt(IMkvReader* pReader, long long pos, long long size, + long long& result_ref) { + if (!pReader || pos < 0 || size < 1 || size > 8) + return E_FILE_FORMAT_INVALID; + + signed char first_byte = 0; + const long status = pReader->Read(pos, 1, (unsigned char*)&first_byte); + + if (status < 0) + return status; + + unsigned long long result = static_cast(first_byte); + ++pos; + + for (long i = 1; i < size; ++i) { + unsigned char b; + + const long status = pReader->Read(pos, 1, &b); + + if (status < 0) + return status; + + result <<= 8; + result |= b; + + ++pos; + } + + result_ref = static_cast(result); + return 0; +} + +long UnserializeString(IMkvReader* pReader, long long pos, long long size, + char*& str) { + delete[] str; + str = NULL; + + if (size >= LONG_MAX || size < 0 || size > kStringElementSizeLimit) + return E_FILE_FORMAT_INVALID; + + // +1 for '\0' terminator + const long required_size = static_cast(size) + 1; + + str = SafeArrayAlloc(1, required_size); + if (str == NULL) + return E_FILE_FORMAT_INVALID; + + unsigned char* const buf = reinterpret_cast(str); + + const long status = pReader->Read(pos, static_cast(size), buf); + + if (status) { + delete[] str; + str = NULL; + + return status; + } + + str[required_size - 1] = '\0'; + return 0; +} + +long ParseElementHeader(IMkvReader* pReader, long long& pos, long long stop, + long long& id, long long& size) { + if (stop >= 0 && pos >= stop) + return E_FILE_FORMAT_INVALID; + + long len; + + id = ReadID(pReader, pos, len); + + if (id < 0) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume id + + if (stop >= 0 && pos >= stop) + return E_FILE_FORMAT_INVALID; + + size = ReadUInt(pReader, pos, len); + + if (size < 0 || len < 1 || len > 8) { + // Invalid: Negative payload size, negative or 0 length integer, or integer + // larger than 64 bits (libwebm cannot handle them). + return E_FILE_FORMAT_INVALID; + } + + // Avoid rolling over pos when very close to LLONG_MAX. + const unsigned long long rollover_check = + static_cast(pos) + len; + if (rollover_check > LLONG_MAX) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume length of size + + // pos now designates payload + + if (stop >= 0 && pos > stop) + return E_FILE_FORMAT_INVALID; + + return 0; // success +} + +bool Match(IMkvReader* pReader, long long& pos, unsigned long expected_id, + long long& val) { + if (!pReader || pos < 0) + return false; + + long long total = 0; + long long available = 0; + + const long status = pReader->Length(&total, &available); + if (status < 0 || (total >= 0 && available > total)) + return false; + + long len = 0; + + const long long id = ReadID(pReader, pos, len); + if (id < 0 || (available - pos) > len) + return false; + + if (static_cast(id) != expected_id) + return false; + + pos += len; // consume id + + const long long size = ReadUInt(pReader, pos, len); + if (size < 0 || size > 8 || len < 1 || len > 8 || (available - pos) > len) + return false; + + pos += len; // consume length of size of payload + + val = UnserializeUInt(pReader, pos, size); + if (val < 0) + return false; + + pos += size; // consume size of payload + + return true; +} + +bool Match(IMkvReader* pReader, long long& pos, unsigned long expected_id, + unsigned char*& buf, size_t& buflen) { + if (!pReader || pos < 0) + return false; + + long long total = 0; + long long available = 0; + + long status = pReader->Length(&total, &available); + if (status < 0 || (total >= 0 && available > total)) + return false; + + long len = 0; + const long long id = ReadID(pReader, pos, len); + if (id < 0 || (available - pos) > len) + return false; + + if (static_cast(id) != expected_id) + return false; + + pos += len; // consume id + + const long long size = ReadUInt(pReader, pos, len); + if (size < 0 || len <= 0 || len > 8 || (available - pos) > len) + return false; + + unsigned long long rollover_check = + static_cast(pos) + len; + if (rollover_check > LLONG_MAX) + return false; + + pos += len; // consume length of size of payload + + rollover_check = static_cast(pos) + size; + if (rollover_check > LLONG_MAX) + return false; + + if ((pos + size) > available) + return false; + + if (size >= LONG_MAX) + return false; + + const long buflen_ = static_cast(size); + + buf = SafeArrayAlloc(1, buflen_); + if (!buf) + return false; + + status = pReader->Read(pos, buflen_, buf); + if (status != 0) + return false; + + buflen = buflen_; + + pos += size; // consume size of payload + return true; +} + +EBMLHeader::EBMLHeader() : m_docType(NULL) { Init(); } + +EBMLHeader::~EBMLHeader() { delete[] m_docType; } + +void EBMLHeader::Init() { + m_version = 1; + m_readVersion = 1; + m_maxIdLength = 4; + m_maxSizeLength = 8; + + if (m_docType) { + delete[] m_docType; + m_docType = NULL; + } + + m_docTypeVersion = 1; + m_docTypeReadVersion = 1; +} + +long long EBMLHeader::Parse(IMkvReader* pReader, long long& pos) { + if (!pReader) + return E_FILE_FORMAT_INVALID; + + long long total, available; + + long status = pReader->Length(&total, &available); + + if (status < 0) // error + return status; + + pos = 0; + + // Scan until we find what looks like the first byte of the EBML header. + const long long kMaxScanBytes = (available >= 1024) ? 1024 : available; + const unsigned char kEbmlByte0 = 0x1A; + unsigned char scan_byte = 0; + + while (pos < kMaxScanBytes) { + status = pReader->Read(pos, 1, &scan_byte); + + if (status < 0) // error + return status; + else if (status > 0) + return E_BUFFER_NOT_FULL; + + if (scan_byte == kEbmlByte0) + break; + + ++pos; + } + + long len = 0; + const long long ebml_id = ReadID(pReader, pos, len); + + if (ebml_id == E_BUFFER_NOT_FULL) + return E_BUFFER_NOT_FULL; + + if (len != 4 || ebml_id != libwebm::kMkvEBML) + return E_FILE_FORMAT_INVALID; + + // Move read pos forward to the EBML header size field. + pos += 4; + + // Read length of size field. + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return E_FILE_FORMAT_INVALID; + else if (result > 0) // need more data + return E_BUFFER_NOT_FULL; + + if (len < 1 || len > 8) + return E_FILE_FORMAT_INVALID; + + if ((total >= 0) && ((total - pos) < len)) + return E_FILE_FORMAT_INVALID; + + if ((available - pos) < len) + return pos + len; // try again later + + // Read the EBML header size. + result = ReadUInt(pReader, pos, len); + + if (result < 0) // error + return result; + + pos += len; // consume size field + + // pos now designates start of payload + + if ((total >= 0) && ((total - pos) < result)) + return E_FILE_FORMAT_INVALID; + + if ((available - pos) < result) + return pos + result; + + const long long end = pos + result; + + Init(); + + while (pos < end) { + long long id, size; + + status = ParseElementHeader(pReader, pos, end, id, size); + + if (status < 0) // error + return status; + + if (size == 0) + return E_FILE_FORMAT_INVALID; + + if (id == libwebm::kMkvEBMLVersion) { + m_version = UnserializeUInt(pReader, pos, size); + + if (m_version <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvEBMLReadVersion) { + m_readVersion = UnserializeUInt(pReader, pos, size); + + if (m_readVersion <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvEBMLMaxIDLength) { + m_maxIdLength = UnserializeUInt(pReader, pos, size); + + if (m_maxIdLength <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvEBMLMaxSizeLength) { + m_maxSizeLength = UnserializeUInt(pReader, pos, size); + + if (m_maxSizeLength <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvDocType) { + if (m_docType) + return E_FILE_FORMAT_INVALID; + + status = UnserializeString(pReader, pos, size, m_docType); + + if (status) // error + return status; + } else if (id == libwebm::kMkvDocTypeVersion) { + m_docTypeVersion = UnserializeUInt(pReader, pos, size); + + if (m_docTypeVersion <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvDocTypeReadVersion) { + m_docTypeReadVersion = UnserializeUInt(pReader, pos, size); + + if (m_docTypeReadVersion <= 0) + return E_FILE_FORMAT_INVALID; + } + + pos += size; + } + + if (pos != end) + return E_FILE_FORMAT_INVALID; + + // Make sure DocType, DocTypeReadVersion, and DocTypeVersion are valid. + if (m_docType == NULL || m_docTypeReadVersion <= 0 || m_docTypeVersion <= 0) + return E_FILE_FORMAT_INVALID; + + // Make sure EBMLMaxIDLength and EBMLMaxSizeLength are valid. + if (m_maxIdLength <= 0 || m_maxIdLength > 4 || m_maxSizeLength <= 0 || + m_maxSizeLength > 8) + return E_FILE_FORMAT_INVALID; + + return 0; +} + +Segment::Segment(IMkvReader* pReader, long long elem_start, + // long long elem_size, + long long start, long long size) + : m_pReader(pReader), + m_element_start(elem_start), + // m_element_size(elem_size), + m_start(start), + m_size(size), + m_pos(start), + m_pUnknownSize(0), + m_pSeekHead(NULL), + m_pInfo(NULL), + m_pTracks(NULL), + m_pCues(NULL), + m_pChapters(NULL), + m_pTags(NULL), + m_clusters(NULL), + m_clusterCount(0), + m_clusterPreloadCount(0), + m_clusterSize(0) {} + +Segment::~Segment() { + const long count = m_clusterCount + m_clusterPreloadCount; + + Cluster** i = m_clusters; + Cluster** j = m_clusters + count; + + while (i != j) { + Cluster* const p = *i++; + delete p; + } + + delete[] m_clusters; + + delete m_pTracks; + delete m_pInfo; + delete m_pCues; + delete m_pChapters; + delete m_pTags; + delete m_pSeekHead; +} + +long long Segment::CreateInstance(IMkvReader* pReader, long long pos, + Segment*& pSegment) { + if (pReader == NULL || pos < 0) + return E_PARSE_FAILED; + + pSegment = NULL; + + long long total, available; + + const long status = pReader->Length(&total, &available); + + if (status < 0) // error + return status; + + if (available < 0) + return -1; + + if ((total >= 0) && (available > total)) + return -1; + + // I would assume that in practice this loop would execute + // exactly once, but we allow for other elements (e.g. Void) + // to immediately follow the EBML header. This is fine for + // the source filter case (since the entire file is available), + // but in the splitter case over a network we should probably + // just give up early. We could for example decide only to + // execute this loop a maximum of, say, 10 times. + // TODO: + // There is an implied "give up early" by only parsing up + // to the available limit. We do do that, but only if the + // total file size is unknown. We could decide to always + // use what's available as our limit (irrespective of whether + // we happen to know the total file length). This would have + // as its sense "parse this much of the file before giving up", + // which a slightly different sense from "try to parse up to + // 10 EMBL elements before giving up". + + for (;;) { + if ((total >= 0) && (pos >= total)) + return E_FILE_FORMAT_INVALID; + + // Read ID + long len; + long long result = GetUIntLength(pReader, pos, len); + + if (result) // error, or too few available bytes + return result; + + if ((total >= 0) && ((pos + len) > total)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > available) + return pos + len; + + const long long idpos = pos; + const long long id = ReadID(pReader, pos, len); + + if (id < 0) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume ID + + // Read Size + + result = GetUIntLength(pReader, pos, len); + + if (result) // error, or too few available bytes + return result; + + if ((total >= 0) && ((pos + len) > total)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > available) + return pos + len; + + long long size = ReadUInt(pReader, pos, len); + + if (size < 0) // error + return size; + + pos += len; // consume length of size of element + + // Pos now points to start of payload + + // Handle "unknown size" for live streaming of webm files. + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (id == libwebm::kMkvSegment) { + if (size == unknown_size) + size = -1; + + else if (total < 0) + size = -1; + + else if ((pos + size) > total) + size = -1; + + pSegment = new (std::nothrow) Segment(pReader, idpos, pos, size); + if (pSegment == NULL) + return E_PARSE_FAILED; + + return 0; // success + } + + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; + + if ((total >= 0) && ((pos + size) > total)) + return E_FILE_FORMAT_INVALID; + + if ((pos + size) > available) + return pos + size; + + pos += size; // consume payload + } +} + +long long Segment::ParseHeaders() { + // Outermost (level 0) segment object has been constructed, + // and pos designates start of payload. We need to find the + // inner (level 1) elements. + long long total, available; + + const int status = m_pReader->Length(&total, &available); + + if (status < 0) // error + return status; + + if (total > 0 && available > total) + return E_FILE_FORMAT_INVALID; + + const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; + + if ((segment_stop >= 0 && total >= 0 && segment_stop > total) || + (segment_stop >= 0 && m_pos > segment_stop)) { + return E_FILE_FORMAT_INVALID; + } + + for (;;) { + if ((total >= 0) && (m_pos >= total)) + break; + + if ((segment_stop >= 0) && (m_pos >= segment_stop)) + break; + + long long pos = m_pos; + const long long element_start = pos; + + // Avoid rolling over pos when very close to LLONG_MAX. + unsigned long long rollover_check = pos + 1ULL; + if (rollover_check > LLONG_MAX) + return E_FILE_FORMAT_INVALID; + + if ((pos + 1) > available) + return (pos + 1); + + long len; + long long result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return result; + + if (result > 0) { + // MkvReader doesn't have enough data to satisfy this read attempt. + return (pos + 1); + } + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > available) + return pos + len; + + const long long idpos = pos; + const long long id = ReadID(m_pReader, idpos, len); + + if (id < 0) + return E_FILE_FORMAT_INVALID; + + if (id == libwebm::kMkvCluster) + break; + + pos += len; // consume ID + + if ((pos + 1) > available) + return (pos + 1); + + // Read Size + result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return result; + + if (result > 0) { + // MkvReader doesn't have enough data to satisfy this read attempt. + return (pos + 1); + } + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > available) + return pos + len; + + const long long size = ReadUInt(m_pReader, pos, len); + + if (size < 0 || len < 1 || len > 8) { + // TODO(tomfinegan): ReadUInt should return an error when len is < 1 or + // len > 8 is true instead of checking this _everywhere_. + return size; + } + + pos += len; // consume length of size of element + + // Avoid rolling over pos when very close to LLONG_MAX. + rollover_check = static_cast(pos) + size; + if (rollover_check > LLONG_MAX) + return E_FILE_FORMAT_INVALID; + + const long long element_size = size + pos - element_start; + + // Pos now points to start of payload + + if ((segment_stop >= 0) && ((pos + size) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + // We read EBML elements either in total or nothing at all. + + if ((pos + size) > available) + return pos + size; + + if (id == libwebm::kMkvInfo) { + if (m_pInfo) + return E_FILE_FORMAT_INVALID; + + m_pInfo = new (std::nothrow) + SegmentInfo(this, pos, size, element_start, element_size); + + if (m_pInfo == NULL) + return -1; + + const long status = m_pInfo->Parse(); + + if (status) + return status; + } else if (id == libwebm::kMkvTracks) { + if (m_pTracks) + return E_FILE_FORMAT_INVALID; + + m_pTracks = new (std::nothrow) + Tracks(this, pos, size, element_start, element_size); + + if (m_pTracks == NULL) + return -1; + + const long status = m_pTracks->Parse(); + + if (status) + return status; + } else if (id == libwebm::kMkvCues) { + if (m_pCues == NULL) { + m_pCues = new (std::nothrow) + Cues(this, pos, size, element_start, element_size); + + if (m_pCues == NULL) + return -1; + } + } else if (id == libwebm::kMkvSeekHead) { + if (m_pSeekHead == NULL) { + m_pSeekHead = new (std::nothrow) + SeekHead(this, pos, size, element_start, element_size); + + if (m_pSeekHead == NULL) + return -1; + + const long status = m_pSeekHead->Parse(); + + if (status) + return status; + } + } else if (id == libwebm::kMkvChapters) { + if (m_pChapters == NULL) { + m_pChapters = new (std::nothrow) + Chapters(this, pos, size, element_start, element_size); + + if (m_pChapters == NULL) + return -1; + + const long status = m_pChapters->Parse(); + + if (status) + return status; + } + } else if (id == libwebm::kMkvTags) { + if (m_pTags == NULL) { + m_pTags = new (std::nothrow) + Tags(this, pos, size, element_start, element_size); + + if (m_pTags == NULL) + return -1; + + const long status = m_pTags->Parse(); + + if (status) + return status; + } + } + + m_pos = pos + size; // consume payload + } + + if (segment_stop >= 0 && m_pos > segment_stop) + return E_FILE_FORMAT_INVALID; + + if (m_pInfo == NULL) // TODO: liberalize this behavior + return E_FILE_FORMAT_INVALID; + + if (m_pTracks == NULL) + return E_FILE_FORMAT_INVALID; + + return 0; // success +} + +long Segment::LoadCluster(long long& pos, long& len) { + for (;;) { + const long result = DoLoadCluster(pos, len); + + if (result <= 1) + return result; + } +} + +long Segment::DoLoadCluster(long long& pos, long& len) { + if (m_pos < 0) + return DoLoadClusterUnknownSize(pos, len); + + long long total, avail; + + long status = m_pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + if (total >= 0 && avail > total) + return E_FILE_FORMAT_INVALID; + + const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; + + long long cluster_off = -1; // offset relative to start of segment + long long cluster_size = -1; // size of cluster payload + + for (;;) { + if ((total >= 0) && (m_pos >= total)) + return 1; // no more clusters + + if ((segment_stop >= 0) && (m_pos >= segment_stop)) + return 1; // no more clusters + + pos = m_pos; + + // Read ID + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long idpos = pos; + const long long id = ReadID(m_pReader, idpos, len); + + if (id < 0) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume ID + + // Read Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(m_pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + pos += len; // consume length of size of element + + // pos now points to start of payload + + if (size == 0) { + // Missing element payload: move on. + m_pos = pos; + continue; + } + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if ((segment_stop >= 0) && (size != unknown_size) && + ((pos + size) > segment_stop)) { + return E_FILE_FORMAT_INVALID; + } + + if (id == libwebm::kMkvCues) { + if (size == unknown_size) { + // Cues element of unknown size: Not supported. + return E_FILE_FORMAT_INVALID; + } + + if (m_pCues == NULL) { + const long long element_size = (pos - idpos) + size; + + m_pCues = new (std::nothrow) Cues(this, pos, size, idpos, element_size); + if (m_pCues == NULL) + return -1; + } + + m_pos = pos + size; // consume payload + continue; + } + + if (id != libwebm::kMkvCluster) { + // Besides the Segment, Libwebm allows only cluster elements of unknown + // size. Fail the parse upon encountering a non-cluster element reporting + // unknown size. + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; + + m_pos = pos + size; // consume payload + continue; + } + + // We have a cluster. + + cluster_off = idpos - m_start; // relative pos + + if (size != unknown_size) + cluster_size = size; + + break; + } + + if (cluster_off < 0) { + // No cluster, die. + return E_FILE_FORMAT_INVALID; + } + + long long pos_; + long len_; + + status = Cluster::HasBlockEntries(this, cluster_off, pos_, len_); + + if (status < 0) { // error, or underflow + pos = pos_; + len = len_; + + return status; + } + + // status == 0 means "no block entries found" + // status > 0 means "found at least one block entry" + + // TODO: + // The issue here is that the segment increments its own + // pos ptr past the most recent cluster parsed, and then + // starts from there to parse the next cluster. If we + // don't know the size of the current cluster, then we + // must either parse its payload (as we do below), looking + // for the cluster (or cues) ID to terminate the parse. + // This isn't really what we want: rather, we really need + // a way to create the curr cluster object immediately. + // The pity is that cluster::parse can determine its own + // boundary, and we largely duplicate that same logic here. + // + // Maybe we need to get rid of our look-ahead preloading + // in source::parse??? + // + // As we're parsing the blocks in the curr cluster + //(in cluster::parse), we should have some way to signal + // to the segment that we have determined the boundary, + // so it can adjust its own segment::m_pos member. + // + // The problem is that we're asserting in asyncreadinit, + // because we adjust the pos down to the curr seek pos, + // and the resulting adjusted len is > 2GB. I'm suspicious + // that this is even correct, but even if it is, we can't + // be loading that much data in the cache anyway. + + const long idx = m_clusterCount; + + if (m_clusterPreloadCount > 0) { + if (idx >= m_clusterSize) + return E_FILE_FORMAT_INVALID; + + Cluster* const pCluster = m_clusters[idx]; + if (pCluster == NULL || pCluster->m_index >= 0) + return E_FILE_FORMAT_INVALID; + + const long long off = pCluster->GetPosition(); + if (off < 0) + return E_FILE_FORMAT_INVALID; + + if (off == cluster_off) { // preloaded already + if (status == 0) // no entries found + return E_FILE_FORMAT_INVALID; + + if (cluster_size >= 0) + pos += cluster_size; + else { + const long long element_size = pCluster->GetElementSize(); + + if (element_size <= 0) + return E_FILE_FORMAT_INVALID; // TODO: handle this case + + pos = pCluster->m_element_start + element_size; + } + + pCluster->m_index = idx; // move from preloaded to loaded + ++m_clusterCount; + --m_clusterPreloadCount; + + m_pos = pos; // consume payload + if (segment_stop >= 0 && m_pos > segment_stop) + return E_FILE_FORMAT_INVALID; + + return 0; // success + } + } + + if (status == 0) { // no entries found + if (cluster_size >= 0) + pos += cluster_size; + + if ((total >= 0) && (pos >= total)) { + m_pos = total; + return 1; // no more clusters + } + + if ((segment_stop >= 0) && (pos >= segment_stop)) { + m_pos = segment_stop; + return 1; // no more clusters + } + + m_pos = pos; + return 2; // try again + } + + // status > 0 means we have an entry + + Cluster* const pCluster = Cluster::Create(this, idx, cluster_off); + if (pCluster == NULL) + return -1; + + if (!AppendCluster(pCluster)) { + delete pCluster; + return -1; + } + + if (cluster_size >= 0) { + pos += cluster_size; + + m_pos = pos; + + if (segment_stop > 0 && m_pos > segment_stop) + return E_FILE_FORMAT_INVALID; + + return 0; + } + + m_pUnknownSize = pCluster; + m_pos = -pos; + + return 0; // partial success, since we have a new cluster + + // status == 0 means "no block entries found" + // pos designates start of payload + // m_pos has NOT been adjusted yet (in case we need to come back here) +} + +long Segment::DoLoadClusterUnknownSize(long long& pos, long& len) { + if (m_pos >= 0 || m_pUnknownSize == NULL) + return E_PARSE_FAILED; + + const long status = m_pUnknownSize->Parse(pos, len); + + if (status < 0) // error or underflow + return status; + + if (status == 0) // parsed a block + return 2; // continue parsing + + const long long start = m_pUnknownSize->m_element_start; + const long long size = m_pUnknownSize->GetElementSize(); + + if (size < 0) + return E_FILE_FORMAT_INVALID; + + pos = start + size; + m_pos = pos; + + m_pUnknownSize = 0; + + return 2; // continue parsing +} + +bool Segment::AppendCluster(Cluster* pCluster) { + if (pCluster == NULL || pCluster->m_index < 0) + return false; + + const long count = m_clusterCount + m_clusterPreloadCount; + + long& size = m_clusterSize; + const long idx = pCluster->m_index; + + if (size < count || idx != m_clusterCount) + return false; + + if (count >= size) { + const long n = (size <= 0) ? 2048 : 2 * size; + + Cluster** const qq = new (std::nothrow) Cluster*[n]; + if (qq == NULL) + return false; + + Cluster** q = qq; + Cluster** p = m_clusters; + Cluster** const pp = p + count; + + while (p != pp) + *q++ = *p++; + + delete[] m_clusters; + + m_clusters = qq; + size = n; + } + + if (m_clusterPreloadCount > 0) { + Cluster** const p = m_clusters + m_clusterCount; + if (*p == NULL || (*p)->m_index >= 0) + return false; + + Cluster** q = p + m_clusterPreloadCount; + if (q >= (m_clusters + size)) + return false; + + for (;;) { + Cluster** const qq = q - 1; + if ((*qq)->m_index >= 0) + return false; + + *q = *qq; + q = qq; + + if (q == p) + break; + } + } + + m_clusters[idx] = pCluster; + ++m_clusterCount; + return true; +} + +bool Segment::PreloadCluster(Cluster* pCluster, ptrdiff_t idx) { + if (pCluster == NULL || pCluster->m_index >= 0 || idx < m_clusterCount) + return false; + + const long count = m_clusterCount + m_clusterPreloadCount; + + long& size = m_clusterSize; + if (size < count) + return false; + + if (count >= size) { + const long n = (size <= 0) ? 2048 : 2 * size; + + Cluster** const qq = new (std::nothrow) Cluster*[n]; + if (qq == NULL) + return false; + Cluster** q = qq; + + Cluster** p = m_clusters; + Cluster** const pp = p + count; + + while (p != pp) + *q++ = *p++; + + delete[] m_clusters; + + m_clusters = qq; + size = n; + } + + if (m_clusters == NULL) + return false; + + Cluster** const p = m_clusters + idx; + + Cluster** q = m_clusters + count; + if (q < p || q >= (m_clusters + size)) + return false; + + while (q > p) { + Cluster** const qq = q - 1; + + if ((*qq)->m_index >= 0) + return false; + + *q = *qq; + q = qq; + } + + m_clusters[idx] = pCluster; + ++m_clusterPreloadCount; + return true; +} + +long Segment::Load() { + if (m_clusters != NULL || m_clusterSize != 0 || m_clusterCount != 0) + return E_PARSE_FAILED; + + // Outermost (level 0) segment object has been constructed, + // and pos designates start of payload. We need to find the + // inner (level 1) elements. + + const long long header_status = ParseHeaders(); + + if (header_status < 0) // error + return static_cast(header_status); + + if (header_status > 0) // underflow + return E_BUFFER_NOT_FULL; + + if (m_pInfo == NULL || m_pTracks == NULL) + return E_FILE_FORMAT_INVALID; + + for (;;) { + const long status = LoadCluster(); + + if (status < 0) // error + return status; + + if (status >= 1) // no more clusters + return 0; + } +} + +SeekHead::Entry::Entry() : id(0), pos(0), element_start(0), element_size(0) {} + +SeekHead::SeekHead(Segment* pSegment, long long start, long long size_, + long long element_start, long long element_size) + : m_pSegment(pSegment), + m_start(start), + m_size(size_), + m_element_start(element_start), + m_element_size(element_size), + m_entries(0), + m_entry_count(0), + m_void_elements(0), + m_void_element_count(0) {} + +SeekHead::~SeekHead() { + delete[] m_entries; + delete[] m_void_elements; +} + +long SeekHead::Parse() { + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long pos = m_start; + const long long stop = m_start + m_size; + + // first count the seek head entries + + long long entry_count = 0; + long long void_element_count = 0; + + while (pos < stop) { + long long id, size; + + const long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (id == libwebm::kMkvSeek) { + ++entry_count; + if (entry_count > INT_MAX) + return E_PARSE_FAILED; + } else if (id == libwebm::kMkvVoid) { + ++void_element_count; + if (void_element_count > INT_MAX) + return E_PARSE_FAILED; + } + + pos += size; // consume payload + + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + if (entry_count > 0) { + m_entries = new (std::nothrow) Entry[static_cast(entry_count)]; + + if (m_entries == NULL) + return -1; + } + + if (void_element_count > 0) { + m_void_elements = + new (std::nothrow) VoidElement[static_cast(void_element_count)]; + + if (m_void_elements == NULL) + return -1; + } + + // now parse the entries and void elements + + Entry* pEntry = m_entries; + VoidElement* pVoidElement = m_void_elements; + + pos = m_start; + + while (pos < stop) { + const long long idpos = pos; + + long long id, size; + + const long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (id == libwebm::kMkvSeek && entry_count > 0) { + if (ParseEntry(pReader, pos, size, pEntry)) { + Entry& e = *pEntry++; + + e.element_start = idpos; + e.element_size = (pos + size) - idpos; + } + } else if (id == libwebm::kMkvVoid && void_element_count > 0) { + VoidElement& e = *pVoidElement++; + + e.element_start = idpos; + e.element_size = (pos + size) - idpos; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + ptrdiff_t count_ = ptrdiff_t(pEntry - m_entries); + assert(count_ >= 0); + assert(static_cast(count_) <= entry_count); + + m_entry_count = static_cast(count_); + + count_ = ptrdiff_t(pVoidElement - m_void_elements); + assert(count_ >= 0); + assert(static_cast(count_) <= void_element_count); + + m_void_element_count = static_cast(count_); + + return 0; +} + +int SeekHead::GetCount() const { return m_entry_count; } + +const SeekHead::Entry* SeekHead::GetEntry(int idx) const { + if (idx < 0) + return 0; + + if (idx >= m_entry_count) + return 0; + + return m_entries + idx; +} + +int SeekHead::GetVoidElementCount() const { return m_void_element_count; } + +const SeekHead::VoidElement* SeekHead::GetVoidElement(int idx) const { + if (idx < 0) + return 0; + + if (idx >= m_void_element_count) + return 0; + + return m_void_elements + idx; +} + +long Segment::ParseCues(long long off, long long& pos, long& len) { + if (m_pCues) + return 0; // success + + if (off < 0) + return -1; + + long long total, avail; + + const int status = m_pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + assert((total < 0) || (avail <= total)); + + pos = m_start + off; + + if ((total < 0) || (pos >= total)) + return 1; // don't bother parsing cues + + const long long element_start = pos; + const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // underflow (weird) + { + len = 1; + return E_BUFFER_NOT_FULL; + } + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long idpos = pos; + + const long long id = ReadID(m_pReader, idpos, len); + + if (id != libwebm::kMkvCues) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume ID + assert((segment_stop < 0) || (pos <= segment_stop)); + + // Read Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // underflow (weird) + { + len = 1; + return E_BUFFER_NOT_FULL; + } + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(m_pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + if (size == 0) // weird, although technically not illegal + return 1; // done + + pos += len; // consume length of size of element + assert((segment_stop < 0) || (pos <= segment_stop)); + + // Pos now points to start of payload + + const long long element_stop = pos + size; + + if ((segment_stop >= 0) && (element_stop > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((total >= 0) && (element_stop > total)) + return 1; // don't bother parsing anymore + + len = static_cast(size); + + if (element_stop > avail) + return E_BUFFER_NOT_FULL; + + const long long element_size = element_stop - element_start; + + m_pCues = + new (std::nothrow) Cues(this, pos, size, element_start, element_size); + if (m_pCues == NULL) + return -1; + + return 0; // success +} + +bool SeekHead::ParseEntry(IMkvReader* pReader, long long start, long long size_, + Entry* pEntry) { + if (size_ <= 0) + return false; + + long long pos = start; + const long long stop = start + size_; + + long len; + + // parse the container for the level-1 element ID + + const long long seekIdId = ReadID(pReader, pos, len); + if (seekIdId < 0) + return false; + + if (seekIdId != libwebm::kMkvSeekID) + return false; + + if ((pos + len) > stop) + return false; + + pos += len; // consume SeekID id + + const long long seekIdSize = ReadUInt(pReader, pos, len); + + if (seekIdSize <= 0) + return false; + + if ((pos + len) > stop) + return false; + + pos += len; // consume size of field + + if ((pos + seekIdSize) > stop) + return false; + + pEntry->id = ReadID(pReader, pos, len); // payload + + if (pEntry->id <= 0) + return false; + + if (len != seekIdSize) + return false; + + pos += seekIdSize; // consume SeekID payload + + const long long seekPosId = ReadID(pReader, pos, len); + + if (seekPosId != libwebm::kMkvSeekPosition) + return false; + + if ((pos + len) > stop) + return false; + + pos += len; // consume id + + const long long seekPosSize = ReadUInt(pReader, pos, len); + + if (seekPosSize <= 0) + return false; + + if ((pos + len) > stop) + return false; + + pos += len; // consume size + + if ((pos + seekPosSize) > stop) + return false; + + pEntry->pos = UnserializeUInt(pReader, pos, seekPosSize); + + if (pEntry->pos < 0) + return false; + + pos += seekPosSize; // consume payload + + if (pos != stop) + return false; + + return true; +} + +Cues::Cues(Segment* pSegment, long long start_, long long size_, + long long element_start, long long element_size) + : m_pSegment(pSegment), + m_start(start_), + m_size(size_), + m_element_start(element_start), + m_element_size(element_size), + m_cue_points(NULL), + m_count(0), + m_preload_count(0), + m_pos(start_) {} + +Cues::~Cues() { + const long n = m_count + m_preload_count; + + CuePoint** p = m_cue_points; + CuePoint** const q = p + n; + + while (p != q) { + CuePoint* const pCP = *p++; + assert(pCP); + + delete pCP; + } + + delete[] m_cue_points; +} + +long Cues::GetCount() const { + if (m_cue_points == NULL) + return -1; + + return m_count; // TODO: really ignore preload count? +} + +bool Cues::DoneParsing() const { + const long long stop = m_start + m_size; + return (m_pos >= stop); +} + +bool Cues::Init() const { + if (m_cue_points) + return true; + + if (m_count != 0 || m_preload_count != 0) + return false; + + IMkvReader* const pReader = m_pSegment->m_pReader; + + const long long stop = m_start + m_size; + long long pos = m_start; + + long cue_points_size = 0; + + while (pos < stop) { + const long long idpos = pos; + + long len; + + const long long id = ReadID(pReader, pos, len); + if (id < 0 || (pos + len) > stop) { + return false; + } + + pos += len; // consume ID + + const long long size = ReadUInt(pReader, pos, len); + if (size < 0 || (pos + len > stop)) { + return false; + } + + pos += len; // consume Size field + if (pos + size > stop) { + return false; + } + + if (id == libwebm::kMkvCuePoint) { + if (!PreloadCuePoint(cue_points_size, idpos)) + return false; + } + + pos += size; // skip payload + } + return true; +} + +bool Cues::PreloadCuePoint(long& cue_points_size, long long pos) const { + if (m_count != 0) + return false; + + if (m_preload_count >= cue_points_size) { + const long n = (cue_points_size <= 0) ? 2048 : 2 * cue_points_size; + + CuePoint** const qq = new (std::nothrow) CuePoint*[n]; + if (qq == NULL) + return false; + + CuePoint** q = qq; // beginning of target + + CuePoint** p = m_cue_points; // beginning of source + CuePoint** const pp = p + m_preload_count; // end of source + + while (p != pp) + *q++ = *p++; + + delete[] m_cue_points; + + m_cue_points = qq; + cue_points_size = n; + } + + CuePoint* const pCP = new (std::nothrow) CuePoint(m_preload_count, pos); + if (pCP == NULL) + return false; + + m_cue_points[m_preload_count++] = pCP; + return true; +} + +bool Cues::LoadCuePoint() const { + const long long stop = m_start + m_size; + + if (m_pos >= stop) + return false; // nothing else to do + + if (!Init()) { + m_pos = stop; + return false; + } + + IMkvReader* const pReader = m_pSegment->m_pReader; + + while (m_pos < stop) { + const long long idpos = m_pos; + + long len; + + const long long id = ReadID(pReader, m_pos, len); + if (id < 0 || (m_pos + len) > stop) + return false; + + m_pos += len; // consume ID + + const long long size = ReadUInt(pReader, m_pos, len); + if (size < 0 || (m_pos + len) > stop) + return false; + + m_pos += len; // consume Size field + if ((m_pos + size) > stop) + return false; + + if (id != libwebm::kMkvCuePoint) { + m_pos += size; // consume payload + if (m_pos > stop) + return false; + + continue; + } + + if (m_preload_count < 1) + return false; + + CuePoint* const pCP = m_cue_points[m_count]; + if (!pCP || (pCP->GetTimeCode() < 0 && (-pCP->GetTimeCode() != idpos))) + return false; + + if (!pCP->Load(pReader)) { + m_pos = stop; + return false; + } + ++m_count; + --m_preload_count; + + m_pos += size; // consume payload + if (m_pos > stop) + return false; + + return true; // yes, we loaded a cue point + } + + return false; // no, we did not load a cue point +} + +bool Cues::Find(long long time_ns, const Track* pTrack, const CuePoint*& pCP, + const CuePoint::TrackPosition*& pTP) const { + if (time_ns < 0 || pTrack == NULL || m_cue_points == NULL || m_count == 0) + return false; + + CuePoint** const ii = m_cue_points; + CuePoint** i = ii; + + CuePoint** const jj = ii + m_count; + CuePoint** j = jj; + + pCP = *i; + if (pCP == NULL) + return false; + + if (time_ns <= pCP->GetTime(m_pSegment)) { + pTP = pCP->Find(pTrack); + return (pTP != NULL); + } + + while (i < j) { + // INVARIANT: + //[ii, i) <= time_ns + //[i, j) ? + //[j, jj) > time_ns + + CuePoint** const k = i + (j - i) / 2; + if (k >= jj) + return false; + + CuePoint* const pCP = *k; + if (pCP == NULL) + return false; + + const long long t = pCP->GetTime(m_pSegment); + + if (t <= time_ns) + i = k + 1; + else + j = k; + + if (i > j) + return false; + } + + if (i != j || i > jj || i <= ii) + return false; + + pCP = *--i; + + if (pCP == NULL || pCP->GetTime(m_pSegment) > time_ns) + return false; + + // TODO: here and elsewhere, it's probably not correct to search + // for the cue point with this time, and then search for a matching + // track. In principle, the matching track could be on some earlier + // cue point, and with our current algorithm, we'd miss it. To make + // this bullet-proof, we'd need to create a secondary structure, + // with a list of cue points that apply to a track, and then search + // that track-based structure for a matching cue point. + + pTP = pCP->Find(pTrack); + return (pTP != NULL); +} + +const CuePoint* Cues::GetFirst() const { + if (m_cue_points == NULL || m_count == 0) + return NULL; + + CuePoint* const* const pp = m_cue_points; + if (pp == NULL) + return NULL; + + CuePoint* const pCP = pp[0]; + if (pCP == NULL || pCP->GetTimeCode() < 0) + return NULL; + + return pCP; +} + +const CuePoint* Cues::GetLast() const { + if (m_cue_points == NULL || m_count <= 0) + return NULL; + + const long index = m_count - 1; + + CuePoint* const* const pp = m_cue_points; + if (pp == NULL) + return NULL; + + CuePoint* const pCP = pp[index]; + if (pCP == NULL || pCP->GetTimeCode() < 0) + return NULL; + + return pCP; +} + +const CuePoint* Cues::GetNext(const CuePoint* pCurr) const { + if (pCurr == NULL || pCurr->GetTimeCode() < 0 || m_cue_points == NULL || + m_count < 1) { + return NULL; + } + + long index = pCurr->m_index; + if (index >= m_count) + return NULL; + + CuePoint* const* const pp = m_cue_points; + if (pp == NULL || pp[index] != pCurr) + return NULL; + + ++index; + + if (index >= m_count) + return NULL; + + CuePoint* const pNext = pp[index]; + + if (pNext == NULL || pNext->GetTimeCode() < 0) + return NULL; + + return pNext; +} + +const BlockEntry* Cues::GetBlock(const CuePoint* pCP, + const CuePoint::TrackPosition* pTP) const { + if (pCP == NULL || pTP == NULL) + return NULL; + + return m_pSegment->GetBlock(*pCP, *pTP); +} + +const BlockEntry* Segment::GetBlock(const CuePoint& cp, + const CuePoint::TrackPosition& tp) { + Cluster** const ii = m_clusters; + Cluster** i = ii; + + const long count = m_clusterCount + m_clusterPreloadCount; + + Cluster** const jj = ii + count; + Cluster** j = jj; + + while (i < j) { + // INVARIANT: + //[ii, i) < pTP->m_pos + //[i, j) ? + //[j, jj) > pTP->m_pos + + Cluster** const k = i + (j - i) / 2; + assert(k < jj); + + Cluster* const pCluster = *k; + assert(pCluster); + + // const long long pos_ = pCluster->m_pos; + // assert(pos_); + // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); + + const long long pos = pCluster->GetPosition(); + assert(pos >= 0); + + if (pos < tp.m_pos) + i = k + 1; + else if (pos > tp.m_pos) + j = k; + else + return pCluster->GetEntry(cp, tp); + } + + assert(i == j); + // assert(Cluster::HasBlockEntries(this, tp.m_pos)); + + Cluster* const pCluster = Cluster::Create(this, -1, tp.m_pos); //, -1); + if (pCluster == NULL) + return NULL; + + const ptrdiff_t idx = i - m_clusters; + + if (!PreloadCluster(pCluster, idx)) { + delete pCluster; + return NULL; + } + assert(m_clusters); + assert(m_clusterPreloadCount > 0); + assert(m_clusters[idx] == pCluster); + + return pCluster->GetEntry(cp, tp); +} + +const Cluster* Segment::FindOrPreloadCluster(long long requested_pos) { + if (requested_pos < 0) + return 0; + + Cluster** const ii = m_clusters; + Cluster** i = ii; + + const long count = m_clusterCount + m_clusterPreloadCount; + + Cluster** const jj = ii + count; + Cluster** j = jj; + + while (i < j) { + // INVARIANT: + //[ii, i) < pTP->m_pos + //[i, j) ? + //[j, jj) > pTP->m_pos + + Cluster** const k = i + (j - i) / 2; + assert(k < jj); + + Cluster* const pCluster = *k; + assert(pCluster); + + // const long long pos_ = pCluster->m_pos; + // assert(pos_); + // const long long pos = pos_ * ((pos_ < 0) ? -1 : 1); + + const long long pos = pCluster->GetPosition(); + assert(pos >= 0); + + if (pos < requested_pos) + i = k + 1; + else if (pos > requested_pos) + j = k; + else + return pCluster; + } + + assert(i == j); + // assert(Cluster::HasBlockEntries(this, tp.m_pos)); + + Cluster* const pCluster = Cluster::Create(this, -1, requested_pos); + if (pCluster == NULL) + return NULL; + + const ptrdiff_t idx = i - m_clusters; + + if (!PreloadCluster(pCluster, idx)) { + delete pCluster; + return NULL; + } + assert(m_clusters); + assert(m_clusterPreloadCount > 0); + assert(m_clusters[idx] == pCluster); + + return pCluster; +} + +CuePoint::CuePoint(long idx, long long pos) + : m_element_start(0), + m_element_size(0), + m_index(idx), + m_timecode(-1 * pos), + m_track_positions(NULL), + m_track_positions_count(0) { + assert(pos > 0); +} + +CuePoint::~CuePoint() { delete[] m_track_positions; } + +bool CuePoint::Load(IMkvReader* pReader) { + // odbgstream os; + // os << "CuePoint::Load(begin): timecode=" << m_timecode << endl; + + if (m_timecode >= 0) // already loaded + return true; + + assert(m_track_positions == NULL); + assert(m_track_positions_count == 0); + + long long pos_ = -m_timecode; + const long long element_start = pos_; + + long long stop; + + { + long len; + + const long long id = ReadID(pReader, pos_, len); + if (id != libwebm::kMkvCuePoint) + return false; + + pos_ += len; // consume ID + + const long long size = ReadUInt(pReader, pos_, len); + assert(size >= 0); + + pos_ += len; // consume Size field + // pos_ now points to start of payload + + stop = pos_ + size; + } + + const long long element_size = stop - element_start; + + long long pos = pos_; + + // First count number of track positions + unsigned long long track_positions_count = 0; + while (pos < stop) { + long len; + + const long long id = ReadID(pReader, pos, len); + if ((id < 0) || (pos + len > stop)) { + return false; + } + + pos += len; // consume ID + + const long long size = ReadUInt(pReader, pos, len); + if ((size < 0) || (pos + len > stop)) { + return false; + } + + pos += len; // consume Size field + if ((pos + size) > stop) { + return false; + } + + if (id == libwebm::kMkvCueTime) + m_timecode = UnserializeUInt(pReader, pos, size); + + else if (id == libwebm::kMkvCueTrackPositions) { + ++track_positions_count; + if (track_positions_count > UINT_MAX) + return E_PARSE_FAILED; + } + + pos += size; // consume payload + } + + m_track_positions_count = static_cast(track_positions_count); + + if (m_timecode < 0 || m_track_positions_count <= 0) { + return false; + } + + // os << "CuePoint::Load(cont'd): idpos=" << idpos + // << " timecode=" << m_timecode + // << endl; + + m_track_positions = new (std::nothrow) TrackPosition[m_track_positions_count]; + if (m_track_positions == NULL) + return false; + + // Now parse track positions + + TrackPosition* p = m_track_positions; + pos = pos_; + + while (pos < stop) { + long len; + + const long long id = ReadID(pReader, pos, len); + if (id < 0 || (pos + len) > stop) + return false; + + pos += len; // consume ID + + const long long size = ReadUInt(pReader, pos, len); + assert(size >= 0); + assert((pos + len) <= stop); + + pos += len; // consume Size field + assert((pos + size) <= stop); + + if (id == libwebm::kMkvCueTrackPositions) { + TrackPosition& tp = *p++; + if (!tp.Parse(pReader, pos, size)) { + return false; + } + } + + pos += size; // consume payload + if (pos > stop) + return false; + } + + assert(size_t(p - m_track_positions) == m_track_positions_count); + + m_element_start = element_start; + m_element_size = element_size; + + return true; +} + +bool CuePoint::TrackPosition::Parse(IMkvReader* pReader, long long start_, + long long size_) { + const long long stop = start_ + size_; + long long pos = start_; + + m_track = -1; + m_pos = -1; + m_block = 1; // default + + while (pos < stop) { + long len; + + const long long id = ReadID(pReader, pos, len); + if ((id < 0) || ((pos + len) > stop)) { + return false; + } + + pos += len; // consume ID + + const long long size = ReadUInt(pReader, pos, len); + if ((size < 0) || ((pos + len) > stop)) { + return false; + } + + pos += len; // consume Size field + if ((pos + size) > stop) { + return false; + } + + if (id == libwebm::kMkvCueTrack) + m_track = UnserializeUInt(pReader, pos, size); + else if (id == libwebm::kMkvCueClusterPosition) + m_pos = UnserializeUInt(pReader, pos, size); + else if (id == libwebm::kMkvCueBlockNumber) + m_block = UnserializeUInt(pReader, pos, size); + + pos += size; // consume payload + } + + if ((m_pos < 0) || (m_track <= 0) || (m_block < 0) || (m_block > LONG_MAX)) { + return false; + } + + return true; +} + +const CuePoint::TrackPosition* CuePoint::Find(const Track* pTrack) const { + if (pTrack == NULL) { + return NULL; + } + + const long long n = pTrack->GetNumber(); + + const TrackPosition* i = m_track_positions; + const TrackPosition* const j = i + m_track_positions_count; + + while (i != j) { + const TrackPosition& p = *i++; + + if (p.m_track == n) + return &p; + } + + return NULL; // no matching track number found +} + +long long CuePoint::GetTimeCode() const { return m_timecode; } + +long long CuePoint::GetTime(const Segment* pSegment) const { + assert(pSegment); + assert(m_timecode >= 0); + + const SegmentInfo* const pInfo = pSegment->GetInfo(); + assert(pInfo); + + const long long scale = pInfo->GetTimeCodeScale(); + assert(scale >= 1); + + const long long time = scale * m_timecode; + + return time; +} + +bool Segment::DoneParsing() const { + if (m_size < 0) { + long long total, avail; + + const int status = m_pReader->Length(&total, &avail); + + if (status < 0) // error + return true; // must assume done + + if (total < 0) + return false; // assume live stream + + return (m_pos >= total); + } + + const long long stop = m_start + m_size; + + return (m_pos >= stop); +} + +const Cluster* Segment::GetFirst() const { + if ((m_clusters == NULL) || (m_clusterCount <= 0)) + return &m_eos; + + Cluster* const pCluster = m_clusters[0]; + assert(pCluster); + + return pCluster; +} + +const Cluster* Segment::GetLast() const { + if ((m_clusters == NULL) || (m_clusterCount <= 0)) + return &m_eos; + + const long idx = m_clusterCount - 1; + + Cluster* const pCluster = m_clusters[idx]; + assert(pCluster); + + return pCluster; +} + +unsigned long Segment::GetCount() const { return m_clusterCount; } + +const Cluster* Segment::GetNext(const Cluster* pCurr) { + assert(pCurr); + assert(pCurr != &m_eos); + assert(m_clusters); + + long idx = pCurr->m_index; + + if (idx >= 0) { + assert(m_clusterCount > 0); + assert(idx < m_clusterCount); + assert(pCurr == m_clusters[idx]); + + ++idx; + + if (idx >= m_clusterCount) + return &m_eos; // caller will LoadCluster as desired + + Cluster* const pNext = m_clusters[idx]; + assert(pNext); + assert(pNext->m_index >= 0); + assert(pNext->m_index == idx); + + return pNext; + } + + assert(m_clusterPreloadCount > 0); + + long long pos = pCurr->m_element_start; + + assert(m_size >= 0); // TODO + const long long stop = m_start + m_size; // end of segment + + { + long len; + + long long result = GetUIntLength(m_pReader, pos, len); + assert(result == 0); + assert((pos + len) <= stop); // TODO + if (result != 0) + return NULL; + + const long long id = ReadID(m_pReader, pos, len); + if (id != libwebm::kMkvCluster) + return NULL; + + pos += len; // consume ID + + // Read Size + result = GetUIntLength(m_pReader, pos, len); + assert(result == 0); // TODO + assert((pos + len) <= stop); // TODO + + const long long size = ReadUInt(m_pReader, pos, len); + assert(size > 0); // TODO + // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); + + pos += len; // consume length of size of element + assert((pos + size) <= stop); // TODO + + // Pos now points to start of payload + + pos += size; // consume payload + } + + long long off_next = 0; + + while (pos < stop) { + long len; + + long long result = GetUIntLength(m_pReader, pos, len); + assert(result == 0); + assert((pos + len) <= stop); // TODO + if (result != 0) + return NULL; + + const long long idpos = pos; // pos of next (potential) cluster + + const long long id = ReadID(m_pReader, idpos, len); + if (id < 0) + return NULL; + + pos += len; // consume ID + + // Read Size + result = GetUIntLength(m_pReader, pos, len); + assert(result == 0); // TODO + assert((pos + len) <= stop); // TODO + + const long long size = ReadUInt(m_pReader, pos, len); + assert(size >= 0); // TODO + + pos += len; // consume length of size of element + assert((pos + size) <= stop); // TODO + + // Pos now points to start of payload + + if (size == 0) // weird + continue; + + if (id == libwebm::kMkvCluster) { + const long long off_next_ = idpos - m_start; + + long long pos_; + long len_; + + const long status = Cluster::HasBlockEntries(this, off_next_, pos_, len_); + + assert(status >= 0); + + if (status > 0) { + off_next = off_next_; + break; + } + } + + pos += size; // consume payload + } + + if (off_next <= 0) + return 0; + + Cluster** const ii = m_clusters + m_clusterCount; + Cluster** i = ii; + + Cluster** const jj = ii + m_clusterPreloadCount; + Cluster** j = jj; + + while (i < j) { + // INVARIANT: + //[0, i) < pos_next + //[i, j) ? + //[j, jj) > pos_next + + Cluster** const k = i + (j - i) / 2; + assert(k < jj); + + Cluster* const pNext = *k; + assert(pNext); + assert(pNext->m_index < 0); + + // const long long pos_ = pNext->m_pos; + // assert(pos_); + // pos = pos_ * ((pos_ < 0) ? -1 : 1); + + pos = pNext->GetPosition(); + + if (pos < off_next) + i = k + 1; + else if (pos > off_next) + j = k; + else + return pNext; + } + + assert(i == j); + + Cluster* const pNext = Cluster::Create(this, -1, off_next); + if (pNext == NULL) + return NULL; + + const ptrdiff_t idx_next = i - m_clusters; // insertion position + + if (!PreloadCluster(pNext, idx_next)) { + delete pNext; + return NULL; + } + assert(m_clusters); + assert(idx_next < m_clusterSize); + assert(m_clusters[idx_next] == pNext); + + return pNext; +} + +long Segment::ParseNext(const Cluster* pCurr, const Cluster*& pResult, + long long& pos, long& len) { + assert(pCurr); + assert(!pCurr->EOS()); + assert(m_clusters); + + pResult = 0; + + if (pCurr->m_index >= 0) { // loaded (not merely preloaded) + assert(m_clusters[pCurr->m_index] == pCurr); + + const long next_idx = pCurr->m_index + 1; + + if (next_idx < m_clusterCount) { + pResult = m_clusters[next_idx]; + return 0; // success + } + + // curr cluster is last among loaded + + const long result = LoadCluster(pos, len); + + if (result < 0) // error or underflow + return result; + + if (result > 0) // no more clusters + { + // pResult = &m_eos; + return 1; + } + + pResult = GetLast(); + return 0; // success + } + + assert(m_pos > 0); + + long long total, avail; + + long status = m_pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + assert((total < 0) || (avail <= total)); + + const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; + + // interrogate curr cluster + + pos = pCurr->m_element_start; + + if (pCurr->m_element_size >= 0) + pos += pCurr->m_element_size; + else { + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long id = ReadUInt(m_pReader, pos, len); + + if (id != libwebm::kMkvCluster) + return -1; + + pos += len; // consume ID + + // Read Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(m_pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + pos += len; // consume size field + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size == unknown_size) // TODO: should never happen + return E_FILE_FORMAT_INVALID; // TODO: resolve this + + // assert((pCurr->m_size <= 0) || (pCurr->m_size == size)); + + if ((segment_stop >= 0) && ((pos + size) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + // Pos now points to start of payload + + pos += size; // consume payload (that is, the current cluster) + if (segment_stop >= 0 && pos > segment_stop) + return E_FILE_FORMAT_INVALID; + + // By consuming the payload, we are assuming that the curr + // cluster isn't interesting. That is, we don't bother checking + // whether the payload of the curr cluster is less than what + // happens to be available (obtained via IMkvReader::Length). + // Presumably the caller has already dispensed with the current + // cluster, and really does want the next cluster. + } + + // pos now points to just beyond the last fully-loaded cluster + + for (;;) { + const long status = DoParseNext(pResult, pos, len); + + if (status <= 1) + return status; + } +} + +long Segment::DoParseNext(const Cluster*& pResult, long long& pos, long& len) { + long long total, avail; + + long status = m_pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + assert((total < 0) || (avail <= total)); + + const long long segment_stop = (m_size < 0) ? -1 : m_start + m_size; + + // Parse next cluster. This is strictly a parsing activity. + // Creation of a new cluster object happens later, after the + // parsing is done. + + long long off_next = 0; + long long cluster_size = -1; + + for (;;) { + if ((total >= 0) && (pos >= total)) + return 1; // EOF + + if ((segment_stop >= 0) && (pos >= segment_stop)) + return 1; // EOF + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long idpos = pos; // absolute + const long long idoff = pos - m_start; // relative + + const long long id = ReadID(m_pReader, idpos, len); // absolute + + if (id < 0) // error + return static_cast(id); + + if (id == 0) // weird + return -1; // generic error + + pos += len; // consume ID + + // Read Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(m_pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + pos += len; // consume length of size of element + + // Pos now points to start of payload + + if (size == 0) // weird + continue; + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if ((segment_stop >= 0) && (size != unknown_size) && + ((pos + size) > segment_stop)) { + return E_FILE_FORMAT_INVALID; + } + + if (id == libwebm::kMkvCues) { + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; + + const long long element_stop = pos + size; + + if ((segment_stop >= 0) && (element_stop > segment_stop)) + return E_FILE_FORMAT_INVALID; + + const long long element_start = idpos; + const long long element_size = element_stop - element_start; + + if (m_pCues == NULL) { + m_pCues = new (std::nothrow) + Cues(this, pos, size, element_start, element_size); + if (m_pCues == NULL) + return false; + } + + pos += size; // consume payload + if (segment_stop >= 0 && pos > segment_stop) + return E_FILE_FORMAT_INVALID; + + continue; + } + + if (id != libwebm::kMkvCluster) { // not a Cluster ID + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; + + pos += size; // consume payload + if (segment_stop >= 0 && pos > segment_stop) + return E_FILE_FORMAT_INVALID; + + continue; + } + + // We have a cluster. + off_next = idoff; + + if (size != unknown_size) + cluster_size = size; + + break; + } + + assert(off_next > 0); // have cluster + + // We have parsed the next cluster. + // We have not created a cluster object yet. What we need + // to do now is determine whether it has already be preloaded + //(in which case, an object for this cluster has already been + // created), and if not, create a new cluster object. + + Cluster** const ii = m_clusters + m_clusterCount; + Cluster** i = ii; + + Cluster** const jj = ii + m_clusterPreloadCount; + Cluster** j = jj; + + while (i < j) { + // INVARIANT: + //[0, i) < pos_next + //[i, j) ? + //[j, jj) > pos_next + + Cluster** const k = i + (j - i) / 2; + assert(k < jj); + + const Cluster* const pNext = *k; + assert(pNext); + assert(pNext->m_index < 0); + + pos = pNext->GetPosition(); + assert(pos >= 0); + + if (pos < off_next) + i = k + 1; + else if (pos > off_next) + j = k; + else { + pResult = pNext; + return 0; // success + } + } + + assert(i == j); + + long long pos_; + long len_; + + status = Cluster::HasBlockEntries(this, off_next, pos_, len_); + + if (status < 0) { // error or underflow + pos = pos_; + len = len_; + + return status; + } + + if (status > 0) { // means "found at least one block entry" + Cluster* const pNext = Cluster::Create(this, + -1, // preloaded + off_next); + if (pNext == NULL) + return -1; + + const ptrdiff_t idx_next = i - m_clusters; // insertion position + + if (!PreloadCluster(pNext, idx_next)) { + delete pNext; + return -1; + } + assert(m_clusters); + assert(idx_next < m_clusterSize); + assert(m_clusters[idx_next] == pNext); + + pResult = pNext; + return 0; // success + } + + // status == 0 means "no block entries found" + + if (cluster_size < 0) { // unknown size + const long long payload_pos = pos; // absolute pos of cluster payload + + for (;;) { // determine cluster size + if ((total >= 0) && (pos >= total)) + break; + + if ((segment_stop >= 0) && (pos >= segment_stop)) + break; // no more clusters + + // Read ID + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long idpos = pos; + const long long id = ReadID(m_pReader, idpos, len); + + if (id < 0) // error (or underflow) + return static_cast(id); + + // This is the distinguished set of ID's we use to determine + // that we have exhausted the sub-element's inside the cluster + // whose ID we parsed earlier. + + if (id == libwebm::kMkvCluster || id == libwebm::kMkvCues) + break; + + pos += len; // consume ID (of sub-element) + + // Read Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(m_pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(m_pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + pos += len; // consume size field of element + + // pos now points to start of sub-element's payload + + if (size == 0) // weird + continue; + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; // not allowed for sub-elements + + if ((segment_stop >= 0) && ((pos + size) > segment_stop)) // weird + return E_FILE_FORMAT_INVALID; + + pos += size; // consume payload of sub-element + if (segment_stop >= 0 && pos > segment_stop) + return E_FILE_FORMAT_INVALID; + } // determine cluster size + + cluster_size = pos - payload_pos; + assert(cluster_size >= 0); // TODO: handle cluster_size = 0 + + pos = payload_pos; // reset and re-parse original cluster + } + + pos += cluster_size; // consume payload + if (segment_stop >= 0 && pos > segment_stop) + return E_FILE_FORMAT_INVALID; + + return 2; // try to find a cluster that follows next +} + +const Cluster* Segment::FindCluster(long long time_ns) const { + if ((m_clusters == NULL) || (m_clusterCount <= 0)) + return &m_eos; + + { + Cluster* const pCluster = m_clusters[0]; + assert(pCluster); + assert(pCluster->m_index == 0); + + if (time_ns <= pCluster->GetTime()) + return pCluster; + } + + // Binary search of cluster array + + long i = 0; + long j = m_clusterCount; + + while (i < j) { + // INVARIANT: + //[0, i) <= time_ns + //[i, j) ? + //[j, m_clusterCount) > time_ns + + const long k = i + (j - i) / 2; + assert(k < m_clusterCount); + + Cluster* const pCluster = m_clusters[k]; + assert(pCluster); + assert(pCluster->m_index == k); + + const long long t = pCluster->GetTime(); + + if (t <= time_ns) + i = k + 1; + else + j = k; + + assert(i <= j); + } + + assert(i == j); + assert(i > 0); + assert(i <= m_clusterCount); + + const long k = i - 1; + + Cluster* const pCluster = m_clusters[k]; + assert(pCluster); + assert(pCluster->m_index == k); + assert(pCluster->GetTime() <= time_ns); + + return pCluster; +} + +const Tracks* Segment::GetTracks() const { return m_pTracks; } +const SegmentInfo* Segment::GetInfo() const { return m_pInfo; } +const Cues* Segment::GetCues() const { return m_pCues; } +const Chapters* Segment::GetChapters() const { return m_pChapters; } +const Tags* Segment::GetTags() const { return m_pTags; } +const SeekHead* Segment::GetSeekHead() const { return m_pSeekHead; } + +long long Segment::GetDuration() const { + assert(m_pInfo); + return m_pInfo->GetDuration(); +} + +Chapters::Chapters(Segment* pSegment, long long payload_start, + long long payload_size, long long element_start, + long long element_size) + : m_pSegment(pSegment), + m_start(payload_start), + m_size(payload_size), + m_element_start(element_start), + m_element_size(element_size), + m_editions(NULL), + m_editions_size(0), + m_editions_count(0) {} + +Chapters::~Chapters() { + while (m_editions_count > 0) { + Edition& e = m_editions[--m_editions_count]; + e.Clear(); + } + delete[] m_editions; +} + +long Chapters::Parse() { + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long pos = m_start; // payload start + const long long stop = pos + m_size; // payload stop + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (size == 0) // weird + continue; + + if (id == libwebm::kMkvEditionEntry) { + status = ParseEdition(pos, size); + + if (status < 0) // error + return status; + } + + pos += size; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + return 0; +} + +int Chapters::GetEditionCount() const { return m_editions_count; } + +const Chapters::Edition* Chapters::GetEdition(int idx) const { + if (idx < 0) + return NULL; + + if (idx >= m_editions_count) + return NULL; + + return m_editions + idx; +} + +bool Chapters::ExpandEditionsArray() { + if (m_editions_size > m_editions_count) + return true; // nothing else to do + + const int size = (m_editions_size == 0) ? 1 : 2 * m_editions_size; + + Edition* const editions = new (std::nothrow) Edition[size]; + + if (editions == NULL) + return false; + + for (int idx = 0; idx < m_editions_count; ++idx) { + m_editions[idx].ShallowCopy(editions[idx]); + } + + delete[] m_editions; + m_editions = editions; + + m_editions_size = size; + return true; +} + +long Chapters::ParseEdition(long long pos, long long size) { + if (!ExpandEditionsArray()) + return -1; + + Edition& e = m_editions[m_editions_count++]; + e.Init(); + + return e.Parse(m_pSegment->m_pReader, pos, size); +} + +Chapters::Edition::Edition() {} + +Chapters::Edition::~Edition() {} + +int Chapters::Edition::GetAtomCount() const { return m_atoms_count; } + +const Chapters::Atom* Chapters::Edition::GetAtom(int index) const { + if (index < 0) + return NULL; + + if (index >= m_atoms_count) + return NULL; + + return m_atoms + index; +} + +void Chapters::Edition::Init() { + m_atoms = NULL; + m_atoms_size = 0; + m_atoms_count = 0; +} + +void Chapters::Edition::ShallowCopy(Edition& rhs) const { + rhs.m_atoms = m_atoms; + rhs.m_atoms_size = m_atoms_size; + rhs.m_atoms_count = m_atoms_count; +} + +void Chapters::Edition::Clear() { + while (m_atoms_count > 0) { + Atom& a = m_atoms[--m_atoms_count]; + a.Clear(); + } + + delete[] m_atoms; + m_atoms = NULL; + + m_atoms_size = 0; +} + +long Chapters::Edition::Parse(IMkvReader* pReader, long long pos, + long long size) { + const long long stop = pos + size; + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (size == 0) + continue; + + if (id == libwebm::kMkvChapterAtom) { + status = ParseAtom(pReader, pos, size); + + if (status < 0) // error + return status; + } + + pos += size; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + return 0; +} + +long Chapters::Edition::ParseAtom(IMkvReader* pReader, long long pos, + long long size) { + if (!ExpandAtomsArray()) + return -1; + + Atom& a = m_atoms[m_atoms_count++]; + a.Init(); + + return a.Parse(pReader, pos, size); +} + +bool Chapters::Edition::ExpandAtomsArray() { + if (m_atoms_size > m_atoms_count) + return true; // nothing else to do + + const int size = (m_atoms_size == 0) ? 1 : 2 * m_atoms_size; + + Atom* const atoms = new (std::nothrow) Atom[size]; + + if (atoms == NULL) + return false; + + for (int idx = 0; idx < m_atoms_count; ++idx) { + m_atoms[idx].ShallowCopy(atoms[idx]); + } + + delete[] m_atoms; + m_atoms = atoms; + + m_atoms_size = size; + return true; +} + +Chapters::Atom::Atom() {} + +Chapters::Atom::~Atom() {} + +unsigned long long Chapters::Atom::GetUID() const { return m_uid; } + +const char* Chapters::Atom::GetStringUID() const { return m_string_uid; } + +long long Chapters::Atom::GetStartTimecode() const { return m_start_timecode; } + +long long Chapters::Atom::GetStopTimecode() const { return m_stop_timecode; } + +long long Chapters::Atom::GetStartTime(const Chapters* pChapters) const { + return GetTime(pChapters, m_start_timecode); +} + +long long Chapters::Atom::GetStopTime(const Chapters* pChapters) const { + return GetTime(pChapters, m_stop_timecode); +} + +int Chapters::Atom::GetDisplayCount() const { return m_displays_count; } + +const Chapters::Display* Chapters::Atom::GetDisplay(int index) const { + if (index < 0) + return NULL; + + if (index >= m_displays_count) + return NULL; + + return m_displays + index; +} + +void Chapters::Atom::Init() { + m_string_uid = NULL; + m_uid = 0; + m_start_timecode = -1; + m_stop_timecode = -1; + + m_displays = NULL; + m_displays_size = 0; + m_displays_count = 0; +} + +void Chapters::Atom::ShallowCopy(Atom& rhs) const { + rhs.m_string_uid = m_string_uid; + rhs.m_uid = m_uid; + rhs.m_start_timecode = m_start_timecode; + rhs.m_stop_timecode = m_stop_timecode; + + rhs.m_displays = m_displays; + rhs.m_displays_size = m_displays_size; + rhs.m_displays_count = m_displays_count; +} + +void Chapters::Atom::Clear() { + delete[] m_string_uid; + m_string_uid = NULL; + + while (m_displays_count > 0) { + Display& d = m_displays[--m_displays_count]; + d.Clear(); + } + + delete[] m_displays; + m_displays = NULL; + + m_displays_size = 0; +} + +long Chapters::Atom::Parse(IMkvReader* pReader, long long pos, long long size) { + const long long stop = pos + size; + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (size == 0) // 0 length payload, skip. + continue; + + if (id == libwebm::kMkvChapterDisplay) { + status = ParseDisplay(pReader, pos, size); + + if (status < 0) // error + return status; + } else if (id == libwebm::kMkvChapterStringUID) { + status = UnserializeString(pReader, pos, size, m_string_uid); + + if (status < 0) // error + return status; + } else if (id == libwebm::kMkvChapterUID) { + long long val; + status = UnserializeInt(pReader, pos, size, val); + + if (status < 0) // error + return status; + + m_uid = static_cast(val); + } else if (id == libwebm::kMkvChapterTimeStart) { + const long long val = UnserializeUInt(pReader, pos, size); + + if (val < 0) // error + return static_cast(val); + + m_start_timecode = val; + } else if (id == libwebm::kMkvChapterTimeEnd) { + const long long val = UnserializeUInt(pReader, pos, size); + + if (val < 0) // error + return static_cast(val); + + m_stop_timecode = val; + } + + pos += size; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + return 0; +} + +long long Chapters::Atom::GetTime(const Chapters* pChapters, + long long timecode) { + if (pChapters == NULL) + return -1; + + Segment* const pSegment = pChapters->m_pSegment; + + if (pSegment == NULL) // weird + return -1; + + const SegmentInfo* const pInfo = pSegment->GetInfo(); + + if (pInfo == NULL) + return -1; + + const long long timecode_scale = pInfo->GetTimeCodeScale(); + + if (timecode_scale < 1) // weird + return -1; + + if (timecode < 0) + return -1; + + const long long result = timecode_scale * timecode; + + return result; +} + +long Chapters::Atom::ParseDisplay(IMkvReader* pReader, long long pos, + long long size) { + if (!ExpandDisplaysArray()) + return -1; + + Display& d = m_displays[m_displays_count++]; + d.Init(); + + return d.Parse(pReader, pos, size); +} + +bool Chapters::Atom::ExpandDisplaysArray() { + if (m_displays_size > m_displays_count) + return true; // nothing else to do + + const int size = (m_displays_size == 0) ? 1 : 2 * m_displays_size; + + Display* const displays = new (std::nothrow) Display[size]; + + if (displays == NULL) + return false; + + for (int idx = 0; idx < m_displays_count; ++idx) { + m_displays[idx].ShallowCopy(displays[idx]); + } + + delete[] m_displays; + m_displays = displays; + + m_displays_size = size; + return true; +} + +Chapters::Display::Display() {} + +Chapters::Display::~Display() {} + +const char* Chapters::Display::GetString() const { return m_string; } + +const char* Chapters::Display::GetLanguage() const { return m_language; } + +const char* Chapters::Display::GetCountry() const { return m_country; } + +void Chapters::Display::Init() { + m_string = NULL; + m_language = NULL; + m_country = NULL; +} + +void Chapters::Display::ShallowCopy(Display& rhs) const { + rhs.m_string = m_string; + rhs.m_language = m_language; + rhs.m_country = m_country; +} + +void Chapters::Display::Clear() { + delete[] m_string; + m_string = NULL; + + delete[] m_language; + m_language = NULL; + + delete[] m_country; + m_country = NULL; +} + +long Chapters::Display::Parse(IMkvReader* pReader, long long pos, + long long size) { + const long long stop = pos + size; + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (size == 0) // No payload. + continue; + + if (id == libwebm::kMkvChapString) { + status = UnserializeString(pReader, pos, size, m_string); + + if (status) + return status; + } else if (id == libwebm::kMkvChapLanguage) { + status = UnserializeString(pReader, pos, size, m_language); + + if (status) + return status; + } else if (id == libwebm::kMkvChapCountry) { + status = UnserializeString(pReader, pos, size, m_country); + + if (status) + return status; + } + + pos += size; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + return 0; +} + +Tags::Tags(Segment* pSegment, long long payload_start, long long payload_size, + long long element_start, long long element_size) + : m_pSegment(pSegment), + m_start(payload_start), + m_size(payload_size), + m_element_start(element_start), + m_element_size(element_size), + m_tags(NULL), + m_tags_size(0), + m_tags_count(0) {} + +Tags::~Tags() { + while (m_tags_count > 0) { + Tag& t = m_tags[--m_tags_count]; + t.Clear(); + } + delete[] m_tags; +} + +long Tags::Parse() { + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long pos = m_start; // payload start + const long long stop = pos + m_size; // payload stop + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) + return status; + + if (size == 0) // 0 length tag, read another + continue; + + if (id == libwebm::kMkvTag) { + status = ParseTag(pos, size); + + if (status < 0) + return status; + } + + pos += size; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + return 0; +} + +int Tags::GetTagCount() const { return m_tags_count; } + +const Tags::Tag* Tags::GetTag(int idx) const { + if (idx < 0) + return NULL; + + if (idx >= m_tags_count) + return NULL; + + return m_tags + idx; +} + +bool Tags::ExpandTagsArray() { + if (m_tags_size > m_tags_count) + return true; // nothing else to do + + const int size = (m_tags_size == 0) ? 1 : 2 * m_tags_size; + + Tag* const tags = new (std::nothrow) Tag[size]; + + if (tags == NULL) + return false; + + for (int idx = 0; idx < m_tags_count; ++idx) { + m_tags[idx].ShallowCopy(tags[idx]); + } + + delete[] m_tags; + m_tags = tags; + + m_tags_size = size; + return true; +} + +long Tags::ParseTag(long long pos, long long size) { + if (!ExpandTagsArray()) + return -1; + + Tag& t = m_tags[m_tags_count++]; + t.Init(); + + return t.Parse(m_pSegment->m_pReader, pos, size); +} + +Tags::Tag::Tag() {} + +Tags::Tag::~Tag() {} + +int Tags::Tag::GetSimpleTagCount() const { return m_simple_tags_count; } + +const Tags::SimpleTag* Tags::Tag::GetSimpleTag(int index) const { + if (index < 0) + return NULL; + + if (index >= m_simple_tags_count) + return NULL; + + return m_simple_tags + index; +} + +void Tags::Tag::Init() { + m_simple_tags = NULL; + m_simple_tags_size = 0; + m_simple_tags_count = 0; +} + +void Tags::Tag::ShallowCopy(Tag& rhs) const { + rhs.m_simple_tags = m_simple_tags; + rhs.m_simple_tags_size = m_simple_tags_size; + rhs.m_simple_tags_count = m_simple_tags_count; +} + +void Tags::Tag::Clear() { + while (m_simple_tags_count > 0) { + SimpleTag& d = m_simple_tags[--m_simple_tags_count]; + d.Clear(); + } + + delete[] m_simple_tags; + m_simple_tags = NULL; + + m_simple_tags_size = 0; +} + +long Tags::Tag::Parse(IMkvReader* pReader, long long pos, long long size) { + const long long stop = pos + size; + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) + return status; + + if (size == 0) // 0 length tag, read another + continue; + + if (id == libwebm::kMkvSimpleTag) { + status = ParseSimpleTag(pReader, pos, size); + + if (status < 0) + return status; + } + + pos += size; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + return 0; +} + +long Tags::Tag::ParseSimpleTag(IMkvReader* pReader, long long pos, + long long size) { + if (!ExpandSimpleTagsArray()) + return -1; + + SimpleTag& st = m_simple_tags[m_simple_tags_count++]; + st.Init(); + + return st.Parse(pReader, pos, size); +} + +bool Tags::Tag::ExpandSimpleTagsArray() { + if (m_simple_tags_size > m_simple_tags_count) + return true; // nothing else to do + + const int size = (m_simple_tags_size == 0) ? 1 : 2 * m_simple_tags_size; + + SimpleTag* const displays = new (std::nothrow) SimpleTag[size]; + + if (displays == NULL) + return false; + + for (int idx = 0; idx < m_simple_tags_count; ++idx) { + m_simple_tags[idx].ShallowCopy(displays[idx]); + } + + delete[] m_simple_tags; + m_simple_tags = displays; + + m_simple_tags_size = size; + return true; +} + +Tags::SimpleTag::SimpleTag() {} + +Tags::SimpleTag::~SimpleTag() {} + +const char* Tags::SimpleTag::GetTagName() const { return m_tag_name; } + +const char* Tags::SimpleTag::GetTagString() const { return m_tag_string; } + +void Tags::SimpleTag::Init() { + m_tag_name = NULL; + m_tag_string = NULL; +} + +void Tags::SimpleTag::ShallowCopy(SimpleTag& rhs) const { + rhs.m_tag_name = m_tag_name; + rhs.m_tag_string = m_tag_string; +} + +void Tags::SimpleTag::Clear() { + delete[] m_tag_name; + m_tag_name = NULL; + + delete[] m_tag_string; + m_tag_string = NULL; +} + +long Tags::SimpleTag::Parse(IMkvReader* pReader, long long pos, + long long size) { + const long long stop = pos + size; + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (size == 0) // weird + continue; + + if (id == libwebm::kMkvTagName) { + status = UnserializeString(pReader, pos, size, m_tag_name); + + if (status) + return status; + } else if (id == libwebm::kMkvTagString) { + status = UnserializeString(pReader, pos, size, m_tag_string); + + if (status) + return status; + } + + pos += size; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + return 0; +} + +SegmentInfo::SegmentInfo(Segment* pSegment, long long start, long long size_, + long long element_start, long long element_size) + : m_pSegment(pSegment), + m_start(start), + m_size(size_), + m_element_start(element_start), + m_element_size(element_size), + m_pMuxingAppAsUTF8(NULL), + m_pWritingAppAsUTF8(NULL), + m_pTitleAsUTF8(NULL) {} + +SegmentInfo::~SegmentInfo() { + delete[] m_pMuxingAppAsUTF8; + m_pMuxingAppAsUTF8 = NULL; + + delete[] m_pWritingAppAsUTF8; + m_pWritingAppAsUTF8 = NULL; + + delete[] m_pTitleAsUTF8; + m_pTitleAsUTF8 = NULL; +} + +long SegmentInfo::Parse() { + assert(m_pMuxingAppAsUTF8 == NULL); + assert(m_pWritingAppAsUTF8 == NULL); + assert(m_pTitleAsUTF8 == NULL); + + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long pos = m_start; + const long long stop = m_start + m_size; + + m_timecodeScale = 1000000; + m_duration = -1; + + while (pos < stop) { + long long id, size; + + const long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (id == libwebm::kMkvTimecodeScale) { + m_timecodeScale = UnserializeUInt(pReader, pos, size); + + if (m_timecodeScale <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvDuration) { + const long status = UnserializeFloat(pReader, pos, size, m_duration); + + if (status < 0) + return status; + + if (m_duration < 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvMuxingApp) { + const long status = + UnserializeString(pReader, pos, size, m_pMuxingAppAsUTF8); + + if (status) + return status; + } else if (id == libwebm::kMkvWritingApp) { + const long status = + UnserializeString(pReader, pos, size, m_pWritingAppAsUTF8); + + if (status) + return status; + } else if (id == libwebm::kMkvTitle) { + const long status = UnserializeString(pReader, pos, size, m_pTitleAsUTF8); + + if (status) + return status; + } + + pos += size; + + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + const double rollover_check = m_duration * m_timecodeScale; + if (rollover_check > static_cast(LLONG_MAX)) + return E_FILE_FORMAT_INVALID; + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + return 0; +} + +long long SegmentInfo::GetTimeCodeScale() const { return m_timecodeScale; } + +long long SegmentInfo::GetDuration() const { + if (m_duration < 0) + return -1; + + assert(m_timecodeScale >= 1); + + const double dd = double(m_duration) * double(m_timecodeScale); + const long long d = static_cast(dd); + + return d; +} + +const char* SegmentInfo::GetMuxingAppAsUTF8() const { + return m_pMuxingAppAsUTF8; +} + +const char* SegmentInfo::GetWritingAppAsUTF8() const { + return m_pWritingAppAsUTF8; +} + +const char* SegmentInfo::GetTitleAsUTF8() const { return m_pTitleAsUTF8; } + +/////////////////////////////////////////////////////////////// +// ContentEncoding element +ContentEncoding::ContentCompression::ContentCompression() + : algo(0), settings(NULL), settings_len(0) {} + +ContentEncoding::ContentCompression::~ContentCompression() { + delete[] settings; +} + +ContentEncoding::ContentEncryption::ContentEncryption() + : algo(0), + key_id(NULL), + key_id_len(0), + signature(NULL), + signature_len(0), + sig_key_id(NULL), + sig_key_id_len(0), + sig_algo(0), + sig_hash_algo(0) {} + +ContentEncoding::ContentEncryption::~ContentEncryption() { + delete[] key_id; + delete[] signature; + delete[] sig_key_id; +} + +ContentEncoding::ContentEncoding() + : compression_entries_(NULL), + compression_entries_end_(NULL), + encryption_entries_(NULL), + encryption_entries_end_(NULL), + encoding_order_(0), + encoding_scope_(1), + encoding_type_(0) {} + +ContentEncoding::~ContentEncoding() { + ContentCompression** comp_i = compression_entries_; + ContentCompression** const comp_j = compression_entries_end_; + + while (comp_i != comp_j) { + ContentCompression* const comp = *comp_i++; + delete comp; + } + + delete[] compression_entries_; + + ContentEncryption** enc_i = encryption_entries_; + ContentEncryption** const enc_j = encryption_entries_end_; + + while (enc_i != enc_j) { + ContentEncryption* const enc = *enc_i++; + delete enc; + } + + delete[] encryption_entries_; +} + +const ContentEncoding::ContentCompression* +ContentEncoding::GetCompressionByIndex(unsigned long idx) const { + const ptrdiff_t count = compression_entries_end_ - compression_entries_; + assert(count >= 0); + + if (idx >= static_cast(count)) + return NULL; + + return compression_entries_[idx]; +} + +unsigned long ContentEncoding::GetCompressionCount() const { + const ptrdiff_t count = compression_entries_end_ - compression_entries_; + assert(count >= 0); + + return static_cast(count); +} + +const ContentEncoding::ContentEncryption* ContentEncoding::GetEncryptionByIndex( + unsigned long idx) const { + const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; + assert(count >= 0); + + if (idx >= static_cast(count)) + return NULL; + + return encryption_entries_[idx]; +} + +unsigned long ContentEncoding::GetEncryptionCount() const { + const ptrdiff_t count = encryption_entries_end_ - encryption_entries_; + assert(count >= 0); + + return static_cast(count); +} + +long ContentEncoding::ParseContentEncAESSettingsEntry( + long long start, long long size, IMkvReader* pReader, + ContentEncAESSettings* aes) { + assert(pReader); + assert(aes); + + long long pos = start; + const long long stop = start + size; + + while (pos < stop) { + long long id, size; + const long status = ParseElementHeader(pReader, pos, stop, id, size); + if (status < 0) // error + return status; + + if (id == libwebm::kMkvAESSettingsCipherMode) { + aes->cipher_mode = UnserializeUInt(pReader, pos, size); + if (aes->cipher_mode != 1) + return E_FILE_FORMAT_INVALID; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + return 0; +} + +long ContentEncoding::ParseContentEncodingEntry(long long start, long long size, + IMkvReader* pReader) { + assert(pReader); + + long long pos = start; + const long long stop = start + size; + + // Count ContentCompression and ContentEncryption elements. + long long compression_count = 0; + long long encryption_count = 0; + + while (pos < stop) { + long long id, size; + const long status = ParseElementHeader(pReader, pos, stop, id, size); + if (status < 0) // error + return status; + + if (id == libwebm::kMkvContentCompression) { + ++compression_count; + if (compression_count > INT_MAX) + return E_PARSE_FAILED; + } + + if (id == libwebm::kMkvContentEncryption) { + ++encryption_count; + if (encryption_count > INT_MAX) + return E_PARSE_FAILED; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (compression_count <= 0 && encryption_count <= 0) + return -1; + + if (compression_count > 0) { + compression_entries_ = new (std::nothrow) + ContentCompression*[static_cast(compression_count)]; + if (!compression_entries_) + return -1; + compression_entries_end_ = compression_entries_; + } + + if (encryption_count > 0) { + encryption_entries_ = new (std::nothrow) + ContentEncryption*[static_cast(encryption_count)]; + if (!encryption_entries_) { + delete[] compression_entries_; + compression_entries_ = NULL; + return -1; + } + encryption_entries_end_ = encryption_entries_; + } + + pos = start; + while (pos < stop) { + long long id, size; + long status = ParseElementHeader(pReader, pos, stop, id, size); + if (status < 0) // error + return status; + + if (id == libwebm::kMkvContentEncodingOrder) { + encoding_order_ = UnserializeUInt(pReader, pos, size); + } else if (id == libwebm::kMkvContentEncodingScope) { + encoding_scope_ = UnserializeUInt(pReader, pos, size); + if (encoding_scope_ < 1) + return -1; + } else if (id == libwebm::kMkvContentEncodingType) { + encoding_type_ = UnserializeUInt(pReader, pos, size); + } else if (id == libwebm::kMkvContentCompression) { + ContentCompression* const compression = + new (std::nothrow) ContentCompression(); + if (!compression) + return -1; + + status = ParseCompressionEntry(pos, size, pReader, compression); + if (status) { + delete compression; + return status; + } + assert(compression_count > 0); + *compression_entries_end_++ = compression; + } else if (id == libwebm::kMkvContentEncryption) { + ContentEncryption* const encryption = + new (std::nothrow) ContentEncryption(); + if (!encryption) + return -1; + + status = ParseEncryptionEntry(pos, size, pReader, encryption); + if (status) { + delete encryption; + return status; + } + assert(encryption_count > 0); + *encryption_entries_end_++ = encryption; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + return 0; +} + +long ContentEncoding::ParseCompressionEntry(long long start, long long size, + IMkvReader* pReader, + ContentCompression* compression) { + assert(pReader); + assert(compression); + + long long pos = start; + const long long stop = start + size; + + bool valid = false; + + while (pos < stop) { + long long id, size; + const long status = ParseElementHeader(pReader, pos, stop, id, size); + if (status < 0) // error + return status; + + if (id == libwebm::kMkvContentCompAlgo) { + long long algo = UnserializeUInt(pReader, pos, size); + if (algo < 0) + return E_FILE_FORMAT_INVALID; + compression->algo = algo; + valid = true; + } else if (id == libwebm::kMkvContentCompSettings) { + if (size <= 0) + return E_FILE_FORMAT_INVALID; + + const size_t buflen = static_cast(size); + unsigned char* buf = SafeArrayAlloc(1, buflen); + if (buf == NULL) + return -1; + + const int read_status = + pReader->Read(pos, static_cast(buflen), buf); + if (read_status) { + delete[] buf; + return status; + } + + // There should be only one settings element per content compression. + if (compression->settings != NULL) { + delete[] buf; + return E_FILE_FORMAT_INVALID; + } + + compression->settings = buf; + compression->settings_len = buflen; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + // ContentCompAlgo is mandatory + if (!valid) + return E_FILE_FORMAT_INVALID; + + return 0; +} + +long ContentEncoding::ParseEncryptionEntry(long long start, long long size, + IMkvReader* pReader, + ContentEncryption* encryption) { + assert(pReader); + assert(encryption); + + long long pos = start; + const long long stop = start + size; + + while (pos < stop) { + long long id, size; + const long status = ParseElementHeader(pReader, pos, stop, id, size); + if (status < 0) // error + return status; + + if (id == libwebm::kMkvContentEncAlgo) { + encryption->algo = UnserializeUInt(pReader, pos, size); + if (encryption->algo != 5) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvContentEncKeyID) { + delete[] encryption->key_id; + encryption->key_id = NULL; + encryption->key_id_len = 0; + + if (size <= 0) + return E_FILE_FORMAT_INVALID; + + const size_t buflen = static_cast(size); + unsigned char* buf = SafeArrayAlloc(1, buflen); + if (buf == NULL) + return -1; + + const int read_status = + pReader->Read(pos, static_cast(buflen), buf); + if (read_status) { + delete[] buf; + return status; + } + + encryption->key_id = buf; + encryption->key_id_len = buflen; + } else if (id == libwebm::kMkvContentSignature) { + delete[] encryption->signature; + encryption->signature = NULL; + encryption->signature_len = 0; + + if (size <= 0) + return E_FILE_FORMAT_INVALID; + + const size_t buflen = static_cast(size); + unsigned char* buf = SafeArrayAlloc(1, buflen); + if (buf == NULL) + return -1; + + const int read_status = + pReader->Read(pos, static_cast(buflen), buf); + if (read_status) { + delete[] buf; + return status; + } + + encryption->signature = buf; + encryption->signature_len = buflen; + } else if (id == libwebm::kMkvContentSigKeyID) { + delete[] encryption->sig_key_id; + encryption->sig_key_id = NULL; + encryption->sig_key_id_len = 0; + + if (size <= 0) + return E_FILE_FORMAT_INVALID; + + const size_t buflen = static_cast(size); + unsigned char* buf = SafeArrayAlloc(1, buflen); + if (buf == NULL) + return -1; + + const int read_status = + pReader->Read(pos, static_cast(buflen), buf); + if (read_status) { + delete[] buf; + return status; + } + + encryption->sig_key_id = buf; + encryption->sig_key_id_len = buflen; + } else if (id == libwebm::kMkvContentSigAlgo) { + encryption->sig_algo = UnserializeUInt(pReader, pos, size); + } else if (id == libwebm::kMkvContentSigHashAlgo) { + encryption->sig_hash_algo = UnserializeUInt(pReader, pos, size); + } else if (id == libwebm::kMkvContentEncAESSettings) { + const long status = ParseContentEncAESSettingsEntry( + pos, size, pReader, &encryption->aes_settings); + if (status) + return status; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + return 0; +} + +Track::Track(Segment* pSegment, long long element_start, long long element_size) + : m_pSegment(pSegment), + m_element_start(element_start), + m_element_size(element_size), + content_encoding_entries_(NULL), + content_encoding_entries_end_(NULL) {} + +Track::~Track() { + Info& info = const_cast(m_info); + info.Clear(); + + ContentEncoding** i = content_encoding_entries_; + ContentEncoding** const j = content_encoding_entries_end_; + + while (i != j) { + ContentEncoding* const encoding = *i++; + delete encoding; + } + + delete[] content_encoding_entries_; +} + +long Track::Create(Segment* pSegment, const Info& info, long long element_start, + long long element_size, Track*& pResult) { + if (pResult) + return -1; + + Track* const pTrack = + new (std::nothrow) Track(pSegment, element_start, element_size); + + if (pTrack == NULL) + return -1; // generic error + + const int status = info.Copy(pTrack->m_info); + + if (status) { // error + delete pTrack; + return status; + } + + pResult = pTrack; + return 0; // success +} + +Track::Info::Info() + : uid(0), + defaultDuration(0), + codecDelay(0), + seekPreRoll(0), + nameAsUTF8(NULL), + language(NULL), + codecId(NULL), + codecNameAsUTF8(NULL), + codecPrivate(NULL), + codecPrivateSize(0), + lacing(false) {} + +Track::Info::~Info() { Clear(); } + +void Track::Info::Clear() { + delete[] nameAsUTF8; + nameAsUTF8 = NULL; + + delete[] language; + language = NULL; + + delete[] codecId; + codecId = NULL; + + delete[] codecPrivate; + codecPrivate = NULL; + codecPrivateSize = 0; + + delete[] codecNameAsUTF8; + codecNameAsUTF8 = NULL; +} + +int Track::Info::CopyStr(char* Info::*str, Info& dst_) const { + if (str == static_cast(NULL)) + return -1; + + char*& dst = dst_.*str; + + if (dst) // should be NULL already + return -1; + + const char* const src = this->*str; + + if (src == NULL) + return 0; + + const size_t len = strlen(src); + + dst = SafeArrayAlloc(1, len + 1); + + if (dst == NULL) + return -1; + + memcpy(dst, src, len); + dst[len] = '\0'; + + return 0; +} + +int Track::Info::Copy(Info& dst) const { + if (&dst == this) + return 0; + + dst.type = type; + dst.number = number; + dst.defaultDuration = defaultDuration; + dst.codecDelay = codecDelay; + dst.seekPreRoll = seekPreRoll; + dst.uid = uid; + dst.lacing = lacing; + dst.settings = settings; + + // We now copy the string member variables from src to dst. + // This involves memory allocation so in principle the operation + // can fail (indeed, that's why we have Info::Copy), so we must + // report this to the caller. An error return from this function + // therefore implies that the copy was only partially successful. + + if (int status = CopyStr(&Info::nameAsUTF8, dst)) + return status; + + if (int status = CopyStr(&Info::language, dst)) + return status; + + if (int status = CopyStr(&Info::codecId, dst)) + return status; + + if (int status = CopyStr(&Info::codecNameAsUTF8, dst)) + return status; + + if (codecPrivateSize > 0) { + if (codecPrivate == NULL) + return -1; + + if (dst.codecPrivate) + return -1; + + if (dst.codecPrivateSize != 0) + return -1; + + dst.codecPrivate = SafeArrayAlloc(1, codecPrivateSize); + + if (dst.codecPrivate == NULL) + return -1; + + memcpy(dst.codecPrivate, codecPrivate, codecPrivateSize); + dst.codecPrivateSize = codecPrivateSize; + } + + return 0; +} + +const BlockEntry* Track::GetEOS() const { return &m_eos; } + +long Track::GetType() const { return m_info.type; } + +long Track::GetNumber() const { return m_info.number; } + +unsigned long long Track::GetUid() const { return m_info.uid; } + +const char* Track::GetNameAsUTF8() const { return m_info.nameAsUTF8; } + +const char* Track::GetLanguage() const { return m_info.language; } + +const char* Track::GetCodecNameAsUTF8() const { return m_info.codecNameAsUTF8; } + +const char* Track::GetCodecId() const { return m_info.codecId; } + +const unsigned char* Track::GetCodecPrivate(size_t& size) const { + size = m_info.codecPrivateSize; + return m_info.codecPrivate; +} + +bool Track::GetLacing() const { return m_info.lacing; } + +unsigned long long Track::GetDefaultDuration() const { + return m_info.defaultDuration; +} + +unsigned long long Track::GetCodecDelay() const { return m_info.codecDelay; } + +unsigned long long Track::GetSeekPreRoll() const { return m_info.seekPreRoll; } + +long Track::GetFirst(const BlockEntry*& pBlockEntry) const { + const Cluster* pCluster = m_pSegment->GetFirst(); + + for (int i = 0;;) { + if (pCluster == NULL) { + pBlockEntry = GetEOS(); + return 1; + } + + if (pCluster->EOS()) { + if (m_pSegment->DoneParsing()) { + pBlockEntry = GetEOS(); + return 1; + } + + pBlockEntry = 0; + return E_BUFFER_NOT_FULL; + } + + long status = pCluster->GetFirst(pBlockEntry); + + if (status < 0) // error + return status; + + if (pBlockEntry == 0) { // empty cluster + pCluster = m_pSegment->GetNext(pCluster); + continue; + } + + for (;;) { + const Block* const pBlock = pBlockEntry->GetBlock(); + assert(pBlock); + + const long long tn = pBlock->GetTrackNumber(); + + if ((tn == m_info.number) && VetEntry(pBlockEntry)) + return 0; + + const BlockEntry* pNextEntry; + + status = pCluster->GetNext(pBlockEntry, pNextEntry); + + if (status < 0) // error + return status; + + if (pNextEntry == 0) + break; + + pBlockEntry = pNextEntry; + } + + ++i; + + if (i >= 100) + break; + + pCluster = m_pSegment->GetNext(pCluster); + } + + // NOTE: if we get here, it means that we didn't find a block with + // a matching track number. We interpret that as an error (which + // might be too conservative). + + pBlockEntry = GetEOS(); // so we can return a non-NULL value + return 1; +} + +long Track::GetNext(const BlockEntry* pCurrEntry, + const BlockEntry*& pNextEntry) const { + assert(pCurrEntry); + assert(!pCurrEntry->EOS()); //? + + const Block* const pCurrBlock = pCurrEntry->GetBlock(); + assert(pCurrBlock && pCurrBlock->GetTrackNumber() == m_info.number); + if (!pCurrBlock || pCurrBlock->GetTrackNumber() != m_info.number) + return -1; + + const Cluster* pCluster = pCurrEntry->GetCluster(); + assert(pCluster); + assert(!pCluster->EOS()); + + long status = pCluster->GetNext(pCurrEntry, pNextEntry); + + if (status < 0) // error + return status; + + for (int i = 0;;) { + while (pNextEntry) { + const Block* const pNextBlock = pNextEntry->GetBlock(); + assert(pNextBlock); + + if (pNextBlock->GetTrackNumber() == m_info.number) + return 0; + + pCurrEntry = pNextEntry; + + status = pCluster->GetNext(pCurrEntry, pNextEntry); + + if (status < 0) // error + return status; + } + + pCluster = m_pSegment->GetNext(pCluster); + + if (pCluster == NULL) { + pNextEntry = GetEOS(); + return 1; + } + + if (pCluster->EOS()) { + if (m_pSegment->DoneParsing()) { + pNextEntry = GetEOS(); + return 1; + } + + // TODO: there is a potential O(n^2) problem here: we tell the + // caller to (pre)load another cluster, which he does, but then he + // calls GetNext again, which repeats the same search. This is + // a pathological case, since the only way it can happen is if + // there exists a long sequence of clusters none of which contain a + // block from this track. One way around this problem is for the + // caller to be smarter when he loads another cluster: don't call + // us back until you have a cluster that contains a block from this + // track. (Of course, that's not cheap either, since our caller + // would have to scan the each cluster as it's loaded, so that + // would just push back the problem.) + + pNextEntry = NULL; + return E_BUFFER_NOT_FULL; + } + + status = pCluster->GetFirst(pNextEntry); + + if (status < 0) // error + return status; + + if (pNextEntry == NULL) // empty cluster + continue; + + ++i; + + if (i >= 100) + break; + } + + // NOTE: if we get here, it means that we didn't find a block with + // a matching track number after lots of searching, so we give + // up trying. + + pNextEntry = GetEOS(); // so we can return a non-NULL value + return 1; +} + +bool Track::VetEntry(const BlockEntry* pBlockEntry) const { + assert(pBlockEntry); + const Block* const pBlock = pBlockEntry->GetBlock(); + assert(pBlock); + assert(pBlock->GetTrackNumber() == m_info.number); + if (!pBlock || pBlock->GetTrackNumber() != m_info.number) + return false; + + // This function is used during a seek to determine whether the + // frame is a valid seek target. This default function simply + // returns true, which means all frames are valid seek targets. + // It gets overridden by the VideoTrack class, because only video + // keyframes can be used as seek target. + + return true; +} + +long Track::Seek(long long time_ns, const BlockEntry*& pResult) const { + const long status = GetFirst(pResult); + + if (status < 0) // buffer underflow, etc + return status; + + assert(pResult); + + if (pResult->EOS()) + return 0; + + const Cluster* pCluster = pResult->GetCluster(); + assert(pCluster); + assert(pCluster->GetIndex() >= 0); + + if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) + return 0; + + Cluster** const clusters = m_pSegment->m_clusters; + assert(clusters); + + const long count = m_pSegment->GetCount(); // loaded only, not preloaded + assert(count > 0); + + Cluster** const i = clusters + pCluster->GetIndex(); + assert(i); + assert(*i == pCluster); + assert(pCluster->GetTime() <= time_ns); + + Cluster** const j = clusters + count; + + Cluster** lo = i; + Cluster** hi = j; + + while (lo < hi) { + // INVARIANT: + //[i, lo) <= time_ns + //[lo, hi) ? + //[hi, j) > time_ns + + Cluster** const mid = lo + (hi - lo) / 2; + assert(mid < hi); + + pCluster = *mid; + assert(pCluster); + assert(pCluster->GetIndex() >= 0); + assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); + + const long long t = pCluster->GetTime(); + + if (t <= time_ns) + lo = mid + 1; + else + hi = mid; + + assert(lo <= hi); + } + + assert(lo == hi); + assert(lo > i); + assert(lo <= j); + + while (lo > i) { + pCluster = *--lo; + assert(pCluster); + assert(pCluster->GetTime() <= time_ns); + + pResult = pCluster->GetEntry(this); + + if ((pResult != 0) && !pResult->EOS()) + return 0; + + // landed on empty cluster (no entries) + } + + pResult = GetEOS(); // weird + return 0; +} + +const ContentEncoding* Track::GetContentEncodingByIndex( + unsigned long idx) const { + const ptrdiff_t count = + content_encoding_entries_end_ - content_encoding_entries_; + assert(count >= 0); + + if (idx >= static_cast(count)) + return NULL; + + return content_encoding_entries_[idx]; +} + +unsigned long Track::GetContentEncodingCount() const { + const ptrdiff_t count = + content_encoding_entries_end_ - content_encoding_entries_; + assert(count >= 0); + + return static_cast(count); +} + +long Track::ParseContentEncodingsEntry(long long start, long long size) { + IMkvReader* const pReader = m_pSegment->m_pReader; + assert(pReader); + + long long pos = start; + const long long stop = start + size; + + // Count ContentEncoding elements. + long long count = 0; + while (pos < stop) { + long long id, size; + const long status = ParseElementHeader(pReader, pos, stop, id, size); + if (status < 0) // error + return status; + + // pos now designates start of element + if (id == libwebm::kMkvContentEncoding) { + ++count; + if (count > INT_MAX) + return E_PARSE_FAILED; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (count <= 0) + return -1; + + content_encoding_entries_ = + new (std::nothrow) ContentEncoding*[static_cast(count)]; + if (!content_encoding_entries_) + return -1; + + content_encoding_entries_end_ = content_encoding_entries_; + + pos = start; + while (pos < stop) { + long long id, size; + long status = ParseElementHeader(pReader, pos, stop, id, size); + if (status < 0) // error + return status; + + // pos now designates start of element + if (id == libwebm::kMkvContentEncoding) { + ContentEncoding* const content_encoding = + new (std::nothrow) ContentEncoding(); + if (!content_encoding) + return -1; + + status = content_encoding->ParseContentEncodingEntry(pos, size, pReader); + if (status) { + delete content_encoding; + return status; + } + + *content_encoding_entries_end_++ = content_encoding; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + return 0; +} + +Track::EOSBlock::EOSBlock() : BlockEntry(NULL, LONG_MIN) {} + +BlockEntry::Kind Track::EOSBlock::GetKind() const { return kBlockEOS; } + +const Block* Track::EOSBlock::GetBlock() const { return NULL; } + +bool PrimaryChromaticity::Parse(IMkvReader* reader, long long read_pos, + long long value_size, bool is_x, + PrimaryChromaticity** chromaticity) { + if (!reader) + return false; + + if (!*chromaticity) + *chromaticity = new PrimaryChromaticity(); + + if (!*chromaticity) + return false; + + PrimaryChromaticity* pc = *chromaticity; + float* value = is_x ? &pc->x : &pc->y; + + double parser_value = 0; + const long long parse_status = + UnserializeFloat(reader, read_pos, value_size, parser_value); + + // Valid range is [0, 1]. Make sure the double is representable as a float + // before casting. + if (parse_status < 0 || parser_value < 0.0 || parser_value > 1.0 || + (parser_value > 0.0 && parser_value < FLT_MIN)) + return false; + + *value = static_cast(parser_value); + + return true; +} + +bool MasteringMetadata::Parse(IMkvReader* reader, long long mm_start, + long long mm_size, MasteringMetadata** mm) { + if (!reader || *mm) + return false; + + std::unique_ptr mm_ptr(new MasteringMetadata()); + if (!mm_ptr.get()) + return false; + + const long long mm_end = mm_start + mm_size; + long long read_pos = mm_start; + + while (read_pos < mm_end) { + long long child_id = 0; + long long child_size = 0; + + const long long status = + ParseElementHeader(reader, read_pos, mm_end, child_id, child_size); + if (status < 0) + return false; + + if (child_id == libwebm::kMkvLuminanceMax) { + double value = 0; + const long long value_parse_status = + UnserializeFloat(reader, read_pos, child_size, value); + if (value < -FLT_MAX || value > FLT_MAX || + (value > 0.0 && value < FLT_MIN)) { + return false; + } + mm_ptr->luminance_max = static_cast(value); + if (value_parse_status < 0 || mm_ptr->luminance_max < 0.0 || + mm_ptr->luminance_max > 9999.99) { + return false; + } + } else if (child_id == libwebm::kMkvLuminanceMin) { + double value = 0; + const long long value_parse_status = + UnserializeFloat(reader, read_pos, child_size, value); + if (value < -FLT_MAX || value > FLT_MAX || + (value > 0.0 && value < FLT_MIN)) { + return false; + } + mm_ptr->luminance_min = static_cast(value); + if (value_parse_status < 0 || mm_ptr->luminance_min < 0.0 || + mm_ptr->luminance_min > 999.9999) { + return false; + } + } else { + bool is_x = false; + PrimaryChromaticity** chromaticity; + switch (child_id) { + case libwebm::kMkvPrimaryRChromaticityX: + case libwebm::kMkvPrimaryRChromaticityY: + is_x = child_id == libwebm::kMkvPrimaryRChromaticityX; + chromaticity = &mm_ptr->r; + break; + case libwebm::kMkvPrimaryGChromaticityX: + case libwebm::kMkvPrimaryGChromaticityY: + is_x = child_id == libwebm::kMkvPrimaryGChromaticityX; + chromaticity = &mm_ptr->g; + break; + case libwebm::kMkvPrimaryBChromaticityX: + case libwebm::kMkvPrimaryBChromaticityY: + is_x = child_id == libwebm::kMkvPrimaryBChromaticityX; + chromaticity = &mm_ptr->b; + break; + case libwebm::kMkvWhitePointChromaticityX: + case libwebm::kMkvWhitePointChromaticityY: + is_x = child_id == libwebm::kMkvWhitePointChromaticityX; + chromaticity = &mm_ptr->white_point; + break; + default: + return false; + } + const bool value_parse_status = PrimaryChromaticity::Parse( + reader, read_pos, child_size, is_x, chromaticity); + if (!value_parse_status) + return false; + } + + read_pos += child_size; + if (read_pos > mm_end) + return false; + } + + *mm = mm_ptr.release(); + return true; +} + +bool Colour::Parse(IMkvReader* reader, long long colour_start, + long long colour_size, Colour** colour) { + if (!reader || *colour) + return false; + + std::unique_ptr colour_ptr(new Colour()); + if (!colour_ptr.get()) + return false; + + const long long colour_end = colour_start + colour_size; + long long read_pos = colour_start; + + while (read_pos < colour_end) { + long long child_id = 0; + long long child_size = 0; + + const long status = + ParseElementHeader(reader, read_pos, colour_end, child_id, child_size); + if (status < 0) + return false; + + if (child_id == libwebm::kMkvMatrixCoefficients) { + colour_ptr->matrix_coefficients = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->matrix_coefficients < 0) + return false; + } else if (child_id == libwebm::kMkvBitsPerChannel) { + colour_ptr->bits_per_channel = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->bits_per_channel < 0) + return false; + } else if (child_id == libwebm::kMkvChromaSubsamplingHorz) { + colour_ptr->chroma_subsampling_horz = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->chroma_subsampling_horz < 0) + return false; + } else if (child_id == libwebm::kMkvChromaSubsamplingVert) { + colour_ptr->chroma_subsampling_vert = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->chroma_subsampling_vert < 0) + return false; + } else if (child_id == libwebm::kMkvCbSubsamplingHorz) { + colour_ptr->cb_subsampling_horz = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->cb_subsampling_horz < 0) + return false; + } else if (child_id == libwebm::kMkvCbSubsamplingVert) { + colour_ptr->cb_subsampling_vert = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->cb_subsampling_vert < 0) + return false; + } else if (child_id == libwebm::kMkvChromaSitingHorz) { + colour_ptr->chroma_siting_horz = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->chroma_siting_horz < 0) + return false; + } else if (child_id == libwebm::kMkvChromaSitingVert) { + colour_ptr->chroma_siting_vert = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->chroma_siting_vert < 0) + return false; + } else if (child_id == libwebm::kMkvRange) { + colour_ptr->range = UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->range < 0) + return false; + } else if (child_id == libwebm::kMkvTransferCharacteristics) { + colour_ptr->transfer_characteristics = + UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->transfer_characteristics < 0) + return false; + } else if (child_id == libwebm::kMkvPrimaries) { + colour_ptr->primaries = UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->primaries < 0) + return false; + } else if (child_id == libwebm::kMkvMaxCLL) { + colour_ptr->max_cll = UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->max_cll < 0) + return false; + } else if (child_id == libwebm::kMkvMaxFALL) { + colour_ptr->max_fall = UnserializeUInt(reader, read_pos, child_size); + if (colour_ptr->max_fall < 0) + return false; + } else if (child_id == libwebm::kMkvMasteringMetadata) { + if (!MasteringMetadata::Parse(reader, read_pos, child_size, + &colour_ptr->mastering_metadata)) + return false; + } else { + return false; + } + + read_pos += child_size; + if (read_pos > colour_end) + return false; + } + *colour = colour_ptr.release(); + return true; +} + +bool Projection::Parse(IMkvReader* reader, long long start, long long size, + Projection** projection) { + if (!reader || *projection) + return false; + + std::unique_ptr projection_ptr(new Projection()); + if (!projection_ptr.get()) + return false; + + const long long end = start + size; + long long read_pos = start; + + while (read_pos < end) { + long long child_id = 0; + long long child_size = 0; + + const long long status = + ParseElementHeader(reader, read_pos, end, child_id, child_size); + if (status < 0) + return false; + + if (child_id == libwebm::kMkvProjectionType) { + long long projection_type = kTypeNotPresent; + projection_type = UnserializeUInt(reader, read_pos, child_size); + if (projection_type < 0) + return false; + + projection_ptr->type = static_cast(projection_type); + } else if (child_id == libwebm::kMkvProjectionPrivate) { + if (projection_ptr->private_data != NULL) + return false; + unsigned char* data = SafeArrayAlloc(1, child_size); + + if (data == NULL) + return false; + + const int status = + reader->Read(read_pos, static_cast(child_size), data); + + if (status) { + delete[] data; + return false; + } + + projection_ptr->private_data = data; + projection_ptr->private_data_length = static_cast(child_size); + } else { + double value = 0; + const long long value_parse_status = + UnserializeFloat(reader, read_pos, child_size, value); + // Make sure value is representable as a float before casting. + if (value_parse_status < 0 || value < -FLT_MAX || value > FLT_MAX || + (value > 0.0 && value < FLT_MIN)) { + return false; + } + + switch (child_id) { + case libwebm::kMkvProjectionPoseYaw: + projection_ptr->pose_yaw = static_cast(value); + break; + case libwebm::kMkvProjectionPosePitch: + projection_ptr->pose_pitch = static_cast(value); + break; + case libwebm::kMkvProjectionPoseRoll: + projection_ptr->pose_roll = static_cast(value); + break; + default: + return false; + } + } + + read_pos += child_size; + if (read_pos > end) + return false; + } + + *projection = projection_ptr.release(); + return true; +} + +VideoTrack::VideoTrack(Segment* pSegment, long long element_start, + long long element_size) + : Track(pSegment, element_start, element_size), + m_colour_space(NULL), + m_colour(NULL), + m_projection(NULL) {} + +VideoTrack::~VideoTrack() { + delete[] m_colour_space; + delete m_colour; + delete m_projection; +} + +long VideoTrack::Parse(Segment* pSegment, const Info& info, + long long element_start, long long element_size, + VideoTrack*& pResult) { + if (pResult) + return -1; + + if (info.type != Track::kVideo) + return -1; + + long long width = 0; + long long height = 0; + long long display_width = 0; + long long display_height = 0; + long long display_unit = 0; + long long stereo_mode = 0; + + double rate = 0.0; + std::unique_ptr colour_space_ptr; + + IMkvReader* const pReader = pSegment->m_pReader; + + const Settings& s = info.settings; + assert(s.start >= 0); + assert(s.size >= 0); + + long long pos = s.start; + assert(pos >= 0); + + const long long stop = pos + s.size; + + std::unique_ptr colour_ptr; + std::unique_ptr projection_ptr; + + while (pos < stop) { + long long id, size; + + const long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (id == libwebm::kMkvPixelWidth) { + width = UnserializeUInt(pReader, pos, size); + + if (width <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvPixelHeight) { + height = UnserializeUInt(pReader, pos, size); + + if (height <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvDisplayWidth) { + display_width = UnserializeUInt(pReader, pos, size); + + if (display_width <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvDisplayHeight) { + display_height = UnserializeUInt(pReader, pos, size); + + if (display_height <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvDisplayUnit) { + display_unit = UnserializeUInt(pReader, pos, size); + + if (display_unit < 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvStereoMode) { + stereo_mode = UnserializeUInt(pReader, pos, size); + + if (stereo_mode < 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvFrameRate) { + const long status = UnserializeFloat(pReader, pos, size, rate); + + if (status < 0) + return status; + + if (rate <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvColour) { + Colour* colour = NULL; + if (!Colour::Parse(pReader, pos, size, &colour)) { + return E_FILE_FORMAT_INVALID; + } else { + colour_ptr.reset(colour); + } + } else if (id == libwebm::kMkvProjection) { + Projection* projection = NULL; + if (!Projection::Parse(pReader, pos, size, &projection)) { + return E_FILE_FORMAT_INVALID; + } else { + projection_ptr.reset(projection); + } + } else if (id == libwebm::kMkvColourSpace) { + char* colour_space = NULL; + const long status = UnserializeString(pReader, pos, size, colour_space); + if (status < 0) + return status; + colour_space_ptr.reset(colour_space); + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + VideoTrack* const pTrack = + new (std::nothrow) VideoTrack(pSegment, element_start, element_size); + + if (pTrack == NULL) + return -1; // generic error + + const int status = info.Copy(pTrack->m_info); + + if (status) { // error + delete pTrack; + return status; + } + + pTrack->m_width = width; + pTrack->m_height = height; + pTrack->m_display_width = display_width; + pTrack->m_display_height = display_height; + pTrack->m_display_unit = display_unit; + pTrack->m_stereo_mode = stereo_mode; + pTrack->m_rate = rate; + pTrack->m_colour = colour_ptr.release(); + pTrack->m_colour_space = colour_space_ptr.release(); + pTrack->m_projection = projection_ptr.release(); + + pResult = pTrack; + return 0; // success +} + +bool VideoTrack::VetEntry(const BlockEntry* pBlockEntry) const { + return Track::VetEntry(pBlockEntry) && pBlockEntry->GetBlock()->IsKey(); +} + +long VideoTrack::Seek(long long time_ns, const BlockEntry*& pResult) const { + const long status = GetFirst(pResult); + + if (status < 0) // buffer underflow, etc + return status; + + assert(pResult); + + if (pResult->EOS()) + return 0; + + const Cluster* pCluster = pResult->GetCluster(); + assert(pCluster); + assert(pCluster->GetIndex() >= 0); + + if (time_ns <= pResult->GetBlock()->GetTime(pCluster)) + return 0; + + Cluster** const clusters = m_pSegment->m_clusters; + assert(clusters); + + const long count = m_pSegment->GetCount(); // loaded only, not pre-loaded + assert(count > 0); + + Cluster** const i = clusters + pCluster->GetIndex(); + assert(i); + assert(*i == pCluster); + assert(pCluster->GetTime() <= time_ns); + + Cluster** const j = clusters + count; + + Cluster** lo = i; + Cluster** hi = j; + + while (lo < hi) { + // INVARIANT: + //[i, lo) <= time_ns + //[lo, hi) ? + //[hi, j) > time_ns + + Cluster** const mid = lo + (hi - lo) / 2; + assert(mid < hi); + + pCluster = *mid; + assert(pCluster); + assert(pCluster->GetIndex() >= 0); + assert(pCluster->GetIndex() == long(mid - m_pSegment->m_clusters)); + + const long long t = pCluster->GetTime(); + + if (t <= time_ns) + lo = mid + 1; + else + hi = mid; + + assert(lo <= hi); + } + + assert(lo == hi); + assert(lo > i); + assert(lo <= j); + + pCluster = *--lo; + assert(pCluster); + assert(pCluster->GetTime() <= time_ns); + + pResult = pCluster->GetEntry(this, time_ns); + + if ((pResult != 0) && !pResult->EOS()) // found a keyframe + return 0; + + while (lo != i) { + pCluster = *--lo; + assert(pCluster); + assert(pCluster->GetTime() <= time_ns); + + pResult = pCluster->GetEntry(this, time_ns); + + if ((pResult != 0) && !pResult->EOS()) + return 0; + } + + // weird: we're on the first cluster, but no keyframe found + // should never happen but we must return something anyway + + pResult = GetEOS(); + return 0; +} + +Colour* VideoTrack::GetColour() const { return m_colour; } + +Projection* VideoTrack::GetProjection() const { return m_projection; } + +long long VideoTrack::GetWidth() const { return m_width; } + +long long VideoTrack::GetHeight() const { return m_height; } + +long long VideoTrack::GetDisplayWidth() const { + return m_display_width > 0 ? m_display_width : GetWidth(); +} + +long long VideoTrack::GetDisplayHeight() const { + return m_display_height > 0 ? m_display_height : GetHeight(); +} + +long long VideoTrack::GetDisplayUnit() const { return m_display_unit; } + +long long VideoTrack::GetStereoMode() const { return m_stereo_mode; } + +double VideoTrack::GetFrameRate() const { return m_rate; } + +AudioTrack::AudioTrack(Segment* pSegment, long long element_start, + long long element_size) + : Track(pSegment, element_start, element_size) {} + +long AudioTrack::Parse(Segment* pSegment, const Info& info, + long long element_start, long long element_size, + AudioTrack*& pResult) { + if (pResult) + return -1; + + if (info.type != Track::kAudio) + return -1; + + IMkvReader* const pReader = pSegment->m_pReader; + + const Settings& s = info.settings; + assert(s.start >= 0); + assert(s.size >= 0); + + long long pos = s.start; + assert(pos >= 0); + + const long long stop = pos + s.size; + + double rate = 8000.0; // MKV default + long long channels = 1; + long long bit_depth = 0; + + while (pos < stop) { + long long id, size; + + long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (id == libwebm::kMkvSamplingFrequency) { + status = UnserializeFloat(pReader, pos, size, rate); + + if (status < 0) + return status; + + if (rate <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvChannels) { + channels = UnserializeUInt(pReader, pos, size); + + if (channels <= 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvBitDepth) { + bit_depth = UnserializeUInt(pReader, pos, size); + + if (bit_depth <= 0) + return E_FILE_FORMAT_INVALID; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + AudioTrack* const pTrack = + new (std::nothrow) AudioTrack(pSegment, element_start, element_size); + + if (pTrack == NULL) + return -1; // generic error + + const int status = info.Copy(pTrack->m_info); + + if (status) { + delete pTrack; + return status; + } + + pTrack->m_rate = rate; + pTrack->m_channels = channels; + pTrack->m_bitDepth = bit_depth; + + pResult = pTrack; + return 0; // success +} + +double AudioTrack::GetSamplingRate() const { return m_rate; } + +long long AudioTrack::GetChannels() const { return m_channels; } + +long long AudioTrack::GetBitDepth() const { return m_bitDepth; } + +Tracks::Tracks(Segment* pSegment, long long start, long long size_, + long long element_start, long long element_size) + : m_pSegment(pSegment), + m_start(start), + m_size(size_), + m_element_start(element_start), + m_element_size(element_size), + m_trackEntries(NULL), + m_trackEntriesEnd(NULL) {} + +long Tracks::Parse() { + assert(m_trackEntries == NULL); + assert(m_trackEntriesEnd == NULL); + + const long long stop = m_start + m_size; + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long count = 0; + long long pos = m_start; + + while (pos < stop) { + long long id, size; + + const long status = ParseElementHeader(pReader, pos, stop, id, size); + + if (status < 0) // error + return status; + + if (size == 0) // weird + continue; + + if (id == libwebm::kMkvTrackEntry) { + ++count; + if (count > INT_MAX) + return E_PARSE_FAILED; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + if (count <= 0) + return 0; // success + + m_trackEntries = new (std::nothrow) Track*[static_cast(count)]; + + if (m_trackEntries == NULL) + return -1; + + m_trackEntriesEnd = m_trackEntries; + + pos = m_start; + + while (pos < stop) { + const long long element_start = pos; + + long long id, payload_size; + + const long status = + ParseElementHeader(pReader, pos, stop, id, payload_size); + + if (status < 0) // error + return status; + + if (payload_size == 0) // weird + continue; + + const long long payload_stop = pos + payload_size; + assert(payload_stop <= stop); // checked in ParseElement + + const long long element_size = payload_stop - element_start; + + if (id == libwebm::kMkvTrackEntry) { + Track*& pTrack = *m_trackEntriesEnd; + pTrack = NULL; + + const long status = ParseTrackEntry(pos, payload_size, element_start, + element_size, pTrack); + if (status) + return status; + + if (pTrack) + ++m_trackEntriesEnd; + } + + pos = payload_stop; + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + return 0; // success +} + +unsigned long Tracks::GetTracksCount() const { + const ptrdiff_t result = m_trackEntriesEnd - m_trackEntries; + assert(result >= 0); + + return static_cast(result); +} + +long Tracks::ParseTrackEntry(long long track_start, long long track_size, + long long element_start, long long element_size, + Track*& pResult) const { + if (pResult) + return -1; + + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long pos = track_start; + const long long track_stop = track_start + track_size; + + Track::Info info; + + info.type = 0; + info.number = 0; + info.uid = 0; + info.defaultDuration = 0; + + Track::Settings v; + v.start = -1; + v.size = -1; + + Track::Settings a; + a.start = -1; + a.size = -1; + + Track::Settings e; // content_encodings_settings; + e.start = -1; + e.size = -1; + + long long lacing = 1; // default is true + + while (pos < track_stop) { + long long id, size; + + const long status = ParseElementHeader(pReader, pos, track_stop, id, size); + + if (status < 0) // error + return status; + + if (size < 0) + return E_FILE_FORMAT_INVALID; + + const long long start = pos; + + if (id == libwebm::kMkvVideo) { + v.start = start; + v.size = size; + } else if (id == libwebm::kMkvAudio) { + a.start = start; + a.size = size; + } else if (id == libwebm::kMkvContentEncodings) { + e.start = start; + e.size = size; + } else if (id == libwebm::kMkvTrackUID) { + if (size > 8) + return E_FILE_FORMAT_INVALID; + + info.uid = 0; + + long long pos_ = start; + const long long pos_end = start + size; + + while (pos_ != pos_end) { + unsigned char b; + + const int status = pReader->Read(pos_, 1, &b); + + if (status) + return status; + + info.uid <<= 8; + info.uid |= b; + + ++pos_; + } + } else if (id == libwebm::kMkvTrackNumber) { + const long long num = UnserializeUInt(pReader, pos, size); + + if ((num <= 0) || (num > 127)) + return E_FILE_FORMAT_INVALID; + + info.number = static_cast(num); + } else if (id == libwebm::kMkvTrackType) { + const long long type = UnserializeUInt(pReader, pos, size); + + if ((type <= 0) || (type > 254)) + return E_FILE_FORMAT_INVALID; + + info.type = static_cast(type); + } else if (id == libwebm::kMkvName) { + const long status = + UnserializeString(pReader, pos, size, info.nameAsUTF8); + + if (status) + return status; + } else if (id == libwebm::kMkvLanguage) { + const long status = UnserializeString(pReader, pos, size, info.language); + + if (status) + return status; + } else if (id == libwebm::kMkvDefaultDuration) { + const long long duration = UnserializeUInt(pReader, pos, size); + + if (duration < 0) + return E_FILE_FORMAT_INVALID; + + info.defaultDuration = static_cast(duration); + } else if (id == libwebm::kMkvCodecID) { + const long status = UnserializeString(pReader, pos, size, info.codecId); + + if (status) + return status; + } else if (id == libwebm::kMkvFlagLacing) { + lacing = UnserializeUInt(pReader, pos, size); + + if ((lacing < 0) || (lacing > 1)) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvCodecPrivate) { + delete[] info.codecPrivate; + info.codecPrivate = NULL; + info.codecPrivateSize = 0; + + const size_t buflen = static_cast(size); + + if (buflen) { + unsigned char* buf = SafeArrayAlloc(1, buflen); + + if (buf == NULL) + return -1; + + const int status = pReader->Read(pos, static_cast(buflen), buf); + + if (status) { + delete[] buf; + return status; + } + + info.codecPrivate = buf; + info.codecPrivateSize = buflen; + } + } else if (id == libwebm::kMkvCodecName) { + const long status = + UnserializeString(pReader, pos, size, info.codecNameAsUTF8); + + if (status) + return status; + } else if (id == libwebm::kMkvCodecDelay) { + info.codecDelay = UnserializeUInt(pReader, pos, size); + } else if (id == libwebm::kMkvSeekPreRoll) { + info.seekPreRoll = UnserializeUInt(pReader, pos, size); + } + + pos += size; // consume payload + if (pos > track_stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != track_stop) + return E_FILE_FORMAT_INVALID; + + if (info.number <= 0) // not specified + return E_FILE_FORMAT_INVALID; + + if (GetTrackByNumber(info.number)) + return E_FILE_FORMAT_INVALID; + + if (info.type <= 0) // not specified + return E_FILE_FORMAT_INVALID; + + info.lacing = (lacing > 0) ? true : false; + + if (info.type == Track::kVideo) { + if (v.start < 0) + return E_FILE_FORMAT_INVALID; + + if (a.start >= 0) + return E_FILE_FORMAT_INVALID; + + info.settings = v; + + VideoTrack* pTrack = NULL; + + const long status = VideoTrack::Parse(m_pSegment, info, element_start, + element_size, pTrack); + + if (status) + return status; + + pResult = pTrack; + assert(pResult); + + if (e.start >= 0) + pResult->ParseContentEncodingsEntry(e.start, e.size); + } else if (info.type == Track::kAudio) { + if (a.start < 0) + return E_FILE_FORMAT_INVALID; + + if (v.start >= 0) + return E_FILE_FORMAT_INVALID; + + info.settings = a; + + AudioTrack* pTrack = NULL; + + const long status = AudioTrack::Parse(m_pSegment, info, element_start, + element_size, pTrack); + + if (status) + return status; + + pResult = pTrack; + assert(pResult); + + if (e.start >= 0) + pResult->ParseContentEncodingsEntry(e.start, e.size); + } else { + // neither video nor audio - probably metadata or subtitles + + if (a.start >= 0) + return E_FILE_FORMAT_INVALID; + + if (v.start >= 0) + return E_FILE_FORMAT_INVALID; + + if (info.type == Track::kMetadata && e.start >= 0) + return E_FILE_FORMAT_INVALID; + + info.settings.start = -1; + info.settings.size = 0; + + Track* pTrack = NULL; + + const long status = + Track::Create(m_pSegment, info, element_start, element_size, pTrack); + + if (status) + return status; + + pResult = pTrack; + assert(pResult); + } + + return 0; // success +} + +Tracks::~Tracks() { + Track** i = m_trackEntries; + Track** const j = m_trackEntriesEnd; + + while (i != j) { + Track* const pTrack = *i++; + delete pTrack; + } + + delete[] m_trackEntries; +} + +const Track* Tracks::GetTrackByNumber(long tn) const { + if (tn < 0) + return NULL; + + Track** i = m_trackEntries; + Track** const j = m_trackEntriesEnd; + + while (i != j) { + Track* const pTrack = *i++; + + if (pTrack == NULL) + continue; + + if (tn == pTrack->GetNumber()) + return pTrack; + } + + return NULL; // not found +} + +const Track* Tracks::GetTrackByIndex(unsigned long idx) const { + const ptrdiff_t count = m_trackEntriesEnd - m_trackEntries; + + if (idx >= static_cast(count)) + return NULL; + + return m_trackEntries[idx]; +} + +long Cluster::Load(long long& pos, long& len) const { + if (m_pSegment == NULL) + return E_PARSE_FAILED; + + if (m_timecode >= 0) // at least partially loaded + return 0; + + if (m_pos != m_element_start || m_element_size >= 0) + return E_PARSE_FAILED; + + IMkvReader* const pReader = m_pSegment->m_pReader; + long long total, avail; + const int status = pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + if (total >= 0 && (avail > total || m_pos > total)) + return E_FILE_FORMAT_INVALID; + + pos = m_pos; + + long long cluster_size = -1; + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error or underflow + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long id_ = ReadID(pReader, pos, len); + + if (id_ < 0) // error + return static_cast(id_); + + if (id_ != libwebm::kMkvCluster) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume id + + // read cluster size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(pReader, pos, len); + + if (size < 0) // error + return static_cast(cluster_size); + + if (size == 0) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume length of size of element + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size != unknown_size) + cluster_size = size; + + // pos points to start of payload + long long timecode = -1; + long long new_pos = -1; + bool bBlock = false; + + long long cluster_stop = (cluster_size < 0) ? -1 : pos + cluster_size; + + for (;;) { + if ((cluster_stop >= 0) && (pos >= cluster_stop)) + break; + + // Parse ID + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long id = ReadID(pReader, pos, len); + + if (id < 0) // error + return static_cast(id); + + if (id == 0) + return E_FILE_FORMAT_INVALID; + + // This is the distinguished set of ID's we use to determine + // that we have exhausted the sub-element's inside the cluster + // whose ID we parsed earlier. + + if (id == libwebm::kMkvCluster) + break; + + if (id == libwebm::kMkvCues) + break; + + pos += len; // consume ID field + + // Parse Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume size field + + if ((cluster_stop >= 0) && (pos > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + // pos now points to start of payload + + if (size == 0) + continue; + + if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if (id == libwebm::kMkvTimecode) { + len = static_cast(size); + + if ((pos + size) > avail) + return E_BUFFER_NOT_FULL; + + timecode = UnserializeUInt(pReader, pos, size); + + if (timecode < 0) // error (or underflow) + return static_cast(timecode); + + new_pos = pos + size; + + if (bBlock) + break; + } else if (id == libwebm::kMkvBlockGroup) { + bBlock = true; + break; + } else if (id == libwebm::kMkvSimpleBlock) { + bBlock = true; + break; + } + + pos += size; // consume payload + if (cluster_stop >= 0 && pos > cluster_stop) + return E_FILE_FORMAT_INVALID; + } + + if (cluster_stop >= 0 && pos > cluster_stop) + return E_FILE_FORMAT_INVALID; + + if (timecode < 0) // no timecode found + return E_FILE_FORMAT_INVALID; + + if (!bBlock) + return E_FILE_FORMAT_INVALID; + + m_pos = new_pos; // designates position just beyond timecode payload + m_timecode = timecode; // m_timecode >= 0 means we're partially loaded + + if (cluster_size >= 0) + m_element_size = cluster_stop - m_element_start; + + return 0; +} + +long Cluster::Parse(long long& pos, long& len) const { + long status = Load(pos, len); + + if (status < 0) + return status; + + if (m_pos < m_element_start || m_timecode < 0) + return E_PARSE_FAILED; + + const long long cluster_stop = + (m_element_size < 0) ? -1 : m_element_start + m_element_size; + + if ((cluster_stop >= 0) && (m_pos >= cluster_stop)) + return 1; // nothing else to do + + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long total, avail; + + status = pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + if (total >= 0 && avail > total) + return E_FILE_FORMAT_INVALID; + + pos = m_pos; + + for (;;) { + if ((cluster_stop >= 0) && (pos >= cluster_stop)) + break; + + if ((total >= 0) && (pos >= total)) { + if (m_element_size < 0) + m_element_size = pos - m_element_start; + + break; + } + + // Parse ID + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long id = ReadID(pReader, pos, len); + + if (id < 0) + return E_FILE_FORMAT_INVALID; + + // This is the distinguished set of ID's we use to determine + // that we have exhausted the sub-element's inside the cluster + // whose ID we parsed earlier. + + if ((id == libwebm::kMkvCluster) || (id == libwebm::kMkvCues)) { + if (m_element_size < 0) + m_element_size = pos - m_element_start; + + break; + } + + pos += len; // consume ID field + + // Parse Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) + return E_BUFFER_NOT_FULL; + + if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume size field + + if ((cluster_stop >= 0) && (pos > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + // pos now points to start of payload + + if (size == 0) + continue; + + // const long long block_start = pos; + const long long block_stop = pos + size; + + if (cluster_stop >= 0) { + if (block_stop > cluster_stop) { + if (id == libwebm::kMkvBlockGroup || id == libwebm::kMkvSimpleBlock) { + return E_FILE_FORMAT_INVALID; + } + + pos = cluster_stop; + break; + } + } else if ((total >= 0) && (block_stop > total)) { + m_element_size = total - m_element_start; + pos = total; + break; + } else if (block_stop > avail) { + len = static_cast(size); + return E_BUFFER_NOT_FULL; + } + + Cluster* const this_ = const_cast(this); + + if (id == libwebm::kMkvBlockGroup) + return this_->ParseBlockGroup(size, pos, len); + + if (id == libwebm::kMkvSimpleBlock) + return this_->ParseSimpleBlock(size, pos, len); + + pos += size; // consume payload + if (cluster_stop >= 0 && pos > cluster_stop) + return E_FILE_FORMAT_INVALID; + } + + if (m_element_size < 1) + return E_FILE_FORMAT_INVALID; + + m_pos = pos; + if (cluster_stop >= 0 && m_pos > cluster_stop) + return E_FILE_FORMAT_INVALID; + + if (m_entries_count > 0) { + const long idx = m_entries_count - 1; + + const BlockEntry* const pLast = m_entries[idx]; + if (pLast == NULL) + return E_PARSE_FAILED; + + const Block* const pBlock = pLast->GetBlock(); + if (pBlock == NULL) + return E_PARSE_FAILED; + + const long long start = pBlock->m_start; + + if ((total >= 0) && (start > total)) + return E_PARSE_FAILED; // defend against trucated stream + + const long long size = pBlock->m_size; + + const long long stop = start + size; + if (cluster_stop >= 0 && stop > cluster_stop) + return E_FILE_FORMAT_INVALID; + + if ((total >= 0) && (stop > total)) + return E_PARSE_FAILED; // defend against trucated stream + } + + return 1; // no more entries +} + +long Cluster::ParseSimpleBlock(long long block_size, long long& pos, + long& len) { + const long long block_start = pos; + const long long block_stop = pos + block_size; + + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long total, avail; + + long status = pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + assert((total < 0) || (avail <= total)); + + // parse track number + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((pos + len) > block_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long track = ReadUInt(pReader, pos, len); + + if (track < 0) // error + return static_cast(track); + + if (track == 0) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume track number + + if ((pos + 2) > block_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + 2) > avail) { + len = 2; + return E_BUFFER_NOT_FULL; + } + + pos += 2; // consume timecode + + if ((pos + 1) > block_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + unsigned char flags; + + status = pReader->Read(pos, 1, &flags); + + if (status < 0) { // error or underflow + len = 1; + return status; + } + + ++pos; // consume flags byte + assert(pos <= avail); + + if (pos >= block_stop) + return E_FILE_FORMAT_INVALID; + + const int lacing = int(flags & 0x06) >> 1; + + if ((lacing != 0) && (block_stop > avail)) { + len = static_cast(block_stop - pos); + return E_BUFFER_NOT_FULL; + } + + status = CreateBlock(libwebm::kMkvSimpleBlock, block_start, block_size, + 0); // DiscardPadding + + if (status != 0) + return status; + + m_pos = block_stop; + + return 0; // success +} + +long Cluster::ParseBlockGroup(long long payload_size, long long& pos, + long& len) { + const long long payload_start = pos; + const long long payload_stop = pos + payload_size; + + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long total, avail; + + long status = pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + assert((total < 0) || (avail <= total)); + + if ((total >= 0) && (payload_stop > total)) + return E_FILE_FORMAT_INVALID; + + if (payload_stop > avail) { + len = static_cast(payload_size); + return E_BUFFER_NOT_FULL; + } + + long long discard_padding = 0; + + while (pos < payload_stop) { + // parse sub-block element ID + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((pos + len) > payload_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long id = ReadID(pReader, pos, len); + + if (id < 0) // error + return static_cast(id); + + if (id == 0) // not a valid ID + return E_FILE_FORMAT_INVALID; + + pos += len; // consume ID field + + // Parse Size + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((pos + len) > payload_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + pos += len; // consume size field + + // pos now points to start of sub-block group payload + + if (pos > payload_stop) + return E_FILE_FORMAT_INVALID; + + if (size == 0) // weird + continue; + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; + + if (id == libwebm::kMkvDiscardPadding) { + status = UnserializeInt(pReader, pos, size, discard_padding); + + if (status < 0) // error + return status; + } + + if (id != libwebm::kMkvBlock) { + pos += size; // consume sub-part of block group + + if (pos > payload_stop) + return E_FILE_FORMAT_INVALID; + + continue; + } + + const long long block_stop = pos + size; + + if (block_stop > payload_stop) + return E_FILE_FORMAT_INVALID; + + // parse track number + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((pos + len) > block_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long track = ReadUInt(pReader, pos, len); + + if (track < 0) // error + return static_cast(track); + + if (track == 0) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume track number + + if ((pos + 2) > block_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + 2) > avail) { + len = 2; + return E_BUFFER_NOT_FULL; + } + + pos += 2; // consume timecode + + if ((pos + 1) > block_stop) + return E_FILE_FORMAT_INVALID; + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + unsigned char flags; + + status = pReader->Read(pos, 1, &flags); + + if (status < 0) { // error or underflow + len = 1; + return status; + } + + ++pos; // consume flags byte + assert(pos <= avail); + + if (pos >= block_stop) + return E_FILE_FORMAT_INVALID; + + const int lacing = int(flags & 0x06) >> 1; + + if ((lacing != 0) && (block_stop > avail)) { + len = static_cast(block_stop - pos); + return E_BUFFER_NOT_FULL; + } + + pos = block_stop; // consume block-part of block group + if (pos > payload_stop) + return E_FILE_FORMAT_INVALID; + } + + if (pos != payload_stop) + return E_FILE_FORMAT_INVALID; + + status = CreateBlock(libwebm::kMkvBlockGroup, payload_start, payload_size, + discard_padding); + if (status != 0) + return status; + + m_pos = payload_stop; + + return 0; // success +} + +long Cluster::GetEntry(long index, const mkvparser::BlockEntry*& pEntry) const { + assert(m_pos >= m_element_start); + + pEntry = NULL; + + if (index < 0) + return -1; // generic error + + if (m_entries_count < 0) + return E_BUFFER_NOT_FULL; + + assert(m_entries); + assert(m_entries_size > 0); + assert(m_entries_count <= m_entries_size); + + if (index < m_entries_count) { + pEntry = m_entries[index]; + assert(pEntry); + + return 1; // found entry + } + + if (m_element_size < 0) // we don't know cluster end yet + return E_BUFFER_NOT_FULL; // underflow + + const long long element_stop = m_element_start + m_element_size; + + if (m_pos >= element_stop) + return 0; // nothing left to parse + + return E_BUFFER_NOT_FULL; // underflow, since more remains to be parsed +} + +Cluster* Cluster::Create(Segment* pSegment, long idx, long long off) { + if (!pSegment || off < 0) + return NULL; + + const long long element_start = pSegment->m_start + off; + + Cluster* const pCluster = + new (std::nothrow) Cluster(pSegment, idx, element_start); + + return pCluster; +} + +Cluster::Cluster() + : m_pSegment(NULL), + m_element_start(0), + m_index(0), + m_pos(0), + m_element_size(0), + m_timecode(0), + m_entries(NULL), + m_entries_size(0), + m_entries_count(0) // means "no entries" +{} + +Cluster::Cluster(Segment* pSegment, long idx, long long element_start + /* long long element_size */) + : m_pSegment(pSegment), + m_element_start(element_start), + m_index(idx), + m_pos(element_start), + m_element_size(-1 /* element_size */), + m_timecode(-1), + m_entries(NULL), + m_entries_size(0), + m_entries_count(-1) // means "has not been parsed yet" +{} + +Cluster::~Cluster() { + if (m_entries_count <= 0) { + delete[] m_entries; + return; + } + + BlockEntry** i = m_entries; + BlockEntry** const j = m_entries + m_entries_count; + + while (i != j) { + BlockEntry* p = *i++; + assert(p); + + delete p; + } + + delete[] m_entries; +} + +bool Cluster::EOS() const { return (m_pSegment == NULL); } + +long Cluster::GetIndex() const { return m_index; } + +long long Cluster::GetPosition() const { + const long long pos = m_element_start - m_pSegment->m_start; + assert(pos >= 0); + + return pos; +} + +long long Cluster::GetElementSize() const { return m_element_size; } + +long Cluster::HasBlockEntries( + const Segment* pSegment, + long long off, // relative to start of segment payload + long long& pos, long& len) { + assert(pSegment); + assert(off >= 0); // relative to segment + + IMkvReader* const pReader = pSegment->m_pReader; + + long long total, avail; + + long status = pReader->Length(&total, &avail); + + if (status < 0) // error + return status; + + assert((total < 0) || (avail <= total)); + + pos = pSegment->m_start + off; // absolute + + if ((total >= 0) && (pos >= total)) + return 0; // we don't even have a complete cluster + + const long long segment_stop = + (pSegment->m_size < 0) ? -1 : pSegment->m_start + pSegment->m_size; + + long long cluster_stop = -1; // interpreted later to mean "unknown size" + + { + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // need more data + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((total >= 0) && ((pos + len) > total)) + return 0; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long id = ReadID(pReader, pos, len); + + if (id < 0) // error + return static_cast(id); + + if (id != libwebm::kMkvCluster) + return E_PARSE_FAILED; + + pos += len; // consume Cluster ID field + + // read size field + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // weird + return E_BUFFER_NOT_FULL; + + if ((segment_stop >= 0) && ((pos + len) > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((total >= 0) && ((pos + len) > total)) + return 0; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + if (size == 0) + return 0; // cluster does not have entries + + pos += len; // consume size field + + // pos now points to start of payload + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size != unknown_size) { + cluster_stop = pos + size; + assert(cluster_stop >= 0); + + if ((segment_stop >= 0) && (cluster_stop > segment_stop)) + return E_FILE_FORMAT_INVALID; + + if ((total >= 0) && (cluster_stop > total)) + // return E_FILE_FORMAT_INVALID; //too conservative + return 0; // cluster does not have any entries + } + } + + for (;;) { + if ((cluster_stop >= 0) && (pos >= cluster_stop)) + return 0; // no entries detected + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + long long result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // need more data + return E_BUFFER_NOT_FULL; + + if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long id = ReadID(pReader, pos, len); + + if (id < 0) // error + return static_cast(id); + + // This is the distinguished set of ID's we use to determine + // that we have exhausted the sub-element's inside the cluster + // whose ID we parsed earlier. + + if (id == libwebm::kMkvCluster) + return 0; // no entries found + + if (id == libwebm::kMkvCues) + return 0; // no entries found + + pos += len; // consume id field + + if ((cluster_stop >= 0) && (pos >= cluster_stop)) + return E_FILE_FORMAT_INVALID; + + // read size field + + if ((pos + 1) > avail) { + len = 1; + return E_BUFFER_NOT_FULL; + } + + result = GetUIntLength(pReader, pos, len); + + if (result < 0) // error + return static_cast(result); + + if (result > 0) // underflow + return E_BUFFER_NOT_FULL; + + if ((cluster_stop >= 0) && ((pos + len) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > avail) + return E_BUFFER_NOT_FULL; + + const long long size = ReadUInt(pReader, pos, len); + + if (size < 0) // error + return static_cast(size); + + pos += len; // consume size field + + // pos now points to start of payload + + if ((cluster_stop >= 0) && (pos > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if (size == 0) // weird + continue; + + const long long unknown_size = (1LL << (7 * len)) - 1; + + if (size == unknown_size) + return E_FILE_FORMAT_INVALID; // not supported inside cluster + + if ((cluster_stop >= 0) && ((pos + size) > cluster_stop)) + return E_FILE_FORMAT_INVALID; + + if (id == libwebm::kMkvBlockGroup) + return 1; // have at least one entry + + if (id == libwebm::kMkvSimpleBlock) + return 1; // have at least one entry + + pos += size; // consume payload + if (cluster_stop >= 0 && pos > cluster_stop) + return E_FILE_FORMAT_INVALID; + } +} + +long long Cluster::GetTimeCode() const { + long long pos; + long len; + + const long status = Load(pos, len); + + if (status < 0) // error + return status; + + return m_timecode; +} + +long long Cluster::GetTime() const { + const long long tc = GetTimeCode(); + + if (tc < 0) + return tc; + + const SegmentInfo* const pInfo = m_pSegment->GetInfo(); + assert(pInfo); + + const long long scale = pInfo->GetTimeCodeScale(); + assert(scale >= 1); + + const long long t = m_timecode * scale; + + return t; +} + +long long Cluster::GetFirstTime() const { + const BlockEntry* pEntry; + + const long status = GetFirst(pEntry); + + if (status < 0) // error + return status; + + if (pEntry == NULL) // empty cluster + return GetTime(); + + const Block* const pBlock = pEntry->GetBlock(); + assert(pBlock); + + return pBlock->GetTime(this); +} + +long long Cluster::GetLastTime() const { + const BlockEntry* pEntry; + + const long status = GetLast(pEntry); + + if (status < 0) // error + return status; + + if (pEntry == NULL) // empty cluster + return GetTime(); + + const Block* const pBlock = pEntry->GetBlock(); + assert(pBlock); + + return pBlock->GetTime(this); +} + +long Cluster::CreateBlock(long long id, + long long pos, // absolute pos of payload + long long size, long long discard_padding) { + if (id != libwebm::kMkvBlockGroup && id != libwebm::kMkvSimpleBlock) + return E_PARSE_FAILED; + + if (m_entries_count < 0) { // haven't parsed anything yet + assert(m_entries == NULL); + assert(m_entries_size == 0); + + m_entries_size = 1024; + m_entries = new (std::nothrow) BlockEntry*[m_entries_size]; + if (m_entries == NULL) + return -1; + + m_entries_count = 0; + } else { + assert(m_entries); + assert(m_entries_size > 0); + assert(m_entries_count <= m_entries_size); + + if (m_entries_count >= m_entries_size) { + const long entries_size = 2 * m_entries_size; + + BlockEntry** const entries = new (std::nothrow) BlockEntry*[entries_size]; + if (entries == NULL) + return -1; + + BlockEntry** src = m_entries; + BlockEntry** const src_end = src + m_entries_count; + + BlockEntry** dst = entries; + + while (src != src_end) + *dst++ = *src++; + + delete[] m_entries; + + m_entries = entries; + m_entries_size = entries_size; + } + } + + if (id == libwebm::kMkvBlockGroup) + return CreateBlockGroup(pos, size, discard_padding); + else + return CreateSimpleBlock(pos, size); +} + +long Cluster::CreateBlockGroup(long long start_offset, long long size, + long long discard_padding) { + assert(m_entries); + assert(m_entries_size > 0); + assert(m_entries_count >= 0); + assert(m_entries_count < m_entries_size); + + IMkvReader* const pReader = m_pSegment->m_pReader; + + long long pos = start_offset; + const long long stop = start_offset + size; + + // For WebM files, there is a bias towards previous reference times + //(in order to support alt-ref frames, which refer back to the previous + // keyframe). Normally a 0 value is not possible, but here we tenatively + // allow 0 as the value of a reference frame, with the interpretation + // that this is a "previous" reference time. + + long long prev = 1; // nonce + long long next = 0; // nonce + long long duration = -1; // really, this is unsigned + + long long bpos = -1; + long long bsize = -1; + + while (pos < stop) { + long len; + const long long id = ReadID(pReader, pos, len); + if (id < 0 || (pos + len) > stop) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume ID + + const long long size = ReadUInt(pReader, pos, len); + assert(size >= 0); // TODO + assert((pos + len) <= stop); + + pos += len; // consume size + + if (id == libwebm::kMkvBlock) { + if (bpos < 0) { // Block ID + bpos = pos; + bsize = size; + } + } else if (id == libwebm::kMkvBlockDuration) { + if (size > 8) + return E_FILE_FORMAT_INVALID; + + duration = UnserializeUInt(pReader, pos, size); + + if (duration < 0) + return E_FILE_FORMAT_INVALID; + } else if (id == libwebm::kMkvReferenceBlock) { + if (size > 8 || size <= 0) + return E_FILE_FORMAT_INVALID; + const long size_ = static_cast(size); + + long long time; + + long status = UnserializeInt(pReader, pos, size_, time); + assert(status == 0); + if (status != 0) + return -1; + + if (time <= 0) // see note above + prev = time; + else + next = time; + } + + pos += size; // consume payload + if (pos > stop) + return E_FILE_FORMAT_INVALID; + } + if (bpos < 0) + return E_FILE_FORMAT_INVALID; + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + assert(bsize >= 0); + + const long idx = m_entries_count; + + BlockEntry** const ppEntry = m_entries + idx; + BlockEntry*& pEntry = *ppEntry; + + pEntry = new (std::nothrow) + BlockGroup(this, idx, bpos, bsize, prev, next, duration, discard_padding); + + if (pEntry == NULL) + return -1; // generic error + + BlockGroup* const p = static_cast(pEntry); + + const long status = p->Parse(); + + if (status == 0) { // success + ++m_entries_count; + return 0; + } + + delete pEntry; + pEntry = 0; + + return status; +} + +long Cluster::CreateSimpleBlock(long long st, long long sz) { + assert(m_entries); + assert(m_entries_size > 0); + assert(m_entries_count >= 0); + assert(m_entries_count < m_entries_size); + + const long idx = m_entries_count; + + BlockEntry** const ppEntry = m_entries + idx; + BlockEntry*& pEntry = *ppEntry; + + pEntry = new (std::nothrow) SimpleBlock(this, idx, st, sz); + + if (pEntry == NULL) + return -1; // generic error + + SimpleBlock* const p = static_cast(pEntry); + + const long status = p->Parse(); + + if (status == 0) { + ++m_entries_count; + return 0; + } + + delete pEntry; + pEntry = 0; + + return status; +} + +long Cluster::GetFirst(const BlockEntry*& pFirst) const { + if (m_entries_count <= 0) { + long long pos; + long len; + + const long status = Parse(pos, len); + + if (status < 0) { // error + pFirst = NULL; + return status; + } + + if (m_entries_count <= 0) { // empty cluster + pFirst = NULL; + return 0; + } + } + + assert(m_entries); + + pFirst = m_entries[0]; + assert(pFirst); + + return 0; // success +} + +long Cluster::GetLast(const BlockEntry*& pLast) const { + for (;;) { + long long pos; + long len; + + const long status = Parse(pos, len); + + if (status < 0) { // error + pLast = NULL; + return status; + } + + if (status > 0) // no new block + break; + } + + if (m_entries_count <= 0) { + pLast = NULL; + return 0; + } + + assert(m_entries); + + const long idx = m_entries_count - 1; + + pLast = m_entries[idx]; + assert(pLast); + + return 0; +} + +long Cluster::GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const { + assert(pCurr); + assert(m_entries); + assert(m_entries_count > 0); + + size_t idx = pCurr->GetIndex(); + assert(idx < size_t(m_entries_count)); + assert(m_entries[idx] == pCurr); + + ++idx; + + if (idx >= size_t(m_entries_count)) { + long long pos; + long len; + + const long status = Parse(pos, len); + + if (status < 0) { // error + pNext = NULL; + return status; + } + + if (status > 0) { + pNext = NULL; + return 0; + } + + assert(m_entries); + assert(m_entries_count > 0); + assert(idx < size_t(m_entries_count)); + } + + pNext = m_entries[idx]; + assert(pNext); + + return 0; +} + +long Cluster::GetEntryCount() const { return m_entries_count; } + +const BlockEntry* Cluster::GetEntry(const Track* pTrack, + long long time_ns) const { + assert(pTrack); + + if (m_pSegment == NULL) // this is the special EOS cluster + return pTrack->GetEOS(); + + const BlockEntry* pResult = pTrack->GetEOS(); + + long index = 0; + + for (;;) { + if (index >= m_entries_count) { + long long pos; + long len; + + const long status = Parse(pos, len); + assert(status >= 0); + + if (status > 0) // completely parsed, and no more entries + return pResult; + + if (status < 0) // should never happen + return 0; + + assert(m_entries); + assert(index < m_entries_count); + } + + const BlockEntry* const pEntry = m_entries[index]; + assert(pEntry); + assert(!pEntry->EOS()); + + const Block* const pBlock = pEntry->GetBlock(); + assert(pBlock); + + if (pBlock->GetTrackNumber() != pTrack->GetNumber()) { + ++index; + continue; + } + + if (pTrack->VetEntry(pEntry)) { + if (time_ns < 0) // just want first candidate block + return pEntry; + + const long long ns = pBlock->GetTime(this); + + if (ns > time_ns) + return pResult; + + pResult = pEntry; // have a candidate + } else if (time_ns >= 0) { + const long long ns = pBlock->GetTime(this); + + if (ns > time_ns) + return pResult; + } + + ++index; + } +} + +const BlockEntry* Cluster::GetEntry(const CuePoint& cp, + const CuePoint::TrackPosition& tp) const { + assert(m_pSegment); + const long long tc = cp.GetTimeCode(); + + if (tp.m_block > 0) { + const long block = static_cast(tp.m_block); + const long index = block - 1; + + while (index >= m_entries_count) { + long long pos; + long len; + + const long status = Parse(pos, len); + + if (status < 0) // TODO: can this happen? + return NULL; + + if (status > 0) // nothing remains to be parsed + return NULL; + } + + const BlockEntry* const pEntry = m_entries[index]; + assert(pEntry); + assert(!pEntry->EOS()); + + const Block* const pBlock = pEntry->GetBlock(); + assert(pBlock); + + if ((pBlock->GetTrackNumber() == tp.m_track) && + (pBlock->GetTimeCode(this) == tc)) { + return pEntry; + } + } + + long index = 0; + + for (;;) { + if (index >= m_entries_count) { + long long pos; + long len; + + const long status = Parse(pos, len); + + if (status < 0) // TODO: can this happen? + return NULL; + + if (status > 0) // nothing remains to be parsed + return NULL; + + assert(m_entries); + assert(index < m_entries_count); + } + + const BlockEntry* const pEntry = m_entries[index]; + assert(pEntry); + assert(!pEntry->EOS()); + + const Block* const pBlock = pEntry->GetBlock(); + assert(pBlock); + + if (pBlock->GetTrackNumber() != tp.m_track) { + ++index; + continue; + } + + const long long tc_ = pBlock->GetTimeCode(this); + + if (tc_ < tc) { + ++index; + continue; + } + + if (tc_ > tc) + return NULL; + + const Tracks* const pTracks = m_pSegment->GetTracks(); + assert(pTracks); + + const long tn = static_cast(tp.m_track); + const Track* const pTrack = pTracks->GetTrackByNumber(tn); + + if (pTrack == NULL) + return NULL; + + const long long type = pTrack->GetType(); + + if (type == 2) // audio + return pEntry; + + if (type != 1) // not video + return NULL; + + if (!pBlock->IsKey()) + return NULL; + + return pEntry; + } +} + +BlockEntry::BlockEntry(Cluster* p, long idx) : m_pCluster(p), m_index(idx) {} +BlockEntry::~BlockEntry() {} +const Cluster* BlockEntry::GetCluster() const { return m_pCluster; } +long BlockEntry::GetIndex() const { return m_index; } + +SimpleBlock::SimpleBlock(Cluster* pCluster, long idx, long long start, + long long size) + : BlockEntry(pCluster, idx), m_block(start, size, 0) {} + +long SimpleBlock::Parse() { return m_block.Parse(m_pCluster); } +BlockEntry::Kind SimpleBlock::GetKind() const { return kBlockSimple; } +const Block* SimpleBlock::GetBlock() const { return &m_block; } + +BlockGroup::BlockGroup(Cluster* pCluster, long idx, long long block_start, + long long block_size, long long prev, long long next, + long long duration, long long discard_padding) + : BlockEntry(pCluster, idx), + m_block(block_start, block_size, discard_padding), + m_prev(prev), + m_next(next), + m_duration(duration) {} + +long BlockGroup::Parse() { + const long status = m_block.Parse(m_pCluster); + + if (status) + return status; + + m_block.SetKey((m_prev > 0) && (m_next <= 0)); + + return 0; +} + +BlockEntry::Kind BlockGroup::GetKind() const { return kBlockGroup; } +const Block* BlockGroup::GetBlock() const { return &m_block; } +long long BlockGroup::GetPrevTimeCode() const { return m_prev; } +long long BlockGroup::GetNextTimeCode() const { return m_next; } +long long BlockGroup::GetDurationTimeCode() const { return m_duration; } + +Block::Block(long long start, long long size_, long long discard_padding) + : m_start(start), + m_size(size_), + m_track(0), + m_timecode(-1), + m_flags(0), + m_frames(NULL), + m_frame_count(-1), + m_discard_padding(discard_padding) {} + +Block::~Block() { delete[] m_frames; } + +long Block::Parse(const Cluster* pCluster) { + if (pCluster == NULL) + return -1; + + if (pCluster->m_pSegment == NULL) + return -1; + + assert(m_start >= 0); + assert(m_size >= 0); + assert(m_track <= 0); + assert(m_frames == NULL); + assert(m_frame_count <= 0); + + long long pos = m_start; + const long long stop = m_start + m_size; + + long len; + + IMkvReader* const pReader = pCluster->m_pSegment->m_pReader; + + m_track = ReadUInt(pReader, pos, len); + + if (m_track <= 0) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > stop) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume track number + + if ((stop - pos) < 2) + return E_FILE_FORMAT_INVALID; + + long status; + long long value; + + status = UnserializeInt(pReader, pos, 2, value); + + if (status) + return E_FILE_FORMAT_INVALID; + + if (value < SHRT_MIN) + return E_FILE_FORMAT_INVALID; + + if (value > SHRT_MAX) + return E_FILE_FORMAT_INVALID; + + m_timecode = static_cast(value); + + pos += 2; + + if ((stop - pos) <= 0) + return E_FILE_FORMAT_INVALID; + + status = pReader->Read(pos, 1, &m_flags); + + if (status) + return E_FILE_FORMAT_INVALID; + + const int lacing = int(m_flags & 0x06) >> 1; + + ++pos; // consume flags byte + + if (lacing == 0) { // no lacing + if (pos > stop) + return E_FILE_FORMAT_INVALID; + + m_frame_count = 1; + m_frames = new (std::nothrow) Frame[m_frame_count]; + if (m_frames == NULL) + return -1; + + Frame& f = m_frames[0]; + f.pos = pos; + + const long long frame_size = stop - pos; + + if (frame_size > LONG_MAX || frame_size <= 0) + return E_FILE_FORMAT_INVALID; + + f.len = static_cast(frame_size); + + return 0; // success + } + + if (pos >= stop) + return E_FILE_FORMAT_INVALID; + + unsigned char biased_count; + + status = pReader->Read(pos, 1, &biased_count); + + if (status) + return E_FILE_FORMAT_INVALID; + + ++pos; // consume frame count + if (pos > stop) + return E_FILE_FORMAT_INVALID; + + m_frame_count = int(biased_count) + 1; + + m_frames = new (std::nothrow) Frame[m_frame_count]; + if (m_frames == NULL) + return -1; + + if (!m_frames) + return E_FILE_FORMAT_INVALID; + + if (lacing == 1) { // Xiph + Frame* pf = m_frames; + Frame* const pf_end = pf + m_frame_count; + + long long size = 0; + int frame_count = m_frame_count; + + while (frame_count > 1) { + long frame_size = 0; + + for (;;) { + unsigned char val; + + if (pos >= stop) + return E_FILE_FORMAT_INVALID; + + status = pReader->Read(pos, 1, &val); + + if (status) + return E_FILE_FORMAT_INVALID; + + ++pos; // consume xiph size byte + + frame_size += val; + + if (val < 255) + break; + } + + Frame& f = *pf++; + assert(pf < pf_end); + if (pf >= pf_end) + return E_FILE_FORMAT_INVALID; + + f.pos = 0; // patch later + + if (frame_size <= 0) + return E_FILE_FORMAT_INVALID; + + f.len = frame_size; + size += frame_size; // contribution of this frame + + --frame_count; + } + + if (pf >= pf_end || pos > stop) + return E_FILE_FORMAT_INVALID; + + { + Frame& f = *pf++; + + if (pf != pf_end) + return E_FILE_FORMAT_INVALID; + + f.pos = 0; // patch later + + const long long total_size = stop - pos; + + if (total_size < size) + return E_FILE_FORMAT_INVALID; + + const long long frame_size = total_size - size; + + if (frame_size > LONG_MAX || frame_size <= 0) + return E_FILE_FORMAT_INVALID; + + f.len = static_cast(frame_size); + } + + pf = m_frames; + while (pf != pf_end) { + Frame& f = *pf++; + assert((pos + f.len) <= stop); + + if ((pos + f.len) > stop) + return E_FILE_FORMAT_INVALID; + + f.pos = pos; + pos += f.len; + } + + assert(pos == stop); + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + } else if (lacing == 2) { // fixed-size lacing + if (pos >= stop) + return E_FILE_FORMAT_INVALID; + + const long long total_size = stop - pos; + + if ((total_size % m_frame_count) != 0) + return E_FILE_FORMAT_INVALID; + + const long long frame_size = total_size / m_frame_count; + + if (frame_size > LONG_MAX || frame_size <= 0) + return E_FILE_FORMAT_INVALID; + + Frame* pf = m_frames; + Frame* const pf_end = pf + m_frame_count; + + while (pf != pf_end) { + assert((pos + frame_size) <= stop); + if ((pos + frame_size) > stop) + return E_FILE_FORMAT_INVALID; + + Frame& f = *pf++; + + f.pos = pos; + f.len = static_cast(frame_size); + + pos += frame_size; + } + + assert(pos == stop); + if (pos != stop) + return E_FILE_FORMAT_INVALID; + + } else { + assert(lacing == 3); // EBML lacing + + if (pos >= stop) + return E_FILE_FORMAT_INVALID; + + long long size = 0; + int frame_count = m_frame_count; + + long long frame_size = ReadUInt(pReader, pos, len); + + if (frame_size <= 0) + return E_FILE_FORMAT_INVALID; + + if (frame_size > LONG_MAX) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > stop) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume length of size of first frame + + if ((pos + frame_size) > stop) + return E_FILE_FORMAT_INVALID; + + Frame* pf = m_frames; + Frame* const pf_end = pf + m_frame_count; + + { + Frame& curr = *pf; + + curr.pos = 0; // patch later + + curr.len = static_cast(frame_size); + size += curr.len; // contribution of this frame + } + + --frame_count; + + while (frame_count > 1) { + if (pos >= stop) + return E_FILE_FORMAT_INVALID; + + assert(pf < pf_end); + if (pf >= pf_end) + return E_FILE_FORMAT_INVALID; + + const Frame& prev = *pf++; + assert(prev.len == frame_size); + if (prev.len != frame_size) + return E_FILE_FORMAT_INVALID; + + assert(pf < pf_end); + if (pf >= pf_end) + return E_FILE_FORMAT_INVALID; + + Frame& curr = *pf; + + curr.pos = 0; // patch later + + const long long delta_size_ = ReadUInt(pReader, pos, len); + + if (delta_size_ < 0) + return E_FILE_FORMAT_INVALID; + + if ((pos + len) > stop) + return E_FILE_FORMAT_INVALID; + + pos += len; // consume length of (delta) size + if (pos > stop) + return E_FILE_FORMAT_INVALID; + + const long exp = 7 * len - 1; + const long long bias = (1LL << exp) - 1LL; + const long long delta_size = delta_size_ - bias; + + frame_size += delta_size; + + if (frame_size <= 0) + return E_FILE_FORMAT_INVALID; + + if (frame_size > LONG_MAX) + return E_FILE_FORMAT_INVALID; + + curr.len = static_cast(frame_size); + // Check if size + curr.len could overflow. + if (size > LLONG_MAX - curr.len) { + return E_FILE_FORMAT_INVALID; + } + size += curr.len; // contribution of this frame + + --frame_count; + } + + // parse last frame + if (frame_count > 0) { + if (pos > stop || pf >= pf_end) + return E_FILE_FORMAT_INVALID; + + const Frame& prev = *pf++; + assert(prev.len == frame_size); + if (prev.len != frame_size) + return E_FILE_FORMAT_INVALID; + + if (pf >= pf_end) + return E_FILE_FORMAT_INVALID; + + Frame& curr = *pf++; + if (pf != pf_end) + return E_FILE_FORMAT_INVALID; + + curr.pos = 0; // patch later + + const long long total_size = stop - pos; + + if (total_size < size) + return E_FILE_FORMAT_INVALID; + + frame_size = total_size - size; + + if (frame_size > LONG_MAX || frame_size <= 0) + return E_FILE_FORMAT_INVALID; + + curr.len = static_cast(frame_size); + } + + pf = m_frames; + while (pf != pf_end) { + Frame& f = *pf++; + if ((pos + f.len) > stop) + return E_FILE_FORMAT_INVALID; + + f.pos = pos; + pos += f.len; + } + + if (pos != stop) + return E_FILE_FORMAT_INVALID; + } + + return 0; // success +} + +long long Block::GetTimeCode(const Cluster* pCluster) const { + if (pCluster == 0) + return m_timecode; + + const long long tc0 = pCluster->GetTimeCode(); + assert(tc0 >= 0); + + // Check if tc0 + m_timecode would overflow. + if (tc0 < 0 || LLONG_MAX - tc0 < m_timecode) { + return -1; + } + + const long long tc = tc0 + m_timecode; + + return tc; // unscaled timecode units +} + +long long Block::GetTime(const Cluster* pCluster) const { + assert(pCluster); + + const long long tc = GetTimeCode(pCluster); + + const Segment* const pSegment = pCluster->m_pSegment; + const SegmentInfo* const pInfo = pSegment->GetInfo(); + assert(pInfo); + + const long long scale = pInfo->GetTimeCodeScale(); + assert(scale >= 1); + + // Check if tc * scale could overflow. + if (tc != 0 && scale > LLONG_MAX / tc) { + return -1; + } + const long long ns = tc * scale; + + return ns; +} + +long long Block::GetTrackNumber() const { return m_track; } + +bool Block::IsKey() const { + return ((m_flags & static_cast(1 << 7)) != 0); +} + +void Block::SetKey(bool bKey) { + if (bKey) + m_flags |= static_cast(1 << 7); + else + m_flags &= 0x7F; +} + +bool Block::IsInvisible() const { return bool(int(m_flags & 0x08) != 0); } + +Block::Lacing Block::GetLacing() const { + const int value = int(m_flags & 0x06) >> 1; + return static_cast(value); +} + +int Block::GetFrameCount() const { return m_frame_count; } + +const Block::Frame& Block::GetFrame(int idx) const { + assert(idx >= 0); + assert(idx < m_frame_count); + + const Frame& f = m_frames[idx]; + assert(f.pos > 0); + assert(f.len > 0); + + return f; +} + +long Block::Frame::Read(IMkvReader* pReader, unsigned char* buf) const { + assert(pReader); + assert(buf); + + const long status = pReader->Read(pos, len, buf); + return status; +} + +long long Block::GetDiscardPadding() const { return m_discard_padding; } + +} // namespace mkvparser diff --git a/src/sys/libwebm/mkvparser/mkvparser.h b/src/sys/libwebm/mkvparser/mkvparser.h new file mode 100644 index 0000000..848d01f --- /dev/null +++ b/src/sys/libwebm/mkvparser/mkvparser.h @@ -0,0 +1,1147 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef MKVPARSER_MKVPARSER_H_ +#define MKVPARSER_MKVPARSER_H_ + +#include + +namespace mkvparser { + +const int E_PARSE_FAILED = -1; +const int E_FILE_FORMAT_INVALID = -2; +const int E_BUFFER_NOT_FULL = -3; + +class IMkvReader { + public: + virtual int Read(long long pos, long len, unsigned char* buf) = 0; + virtual int Length(long long* total, long long* available) = 0; + + protected: + virtual ~IMkvReader() {} +}; + +template +Type* SafeArrayAlloc(unsigned long long num_elements, + unsigned long long element_size); +long long GetUIntLength(IMkvReader*, long long, long&); +long long ReadUInt(IMkvReader*, long long, long&); +long long ReadID(IMkvReader* pReader, long long pos, long& len); +long long UnserializeUInt(IMkvReader*, long long pos, long long size); + +long UnserializeFloat(IMkvReader*, long long pos, long long size, double&); +long UnserializeInt(IMkvReader*, long long pos, long long size, + long long& result); + +long UnserializeString(IMkvReader*, long long pos, long long size, char*& str); + +long ParseElementHeader(IMkvReader* pReader, + long long& pos, // consume id and size fields + long long stop, // if you know size of element's parent + long long& id, long long& size); + +bool Match(IMkvReader*, long long&, unsigned long, long long&); +bool Match(IMkvReader*, long long&, unsigned long, unsigned char*&, size_t&); + +void GetVersion(int& major, int& minor, int& build, int& revision); + +struct EBMLHeader { + EBMLHeader(); + ~EBMLHeader(); + long long m_version; + long long m_readVersion; + long long m_maxIdLength; + long long m_maxSizeLength; + char* m_docType; + long long m_docTypeVersion; + long long m_docTypeReadVersion; + + long long Parse(IMkvReader*, long long&); + void Init(); +}; + +class Segment; +class Track; +class Cluster; + +class Block { + Block(const Block&); + Block& operator=(const Block&); + + public: + const long long m_start; + const long long m_size; + + Block(long long start, long long size, long long discard_padding); + ~Block(); + + long Parse(const Cluster*); + + long long GetTrackNumber() const; + long long GetTimeCode(const Cluster*) const; // absolute, but not scaled + long long GetTime(const Cluster*) const; // absolute, and scaled (ns) + bool IsKey() const; + void SetKey(bool); + bool IsInvisible() const; + + enum Lacing { kLacingNone, kLacingXiph, kLacingFixed, kLacingEbml }; + Lacing GetLacing() const; + + int GetFrameCount() const; // to index frames: [0, count) + + struct Frame { + long long pos; // absolute offset + long len; + + long Read(IMkvReader*, unsigned char*) const; + }; + + const Frame& GetFrame(int frame_index) const; + + long long GetDiscardPadding() const; + + private: + long long m_track; // Track::Number() + short m_timecode; // relative to cluster + unsigned char m_flags; + + Frame* m_frames; + int m_frame_count; + + protected: + const long long m_discard_padding; +}; + +class BlockEntry { + BlockEntry(const BlockEntry&); + BlockEntry& operator=(const BlockEntry&); + + protected: + BlockEntry(Cluster*, long index); + + public: + virtual ~BlockEntry(); + + bool EOS() const { return (GetKind() == kBlockEOS); } + const Cluster* GetCluster() const; + long GetIndex() const; + virtual const Block* GetBlock() const = 0; + + enum Kind { kBlockEOS, kBlockSimple, kBlockGroup }; + virtual Kind GetKind() const = 0; + + protected: + Cluster* const m_pCluster; + const long m_index; +}; + +class SimpleBlock : public BlockEntry { + SimpleBlock(const SimpleBlock&); + SimpleBlock& operator=(const SimpleBlock&); + + public: + SimpleBlock(Cluster*, long index, long long start, long long size); + long Parse(); + + Kind GetKind() const; + const Block* GetBlock() const; + + protected: + Block m_block; +}; + +class BlockGroup : public BlockEntry { + BlockGroup(const BlockGroup&); + BlockGroup& operator=(const BlockGroup&); + + public: + BlockGroup(Cluster*, long index, + long long block_start, // absolute pos of block's payload + long long block_size, // size of block's payload + long long prev, long long next, long long duration, + long long discard_padding); + + long Parse(); + + Kind GetKind() const; + const Block* GetBlock() const; + + long long GetPrevTimeCode() const; // relative to block's time + long long GetNextTimeCode() const; // as above + long long GetDurationTimeCode() const; + + private: + Block m_block; + const long long m_prev; + const long long m_next; + const long long m_duration; +}; + +/////////////////////////////////////////////////////////////// +// ContentEncoding element +// Elements used to describe if the track data has been encrypted or +// compressed with zlib or header stripping. +class ContentEncoding { + public: + enum { kCTR = 1 }; + + ContentEncoding(); + ~ContentEncoding(); + + // ContentCompression element names + struct ContentCompression { + ContentCompression(); + ~ContentCompression(); + + unsigned long long algo; + unsigned char* settings; + long long settings_len; + }; + + // ContentEncAESSettings element names + struct ContentEncAESSettings { + ContentEncAESSettings() : cipher_mode(kCTR) {} + ~ContentEncAESSettings() {} + + unsigned long long cipher_mode; + }; + + // ContentEncryption element names + struct ContentEncryption { + ContentEncryption(); + ~ContentEncryption(); + + unsigned long long algo; + unsigned char* key_id; + long long key_id_len; + unsigned char* signature; + long long signature_len; + unsigned char* sig_key_id; + long long sig_key_id_len; + unsigned long long sig_algo; + unsigned long long sig_hash_algo; + + ContentEncAESSettings aes_settings; + }; + + // Returns ContentCompression represented by |idx|. Returns NULL if |idx| + // is out of bounds. + const ContentCompression* GetCompressionByIndex(unsigned long idx) const; + + // Returns number of ContentCompression elements in this ContentEncoding + // element. + unsigned long GetCompressionCount() const; + + // Parses the ContentCompression element from |pReader|. |start| is the + // starting offset of the ContentCompression payload. |size| is the size in + // bytes of the ContentCompression payload. |compression| is where the parsed + // values will be stored. + long ParseCompressionEntry(long long start, long long size, + IMkvReader* pReader, + ContentCompression* compression); + + // Returns ContentEncryption represented by |idx|. Returns NULL if |idx| + // is out of bounds. + const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const; + + // Returns number of ContentEncryption elements in this ContentEncoding + // element. + unsigned long GetEncryptionCount() const; + + // Parses the ContentEncAESSettings element from |pReader|. |start| is the + // starting offset of the ContentEncAESSettings payload. |size| is the + // size in bytes of the ContentEncAESSettings payload. |encryption| is + // where the parsed values will be stored. + long ParseContentEncAESSettingsEntry(long long start, long long size, + IMkvReader* pReader, + ContentEncAESSettings* aes); + + // Parses the ContentEncoding element from |pReader|. |start| is the + // starting offset of the ContentEncoding payload. |size| is the size in + // bytes of the ContentEncoding payload. Returns true on success. + long ParseContentEncodingEntry(long long start, long long size, + IMkvReader* pReader); + + // Parses the ContentEncryption element from |pReader|. |start| is the + // starting offset of the ContentEncryption payload. |size| is the size in + // bytes of the ContentEncryption payload. |encryption| is where the parsed + // values will be stored. + long ParseEncryptionEntry(long long start, long long size, + IMkvReader* pReader, ContentEncryption* encryption); + + unsigned long long encoding_order() const { return encoding_order_; } + unsigned long long encoding_scope() const { return encoding_scope_; } + unsigned long long encoding_type() const { return encoding_type_; } + + private: + // Member variables for list of ContentCompression elements. + ContentCompression** compression_entries_; + ContentCompression** compression_entries_end_; + + // Member variables for list of ContentEncryption elements. + ContentEncryption** encryption_entries_; + ContentEncryption** encryption_entries_end_; + + // ContentEncoding element names + unsigned long long encoding_order_; + unsigned long long encoding_scope_; + unsigned long long encoding_type_; + + // LIBWEBM_DISALLOW_COPY_AND_ASSIGN(ContentEncoding); + ContentEncoding(const ContentEncoding&); + ContentEncoding& operator=(const ContentEncoding&); +}; + +class Track { + Track(const Track&); + Track& operator=(const Track&); + + public: + class Info; + static long Create(Segment*, const Info&, long long element_start, + long long element_size, Track*&); + + enum Type { kVideo = 1, kAudio = 2, kSubtitle = 0x11, kMetadata = 0x21 }; + + Segment* const m_pSegment; + const long long m_element_start; + const long long m_element_size; + virtual ~Track(); + + long GetType() const; + long GetNumber() const; + unsigned long long GetUid() const; + const char* GetNameAsUTF8() const; + const char* GetLanguage() const; + const char* GetCodecNameAsUTF8() const; + const char* GetCodecId() const; + const unsigned char* GetCodecPrivate(size_t&) const; + bool GetLacing() const; + unsigned long long GetDefaultDuration() const; + unsigned long long GetCodecDelay() const; + unsigned long long GetSeekPreRoll() const; + + const BlockEntry* GetEOS() const; + + struct Settings { + long long start; + long long size; + }; + + class Info { + public: + Info(); + ~Info(); + int Copy(Info&) const; + void Clear(); + long type; + long number; + unsigned long long uid; + unsigned long long defaultDuration; + unsigned long long codecDelay; + unsigned long long seekPreRoll; + char* nameAsUTF8; + char* language; + char* codecId; + char* codecNameAsUTF8; + unsigned char* codecPrivate; + size_t codecPrivateSize; + bool lacing; + Settings settings; + + private: + Info(const Info&); + Info& operator=(const Info&); + int CopyStr(char* Info::*str, Info&) const; + }; + + long GetFirst(const BlockEntry*&) const; + long GetNext(const BlockEntry* pCurr, const BlockEntry*& pNext) const; + virtual bool VetEntry(const BlockEntry*) const; + virtual long Seek(long long time_ns, const BlockEntry*&) const; + + const ContentEncoding* GetContentEncodingByIndex(unsigned long idx) const; + unsigned long GetContentEncodingCount() const; + + long ParseContentEncodingsEntry(long long start, long long size); + + protected: + Track(Segment*, long long element_start, long long element_size); + + Info m_info; + + class EOSBlock : public BlockEntry { + public: + EOSBlock(); + + Kind GetKind() const; + const Block* GetBlock() const; + }; + + EOSBlock m_eos; + + private: + ContentEncoding** content_encoding_entries_; + ContentEncoding** content_encoding_entries_end_; +}; + +struct PrimaryChromaticity { + PrimaryChromaticity() : x(0), y(0) {} + ~PrimaryChromaticity() {} + static bool Parse(IMkvReader* reader, long long read_pos, + long long value_size, bool is_x, + PrimaryChromaticity** chromaticity); + float x; + float y; +}; + +struct MasteringMetadata { + static const float kValueNotPresent; + + MasteringMetadata() + : r(NULL), + g(NULL), + b(NULL), + white_point(NULL), + luminance_max(kValueNotPresent), + luminance_min(kValueNotPresent) {} + ~MasteringMetadata() { + delete r; + delete g; + delete b; + delete white_point; + } + + static bool Parse(IMkvReader* reader, long long element_start, + long long element_size, + MasteringMetadata** mastering_metadata); + + PrimaryChromaticity* r; + PrimaryChromaticity* g; + PrimaryChromaticity* b; + PrimaryChromaticity* white_point; + float luminance_max; + float luminance_min; +}; + +struct Colour { + static const long long kValueNotPresent; + + // Unless otherwise noted all values assigned upon construction are the + // equivalent of unspecified/default. + Colour() + : matrix_coefficients(kValueNotPresent), + bits_per_channel(kValueNotPresent), + chroma_subsampling_horz(kValueNotPresent), + chroma_subsampling_vert(kValueNotPresent), + cb_subsampling_horz(kValueNotPresent), + cb_subsampling_vert(kValueNotPresent), + chroma_siting_horz(kValueNotPresent), + chroma_siting_vert(kValueNotPresent), + range(kValueNotPresent), + transfer_characteristics(kValueNotPresent), + primaries(kValueNotPresent), + max_cll(kValueNotPresent), + max_fall(kValueNotPresent), + mastering_metadata(NULL) {} + ~Colour() { + delete mastering_metadata; + mastering_metadata = NULL; + } + + static bool Parse(IMkvReader* reader, long long element_start, + long long element_size, Colour** colour); + + long long matrix_coefficients; + long long bits_per_channel; + long long chroma_subsampling_horz; + long long chroma_subsampling_vert; + long long cb_subsampling_horz; + long long cb_subsampling_vert; + long long chroma_siting_horz; + long long chroma_siting_vert; + long long range; + long long transfer_characteristics; + long long primaries; + long long max_cll; + long long max_fall; + + MasteringMetadata* mastering_metadata; +}; + +struct Projection { + enum ProjectionType { + kTypeNotPresent = -1, + kRectangular = 0, + kEquirectangular = 1, + kCubeMap = 2, + kMesh = 3, + }; + static const float kValueNotPresent; + Projection() + : type(kTypeNotPresent), + private_data(NULL), + private_data_length(0), + pose_yaw(kValueNotPresent), + pose_pitch(kValueNotPresent), + pose_roll(kValueNotPresent) {} + ~Projection() { delete[] private_data; } + static bool Parse(IMkvReader* reader, long long element_start, + long long element_size, Projection** projection); + + ProjectionType type; + unsigned char* private_data; + size_t private_data_length; + float pose_yaw; + float pose_pitch; + float pose_roll; +}; + +class VideoTrack : public Track { + VideoTrack(const VideoTrack&); + VideoTrack& operator=(const VideoTrack&); + + VideoTrack(Segment*, long long element_start, long long element_size); + + public: + virtual ~VideoTrack(); + static long Parse(Segment*, const Info&, long long element_start, + long long element_size, VideoTrack*&); + + long long GetWidth() const; + long long GetHeight() const; + long long GetDisplayWidth() const; + long long GetDisplayHeight() const; + long long GetDisplayUnit() const; + long long GetStereoMode() const; + double GetFrameRate() const; + + bool VetEntry(const BlockEntry*) const; + long Seek(long long time_ns, const BlockEntry*&) const; + + Colour* GetColour() const; + + Projection* GetProjection() const; + + const char* GetColourSpace() const { return m_colour_space; } + + private: + long long m_width; + long long m_height; + long long m_display_width; + long long m_display_height; + long long m_display_unit; + long long m_stereo_mode; + char* m_colour_space; + double m_rate; + + Colour* m_colour; + Projection* m_projection; +}; + +class AudioTrack : public Track { + AudioTrack(const AudioTrack&); + AudioTrack& operator=(const AudioTrack&); + + AudioTrack(Segment*, long long element_start, long long element_size); + + public: + static long Parse(Segment*, const Info&, long long element_start, + long long element_size, AudioTrack*&); + + double GetSamplingRate() const; + long long GetChannels() const; + long long GetBitDepth() const; + + private: + double m_rate; + long long m_channels; + long long m_bitDepth; +}; + +class Tracks { + Tracks(const Tracks&); + Tracks& operator=(const Tracks&); + + public: + Segment* const m_pSegment; + const long long m_start; + const long long m_size; + const long long m_element_start; + const long long m_element_size; + + Tracks(Segment*, long long start, long long size, long long element_start, + long long element_size); + + ~Tracks(); + + long Parse(); + + unsigned long GetTracksCount() const; + + const Track* GetTrackByNumber(long tn) const; + const Track* GetTrackByIndex(unsigned long idx) const; + + private: + Track** m_trackEntries; + Track** m_trackEntriesEnd; + + long ParseTrackEntry(long long payload_start, long long payload_size, + long long element_start, long long element_size, + Track*&) const; +}; + +class Chapters { + Chapters(const Chapters&); + Chapters& operator=(const Chapters&); + + public: + Segment* const m_pSegment; + const long long m_start; + const long long m_size; + const long long m_element_start; + const long long m_element_size; + + Chapters(Segment*, long long payload_start, long long payload_size, + long long element_start, long long element_size); + + ~Chapters(); + + long Parse(); + + class Atom; + class Edition; + + class Display { + friend class Atom; + Display(); + Display(const Display&); + ~Display(); + Display& operator=(const Display&); + + public: + const char* GetString() const; + const char* GetLanguage() const; + const char* GetCountry() const; + + private: + void Init(); + void ShallowCopy(Display&) const; + void Clear(); + long Parse(IMkvReader*, long long pos, long long size); + + char* m_string; + char* m_language; + char* m_country; + }; + + class Atom { + friend class Edition; + Atom(); + Atom(const Atom&); + ~Atom(); + Atom& operator=(const Atom&); + + public: + unsigned long long GetUID() const; + const char* GetStringUID() const; + + long long GetStartTimecode() const; + long long GetStopTimecode() const; + + long long GetStartTime(const Chapters*) const; + long long GetStopTime(const Chapters*) const; + + int GetDisplayCount() const; + const Display* GetDisplay(int index) const; + + private: + void Init(); + void ShallowCopy(Atom&) const; + void Clear(); + long Parse(IMkvReader*, long long pos, long long size); + static long long GetTime(const Chapters*, long long timecode); + + long ParseDisplay(IMkvReader*, long long pos, long long size); + bool ExpandDisplaysArray(); + + char* m_string_uid; + unsigned long long m_uid; + long long m_start_timecode; + long long m_stop_timecode; + + Display* m_displays; + int m_displays_size; + int m_displays_count; + }; + + class Edition { + friend class Chapters; + Edition(); + Edition(const Edition&); + ~Edition(); + Edition& operator=(const Edition&); + + public: + int GetAtomCount() const; + const Atom* GetAtom(int index) const; + + private: + void Init(); + void ShallowCopy(Edition&) const; + void Clear(); + long Parse(IMkvReader*, long long pos, long long size); + + long ParseAtom(IMkvReader*, long long pos, long long size); + bool ExpandAtomsArray(); + + Atom* m_atoms; + int m_atoms_size; + int m_atoms_count; + }; + + int GetEditionCount() const; + const Edition* GetEdition(int index) const; + + private: + long ParseEdition(long long pos, long long size); + bool ExpandEditionsArray(); + + Edition* m_editions; + int m_editions_size; + int m_editions_count; +}; + +class Tags { + Tags(const Tags&); + Tags& operator=(const Tags&); + + public: + Segment* const m_pSegment; + const long long m_start; + const long long m_size; + const long long m_element_start; + const long long m_element_size; + + Tags(Segment*, long long payload_start, long long payload_size, + long long element_start, long long element_size); + + ~Tags(); + + long Parse(); + + class Tag; + class SimpleTag; + + class SimpleTag { + friend class Tag; + SimpleTag(); + SimpleTag(const SimpleTag&); + ~SimpleTag(); + SimpleTag& operator=(const SimpleTag&); + + public: + const char* GetTagName() const; + const char* GetTagString() const; + + private: + void Init(); + void ShallowCopy(SimpleTag&) const; + void Clear(); + long Parse(IMkvReader*, long long pos, long long size); + + char* m_tag_name; + char* m_tag_string; + }; + + class Tag { + friend class Tags; + Tag(); + Tag(const Tag&); + ~Tag(); + Tag& operator=(const Tag&); + + public: + int GetSimpleTagCount() const; + const SimpleTag* GetSimpleTag(int index) const; + + private: + void Init(); + void ShallowCopy(Tag&) const; + void Clear(); + long Parse(IMkvReader*, long long pos, long long size); + + long ParseSimpleTag(IMkvReader*, long long pos, long long size); + bool ExpandSimpleTagsArray(); + + SimpleTag* m_simple_tags; + int m_simple_tags_size; + int m_simple_tags_count; + }; + + int GetTagCount() const; + const Tag* GetTag(int index) const; + + private: + long ParseTag(long long pos, long long size); + bool ExpandTagsArray(); + + Tag* m_tags; + int m_tags_size; + int m_tags_count; +}; + +class SegmentInfo { + SegmentInfo(const SegmentInfo&); + SegmentInfo& operator=(const SegmentInfo&); + + public: + Segment* const m_pSegment; + const long long m_start; + const long long m_size; + const long long m_element_start; + const long long m_element_size; + + SegmentInfo(Segment*, long long start, long long size, + long long element_start, long long element_size); + + ~SegmentInfo(); + + long Parse(); + + long long GetTimeCodeScale() const; + long long GetDuration() const; // scaled + const char* GetMuxingAppAsUTF8() const; + const char* GetWritingAppAsUTF8() const; + const char* GetTitleAsUTF8() const; + + private: + long long m_timecodeScale; + double m_duration; + char* m_pMuxingAppAsUTF8; + char* m_pWritingAppAsUTF8; + char* m_pTitleAsUTF8; +}; + +class SeekHead { + SeekHead(const SeekHead&); + SeekHead& operator=(const SeekHead&); + + public: + Segment* const m_pSegment; + const long long m_start; + const long long m_size; + const long long m_element_start; + const long long m_element_size; + + SeekHead(Segment*, long long start, long long size, long long element_start, + long long element_size); + + ~SeekHead(); + + long Parse(); + + struct Entry { + Entry(); + + // the SeekHead entry payload + long long id; + long long pos; + + // absolute pos of SeekEntry ID + long long element_start; + + // SeekEntry ID size + size size + payload + long long element_size; + }; + + int GetCount() const; + const Entry* GetEntry(int idx) const; + + struct VoidElement { + // absolute pos of Void ID + long long element_start; + + // ID size + size size + payload size + long long element_size; + }; + + int GetVoidElementCount() const; + const VoidElement* GetVoidElement(int idx) const; + + private: + Entry* m_entries; + int m_entry_count; + + VoidElement* m_void_elements; + int m_void_element_count; + + static bool ParseEntry(IMkvReader*, + long long pos, // payload + long long size, Entry*); +}; + +class Cues; +class CuePoint { + friend class Cues; + + CuePoint(long, long long); + ~CuePoint(); + + CuePoint(const CuePoint&); + CuePoint& operator=(const CuePoint&); + + public: + long long m_element_start; + long long m_element_size; + + bool Load(IMkvReader*); + + long long GetTimeCode() const; // absolute but unscaled + long long GetTime(const Segment*) const; // absolute and scaled (ns units) + + struct TrackPosition { + long long m_track; + long long m_pos; // of cluster + long long m_block; + // codec_state //defaults to 0 + // reference = clusters containing req'd referenced blocks + // reftime = timecode of the referenced block + + bool Parse(IMkvReader*, long long, long long); + }; + + const TrackPosition* Find(const Track*) const; + + private: + const long m_index; + long long m_timecode; + TrackPosition* m_track_positions; + size_t m_track_positions_count; +}; + +class Cues { + friend class Segment; + + Cues(Segment*, long long start, long long size, long long element_start, + long long element_size); + ~Cues(); + + Cues(const Cues&); + Cues& operator=(const Cues&); + + public: + Segment* const m_pSegment; + const long long m_start; + const long long m_size; + const long long m_element_start; + const long long m_element_size; + + bool Find( // lower bound of time_ns + long long time_ns, const Track*, const CuePoint*&, + const CuePoint::TrackPosition*&) const; + + const CuePoint* GetFirst() const; + const CuePoint* GetLast() const; + const CuePoint* GetNext(const CuePoint*) const; + + const BlockEntry* GetBlock(const CuePoint*, + const CuePoint::TrackPosition*) const; + + bool LoadCuePoint() const; + long GetCount() const; // loaded only + // long GetTotal() const; //loaded + preloaded + bool DoneParsing() const; + + private: + bool Init() const; + bool PreloadCuePoint(long&, long long) const; + + mutable CuePoint** m_cue_points; + mutable long m_count; + mutable long m_preload_count; + mutable long long m_pos; +}; + +class Cluster { + friend class Segment; + + Cluster(const Cluster&); + Cluster& operator=(const Cluster&); + + public: + Segment* const m_pSegment; + + public: + static Cluster* Create(Segment*, + long index, // index in segment + long long off); // offset relative to segment + // long long element_size); + + Cluster(); // EndOfStream + ~Cluster(); + + bool EOS() const; + + long long GetTimeCode() const; // absolute, but not scaled + long long GetTime() const; // absolute, and scaled (nanosecond units) + long long GetFirstTime() const; // time (ns) of first (earliest) block + long long GetLastTime() const; // time (ns) of last (latest) block + + long GetFirst(const BlockEntry*&) const; + long GetLast(const BlockEntry*&) const; + long GetNext(const BlockEntry* curr, const BlockEntry*& next) const; + + const BlockEntry* GetEntry(const Track*, long long ns = -1) const; + const BlockEntry* GetEntry(const CuePoint&, + const CuePoint::TrackPosition&) const; + // const BlockEntry* GetMaxKey(const VideoTrack*) const; + + // static bool HasBlockEntries(const Segment*, long long); + + static long HasBlockEntries(const Segment*, long long idoff, long long& pos, + long& size); + + long GetEntryCount() const; + + long Load(long long& pos, long& size) const; + + long Parse(long long& pos, long& size) const; + long GetEntry(long index, const mkvparser::BlockEntry*&) const; + + protected: + Cluster(Segment*, long index, long long element_start); + // long long element_size); + + public: + const long long m_element_start; + long long GetPosition() const; // offset relative to segment + + long GetIndex() const; + long long GetElementSize() const; + // long long GetPayloadSize() const; + + // long long Unparsed() const; + + private: + long m_index; + mutable long long m_pos; + // mutable long long m_size; + mutable long long m_element_size; + mutable long long m_timecode; + mutable BlockEntry** m_entries; + mutable long m_entries_size; + mutable long m_entries_count; + + long ParseSimpleBlock(long long, long long&, long&); + long ParseBlockGroup(long long, long long&, long&); + + long CreateBlock(long long id, long long pos, long long size, + long long discard_padding); + long CreateBlockGroup(long long start_offset, long long size, + long long discard_padding); + long CreateSimpleBlock(long long, long long); +}; + +class Segment { + friend class Cues; + friend class Track; + friend class VideoTrack; + + Segment(const Segment&); + Segment& operator=(const Segment&); + + private: + Segment(IMkvReader*, long long elem_start, + // long long elem_size, + long long pos, long long size); + + public: + IMkvReader* const m_pReader; + const long long m_element_start; + // const long long m_element_size; + const long long m_start; // posn of segment payload + const long long m_size; // size of segment payload + Cluster m_eos; // TODO: make private? + + static long long CreateInstance(IMkvReader*, long long, Segment*&); + ~Segment(); + + long Load(); // loads headers and all clusters + + // for incremental loading + // long long Unparsed() const; + bool DoneParsing() const; + long long ParseHeaders(); // stops when first cluster is found + // long FindNextCluster(long long& pos, long& size) const; + long LoadCluster(long long& pos, long& size); // load one cluster + long LoadCluster(); + + long ParseNext(const Cluster* pCurr, const Cluster*& pNext, long long& pos, + long& size); + + const SeekHead* GetSeekHead() const; + const Tracks* GetTracks() const; + const SegmentInfo* GetInfo() const; + const Cues* GetCues() const; + const Chapters* GetChapters() const; + const Tags* GetTags() const; + + long long GetDuration() const; + + unsigned long GetCount() const; + const Cluster* GetFirst() const; + const Cluster* GetLast() const; + const Cluster* GetNext(const Cluster*); + + const Cluster* FindCluster(long long time_nanoseconds) const; + // const BlockEntry* Seek(long long time_nanoseconds, const Track*) const; + + const Cluster* FindOrPreloadCluster(long long pos); + + long ParseCues(long long cues_off, // offset relative to start of segment + long long& parse_pos, long& parse_len); + + private: + long long m_pos; // absolute file posn; what has been consumed so far + Cluster* m_pUnknownSize; + + SeekHead* m_pSeekHead; + SegmentInfo* m_pInfo; + Tracks* m_pTracks; + Cues* m_pCues; + Chapters* m_pChapters; + Tags* m_pTags; + Cluster** m_clusters; + long m_clusterCount; // number of entries for which m_index >= 0 + long m_clusterPreloadCount; // number of entries for which m_index < 0 + long m_clusterSize; // array size + + long DoLoadCluster(long long&, long&); + long DoLoadClusterUnknownSize(long long&, long&); + long DoParseNext(const Cluster*&, long long&, long&); + + bool AppendCluster(Cluster*); + bool PreloadCluster(Cluster*, ptrdiff_t); + + // void ParseSeekHead(long long pos, long long size); + // void ParseSeekEntry(long long pos, long long size); + // void ParseCues(long long); + + const BlockEntry* GetBlock(const CuePoint&, const CuePoint::TrackPosition&); +}; + +} // namespace mkvparser + +inline long mkvparser::Segment::LoadCluster() { + long long pos; + long size; + + return LoadCluster(pos, size); +} + +#endif // MKVPARSER_MKVPARSER_H_ diff --git a/src/sys/libwebm/mkvparser/mkvreader.cc b/src/sys/libwebm/mkvparser/mkvreader.cc new file mode 100644 index 0000000..9d19c1b --- /dev/null +++ b/src/sys/libwebm/mkvparser/mkvreader.cc @@ -0,0 +1,135 @@ +// Copyright (c) 2010 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "mkvparser/mkvreader.h" + +#include + +#include + +namespace mkvparser { + +MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {} + +MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) { + GetFileSize(); +} + +MkvReader::~MkvReader() { + if (reader_owns_file_) + Close(); + m_file = NULL; +} + +int MkvReader::Open(const char* fileName) { + if (fileName == NULL) + return -1; + + if (m_file) + return -1; + +#ifdef _MSC_VER + const errno_t e = fopen_s(&m_file, fileName, "rb"); + + if (e) + return -1; // error +#else + m_file = fopen(fileName, "rb"); + + if (m_file == NULL) + return -1; +#endif + return !GetFileSize(); +} + +bool MkvReader::GetFileSize() { + if (m_file == NULL) + return false; +#ifdef _MSC_VER + int status = _fseeki64(m_file, 0L, SEEK_END); + + if (status) + return false; // error + + m_length = _ftelli64(m_file); +#else + fseek(m_file, 0L, SEEK_END); + m_length = ftell(m_file); +#endif + assert(m_length >= 0); + + if (m_length < 0) + return false; + +#ifdef _MSC_VER + status = _fseeki64(m_file, 0L, SEEK_SET); + + if (status) + return false; // error +#else + fseek(m_file, 0L, SEEK_SET); +#endif + + return true; +} + +void MkvReader::Close() { + if (m_file != NULL) { + fclose(m_file); + m_file = NULL; + } +} + +int MkvReader::Length(long long* total, long long* available) { + if (m_file == NULL) + return -1; + + if (total) + *total = m_length; + + if (available) + *available = m_length; + + return 0; +} + +int MkvReader::Read(long long offset, long len, unsigned char* buffer) { + if (m_file == NULL) + return -1; + + if (offset < 0) + return -1; + + if (len < 0) + return -1; + + if (len == 0) + return 0; + + if (offset >= m_length) + return -1; + +#ifdef _MSC_VER + const int status = _fseeki64(m_file, offset, SEEK_SET); + + if (status) + return -1; // error +#elif defined(_WIN32) + fseeko64(m_file, static_cast(offset), SEEK_SET); +#else + fseeko(m_file, static_cast(offset), SEEK_SET); +#endif + + const size_t size = fread(buffer, 1, len, m_file); + + if (size < size_t(len)) + return -1; // error + + return 0; // success +} + +} // namespace mkvparser diff --git a/src/sys/libwebm/mkvparser/mkvreader.h b/src/sys/libwebm/mkvparser/mkvreader.h new file mode 100644 index 0000000..9831ecf --- /dev/null +++ b/src/sys/libwebm/mkvparser/mkvreader.h @@ -0,0 +1,45 @@ +// Copyright (c) 2010 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef MKVPARSER_MKVREADER_H_ +#define MKVPARSER_MKVREADER_H_ + +#include + +#include "mkvparser/mkvparser.h" + +namespace mkvparser { + +class MkvReader : public IMkvReader { + public: + MkvReader(); + explicit MkvReader(FILE* fp); + virtual ~MkvReader(); + + int Open(const char*); + void Close(); + + virtual int Read(long long position, long length, unsigned char* buffer); + virtual int Length(long long* total, long long* available); + + private: + MkvReader(const MkvReader&); + MkvReader& operator=(const MkvReader&); + + // Determines the size of the file. This is called either by the constructor + // or by the Open function depending on file ownership. Returns true on + // success. + bool GetFileSize(); + + long long m_length; + FILE* m_file; + bool reader_owns_file_; +}; + +} // namespace mkvparser + +#endif // MKVPARSER_MKVREADER_H_ diff --git a/src/sys/libwebm/mkvparser_sample.cc b/src/sys/libwebm/mkvparser_sample.cc new file mode 100644 index 0000000..f285c3e --- /dev/null +++ b/src/sys/libwebm/mkvparser_sample.cc @@ -0,0 +1,459 @@ +// Copyright (c) 2010 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// +// This sample application demonstrates how to use the Matroska parser +// library, which allows clients to handle a Matroska format file. +#include +#include +#include +#include + +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" + +namespace { +const wchar_t* utf8towcs(const char* str) { + if (str == NULL) + return NULL; + + // TODO: this probably requires that the locale be + // configured somehow: + + const size_t size = mbstowcs(NULL, str, 0); + + if (size == 0 || size == static_cast(-1)) + return NULL; + + wchar_t* const val = new (std::nothrow) wchar_t[size + 1]; + if (val == NULL) + return NULL; + + mbstowcs(val, str, size); + val[size] = L'\0'; + + return val; +} + +bool InputHasCues(const mkvparser::Segment* const segment) { + const mkvparser::Cues* const cues = segment->GetCues(); + if (cues == NULL) + return false; + + while (!cues->DoneParsing()) + cues->LoadCuePoint(); + + const mkvparser::CuePoint* const cue_point = cues->GetFirst(); + if (cue_point == NULL) + return false; + + return true; +} + +bool MasteringMetadataValuePresent(double value) { + return value != mkvparser::MasteringMetadata::kValueNotPresent; +} + +bool ColourValuePresent(long long value) { + return value != mkvparser::Colour::kValueNotPresent; +} +} // namespace + +int main(int argc, char* argv[]) { + if (argc == 1) { + printf("Mkv Parser Sample Application\n"); + printf(" Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + mkvparser::MkvReader reader; + + if (reader.Open(argv[1])) { + printf("\n Filename is invalid or error while opening.\n"); + return EXIT_FAILURE; + } + + int maj, min, build, rev; + + mkvparser::GetVersion(maj, min, build, rev); + printf("\t\t libwebm version: %d.%d.%d.%d\n", maj, min, build, rev); + + long long pos = 0; + + mkvparser::EBMLHeader ebmlHeader; + + long long ret = ebmlHeader.Parse(&reader, pos); + if (ret < 0) { + printf("\n EBMLHeader::Parse() failed."); + return EXIT_FAILURE; + } + + printf("\t\t\t EBML Header\n"); + printf("\t\tEBML Version\t\t: %lld\n", ebmlHeader.m_version); + printf("\t\tEBML MaxIDLength\t: %lld\n", ebmlHeader.m_maxIdLength); + printf("\t\tEBML MaxSizeLength\t: %lld\n", ebmlHeader.m_maxSizeLength); + printf("\t\tDoc Type\t\t: %s\n", ebmlHeader.m_docType); + printf("\t\tPos\t\t\t: %lld\n", pos); + + typedef mkvparser::Segment seg_t; + seg_t* pSegment_; + + ret = seg_t::CreateInstance(&reader, pos, pSegment_); + if (ret) { + printf("\n Segment::CreateInstance() failed."); + return EXIT_FAILURE; + } + + const std::unique_ptr pSegment(pSegment_); + + ret = pSegment->Load(); + if (ret < 0) { + printf("\n Segment::Load() failed."); + return EXIT_FAILURE; + } + + const mkvparser::SegmentInfo* const pSegmentInfo = pSegment->GetInfo(); + if (pSegmentInfo == NULL) { + printf("\n Segment::GetInfo() failed."); + return EXIT_FAILURE; + } + + const long long timeCodeScale = pSegmentInfo->GetTimeCodeScale(); + const long long duration_ns = pSegmentInfo->GetDuration(); + + const char* const pTitle_ = pSegmentInfo->GetTitleAsUTF8(); + const wchar_t* const pTitle = utf8towcs(pTitle_); + + const char* const pMuxingApp_ = pSegmentInfo->GetMuxingAppAsUTF8(); + const wchar_t* const pMuxingApp = utf8towcs(pMuxingApp_); + + const char* const pWritingApp_ = pSegmentInfo->GetWritingAppAsUTF8(); + const wchar_t* const pWritingApp = utf8towcs(pWritingApp_); + + printf("\n"); + printf("\t\t\t Segment Info\n"); + printf("\t\tTimeCodeScale\t\t: %lld \n", timeCodeScale); + printf("\t\tDuration\t\t: %lld\n", duration_ns); + + const double duration_sec = double(duration_ns) / 1000000000; + printf("\t\tDuration(secs)\t\t: %7.3lf\n", duration_sec); + + if (pTitle == NULL) + printf("\t\tTrack Name\t\t: NULL\n"); + else { + printf("\t\tTrack Name\t\t: %ls\n", pTitle); + delete[] pTitle; + } + + if (pMuxingApp == NULL) + printf("\t\tMuxing App\t\t: NULL\n"); + else { + printf("\t\tMuxing App\t\t: %ls\n", pMuxingApp); + delete[] pMuxingApp; + } + + if (pWritingApp == NULL) + printf("\t\tWriting App\t\t: NULL\n"); + else { + printf("\t\tWriting App\t\t: %ls\n", pWritingApp); + delete[] pWritingApp; + } + + // pos of segment payload + printf("\t\tPosition(Segment)\t: %lld\n", pSegment->m_start); + + // size of segment payload + printf("\t\tSize(Segment)\t\t: %lld\n", pSegment->m_size); + + const mkvparser::Tracks* pTracks = pSegment->GetTracks(); + + unsigned long track_num = 0; + const unsigned long num_tracks = pTracks->GetTracksCount(); + + printf("\n\t\t\t Track Info\n"); + + while (track_num != num_tracks) { + const mkvparser::Track* const pTrack = + pTracks->GetTrackByIndex(track_num++); + + if (pTrack == NULL) + continue; + + const long trackType = pTrack->GetType(); + const long trackNumber = pTrack->GetNumber(); + const unsigned long long trackUid = pTrack->GetUid(); + const wchar_t* const pTrackName = utf8towcs(pTrack->GetNameAsUTF8()); + + printf("\t\tTrack Type\t\t: %ld\n", trackType); + printf("\t\tTrack Number\t\t: %ld\n", trackNumber); + printf("\t\tTrack Uid\t\t: %lld\n", trackUid); + + if (pTrackName == NULL) + printf("\t\tTrack Name\t\t: NULL\n"); + else { + printf("\t\tTrack Name\t\t: %ls \n", pTrackName); + delete[] pTrackName; + } + + const char* const pCodecId = pTrack->GetCodecId(); + + if (pCodecId == NULL) + printf("\t\tCodec Id\t\t: NULL\n"); + else + printf("\t\tCodec Id\t\t: %s\n", pCodecId); + + size_t codec_private_size = 0; + if (pTrack->GetCodecPrivate(codec_private_size)) { + printf("\t\tCodec private length: %u bytes\n", + static_cast(codec_private_size)); + } + + const char* const pCodecName_ = pTrack->GetCodecNameAsUTF8(); + const wchar_t* const pCodecName = utf8towcs(pCodecName_); + + if (pCodecName == NULL) + printf("\t\tCodec Name\t\t: NULL\n"); + else { + printf("\t\tCodec Name\t\t: %ls\n", pCodecName); + delete[] pCodecName; + } + + if (trackType == mkvparser::Track::kVideo) { + const mkvparser::VideoTrack* const pVideoTrack = + static_cast(pTrack); + + const long long width = pVideoTrack->GetWidth(); + printf("\t\tVideo Width\t\t: %lld\n", width); + + const long long height = pVideoTrack->GetHeight(); + printf("\t\tVideo Height\t\t: %lld\n", height); + + const double rate = pVideoTrack->GetFrameRate(); + printf("\t\tVideo Rate\t\t: %f\n", rate); + + const mkvparser::Colour* const colour = pVideoTrack->GetColour(); + if (colour) { + printf("\t\tVideo Colour:\n"); + if (ColourValuePresent(colour->matrix_coefficients)) + printf("\t\t\tMatrixCoefficients: %lld\n", + colour->matrix_coefficients); + if (ColourValuePresent(colour->bits_per_channel)) + printf("\t\t\tBitsPerChannel: %lld\n", colour->bits_per_channel); + if (ColourValuePresent(colour->chroma_subsampling_horz)) + printf("\t\t\tChromaSubsamplingHorz: %lld\n", + colour->chroma_subsampling_horz); + if (ColourValuePresent(colour->chroma_subsampling_vert)) + printf("\t\t\tChromaSubsamplingVert: %lld\n", + colour->chroma_subsampling_vert); + if (ColourValuePresent(colour->cb_subsampling_horz)) + printf("\t\t\tCbSubsamplingHorz: %lld\n", + colour->cb_subsampling_horz); + if (ColourValuePresent(colour->cb_subsampling_vert)) + printf("\t\t\tCbSubsamplingVert: %lld\n", + colour->cb_subsampling_vert); + if (ColourValuePresent(colour->chroma_siting_horz)) + printf("\t\t\tChromaSitingHorz: %lld\n", colour->chroma_siting_horz); + if (ColourValuePresent(colour->chroma_siting_vert)) + printf("\t\t\tChromaSitingVert: %lld\n", colour->chroma_siting_vert); + if (ColourValuePresent(colour->range)) + printf("\t\t\tRange: %lld\n", colour->range); + if (ColourValuePresent(colour->transfer_characteristics)) + printf("\t\t\tTransferCharacteristics: %lld\n", + colour->transfer_characteristics); + if (ColourValuePresent(colour->primaries)) + printf("\t\t\tPrimaries: %lld\n", colour->primaries); + if (ColourValuePresent(colour->max_cll)) + printf("\t\t\tMaxCLL: %lld\n", colour->max_cll); + if (ColourValuePresent(colour->max_fall)) + printf("\t\t\tMaxFALL: %lld\n", colour->max_fall); + if (colour->mastering_metadata) { + const mkvparser::MasteringMetadata* const mm = + colour->mastering_metadata; + printf("\t\t\tMastering Metadata:\n"); + if (MasteringMetadataValuePresent(mm->luminance_max)) + printf("\t\t\t\tLuminanceMax: %f\n", mm->luminance_max); + if (MasteringMetadataValuePresent(mm->luminance_min)) + printf("\t\t\t\tLuminanceMin: %f\n", mm->luminance_min); + if (mm->r) { + printf("\t\t\t\t\tPrimaryRChromaticityX: %f\n", mm->r->x); + printf("\t\t\t\t\tPrimaryRChromaticityY: %f\n", mm->r->y); + } + if (mm->g) { + printf("\t\t\t\t\tPrimaryGChromaticityX: %f\n", mm->g->x); + printf("\t\t\t\t\tPrimaryGChromaticityY: %f\n", mm->g->y); + } + if (mm->b) { + printf("\t\t\t\t\tPrimaryBChromaticityX: %f\n", mm->b->x); + printf("\t\t\t\t\tPrimaryBChromaticityY: %f\n", mm->b->y); + } + if (mm->white_point) { + printf("\t\t\t\t\tWhitePointChromaticityX: %f\n", + mm->white_point->x); + printf("\t\t\t\t\tWhitePointChromaticityY: %f\n", + mm->white_point->y); + } + } + } + + const mkvparser::Projection* const projection = + pVideoTrack->GetProjection(); + if (projection) { + printf("\t\tVideo Projection:\n"); + if (projection->type != mkvparser::Projection::kTypeNotPresent) + printf("\t\t\tProjectionType: %d\n", + static_cast(projection->type)); + if (projection->private_data) { + printf("\t\t\tProjectionPrivate: %u bytes\n", + static_cast(projection->private_data_length)); + } + if (projection->pose_yaw != mkvparser::Projection::kValueNotPresent) + printf("\t\t\tProjectionPoseYaw: %f\n", projection->pose_yaw); + if (projection->pose_pitch != mkvparser::Projection::kValueNotPresent) + printf("\t\t\tProjectionPosePitch: %f\n", projection->pose_pitch); + if (projection->pose_roll != mkvparser::Projection::kValueNotPresent) + printf("\t\t\tProjectionPosePitch: %f\n", projection->pose_roll); + } + } + + if (trackType == mkvparser::Track::kAudio) { + const mkvparser::AudioTrack* const pAudioTrack = + static_cast(pTrack); + + const long long channels = pAudioTrack->GetChannels(); + printf("\t\tAudio Channels\t\t: %lld\n", channels); + + const long long bitDepth = pAudioTrack->GetBitDepth(); + printf("\t\tAudio BitDepth\t\t: %lld\n", bitDepth); + + const double sampleRate = pAudioTrack->GetSamplingRate(); + printf("\t\tAddio Sample Rate\t: %.3f\n", sampleRate); + + const long long codecDelay = pAudioTrack->GetCodecDelay(); + printf("\t\tAudio Codec Delay\t\t: %lld\n", codecDelay); + + const long long seekPreRoll = pAudioTrack->GetSeekPreRoll(); + printf("\t\tAudio Seek Pre Roll\t\t: %lld\n", seekPreRoll); + } + } + + printf("\n\n\t\t\t Cluster Info\n"); + const unsigned long clusterCount = pSegment->GetCount(); + + printf("\t\tCluster Count\t: %ld\n\n", clusterCount); + + if (clusterCount == 0) { + printf("\t\tSegment has no clusters.\n"); + return EXIT_FAILURE; + } + + const mkvparser::Cluster* pCluster = pSegment->GetFirst(); + + while (pCluster != NULL && !pCluster->EOS()) { + const long long timeCode = pCluster->GetTimeCode(); + printf("\t\tCluster Time Code\t: %lld\n", timeCode); + + const long long time_ns = pCluster->GetTime(); + printf("\t\tCluster Time (ns)\t: %lld\n", time_ns); + + const mkvparser::BlockEntry* pBlockEntry; + + long status = pCluster->GetFirst(pBlockEntry); + + if (status < 0) // error + { + printf("\t\tError parsing first block of cluster\n"); + fflush(stdout); + return EXIT_FAILURE; + } + + while (pBlockEntry != NULL && !pBlockEntry->EOS()) { + const mkvparser::Block* const pBlock = pBlockEntry->GetBlock(); + const long long trackNum = pBlock->GetTrackNumber(); + const unsigned long tn = static_cast(trackNum); + const mkvparser::Track* const pTrack = pTracks->GetTrackByNumber(tn); + + if (pTrack == NULL) + printf("\t\t\tBlock\t\t:UNKNOWN TRACK TYPE\n"); + else { + const long long trackType = pTrack->GetType(); + const int frameCount = pBlock->GetFrameCount(); + const long long time_ns = pBlock->GetTime(pCluster); + const long long discard_padding = pBlock->GetDiscardPadding(); + + printf("\t\t\tBlock\t\t:%s,%s,%15lld,%lld\n", + (trackType == mkvparser::Track::kVideo) ? "V" : "A", + pBlock->IsKey() ? "I" : "P", time_ns, discard_padding); + + for (int i = 0; i < frameCount; ++i) { + const mkvparser::Block::Frame& theFrame = pBlock->GetFrame(i); + const long size = theFrame.len; + const long long offset = theFrame.pos; + printf("\t\t\t %15ld,%15llx\n", size, offset); + } + } + + status = pCluster->GetNext(pBlockEntry, pBlockEntry); + + if (status < 0) { + printf("\t\t\tError parsing next block of cluster\n"); + fflush(stdout); + return EXIT_FAILURE; + } + } + + pCluster = pSegment->GetNext(pCluster); + } + + if (InputHasCues(pSegment.get())) { + // Walk them. + const mkvparser::Cues* const cues = pSegment->GetCues(); + const mkvparser::CuePoint* cue = cues->GetFirst(); + int cue_point_num = 1; + + printf("\t\tCues\n"); + do { + for (track_num = 0; track_num < num_tracks; ++track_num) { + const mkvparser::Track* const track = + pTracks->GetTrackByIndex(track_num); + const mkvparser::CuePoint::TrackPosition* const track_pos = + cue->Find(track); + + if (track_pos != NULL) { + const char track_type = + (track->GetType() == mkvparser::Track::kVideo) ? 'V' : 'A'; + printf( + "\t\t\tCue Point %4d Track %3lu(%c) Time %14lld " + "Block %4lld Pos %8llx\n", + cue_point_num, track->GetNumber(), track_type, + cue->GetTime(pSegment.get()), track_pos->m_block, + track_pos->m_pos); + } + } + + cue = cues->GetNext(cue); + ++cue_point_num; + } while (cue != NULL); + } + + const mkvparser::Tags* const tags = pSegment->GetTags(); + if (tags && tags->GetTagCount() > 0) { + printf("\t\tTags\n"); + for (int i = 0; i < tags->GetTagCount(); ++i) { + const mkvparser::Tags::Tag* const tag = tags->GetTag(i); + printf("\t\t\tTag\n"); + for (int j = 0; j < tag->GetSimpleTagCount(); j++) { + const mkvparser::Tags::SimpleTag* const simple_tag = + tag->GetSimpleTag(j); + printf("\t\t\t\tSimple Tag \"%s\" Value \"%s\"\n", + simple_tag->GetTagName(), simple_tag->GetTagString()); + } + } + } + + fflush(stdout); + return EXIT_SUCCESS; +} diff --git a/src/sys/libwebm/mkvreader.hpp b/src/sys/libwebm/mkvreader.hpp new file mode 100644 index 0000000..d115872 --- /dev/null +++ b/src/sys/libwebm/mkvreader.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_MKVREADER_HPP_ +#define LIBWEBM_MKVREADER_HPP_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "mkvparser/mkvreader.h" + +#endif // LIBWEBM_MKVREADER_HPP_ diff --git a/src/sys/libwebm/mkvwriter.hpp b/src/sys/libwebm/mkvwriter.hpp new file mode 100644 index 0000000..9927b3e --- /dev/null +++ b/src/sys/libwebm/mkvwriter.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_MKVWRITER_HPP_ +#define LIBWEBM_MKVWRITER_HPP_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "mkvmuxer/mkvwriter.h" + +#endif // LIBWEBM_MKVWRITER_HPP_ diff --git a/src/sys/libwebm/sample_muxer_metadata.cc b/src/sys/libwebm/sample_muxer_metadata.cc new file mode 100644 index 0000000..6eadcfd --- /dev/null +++ b/src/sys/libwebm/sample_muxer_metadata.cc @@ -0,0 +1,391 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// +// This sample application demonstrates how to use the matroska parser +// library, which allows clients to handle a matroska format file. + +#include "sample_muxer_metadata.h" + +#include +#include + +#include "mkvmuxer/mkvmuxer.h" +#include "webvtt/vttreader.h" + +SampleMuxerMetadata::SampleMuxerMetadata() : segment_(NULL) {} + +bool SampleMuxerMetadata::Init(mkvmuxer::Segment* segment) { + if (segment == NULL || segment_ != NULL) + return false; + + segment_ = segment; + return true; +} + +bool SampleMuxerMetadata::Load(const char* file, Kind kind) { + if (kind == kChapters) + return LoadChapters(file); + + uint64_t track_num; + + if (!AddTrack(kind, &track_num)) { + printf("Unable to add track for WebVTT file \"%s\"\n", file); + return false; + } + + return Parse(file, kind, track_num); +} + +bool SampleMuxerMetadata::AddChapters() { + typedef cue_list_t::const_iterator iter_t; + iter_t i = chapter_cues_.begin(); + const iter_t j = chapter_cues_.end(); + + while (i != j) { + const cue_t& chapter = *i++; + + if (!AddChapter(chapter)) + return false; + } + + return true; +} + +bool SampleMuxerMetadata::Write(int64_t time_ns) { + typedef cues_set_t::iterator iter_t; + + iter_t i = cues_set_.begin(); + const iter_t j = cues_set_.end(); + + while (i != j) { + const cues_set_t::value_type& v = *i; + + if (time_ns >= 0 && v > time_ns) + return true; // nothing else to do just yet + + if (!v.Write(segment_)) { + printf("\nCould not add metadata.\n"); + return false; // error + } + + cues_set_.erase(i++); + } + + return true; +} + +bool SampleMuxerMetadata::LoadChapters(const char* file) { + if (!chapter_cues_.empty()) { + printf("Support for more than one chapters file is not yet implemented\n"); + return false; + } + + cue_list_t cues; + + if (!ParseChapters(file, &cues)) + return false; + + // TODO(matthewjheaney): support more than one chapters file + chapter_cues_.swap(cues); + + return true; +} + +bool SampleMuxerMetadata::ParseChapters(const char* file, + cue_list_t* cues_ptr) { + cue_list_t& cues = *cues_ptr; + cues.clear(); + + libwebvtt::VttReader r; + int e = r.Open(file); + + if (e) { + printf("Unable to open WebVTT file: \"%s\"\n", file); + return false; + } + + libwebvtt::Parser p(&r); + e = p.Init(); + + if (e < 0) { // error + printf("Error parsing WebVTT file: \"%s\"\n", file); + return false; + } + + libwebvtt::Time t; + t.hours = -1; + + for (;;) { + cue_t c; + e = p.Parse(&c); + + if (e < 0) { // error + printf("Error parsing WebVTT file: \"%s\"\n", file); + return false; + } + + if (e > 0) // EOF + return true; + + if (c.start_time < t) { + printf("bad WebVTT cue timestamp (out-of-order)\n"); + return false; + } + + if (c.stop_time < c.start_time) { + printf("bad WebVTT cue timestamp (stop < start)\n"); + return false; + } + + t = c.start_time; + cues.push_back(c); + } +} + +bool SampleMuxerMetadata::AddChapter(const cue_t& cue) { + // TODO(matthewjheaney): support language and country + + mkvmuxer::Chapter* const chapter = segment_->AddChapter(); + + if (chapter == NULL) { + printf("Unable to add chapter\n"); + return false; + } + + if (cue.identifier.empty()) { + chapter->set_id(NULL); + } else { + const char* const id = cue.identifier.c_str(); + if (!chapter->set_id(id)) { + printf("Unable to set chapter id\n"); + return false; + } + } + + typedef libwebvtt::presentation_t time_ms_t; + const time_ms_t start_time_ms = cue.start_time.presentation(); + const time_ms_t stop_time_ms = cue.stop_time.presentation(); + + enum { kNsPerMs = 1000000 }; + const uint64_t start_time_ns = start_time_ms * kNsPerMs; + const uint64_t stop_time_ns = stop_time_ms * kNsPerMs; + + chapter->set_time(*segment_, start_time_ns, stop_time_ns); + + typedef libwebvtt::Cue::payload_t::const_iterator iter_t; + iter_t i = cue.payload.begin(); + const iter_t j = cue.payload.end(); + + std::string title; + + for (;;) { + title += *i++; + + if (i == j) + break; + + enum { kLF = '\x0A' }; + title += kLF; + } + + if (!chapter->add_string(title.c_str(), NULL, NULL)) { + printf("Unable to set chapter title\n"); + return false; + } + + return true; +} + +bool SampleMuxerMetadata::AddTrack(Kind kind, uint64_t* track_num) { + *track_num = 0; + + // Track number value 0 means "let muxer choose track number" + mkvmuxer::Track* const track = segment_->AddTrack(0); + + if (track == NULL) // error + return false; + + // Return the track number value chosen by the muxer + *track_num = track->number(); + + int type; + const char* codec_id; + + switch (kind) { + case kSubtitles: + type = 0x11; + codec_id = "D_WEBVTT/SUBTITLES"; + break; + + case kCaptions: + type = 0x11; + codec_id = "D_WEBVTT/CAPTIONS"; + break; + + case kDescriptions: + type = 0x21; + codec_id = "D_WEBVTT/DESCRIPTIONS"; + break; + + case kMetadata: + type = 0x21; + codec_id = "D_WEBVTT/METADATA"; + break; + + default: + return false; + } + + track->set_type(type); + track->set_codec_id(codec_id); + + // TODO(matthewjheaney): set name and language + + return true; +} + +bool SampleMuxerMetadata::Parse(const char* file, Kind /* kind */, + uint64_t track_num) { + libwebvtt::VttReader r; + int e = r.Open(file); + + if (e) { + printf("Unable to open WebVTT file: \"%s\"\n", file); + return false; + } + + libwebvtt::Parser p(&r); + + e = p.Init(); + + if (e < 0) { // error + printf("Error parsing WebVTT file: \"%s\"\n", file); + return false; + } + + SortableCue cue; + cue.track_num = track_num; + + libwebvtt::Time t; + t.hours = -1; + + for (;;) { + cue_t& c = cue.cue; + e = p.Parse(&c); + + if (e < 0) { // error + printf("Error parsing WebVTT file: \"%s\"\n", file); + return false; + } + + if (e > 0) // EOF + return true; + + if (c.start_time >= t) { + t = c.start_time; + } else { + printf("bad WebVTT cue timestamp (out-of-order)\n"); + return false; + } + + if (c.stop_time < c.start_time) { + printf("bad WebVTT cue timestamp (stop < start)\n"); + return false; + } + + cues_set_.insert(cue); + } +} + +void SampleMuxerMetadata::MakeFrame(const cue_t& c, std::string* pf) { + pf->clear(); + WriteCueIdentifier(c.identifier, pf); + WriteCueSettings(c.settings, pf); + WriteCuePayload(c.payload, pf); +} + +void SampleMuxerMetadata::WriteCueIdentifier(const std::string& identifier, + std::string* pf) { + pf->append(identifier); + pf->push_back('\x0A'); // LF +} + +void SampleMuxerMetadata::WriteCueSettings(const cue_t::settings_t& settings, + std::string* pf) { + if (settings.empty()) { + pf->push_back('\x0A'); // LF + return; + } + + typedef cue_t::settings_t::const_iterator iter_t; + + iter_t i = settings.begin(); + const iter_t j = settings.end(); + + for (;;) { + const libwebvtt::Setting& setting = *i++; + + pf->append(setting.name); + pf->push_back(':'); + pf->append(setting.value); + + if (i == j) + break; + + pf->push_back(' '); // separate settings with whitespace + } + + pf->push_back('\x0A'); // LF +} + +void SampleMuxerMetadata::WriteCuePayload(const cue_t::payload_t& payload, + std::string* pf) { + typedef cue_t::payload_t::const_iterator iter_t; + + iter_t i = payload.begin(); + const iter_t j = payload.end(); + + while (i != j) { + const std::string& line = *i++; + pf->append(line); + pf->push_back('\x0A'); // LF + } +} + +bool SampleMuxerMetadata::SortableCue::Write(mkvmuxer::Segment* segment) const { + // Cue start time expressed in milliseconds + const int64_t start_ms = cue.start_time.presentation(); + + // Cue start time expressed in nanoseconds (MKV time) + const int64_t start_ns = start_ms * 1000000; + + // Cue stop time expressed in milliseconds + const int64_t stop_ms = cue.stop_time.presentation(); + + // Cue stop time expressed in nanonseconds + const int64_t stop_ns = stop_ms * 1000000; + + // Metadata blocks always specify the block duration. + const int64_t duration_ns = stop_ns - start_ns; + + std::string frame; + MakeFrame(cue, &frame); + + typedef const uint8_t* data_t; + const data_t buf = reinterpret_cast(frame.data()); + const uint64_t len = frame.length(); + + mkvmuxer::Frame muxer_frame; + if (!muxer_frame.Init(buf, len)) + return 0; + muxer_frame.set_track_number(track_num); + muxer_frame.set_timestamp(start_ns); + muxer_frame.set_duration(duration_ns); + muxer_frame.set_is_key(true); // All metadata frames are keyframes. + return segment->AddGenericFrame(&muxer_frame); +} \ No newline at end of file diff --git a/src/sys/libwebm/sample_muxer_metadata.h b/src/sys/libwebm/sample_muxer_metadata.h new file mode 100644 index 0000000..d76ccf5 --- /dev/null +++ b/src/sys/libwebm/sample_muxer_metadata.h @@ -0,0 +1,137 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#ifndef SAMPLE_MUXER_METADATA_H_ // NOLINT +#define SAMPLE_MUXER_METADATA_H_ + +#include + +#include +#include +#include + +#include "webvtt/webvttparser.h" + +namespace mkvmuxer { +class Chapter; +class Frame; +class Segment; +class Track; +} // namespace mkvmuxer + +class SampleMuxerMetadata { + public: + enum Kind { kSubtitles, kCaptions, kDescriptions, kMetadata, kChapters }; + + SampleMuxerMetadata(); + + // Bind this metadata object to the muxer instance. Returns false + // if segment equals NULL, or Init has already been called. + bool Init(mkvmuxer::Segment* segment); + + // Parse the WebVTT file |filename| having the indicated |kind|, and + // create a corresponding track (or chapters element) in the + // segment. Returns false on error. + bool Load(const char* filename, Kind kind); + + bool AddChapters(); + + // Write any WebVTT cues whose time is less or equal to |time_ns| as + // a metadata block in its corresponding track. If |time_ns| is + // negative, write all remaining cues. Returns false on error. + bool Write(int64_t time_ns); + + private: + typedef libwebvtt::Cue cue_t; + + // Used to sort cues as they are loaded. + struct SortableCue { + bool operator>(int64_t time_ns) const { + // Cue start time expressed in milliseconds + const int64_t start_ms = cue.start_time.presentation(); + + // Cue start time expressed in nanoseconds (MKV time) + const int64_t start_ns = start_ms * 1000000; + + return (start_ns > time_ns); + } + + bool operator<(const SortableCue& rhs) const { + if (cue.start_time < rhs.cue.start_time) + return true; + + if (cue.start_time > rhs.cue.start_time) + return false; + + return (track_num < rhs.track_num); + } + + // Write this cue as a metablock to |segment|. Returns false on + // error. + bool Write(mkvmuxer::Segment* segment) const; + + uint64_t track_num; + cue_t cue; + }; + + typedef std::multiset cues_set_t; + typedef std::list cue_list_t; + + // Parse the WebVTT cues in the named |file|, returning false on + // error. We handle chapters as a special case, because they are + // stored in their own, dedicated level-1 element. + bool LoadChapters(const char* file); + + // Parse the WebVTT chapters in |file| to populate |cues|. Returns + // false on error. + static bool ParseChapters(const char* file, cue_list_t* cues); + + // Adds WebVTT cue |chapter| to the chapters element of the output + // file's segment element. Returns false on error. + bool AddChapter(const cue_t& chapter); + + // Add a metadata track to the segment having the indicated |kind|, + // returning the |track_num| that has been chosen for this track. + // Returns false on error. + bool AddTrack(Kind kind, uint64_t* track_num); + + // Parse the WebVTT |file| having the indicated |kind| and + // |track_num|, adding each parsed cue to cues set. Returns false + // on error. + bool Parse(const char* file, Kind kind, uint64_t track_num); + + // Converts a WebVTT cue to a Matroska metadata block. + static void MakeFrame(const cue_t& cue, std::string* frame); + + // Populate the cue identifier part of the metadata block. + static void WriteCueIdentifier(const std::string& identifier, + std::string* frame); + + // Populate the cue settings part of the metadata block. + static void WriteCueSettings(const cue_t::settings_t& settings, + std::string* frame); + + // Populate the payload part of the metadata block. + static void WriteCuePayload(const cue_t::payload_t& payload, + std::string* frame); + + mkvmuxer::Segment* segment_; + + // Set of cues ordered by time and then by track number. + cues_set_t cues_set_; + + // The cues that will be used to populate the Chapters level-1 + // element of the output file. + cue_list_t chapter_cues_; + + // Disable copy ctor and copy assign. + SampleMuxerMetadata(const SampleMuxerMetadata&); + SampleMuxerMetadata& operator=(const SampleMuxerMetadata&); +}; + +#endif // SAMPLE_MUXER_METADATA_H_ // NOLINT diff --git a/src/sys/libwebm/testing/mkvmuxer_tests.cc b/src/sys/libwebm/testing/mkvmuxer_tests.cc new file mode 100644 index 0000000..3374058 --- /dev/null +++ b/src/sys/libwebm/testing/mkvmuxer_tests.cc @@ -0,0 +1,1010 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" + +#include "common/file_util.h" +#include "common/libwebm_util.h" +#include "mkvmuxer/mkvmuxer.h" +#include "mkvmuxer/mkvwriter.h" +#include "mkvparser/mkvreader.h" +#include "testing/test_util.h" + +using mkvmuxer::AudioTrack; +using mkvmuxer::Chapter; +using mkvmuxer::Frame; +using mkvmuxer::MkvWriter; +using mkvmuxer::Segment; +using mkvmuxer::SegmentInfo; +using mkvmuxer::Tag; +using mkvmuxer::Track; +using mkvmuxer::VideoTrack; + +namespace test { + +// Base class containing boiler plate stuff. +class MuxerTest : public testing::Test { + public: + MuxerTest() { Init(); } + + ~MuxerTest() { CloseWriter(); } + + // Simple init function for use by constructor. Calls made here to allow use + // of ASSERT_* macros-- this is necessary here because all failures in Init() + // are fatal, but the ASSERT_* gtest macros cannot be used in a constructor. + void Init() { + ASSERT_TRUE(GetTestDataDir().length() > 0); + filename_ = libwebm::GetTempFileName(); + ASSERT_GT(filename_.length(), 0u); + temp_file_ = libwebm::FilePtr(std::fopen(filename_.c_str(), "wb"), + libwebm::FILEDeleter()); + ASSERT_TRUE(temp_file_.get() != nullptr); + writer_.reset(new MkvWriter(temp_file_.get())); + is_writer_open_ = true; + memset(dummy_data_, 0, kFrameLength); + } + + void AddDummyFrameAndFinalize(int track_number) { + EXPECT_TRUE(segment_.AddFrame(&dummy_data_[0], kFrameLength, track_number, + 0, false)); + EXPECT_TRUE(segment_.Finalize()); + } + + void AddVideoTrack() { + const int vid_track = static_cast( + segment_.AddVideoTrack(kWidth, kHeight, kVideoTrackNumber)); + ASSERT_EQ(kVideoTrackNumber, vid_track); + VideoTrack* const video = + dynamic_cast(segment_.GetTrackByNumber(vid_track)); + ASSERT_TRUE(video != NULL); + video->set_uid(kVideoTrackNumber); + } + + void AddAudioTrack() { + const int aud_track = static_cast( + segment_.AddAudioTrack(kSampleRate, kChannels, kAudioTrackNumber)); + ASSERT_EQ(kAudioTrackNumber, aud_track); + AudioTrack* const audio = + dynamic_cast(segment_.GetTrackByNumber(aud_track)); + ASSERT_TRUE(audio != NULL); + audio->set_uid(kAudioTrackNumber); + audio->set_codec_id(kOpusCodecId); + } + + void CloseWriter() { + if (is_writer_open_) + writer_->Close(); + is_writer_open_ = false; + } + + bool SegmentInit(bool output_cues, bool accurate_cluster_duration, + bool fixed_size_cluster_timecode) { + if (!segment_.Init(writer_.get())) + return false; + SegmentInfo* const info = segment_.GetSegmentInfo(); + info->set_writing_app(kAppString); + info->set_muxing_app(kAppString); + segment_.OutputCues(output_cues); + segment_.AccurateClusterDuration(accurate_cluster_duration); + segment_.UseFixedSizeClusterTimecode(fixed_size_cluster_timecode); + return true; + } + + protected: + virtual void TearDown() { + remove(filename_.c_str()); + testing::Test::TearDown(); + } + + std::unique_ptr writer_; + bool is_writer_open_ = false; + Segment segment_; + std::string filename_; + libwebm::FilePtr temp_file_; + std::uint8_t dummy_data_[kFrameLength]; +}; + +TEST_F(MuxerTest, SegmentInfo) { + EXPECT_TRUE(SegmentInit(false, false, false)); + SegmentInfo* const info = segment_.GetSegmentInfo(); + info->set_timecode_scale(kTimeCodeScale); + info->set_duration(2.345); + EXPECT_STREQ(kAppString, info->muxing_app()); + EXPECT_STREQ(kAppString, info->writing_app()); + EXPECT_EQ(static_cast(kTimeCodeScale), info->timecode_scale()); + EXPECT_DOUBLE_EQ(2.345, info->duration()); + AddVideoTrack(); + + AddDummyFrameAndFinalize(kVideoTrackNumber); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("segment_info.webm"), filename_)); +} + +TEST_F(MuxerTest, AddTracks) { + EXPECT_TRUE(SegmentInit(false, false, false)); + + // Add a Video Track + AddVideoTrack(); + VideoTrack* const video = + dynamic_cast(segment_.GetTrackByNumber(kVideoTrackNumber)); + ASSERT_TRUE(video != NULL); + EXPECT_EQ(static_cast(kWidth), video->width()); + EXPECT_EQ(static_cast(kHeight), video->height()); + video->set_name(kTrackName); + video->set_display_width(kWidth - 10); + video->set_display_height(kHeight - 10); + video->set_frame_rate(0.5); + EXPECT_STREQ(kTrackName, video->name()); + const uint64_t kDisplayWidth = kWidth - 10; + EXPECT_EQ(kDisplayWidth, video->display_width()); + const uint64_t kDisplayHeight = kHeight - 10; + EXPECT_EQ(kDisplayHeight, video->display_height()); + EXPECT_DOUBLE_EQ(0.5, video->frame_rate()); + EXPECT_EQ(static_cast(kVideoTrackNumber), video->uid()); + + // Add an Audio Track + const int aud_track = static_cast( + segment_.AddAudioTrack(kSampleRate, kChannels, kAudioTrackNumber)); + EXPECT_EQ(kAudioTrackNumber, aud_track); + AudioTrack* const audio = + dynamic_cast(segment_.GetTrackByNumber(aud_track)); + EXPECT_EQ(kSampleRate, audio->sample_rate()); + EXPECT_EQ(static_cast(kChannels), audio->channels()); + ASSERT_TRUE(audio != NULL); + audio->set_name(kTrackName); + audio->set_bit_depth(kBitDepth); + audio->set_uid(kAudioTrackNumber); + EXPECT_STREQ(kTrackName, audio->name()); + EXPECT_EQ(static_cast(kBitDepth), audio->bit_depth()); + EXPECT_EQ(static_cast(kAudioTrackNumber), audio->uid()); + + AddDummyFrameAndFinalize(kVideoTrackNumber); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("tracks.webm"), filename_)); +} + +TEST_F(MuxerTest, AddChapters) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + // Add a Chapter + Chapter* chapter = segment_.AddChapter(); + EXPECT_TRUE(chapter->set_id("unit_test")); + chapter->set_time(segment_, 0, 1000000000); + EXPECT_TRUE(chapter->add_string("unit_test", "english", "us")); + chapter->set_uid(1); + + AddDummyFrameAndFinalize(kVideoTrackNumber); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("chapters.webm"), filename_)); +} + +TEST_F(MuxerTest, SimpleBlock) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + // Valid Frame + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, + false)); + + // Valid Frame + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + + // Invalid Frame - Non monotonically increasing timestamp + EXPECT_FALSE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 1, false)); + + // Invalid Frame - Null pointer + EXPECT_FALSE(segment_.AddFrame(NULL, 0, kVideoTrackNumber, 8000000, false)); + + // Invalid Frame - Invalid track number + EXPECT_FALSE(segment_.AddFrame(NULL, 0, kInvalidTrackNumber, 8000000, false)); + + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("simple_block.webm"), filename_)); +} + +TEST_F(MuxerTest, SimpleBlockWithAddGenericFrame) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + Frame frame; + frame.Init(dummy_data_, kFrameLength); + frame.set_track_number(kVideoTrackNumber); + frame.set_is_key(false); + + // Valid Frame + frame.set_timestamp(0); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + + // Valid Frame + frame.set_timestamp(2000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + + // Invalid Frame - Non monotonically increasing timestamp + frame.set_timestamp(1); + EXPECT_FALSE(segment_.AddGenericFrame(&frame)); + + // Invalid Frame - Invalid track number + frame.set_track_number(kInvalidTrackNumber); + frame.set_timestamp(8000000); + EXPECT_FALSE(segment_.AddGenericFrame(&frame)); + + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("simple_block.webm"), filename_)); +} + +TEST_F(MuxerTest, MetadataBlock) { + EXPECT_TRUE(SegmentInit(false, false, false)); + Track* const track = segment_.AddTrack(kMetadataTrackNumber); + track->set_uid(kMetadataTrackNumber); + track->set_type(kMetadataTrackType); + track->set_codec_id(kMetadataCodecId); + + // Valid Frame + EXPECT_TRUE(segment_.AddMetadata(dummy_data_, kFrameLength, + kMetadataTrackNumber, 0, 2000000)); + + // Valid Frame + EXPECT_TRUE(segment_.AddMetadata(dummy_data_, kFrameLength, + kMetadataTrackNumber, 2000000, 6000000)); + + // Invalid Frame - Non monotonically increasing timestamp + EXPECT_FALSE(segment_.AddMetadata(dummy_data_, kFrameLength, + kMetadataTrackNumber, 1, 2000000)); + + // Invalid Frame - Null pointer + EXPECT_FALSE(segment_.AddMetadata(NULL, 0, kMetadataTrackNumber, 0, 8000000)); + + // Invalid Frame - Invalid track number + EXPECT_FALSE(segment_.AddMetadata(NULL, 0, kInvalidTrackNumber, 0, 8000000)); + + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("metadata_block.webm"), filename_)); +} + +TEST_F(MuxerTest, TrackType) { + EXPECT_TRUE(SegmentInit(false, false, false)); + Track* const track = segment_.AddTrack(kMetadataTrackNumber); + track->set_uid(kMetadataTrackNumber); + track->set_codec_id(kMetadataCodecId); + + // Invalid Frame - Incomplete track information (Track Type not set). + EXPECT_FALSE(segment_.AddMetadata(dummy_data_, kFrameLength, + kMetadataTrackNumber, 0, 2000000)); + + track->set_type(kMetadataTrackType); + + // Valid Frame + EXPECT_TRUE(segment_.AddMetadata(dummy_data_, kFrameLength, + kMetadataTrackNumber, 0, 2000000)); + + segment_.Finalize(); + CloseWriter(); +} + +TEST_F(MuxerTest, BlockWithAdditional) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + // Valid Frame + EXPECT_TRUE(segment_.AddFrameWithAdditional(dummy_data_, kFrameLength, + dummy_data_, kFrameLength, 1, + kVideoTrackNumber, 0, true)); + + // Valid Frame + EXPECT_TRUE(segment_.AddFrameWithAdditional( + dummy_data_, kFrameLength, dummy_data_, kFrameLength, 1, + kVideoTrackNumber, 2000000, false)); + + // Invalid Frame - Non monotonically increasing timestamp + EXPECT_FALSE(segment_.AddFrameWithAdditional(dummy_data_, kFrameLength, + dummy_data_, kFrameLength, 1, + kVideoTrackNumber, 1, false)); + + // Invalid Frame - Null frame pointer + EXPECT_FALSE( + segment_.AddFrameWithAdditional(NULL, 0, dummy_data_, kFrameLength, 1, + kVideoTrackNumber, 3000000, false)); + + // Invalid Frame - Null additional pointer + EXPECT_FALSE(segment_.AddFrameWithAdditional(dummy_data_, kFrameLength, NULL, + 0, 1, kVideoTrackNumber, 4000000, + false)); + + // Invalid Frame - Invalid track number + EXPECT_FALSE(segment_.AddFrameWithAdditional( + dummy_data_, kFrameLength, dummy_data_, kFrameLength, 1, + kInvalidTrackNumber, 8000000, false)); + + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("block_with_additional.webm"), filename_)); +} + +TEST_F(MuxerTest, BlockAdditionalWithAddGenericFrame) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + Frame frame; + frame.Init(dummy_data_, kFrameLength); + frame.AddAdditionalData(dummy_data_, kFrameLength, 1); + frame.set_track_number(kVideoTrackNumber); + frame.set_is_key(true); + + // Valid Frame + frame.set_timestamp(0); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + + // Valid Frame + frame.set_timestamp(2000000); + frame.set_is_key(false); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + + // Invalid Frame - Non monotonically increasing timestamp + frame.set_timestamp(1); + EXPECT_FALSE(segment_.AddGenericFrame(&frame)); + + // Invalid Frame - Invalid track number + frame.set_track_number(kInvalidTrackNumber); + frame.set_timestamp(4000000); + EXPECT_FALSE(segment_.AddGenericFrame(&frame)); + + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("block_with_additional.webm"), filename_)); +} + +TEST_F(MuxerTest, SegmentDurationComputation) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + Frame frame; + frame.Init(dummy_data_, kFrameLength); + frame.set_track_number(kVideoTrackNumber); + frame.set_timestamp(0); + frame.set_is_key(false); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + frame.set_timestamp(2000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + frame.set_timestamp(4000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + frame.set_timestamp(6000000); + frame.set_duration(2000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.Finalize(); + + // SegmentInfo's duration is in timecode scale + EXPECT_EQ(8, segment_.GetSegmentInfo()->duration()); + + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("segment_duration.webm"), filename_)); +} + +TEST_F(MuxerTest, SetSegmentDuration) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, + false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + + segment_.set_duration(10500.0); + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("set_segment_duration.webm"), filename_)); +} + +TEST_F(MuxerTest, ForceNewCluster) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, + false)); + segment_.ForceNewClusterOnNextFrame(); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 4000000, false)); + segment_.ForceNewClusterOnNextFrame(); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 6000000, false)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("force_new_cluster.webm"), filename_)); +} + +TEST_F(MuxerTest, OutputCues) { + EXPECT_TRUE(SegmentInit(true, false, false)); + AddVideoTrack(); + + EXPECT_TRUE( + segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, true)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 4000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 6000000, true)); + EXPECT_TRUE(segment_.AddCuePoint(4000000, kVideoTrackNumber)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("output_cues.webm"), filename_)); +} + +TEST_F(MuxerTest, CuesBeforeClusters) { + EXPECT_TRUE(SegmentInit(true, false, false)); + AddVideoTrack(); + + EXPECT_TRUE( + segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, true)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 4000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 6000000, true)); + segment_.Finalize(); + CloseWriter(); +#ifdef _MSC_VER + // Close the output file: the MS run time won't allow mkvparser::MkvReader + // to open a file for reading when it's still open for writing. + temp_file_.reset(); +#endif + mkvparser::MkvReader reader; + ASSERT_EQ(0, reader.Open(filename_.c_str())); + MkvWriter cues_writer; + std::string cues_filename = libwebm::GetTempFileName(); + ASSERT_GT(cues_filename.length(), 0u); + cues_writer.Open(cues_filename.c_str()); + EXPECT_TRUE(segment_.CopyAndMoveCuesBeforeClusters(&reader, &cues_writer)); + reader.Close(); + cues_writer.Close(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("cues_before_clusters.webm"), + cues_filename)); + MkvParser parser; + ASSERT_TRUE(ParseMkvFileReleaseParser(cues_filename, &parser)); + int64_t cues_offset = 0; + ASSERT_TRUE(HasCuePoints(parser.segment, &cues_offset)); + ASSERT_GT(cues_offset, 0); + ASSERT_TRUE(ValidateCues(parser.segment, parser.reader)); + remove(cues_filename.c_str()); +} + +TEST_F(MuxerTest, MaxClusterSize) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + const uint64_t kMaxClusterSize = 20; + segment_.set_max_cluster_size(kMaxClusterSize); + EXPECT_EQ(kMaxClusterSize, segment_.max_cluster_size()); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, 1, kVideoTrackNumber, 0, false)); + EXPECT_TRUE( + segment_.AddFrame(dummy_data_, 1, kVideoTrackNumber, 2000000, false)); + EXPECT_TRUE( + segment_.AddFrame(dummy_data_, 1, kVideoTrackNumber, 4000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 6000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 8000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 9000000, false)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("max_cluster_size.webm"), filename_)); +} + +TEST_F(MuxerTest, MaxClusterDuration) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + const uint64_t kMaxClusterDuration = 4000000; + segment_.set_max_cluster_duration(kMaxClusterDuration); + + EXPECT_EQ(kMaxClusterDuration, segment_.max_cluster_duration()); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, + false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 4000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 6000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 8000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 9000000, false)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("max_cluster_duration.webm"), filename_)); +} + +TEST_F(MuxerTest, SetCuesTrackNumber) { + const uint64_t kTrackNumber = 10; + EXPECT_TRUE(SegmentInit(true, false, false)); + const uint64_t vid_track = + segment_.AddVideoTrack(kWidth, kHeight, kTrackNumber); + EXPECT_EQ(kTrackNumber, vid_track); + segment_.GetTrackByNumber(vid_track)->set_uid(kVideoTrackNumber); + EXPECT_TRUE(segment_.CuesTrack(vid_track)); + + EXPECT_EQ(vid_track, segment_.cues_track()); + EXPECT_TRUE( + segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber, 0, true)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber, + 2000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber, + 4000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber, + 6000000, true)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber, + 8000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kTrackNumber, + 9000000, false)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("set_cues_track_number.webm"), filename_)); +} + +TEST_F(MuxerTest, BlockWithDiscardPadding) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddAudioTrack(); + + int timecode = 1000; + // 12810000 == 0xc37710, should be 0-extended to avoid changing the sign. + // The next two should be written as 1 byte. + std::array values = {{12810000, 127, -128}}; + for (const std::int64_t discard_padding : values) { + EXPECT_TRUE(segment_.AddFrameWithDiscardPadding( + dummy_data_, kFrameLength, discard_padding, kAudioTrackNumber, timecode, + true)) + << "discard_padding: " << discard_padding; + timecode += 1000; + } + + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("discard_padding.webm"), filename_)); +} + +TEST_F(MuxerTest, AccurateClusterDuration) { + EXPECT_TRUE(SegmentInit(false, true, false)); + AddVideoTrack(); + + Frame frame; + frame.Init(dummy_data_, kFrameLength); + frame.set_track_number(kVideoTrackNumber); + frame.set_timestamp(0); + frame.set_is_key(true); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.ForceNewClusterOnNextFrame(); + frame.set_timestamp(2000000); + frame.set_is_key(false); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + frame.set_timestamp(4000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.ForceNewClusterOnNextFrame(); + frame.set_timestamp(6000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("accurate_cluster_duration.webm"), + filename_)); +} + +// Tests AccurateClusterDuration flag with the duration of the very last block +// of the file set explicitly. +TEST_F(MuxerTest, AccurateClusterDurationExplicitLastFrameDuration) { + EXPECT_TRUE(SegmentInit(false, true, false)); + AddVideoTrack(); + + Frame frame; + frame.Init(dummy_data_, kFrameLength); + frame.set_track_number(kVideoTrackNumber); + frame.set_timestamp(0); + frame.set_is_key(true); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.ForceNewClusterOnNextFrame(); + frame.set_timestamp(2000000); + frame.set_is_key(false); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + frame.set_timestamp(4000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.ForceNewClusterOnNextFrame(); + frame.set_timestamp(6000000); + frame.set_duration(2000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.Finalize(); + + // SegmentInfo's duration is in timecode scale + EXPECT_EQ(8, segment_.GetSegmentInfo()->duration()); + + CloseWriter(); + + EXPECT_TRUE(CompareFiles( + GetTestFilePath("accurate_cluster_duration_last_frame.webm"), filename_)); +} + +TEST_F(MuxerTest, AccurateClusterDurationTwoTracks) { + EXPECT_TRUE(SegmentInit(false, true, false)); + AddVideoTrack(); + AddAudioTrack(); + + Frame video_frame; + video_frame.Init(dummy_data_, kFrameLength); + video_frame.set_track_number(kVideoTrackNumber); + Frame audio_frame; + audio_frame.Init(dummy_data_, kFrameLength); + audio_frame.set_track_number(kAudioTrackNumber); + std::array cluster_timestamps = {{0, 40000000}}; + for (const std::uint64_t cluster_timestamp : cluster_timestamps) { + // Add video and audio frames with timestamp 0. + video_frame.set_timestamp(cluster_timestamp); + video_frame.set_is_key(true); + EXPECT_TRUE(segment_.AddGenericFrame(&video_frame)); + audio_frame.set_timestamp(cluster_timestamp); + audio_frame.set_is_key(true); + EXPECT_TRUE(segment_.AddGenericFrame(&audio_frame)); + + // Add 3 consecutive audio frames. + std::array audio_timestamps = { + {10000000, 20000000, 30000000}}; + for (const std::uint64_t audio_timestamp : audio_timestamps) { + audio_frame.set_timestamp(cluster_timestamp + audio_timestamp); + // Explicitly set duration for the very last audio frame. + if (cluster_timestamp == 40000000 && audio_timestamp == 30000000) { + audio_frame.set_duration(10000000); + } + EXPECT_TRUE(segment_.AddGenericFrame(&audio_frame)); + } + + // Add a video frame with timestamp 33ms. + video_frame.set_is_key(false); + // Explicitly set duration for the very last video frame. + if (cluster_timestamp == 40000000) { + video_frame.set_duration(7000000); + } + video_frame.set_timestamp(cluster_timestamp + 33000000); + EXPECT_TRUE(segment_.AddGenericFrame(&video_frame)); + segment_.ForceNewClusterOnNextFrame(); + } + segment_.Finalize(); + + // SegmentInfo's duration is in timecode scale + EXPECT_EQ(80, segment_.GetSegmentInfo()->duration()); + + CloseWriter(); + + EXPECT_TRUE(CompareFiles( + GetTestFilePath("accurate_cluster_duration_two_tracks.webm"), filename_)); +} + +TEST_F(MuxerTest, AccurateClusterDurationWithoutFinalizingCluster) { + EXPECT_TRUE(SegmentInit(false, true, false)); + AddVideoTrack(); + + // Add a couple of frames and then bail out without finalizing the Segment + // (and thereby not finalizing the Cluster). The expectation here is that + // there shouldn't be any leaks. The test will fail under valgrind if there's + // a leak. + Frame video_frame; + video_frame.Init(dummy_data_, kFrameLength); + video_frame.set_track_number(kVideoTrackNumber); + video_frame.set_timestamp(0); + video_frame.set_is_key(true); + EXPECT_TRUE(segment_.AddGenericFrame(&video_frame)); + video_frame.set_timestamp(33000000); + EXPECT_TRUE(segment_.AddGenericFrame(&video_frame)); + + CloseWriter(); +} + +TEST_F(MuxerTest, UseFixedSizeClusterTimecode) { + EXPECT_TRUE(SegmentInit(false, false, true)); + AddVideoTrack(); + + Frame frame; + frame.Init(dummy_data_, kFrameLength); + frame.set_track_number(kVideoTrackNumber); + frame.set_timestamp(0); + frame.set_is_key(true); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.ForceNewClusterOnNextFrame(); + frame.set_timestamp(2000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.ForceNewClusterOnNextFrame(); + frame.set_timestamp(4000000); + EXPECT_TRUE(segment_.AddGenericFrame(&frame)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("fixed_size_cluster_timecode.webm"), + filename_)); +} + +TEST_F(MuxerTest, DocTypeWebm) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + Track* const vid_track = segment_.GetTrackByNumber(kVideoTrackNumber); + vid_track->set_codec_id(kVP9CodecId); + AddDummyFrameAndFinalize(kVideoTrackNumber); + EXPECT_TRUE(CompareFiles(GetTestFilePath("webm_doctype.webm"), filename_)); +} + +TEST_F(MuxerTest, DocTypeMatroska) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + Track* const vid_track = segment_.GetTrackByNumber(kVideoTrackNumber); + vid_track->set_codec_id("V_SOMETHING_NOT_IN_WEBM"); + AddDummyFrameAndFinalize(kVideoTrackNumber); + EXPECT_TRUE(CompareFiles(GetTestFilePath("matroska_doctype.mkv"), filename_)); +} + +TEST_F(MuxerTest, Colour) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + mkvmuxer::PrimaryChromaticity muxer_pc(.1, .2); + mkvmuxer::MasteringMetadata muxer_mm; + muxer_mm.set_luminance_min(30.0); + muxer_mm.set_luminance_max(40.0); + ASSERT_TRUE( + muxer_mm.SetChromaticity(&muxer_pc, &muxer_pc, &muxer_pc, &muxer_pc)); + + mkvmuxer::Colour muxer_colour; + muxer_colour.set_matrix_coefficients(mkvmuxer::Colour::kGbr); + muxer_colour.set_bits_per_channel(1); + muxer_colour.set_chroma_subsampling_horz(2); + muxer_colour.set_chroma_subsampling_vert(3); + muxer_colour.set_cb_subsampling_horz(4); + muxer_colour.set_cb_subsampling_vert(5); + muxer_colour.set_chroma_siting_horz(mkvmuxer::Colour::kLeftCollocated); + muxer_colour.set_chroma_siting_vert(mkvmuxer::Colour::kTopCollocated); + muxer_colour.set_range(mkvmuxer::Colour::kFullRange); + muxer_colour.set_transfer_characteristics(mkvmuxer::Colour::kLog); + muxer_colour.set_primaries(mkvmuxer::Colour::kSmpteSt4281P); + muxer_colour.set_max_cll(11); + muxer_colour.set_max_fall(12); + ASSERT_TRUE(muxer_colour.SetMasteringMetadata(muxer_mm)); + + VideoTrack* const video_track = + dynamic_cast(segment_.GetTrackByNumber(kVideoTrackNumber)); + ASSERT_TRUE(video_track != nullptr); + ASSERT_TRUE(video_track->SetColour(muxer_colour)); + ASSERT_NO_FATAL_FAILURE(AddDummyFrameAndFinalize(kVideoTrackNumber)); + + MkvParser parser; + ASSERT_TRUE(ParseMkvFileReleaseParser(filename_, &parser)); + + const mkvparser::VideoTrack* const parser_track = + static_cast( + parser.segment->GetTracks()->GetTrackByIndex(0)); + const mkvparser::Colour* parser_colour = parser_track->GetColour(); + ASSERT_TRUE(parser_colour != nullptr); + EXPECT_EQ(static_cast(muxer_colour.matrix_coefficients()), + parser_colour->matrix_coefficients); + EXPECT_EQ(static_cast(muxer_colour.bits_per_channel()), + parser_colour->bits_per_channel); + EXPECT_EQ(static_cast(muxer_colour.chroma_subsampling_horz()), + parser_colour->chroma_subsampling_horz); + EXPECT_EQ(static_cast(muxer_colour.chroma_subsampling_vert()), + parser_colour->chroma_subsampling_vert); + EXPECT_EQ(static_cast(muxer_colour.cb_subsampling_horz()), + parser_colour->cb_subsampling_horz); + EXPECT_EQ(static_cast(muxer_colour.cb_subsampling_vert()), + parser_colour->cb_subsampling_vert); + EXPECT_EQ(static_cast(muxer_colour.chroma_siting_horz()), + parser_colour->chroma_siting_horz); + EXPECT_EQ(static_cast(muxer_colour.chroma_siting_vert()), + parser_colour->chroma_siting_vert); + EXPECT_EQ(static_cast(muxer_colour.range()), parser_colour->range); + EXPECT_EQ(static_cast(muxer_colour.transfer_characteristics()), + parser_colour->transfer_characteristics); + EXPECT_EQ(static_cast(muxer_colour.primaries()), + parser_colour->primaries); + EXPECT_EQ(static_cast(muxer_colour.max_cll()), + parser_colour->max_cll); + EXPECT_EQ(static_cast(muxer_colour.max_fall()), + parser_colour->max_fall); + + const mkvparser::MasteringMetadata* const parser_mm = + parser_colour->mastering_metadata; + ASSERT_TRUE(parser_mm != nullptr); + EXPECT_FLOAT_EQ(muxer_mm.luminance_min(), parser_mm->luminance_min); + EXPECT_FLOAT_EQ(muxer_mm.luminance_max(), parser_mm->luminance_max); + EXPECT_FLOAT_EQ(muxer_mm.r()->x(), parser_mm->r->x); + EXPECT_FLOAT_EQ(muxer_mm.r()->y(), parser_mm->r->y); + EXPECT_FLOAT_EQ(muxer_mm.g()->x(), parser_mm->g->x); + EXPECT_FLOAT_EQ(muxer_mm.g()->y(), parser_mm->g->y); + EXPECT_FLOAT_EQ(muxer_mm.b()->x(), parser_mm->b->x); + EXPECT_FLOAT_EQ(muxer_mm.b()->y(), parser_mm->b->y); + EXPECT_FLOAT_EQ(muxer_mm.white_point()->x(), parser_mm->white_point->x); + EXPECT_FLOAT_EQ(muxer_mm.white_point()->y(), parser_mm->white_point->y); + EXPECT_TRUE(CompareFiles(GetTestFilePath("colour.webm"), filename_)); +} + +TEST_F(MuxerTest, ColourPartial) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + mkvmuxer::Colour muxer_colour; + muxer_colour.set_matrix_coefficients( + mkvmuxer::Colour::kBt2020NonConstantLuminance); + + VideoTrack* const video_track = + dynamic_cast(segment_.GetTrackByNumber(kVideoTrackNumber)); + ASSERT_TRUE(video_track != nullptr); + ASSERT_TRUE(video_track->SetColour(muxer_colour)); + ASSERT_NO_FATAL_FAILURE(AddDummyFrameAndFinalize(kVideoTrackNumber)); + + MkvParser parser; + ASSERT_TRUE(ParseMkvFileReleaseParser(filename_, &parser)); + + const mkvparser::VideoTrack* const parser_track = + static_cast( + parser.segment->GetTracks()->GetTrackByIndex(0)); + const mkvparser::Colour* parser_colour = parser_track->GetColour(); + EXPECT_EQ(static_cast(muxer_colour.matrix_coefficients()), + parser_colour->matrix_coefficients); +} + +TEST_F(MuxerTest, Projection) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + + mkvmuxer::Projection muxer_proj; + muxer_proj.set_type(mkvmuxer::Projection::kRectangular); + muxer_proj.set_pose_yaw(1); + muxer_proj.set_pose_pitch(2); + muxer_proj.set_pose_roll(3); + const uint8_t muxer_proj_private[1] = {4}; + const uint64_t muxer_proj_private_length = 1; + ASSERT_TRUE(muxer_proj.SetProjectionPrivate(&muxer_proj_private[0], + muxer_proj_private_length)); + + VideoTrack* const video_track = + static_cast(segment_.GetTrackByNumber(kVideoTrackNumber)); + ASSERT_TRUE(video_track != nullptr); + ASSERT_TRUE(video_track->SetProjection(muxer_proj)); + ASSERT_NO_FATAL_FAILURE(AddDummyFrameAndFinalize(kVideoTrackNumber)); + + MkvParser parser; + ASSERT_TRUE(ParseMkvFileReleaseParser(filename_, &parser)); + + const mkvparser::VideoTrack* const parser_track = + static_cast( + parser.segment->GetTracks()->GetTrackByIndex(0)); + + const mkvparser::Projection* const parser_proj = + parser_track->GetProjection(); + ASSERT_TRUE(parser_proj != nullptr); + EXPECT_FLOAT_EQ(muxer_proj.pose_yaw(), parser_proj->pose_yaw); + EXPECT_FLOAT_EQ(muxer_proj.pose_pitch(), parser_proj->pose_pitch); + EXPECT_FLOAT_EQ(muxer_proj.pose_roll(), parser_proj->pose_roll); + ASSERT_TRUE(parser_proj->private_data != nullptr); + EXPECT_EQ(static_cast(muxer_proj.private_data_length()), + parser_proj->private_data_length); + + EXPECT_EQ(muxer_proj.private_data()[0], parser_proj->private_data[0]); + typedef mkvparser::Projection::ProjectionType ParserProjType; + EXPECT_EQ(static_cast(muxer_proj.type()), parser_proj->type); + EXPECT_TRUE(CompareFiles(GetTestFilePath("projection.webm"), filename_)); +} + +TEST_F(MuxerTest, EstimateDuration) { + EXPECT_TRUE(SegmentInit(false, false, false)); + segment_.set_estimate_file_duration(true); + AddVideoTrack(); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, + false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 4000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 6000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 8000000, false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 9000000, false)); + segment_.Finalize(); + + CloseWriter(); + + EXPECT_TRUE( + CompareFiles(GetTestFilePath("estimate_duration.webm"), filename_)); +} + +TEST_F(MuxerTest, SetPixelWidthPixelHeight) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + VideoTrack* const video_track = + static_cast(segment_.GetTrackByNumber(kVideoTrackNumber)); + ASSERT_TRUE(video_track != nullptr); + video_track->set_pixel_width(500); + video_track->set_pixel_height(650); + + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, + false)); + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, + 2000000, false)); + + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("set_pixelwidth_pixelheight.webm"), + filename_)); +} + +TEST_F(MuxerTest, LongTagString) { + EXPECT_TRUE(SegmentInit(false, false, false)); + AddVideoTrack(); + Tag* const tag = segment_.AddTag(); + // 160 needs two bytes when varint encoded. + const std::string dummy_string(160, '0'); + tag->add_simple_tag("long_tag", dummy_string.c_str()); + + EXPECT_TRUE(segment_.AddFrame(dummy_data_, kFrameLength, kVideoTrackNumber, 0, + false)); + + segment_.Finalize(); + CloseWriter(); + + EXPECT_TRUE(CompareFiles(GetTestFilePath("long_tag_string.webm"), filename_)); +} + +} // namespace test + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/sys/libwebm/testing/mkvparser_fuzzer.cc b/src/sys/libwebm/testing/mkvparser_fuzzer.cc new file mode 100644 index 0000000..b3bb799 --- /dev/null +++ b/src/sys/libwebm/testing/mkvparser_fuzzer.cc @@ -0,0 +1,160 @@ +// Copyright (c) 2022 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include +#include +#include +#include +#include +#include +#include + +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" + +namespace { + +class MemoryReader : public mkvparser::IMkvReader { + public: + MemoryReader(const uint8_t* data, size_t size) : data_(data), size_(size) {} + + int Read(long long pos, long len, unsigned char* buf) override { + if (pos < 0 || len < 0) { + abort(); + } + if (pos >= size_ || size_ - pos < len) { + return -1; + } + memcpy(buf, data_ + pos, len); + return 0; + } + + int Length(long long* total, long long* available) override { + if (total != nullptr) { + *total = size_; + } + if (available != nullptr) { + *available = size_; + } + return 0; + } + + private: + const uint8_t* data_; + size_t size_; +}; + +void ParseCues(const mkvparser::Segment& segment) { + const mkvparser::Cues* const cues = segment.GetCues(); + if (cues == nullptr) { + return; + } + + while (!cues->DoneParsing()) { + cues->LoadCuePoint(); + } +} + +const mkvparser::BlockEntry* GetBlockEntryFromCues( + const void* ctx, const mkvparser::CuePoint* cue, + const mkvparser::CuePoint::TrackPosition* track_pos) { + const auto* const cues = static_cast(ctx); + return cues->GetBlock(cue, track_pos); +} + +const mkvparser::BlockEntry* GetBlockEntryFromCluster( + const void* ctx, const mkvparser::CuePoint* cue, + const mkvparser::CuePoint::TrackPosition* track_pos) { + if (track_pos == nullptr) { + return nullptr; + } + const auto* const cluster = static_cast(ctx); + const mkvparser::BlockEntry* block_entry = + cluster->GetEntry(*cue, *track_pos); + return block_entry; +} + +void WalkCues(const mkvparser::Segment& segment, + std::function + get_block_entry, + const void* ctx) { + const mkvparser::Cues* const cues = segment.GetCues(); + const mkvparser::Tracks* tracks = segment.GetTracks(); + if (cues == nullptr || tracks == nullptr) { + return; + } + const unsigned long num_tracks = tracks->GetTracksCount(); + + for (const mkvparser::CuePoint* cue = cues->GetFirst(); cue != nullptr; + cue = cues->GetNext(cue)) { + for (unsigned long track_num = 0; track_num < num_tracks; ++track_num) { + const mkvparser::Track* const track = tracks->GetTrackByIndex(track_num); + const mkvparser::CuePoint::TrackPosition* const track_pos = + cue->Find(track); + const mkvparser::BlockEntry* block_entry = + get_block_entry(ctx, cue, track_pos); + static_cast(block_entry); + } + } +} + +void ParseCluster(const mkvparser::Cluster& cluster) { + const mkvparser::BlockEntry* block_entry; + long status = cluster.GetFirst(block_entry); + if (status != 0) { + return; + } + + while (block_entry != nullptr && !block_entry->EOS()) { + const mkvparser::Block* const block = block_entry->GetBlock(); + if (block == nullptr) { + return; + } + + status = cluster.GetNext(block_entry, block_entry); + if (status != 0) { + return; + } + } +} + +} // namespace + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + MemoryReader reader(data, size); + + long long int pos = 0; + std::unique_ptr ebml_header( + new (std::nothrow) mkvparser::EBMLHeader()); // NOLINT + if (ebml_header->Parse(&reader, pos) < 0) { + return 0; + } + + mkvparser::Segment* temp_segment; + if (mkvparser::Segment::CreateInstance(&reader, pos, temp_segment) != 0) { + return 0; + } + std::unique_ptr segment(temp_segment); + + if (segment->Load() < 0) { + return 0; + } + + ParseCues(*segment); + WalkCues(*segment, GetBlockEntryFromCues, segment->GetCues()); + + const mkvparser::Cluster* cluster = segment->GetFirst(); + while (cluster != nullptr && !cluster->EOS()) { + ParseCluster(*cluster); + WalkCues(*segment, GetBlockEntryFromCluster, cluster); + cluster = segment->GetNext(cluster); + } + + return 0; +} diff --git a/src/sys/libwebm/testing/mkvparser_tests.cc b/src/sys/libwebm/testing/mkvparser_tests.cc new file mode 100644 index 0000000..9c26a1e --- /dev/null +++ b/src/sys/libwebm/testing/mkvparser_tests.cc @@ -0,0 +1,823 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include + +#include "common/hdr_util.h" +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" +#include "testing/test_util.h" + +using mkvparser::AudioTrack; +using mkvparser::Block; +using mkvparser::BlockEntry; +using mkvparser::BlockGroup; +using mkvparser::Cluster; +using mkvparser::CuePoint; +using mkvparser::Cues; +using mkvparser::MkvReader; +using mkvparser::Segment; +using mkvparser::SegmentInfo; +using mkvparser::Track; +using mkvparser::Tracks; +using mkvparser::VideoTrack; + +namespace test { + +// Base class containing boiler plate stuff. +class ParserTest : public testing::Test { + public: + ParserTest() : is_reader_open_(false), segment_(NULL) { + memset(dummy_data_, -1, kFrameLength); + memset(gold_frame_, 0, kFrameLength); + } + + virtual ~ParserTest() { + CloseReader(); + if (segment_ != NULL) { + delete segment_; + segment_ = NULL; + } + } + + void CloseReader() { + if (is_reader_open_) { + reader_.Close(); + } + is_reader_open_ = false; + } + + bool CreateAndLoadSegment(const std::string& filename, + int expected_doc_type_ver) { + filename_ = GetTestFilePath(filename); + if (reader_.Open(filename_.c_str())) { + return false; + } + is_reader_open_ = true; + pos_ = 0; + mkvparser::EBMLHeader ebml_header; + ebml_header.Parse(&reader_, pos_); + EXPECT_EQ(1, ebml_header.m_version); + EXPECT_EQ(1, ebml_header.m_readVersion); + EXPECT_STREQ("webm", ebml_header.m_docType); + EXPECT_EQ(expected_doc_type_ver, ebml_header.m_docTypeVersion); + EXPECT_EQ(2, ebml_header.m_docTypeReadVersion); + + if (mkvparser::Segment::CreateInstance(&reader_, pos_, segment_)) { + return false; + } + return !HasFailure() && segment_->Load() >= 0; + } + + bool CreateAndLoadSegment(const std::string& filename) { + return CreateAndLoadSegment(filename, 4); + } + + void CreateSegmentNoHeaderChecks(const std::string& filename) { + filename_ = GetTestFilePath(filename); + ASSERT_NE(0u, filename_.length()); + ASSERT_EQ(0, reader_.Open(filename_.c_str())); + mkvparser::EBMLHeader ebml_header; + ASSERT_EQ(0, ebml_header.Parse(&reader_, pos_)); + ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, segment_)); + } + + void CompareBlockContents(const Cluster* const cluster, + const Block* const block, std::uint64_t timestamp, + int track_number, bool is_key, int frame_count) { + ASSERT_TRUE(block != NULL); + EXPECT_EQ(track_number, block->GetTrackNumber()); + EXPECT_EQ(static_cast(timestamp), block->GetTime(cluster)); + EXPECT_EQ(is_key, block->IsKey()); + EXPECT_EQ(frame_count, block->GetFrameCount()); + const Block::Frame& frame = block->GetFrame(0); + EXPECT_EQ(kFrameLength, frame.len); + std::memset(dummy_data_, -1, kFrameLength); + frame.Read(&reader_, dummy_data_); + EXPECT_EQ(0, std::memcmp(gold_frame_, dummy_data_, kFrameLength)); + } + + void CompareCuePointContents(const Track* const track, + const CuePoint* const cue_point, + std::uint64_t timestamp, int track_number, + std::uint64_t pos) { + ASSERT_TRUE(cue_point != NULL); + EXPECT_EQ(static_cast(timestamp), cue_point->GetTime(segment_)); + const CuePoint::TrackPosition* const track_position = + cue_point->Find(track); + EXPECT_EQ(track_number, track_position->m_track); + EXPECT_EQ(static_cast(pos), track_position->m_pos); + } + + protected: + MkvReader reader_; + bool is_reader_open_; + Segment* segment_; + std::string filename_; + long long pos_; + std::uint8_t dummy_data_[kFrameLength]; + std::uint8_t gold_frame_[kFrameLength]; +}; + +TEST_F(ParserTest, SegmentInfo) { + ASSERT_TRUE(CreateAndLoadSegment("segment_info.webm")); + const SegmentInfo* const info = segment_->GetInfo(); + EXPECT_EQ(kTimeCodeScale, info->GetTimeCodeScale()); + EXPECT_STREQ(kAppString, info->GetMuxingAppAsUTF8()); + EXPECT_STREQ(kAppString, info->GetWritingAppAsUTF8()); +} + +TEST_F(ParserTest, TrackEntries) { + ASSERT_TRUE(CreateAndLoadSegment("tracks.webm")); + const Tracks* const tracks = segment_->GetTracks(); + const unsigned int kTracksCount = 2; + EXPECT_EQ(kTracksCount, tracks->GetTracksCount()); + for (int i = 0; i < 2; ++i) { + const Track* const track = tracks->GetTrackByIndex(i); + ASSERT_TRUE(track != NULL); + EXPECT_STREQ(kTrackName, track->GetNameAsUTF8()); + if (track->GetType() == Track::kVideo) { + const VideoTrack* const video_track = + dynamic_cast(track); + EXPECT_EQ(kWidth, static_cast(video_track->GetWidth())); + EXPECT_EQ(kHeight, static_cast(video_track->GetHeight())); + EXPECT_STREQ(kVP8CodecId, video_track->GetCodecId()); + EXPECT_DOUBLE_EQ(kVideoFrameRate, video_track->GetFrameRate()); + const unsigned int kTrackUid = 1; + EXPECT_EQ(kTrackUid, video_track->GetUid()); + } else if (track->GetType() == Track::kAudio) { + const AudioTrack* const audio_track = + dynamic_cast(track); + EXPECT_EQ(kSampleRate, audio_track->GetSamplingRate()); + EXPECT_EQ(kChannels, audio_track->GetChannels()); + EXPECT_EQ(kBitDepth, audio_track->GetBitDepth()); + EXPECT_STREQ(kVorbisCodecId, audio_track->GetCodecId()); + const unsigned int kTrackUid = 2; + EXPECT_EQ(kTrackUid, audio_track->GetUid()); + } + } +} + +TEST_F(ParserTest, SimpleBlock) { + ASSERT_TRUE(CreateAndLoadSegment("simple_block.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + // Get the cluster + const Cluster* cluster = segment_->GetFirst(); + ASSERT_TRUE(cluster != NULL); + EXPECT_FALSE(cluster->EOS()); + + // Get the first block + const BlockEntry* block_entry; + EXPECT_EQ(0, cluster->GetFirst(block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + CompareBlockContents(cluster, block_entry->GetBlock(), 0, kVideoTrackNumber, + false, 1); + + // Get the second block + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + CompareBlockContents(cluster, block_entry->GetBlock(), 2000000, + kVideoTrackNumber, false, 1); + + // End of Stream + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + ASSERT_EQ(NULL, block_entry); + cluster = segment_->GetNext(cluster); + EXPECT_TRUE(cluster->EOS()); +} + +TEST_F(ParserTest, MultipleClusters) { + ASSERT_TRUE(CreateAndLoadSegment("force_new_cluster.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + // Get the first cluster + const Cluster* cluster = segment_->GetFirst(); + ASSERT_TRUE(cluster != NULL); + EXPECT_FALSE(cluster->EOS()); + + // Get the first block + const BlockEntry* block_entry; + EXPECT_EQ(0, cluster->GetFirst(block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + CompareBlockContents(cluster, block_entry->GetBlock(), 0, kVideoTrackNumber, + false, 1); + + // Get the second cluster + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + EXPECT_EQ(NULL, block_entry); + cluster = segment_->GetNext(cluster); + ASSERT_TRUE(cluster != NULL); + EXPECT_FALSE(cluster->EOS()); + + // Get the second block + EXPECT_EQ(0, cluster->GetFirst(block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + CompareBlockContents(cluster, block_entry->GetBlock(), 2000000, + kVideoTrackNumber, false, 1); + + // Get the third block + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + CompareBlockContents(cluster, block_entry->GetBlock(), 4000000, + kVideoTrackNumber, false, 1); + + // Get the third cluster + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + EXPECT_EQ(NULL, block_entry); + cluster = segment_->GetNext(cluster); + ASSERT_TRUE(cluster != NULL); + EXPECT_FALSE(cluster->EOS()); + + // Get the fourth block + EXPECT_EQ(0, cluster->GetFirst(block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + CompareBlockContents(cluster, block_entry->GetBlock(), 6000000, + kVideoTrackNumber, false, 1); + + // End of Stream + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + EXPECT_EQ(NULL, block_entry); + cluster = segment_->GetNext(cluster); + EXPECT_TRUE(cluster->EOS()); +} + +TEST_F(ParserTest, BlockGroup) { + ASSERT_TRUE(CreateAndLoadSegment("metadata_block.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + // Get the cluster + const Cluster* cluster = segment_->GetFirst(); + ASSERT_TRUE(cluster != NULL); + EXPECT_FALSE(cluster->EOS()); + + // Get the first block + const BlockEntry* block_entry; + EXPECT_EQ(0, cluster->GetFirst(block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + EXPECT_EQ(BlockEntry::Kind::kBlockGroup, block_entry->GetKind()); + const BlockGroup* block_group = static_cast(block_entry); + EXPECT_EQ(2, block_group->GetDurationTimeCode()); + CompareBlockContents(cluster, block_group->GetBlock(), 0, + kMetadataTrackNumber, true, 1); + + // Get the second block + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + EXPECT_EQ(BlockEntry::Kind::kBlockGroup, block_entry->GetKind()); + block_group = static_cast(block_entry); + EXPECT_EQ(6, block_group->GetDurationTimeCode()); + CompareBlockContents(cluster, block_group->GetBlock(), 2000000, + kMetadataTrackNumber, true, 1); + + // End of Stream + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + EXPECT_EQ(NULL, block_entry); + cluster = segment_->GetNext(cluster); + EXPECT_TRUE(cluster->EOS()); +} + +TEST_F(ParserTest, Cues) { + ASSERT_TRUE(CreateAndLoadSegment("output_cues.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + const Track* const track = segment_->GetTracks()->GetTrackByIndex(0); + const Cues* const cues = segment_->GetCues(); + ASSERT_TRUE(cues != NULL); + while (!cues->DoneParsing()) { + cues->LoadCuePoint(); + } + EXPECT_EQ(3, cues->GetCount()); + + // Get first Cue Point + const CuePoint* cue_point = cues->GetFirst(); + CompareCuePointContents(track, cue_point, 0, kVideoTrackNumber, 206); + + // Get second Cue Point + cue_point = cues->GetNext(cue_point); + CompareCuePointContents(track, cue_point, 6000000, kVideoTrackNumber, 269); + + // Get third (also last) Cue Point + cue_point = cues->GetNext(cue_point); + const CuePoint* last_cue_point = cues->GetLast(); + EXPECT_TRUE(cue_point == last_cue_point); + CompareCuePointContents(track, cue_point, 4000000, kVideoTrackNumber, 269); + + EXPECT_TRUE(ValidateCues(segment_, &reader_)); +} + +TEST_F(ParserTest, CuesBeforeClusters) { + ASSERT_TRUE(CreateAndLoadSegment("cues_before_clusters.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + const Track* const track = segment_->GetTracks()->GetTrackByIndex(0); + const Cues* const cues = segment_->GetCues(); + ASSERT_TRUE(cues != NULL); + while (!cues->DoneParsing()) { + cues->LoadCuePoint(); + } + EXPECT_EQ(2, cues->GetCount()); + + // Get first Cue Point + const CuePoint* cue_point = cues->GetFirst(); + CompareCuePointContents(track, cue_point, 0, kVideoTrackNumber, 238); + + // Get second (also last) Cue Point + cue_point = cues->GetNext(cue_point); + const CuePoint* last_cue_point = cues->GetLast(); + EXPECT_TRUE(cue_point == last_cue_point); + CompareCuePointContents(track, cue_point, 6000000, kVideoTrackNumber, 301); + + EXPECT_TRUE(ValidateCues(segment_, &reader_)); +} + +TEST_F(ParserTest, CuesTrackNumber) { + ASSERT_TRUE(CreateAndLoadSegment("set_cues_track_number.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + const Track* const track = segment_->GetTracks()->GetTrackByIndex(0); + const Cues* const cues = segment_->GetCues(); + ASSERT_TRUE(cues != NULL); + while (!cues->DoneParsing()) { + cues->LoadCuePoint(); + } + EXPECT_EQ(2, cues->GetCount()); + + // Get first Cue Point + const CuePoint* cue_point = cues->GetFirst(); + CompareCuePointContents(track, cue_point, 0, 10, 206); + + // Get second (also last) Cue Point + cue_point = cues->GetNext(cue_point); + const CuePoint* last_cue_point = cues->GetLast(); + EXPECT_TRUE(cue_point == last_cue_point); + CompareCuePointContents(track, cue_point, 6000000, 10, 269); + + EXPECT_TRUE(ValidateCues(segment_, &reader_)); +} + +TEST_F(ParserTest, Opus) { + ASSERT_TRUE(CreateAndLoadSegment("bbb_480p_vp9_opus_1second.webm", 4)); + const unsigned int kTracksCount = 2; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + // -------------------------------------------------------------------------- + // Track Header validation. + const Tracks* const tracks = segment_->GetTracks(); + EXPECT_EQ(kTracksCount, tracks->GetTracksCount()); + for (int i = 0; i < 2; ++i) { + const Track* const track = tracks->GetTrackByIndex(i); + ASSERT_TRUE(track != NULL); + + EXPECT_EQ(NULL, track->GetNameAsUTF8()); + EXPECT_STREQ("und", track->GetLanguage()); + EXPECT_EQ(i + 1, track->GetNumber()); + EXPECT_FALSE(track->GetLacing()); + + if (track->GetType() == Track::kVideo) { + const VideoTrack* const video_track = + dynamic_cast(track); + EXPECT_EQ(854, static_cast(video_track->GetWidth())); + EXPECT_EQ(480, static_cast(video_track->GetHeight())); + EXPECT_STREQ(kVP9CodecId, video_track->GetCodecId()); + EXPECT_DOUBLE_EQ(0., video_track->GetFrameRate()); + EXPECT_EQ(41666666, + static_cast(video_track->GetDefaultDuration())); // 24.000 + const unsigned int kVideoUid = kVideoTrackNumber; + EXPECT_EQ(kVideoUid, video_track->GetUid()); + const unsigned int kCodecDelay = 0; + EXPECT_EQ(kCodecDelay, video_track->GetCodecDelay()); + const unsigned int kSeekPreRoll = 0; + EXPECT_EQ(kSeekPreRoll, video_track->GetSeekPreRoll()); + + size_t video_codec_private_size; + EXPECT_EQ(NULL, video_track->GetCodecPrivate(video_codec_private_size)); + const unsigned int kPrivateSize = 0; + EXPECT_EQ(kPrivateSize, video_codec_private_size); + } else if (track->GetType() == Track::kAudio) { + const AudioTrack* const audio_track = + dynamic_cast(track); + EXPECT_EQ(48000, audio_track->GetSamplingRate()); + EXPECT_EQ(6, audio_track->GetChannels()); + EXPECT_EQ(32, audio_track->GetBitDepth()); + EXPECT_STREQ(kOpusCodecId, audio_track->GetCodecId()); + EXPECT_EQ(kAudioTrackNumber, static_cast(audio_track->GetUid())); + const unsigned int kDefaultDuration = 0; + EXPECT_EQ(kDefaultDuration, audio_track->GetDefaultDuration()); + EXPECT_EQ(kOpusCodecDelay, audio_track->GetCodecDelay()); + EXPECT_EQ(kOpusSeekPreroll, audio_track->GetSeekPreRoll()); + + size_t audio_codec_private_size; + EXPECT_TRUE(audio_track->GetCodecPrivate(audio_codec_private_size) != + NULL); + EXPECT_GE(audio_codec_private_size, kOpusPrivateDataSizeMinimum); + } + } + + // -------------------------------------------------------------------------- + // Parse the file to do block-level validation. + const Cluster* cluster = segment_->GetFirst(); + ASSERT_TRUE(cluster != NULL); + EXPECT_FALSE(cluster->EOS()); + + for (; cluster != NULL && !cluster->EOS(); + cluster = segment_->GetNext(cluster)) { + // Get the first block + const BlockEntry* block_entry; + EXPECT_EQ(0, cluster->GetFirst(block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + + while (block_entry != NULL && !block_entry->EOS()) { + const Block* const block = block_entry->GetBlock(); + ASSERT_TRUE(block != NULL); + EXPECT_FALSE(block->IsInvisible()); + EXPECT_EQ(Block::kLacingNone, block->GetLacing()); + + const std::uint32_t track_number = + static_cast(block->GetTrackNumber()); + const Track* const track = tracks->GetTrackByNumber(track_number); + ASSERT_TRUE(track != NULL); + EXPECT_EQ(track->GetNumber(), block->GetTrackNumber()); + const unsigned int kContentEncodingCount = 0; + EXPECT_EQ(kContentEncodingCount, + track->GetContentEncodingCount()); // no encryption + + const std::int64_t track_type = track->GetType(); + EXPECT_TRUE(track_type == Track::kVideo || track_type == Track::kAudio); + if (track_type == Track::kVideo) { + EXPECT_EQ(BlockEntry::kBlockSimple, block_entry->GetKind()); + EXPECT_EQ(0, block->GetDiscardPadding()); + } else { + EXPECT_TRUE(block->IsKey()); + const std::int64_t kLastAudioTimecode = 1001; + const std::int64_t timecode = block->GetTimeCode(cluster); + // Only the final Opus block should have discard padding. + if (timecode == kLastAudioTimecode) { + EXPECT_EQ(BlockEntry::kBlockGroup, block_entry->GetKind()); + EXPECT_EQ(13500000, block->GetDiscardPadding()); + } else { + EXPECT_EQ(BlockEntry::kBlockSimple, block_entry->GetKind()); + EXPECT_EQ(0, block->GetDiscardPadding()); + } + } + + const int frame_count = block->GetFrameCount(); + const Block::Frame& frame = block->GetFrame(0); + EXPECT_EQ(1, frame_count); + EXPECT_GT(frame.len, 0); + + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + } + } + + ASSERT_TRUE(cluster != NULL); + EXPECT_TRUE(cluster->EOS()); +} + +TEST_F(ParserTest, DiscardPadding) { + // Test an artificial file with some extreme DiscardPadding values. + const std::string file = "discard_padding.webm"; + ASSERT_TRUE(CreateAndLoadSegment(file, 4)); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + // -------------------------------------------------------------------------- + // Track Header validation. + const Tracks* const tracks = segment_->GetTracks(); + EXPECT_EQ(kTracksCount, tracks->GetTracksCount()); + const Track* const track = tracks->GetTrackByIndex(0); + ASSERT_TRUE(track != NULL); + + EXPECT_STREQ(NULL, track->GetNameAsUTF8()); + EXPECT_EQ(NULL, track->GetLanguage()); + EXPECT_EQ(kAudioTrackNumber, track->GetNumber()); + EXPECT_TRUE(track->GetLacing()); + + EXPECT_EQ(Track::kAudio, track->GetType()); + const AudioTrack* const audio_track = dynamic_cast(track); + EXPECT_EQ(30, audio_track->GetSamplingRate()); + EXPECT_EQ(2, audio_track->GetChannels()); + EXPECT_STREQ(kOpusCodecId, audio_track->GetCodecId()); + EXPECT_EQ(kAudioTrackNumber, static_cast(audio_track->GetUid())); + const unsigned int kDefaultDuration = 0; + EXPECT_EQ(kDefaultDuration, audio_track->GetDefaultDuration()); + const unsigned int kCodecDelay = 0; + EXPECT_EQ(kCodecDelay, audio_track->GetCodecDelay()); + const unsigned int kSeekPreRoll = 0; + EXPECT_EQ(kSeekPreRoll, audio_track->GetSeekPreRoll()); + + size_t audio_codec_private_size; + EXPECT_EQ(NULL, audio_track->GetCodecPrivate(audio_codec_private_size)); + const unsigned int kPrivateSize = 0; + EXPECT_EQ(kPrivateSize, audio_codec_private_size); + + // -------------------------------------------------------------------------- + // Parse the file to do block-level validation. + const Cluster* cluster = segment_->GetFirst(); + ASSERT_TRUE(cluster != NULL); + EXPECT_FALSE(cluster->EOS()); + const unsigned int kSegmentCount = 1; + EXPECT_EQ(kSegmentCount, segment_->GetCount()); + + // Get the first block + const BlockEntry* block_entry; + EXPECT_EQ(0, cluster->GetFirst(block_entry)); + ASSERT_TRUE(block_entry != NULL); + EXPECT_FALSE(block_entry->EOS()); + + const std::array discard_padding = {{12810000, 127, -128}}; + int index = 0; + while (block_entry != NULL && !block_entry->EOS()) { + const Block* const block = block_entry->GetBlock(); + ASSERT_TRUE(block != NULL); + EXPECT_FALSE(block->IsInvisible()); + EXPECT_EQ(Block::kLacingNone, block->GetLacing()); + + const std::uint32_t track_number = + static_cast(block->GetTrackNumber()); + const Track* const track = tracks->GetTrackByNumber(track_number); + ASSERT_TRUE(track != NULL); + EXPECT_EQ(track->GetNumber(), block->GetTrackNumber()); + const unsigned int kContentEncodingCount = 0; + EXPECT_EQ(kContentEncodingCount, + track->GetContentEncodingCount()); // no encryption + + const std::int64_t track_type = track->GetType(); + EXPECT_EQ(Track::kAudio, track_type); + EXPECT_TRUE(block->IsKey()); + + // All blocks have DiscardPadding. + EXPECT_EQ(BlockEntry::kBlockGroup, block_entry->GetKind()); + ASSERT_LT(index, static_cast(discard_padding.size())); + EXPECT_EQ(discard_padding[index], block->GetDiscardPadding()); + ++index; + + const int frame_count = block->GetFrameCount(); + const Block::Frame& frame = block->GetFrame(0); + EXPECT_EQ(1, frame_count); + EXPECT_GT(frame.len, 0); + + EXPECT_EQ(0, cluster->GetNext(block_entry, block_entry)); + } + + cluster = segment_->GetNext(cluster); + ASSERT_TRUE(cluster != NULL); + EXPECT_TRUE(cluster->EOS()); +} + +TEST_F(ParserTest, StereoModeParsedCorrectly) { + ASSERT_TRUE(CreateAndLoadSegment("test_stereo_left_right.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + + const VideoTrack* const video_track = dynamic_cast( + segment_->GetTracks()->GetTrackByIndex(0)); + + EXPECT_EQ(1, video_track->GetStereoMode()); + EXPECT_EQ(256, video_track->GetWidth()); + EXPECT_EQ(144, video_track->GetHeight()); + EXPECT_EQ(128, video_track->GetDisplayWidth()); + EXPECT_EQ(144, video_track->GetDisplayHeight()); +} + +TEST_F(ParserTest, CanParseColour) { + ASSERT_TRUE(CreateAndLoadSegment("colour.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + const VideoTrack* const video_track = dynamic_cast( + segment_->GetTracks()->GetTrackByIndex(0)); + + const mkvparser::Colour* const colour = video_track->GetColour(); + ASSERT_TRUE(colour != nullptr); + EXPECT_EQ(0u, colour->matrix_coefficients); + EXPECT_EQ(1u, colour->bits_per_channel); + EXPECT_EQ(2u, colour->chroma_subsampling_horz); + EXPECT_EQ(3u, colour->chroma_subsampling_vert); + EXPECT_EQ(4u, colour->cb_subsampling_horz); + EXPECT_EQ(5u, colour->cb_subsampling_vert); + EXPECT_EQ(1u, colour->chroma_siting_horz); + EXPECT_EQ(1u, colour->chroma_siting_vert); + EXPECT_EQ(2u, colour->range); + EXPECT_EQ(9u, colour->transfer_characteristics); + EXPECT_EQ(10u, colour->primaries); + EXPECT_EQ(11u, colour->max_cll); + EXPECT_EQ(12u, colour->max_fall); + + const mkvparser::MasteringMetadata* const mm = + video_track->GetColour()->mastering_metadata; + ASSERT_TRUE(mm != nullptr); + ASSERT_TRUE(mm->r != nullptr); + ASSERT_TRUE(mm->g != nullptr); + ASSERT_TRUE(mm->b != nullptr); + ASSERT_TRUE(mm->white_point != nullptr); + EXPECT_FLOAT_EQ(.1, mm->r->x); + EXPECT_FLOAT_EQ(.2, mm->r->y); + EXPECT_FLOAT_EQ(.1, mm->g->x); + EXPECT_FLOAT_EQ(.2, mm->g->y); + EXPECT_FLOAT_EQ(.1, mm->b->x); + EXPECT_FLOAT_EQ(.2, mm->b->y); + EXPECT_FLOAT_EQ(.1, mm->white_point->x); + EXPECT_FLOAT_EQ(.2, mm->white_point->y); + EXPECT_FLOAT_EQ(30.0, mm->luminance_min); + EXPECT_FLOAT_EQ(40.0, mm->luminance_max); +} + +TEST_F(ParserTest, CanParseProjection) { + ASSERT_TRUE(CreateAndLoadSegment("projection.webm")); + const unsigned int kTracksCount = 1; + EXPECT_EQ(kTracksCount, segment_->GetTracks()->GetTracksCount()); + const VideoTrack* const video_track = + static_cast(segment_->GetTracks()->GetTrackByIndex(0)); + + const mkvparser::Projection* const projection = video_track->GetProjection(); + ASSERT_TRUE(projection != nullptr); + EXPECT_EQ(mkvparser::Projection::kRectangular, projection->type); + EXPECT_FLOAT_EQ(1, projection->pose_yaw); + EXPECT_FLOAT_EQ(2, projection->pose_pitch); + EXPECT_FLOAT_EQ(3, projection->pose_roll); + EXPECT_EQ(1u, projection->private_data_length); + ASSERT_TRUE(projection->private_data != nullptr); + EXPECT_EQ(4u, projection->private_data[0]); +} + +TEST_F(ParserTest, Vp9CodecLevelTest) { + const int kCodecPrivateLength = 3; + const uint8_t good_codec_private_level[kCodecPrivateLength] = {2, 1, 11}; + libwebm::Vp9CodecFeatures features; + EXPECT_TRUE(libwebm::ParseVpxCodecPrivate(&good_codec_private_level[0], + kCodecPrivateLength, &features)); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.profile); + EXPECT_EQ(11, features.level); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.bit_depth); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, + features.chroma_subsampling); +} + +TEST_F(ParserTest, Vp9CodecProfileTest) { + const int kCodecPrivateLength = 3; + const uint8_t good_codec_private_profile[kCodecPrivateLength] = {1, 1, 1}; + libwebm::Vp9CodecFeatures features; + EXPECT_TRUE(libwebm::ParseVpxCodecPrivate(&good_codec_private_profile[0], + kCodecPrivateLength, &features)); + EXPECT_EQ(1, features.profile); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.level); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.bit_depth); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, + features.chroma_subsampling); +} + +TEST_F(ParserTest, Vp9CodecBitDepthTest) { + const int kCodecPrivateLength = 3; + const uint8_t good_codec_private_profile[kCodecPrivateLength] = {3, 1, 8}; + libwebm::Vp9CodecFeatures features; + EXPECT_TRUE(libwebm::ParseVpxCodecPrivate(&good_codec_private_profile[0], + kCodecPrivateLength, &features)); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.profile); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.level); + EXPECT_EQ(8, features.bit_depth); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, + features.chroma_subsampling); +} + +TEST_F(ParserTest, Vp9CodecChromaSubsamplingTest) { + const int kCodecPrivateLength = 3; + const uint8_t good_codec_private_profile[kCodecPrivateLength] = {4, 1, 0}; + libwebm::Vp9CodecFeatures features; + EXPECT_TRUE(libwebm::ParseVpxCodecPrivate(&good_codec_private_profile[0], + kCodecPrivateLength, &features)); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.profile); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.level); + EXPECT_EQ(libwebm::Vp9CodecFeatures::kValueNotPresent, features.bit_depth); + EXPECT_EQ(0, features.chroma_subsampling); +} + +TEST_F(ParserTest, Vp9CodecProfileLevelTest) { + const int kCodecPrivateLength = 6; + const uint8_t codec_private[kCodecPrivateLength] = {1, 1, 1, 2, 1, 11}; + libwebm::Vp9CodecFeatures features; + EXPECT_TRUE(libwebm::ParseVpxCodecPrivate(&codec_private[0], + kCodecPrivateLength, &features)); + EXPECT_EQ(1, features.profile); + EXPECT_EQ(11, features.level); +} + +TEST_F(ParserTest, Vp9CodecAllTest) { + const int kCodecPrivateLength = 12; + const uint8_t codec_private[kCodecPrivateLength] = {1, 1, 1, 2, 1, 11, + 3, 1, 8, 4, 1, 0}; + libwebm::Vp9CodecFeatures features; + EXPECT_TRUE(libwebm::ParseVpxCodecPrivate(&codec_private[0], + kCodecPrivateLength, &features)); + EXPECT_EQ(1, features.profile); + EXPECT_EQ(11, features.level); + EXPECT_EQ(8, features.bit_depth); + EXPECT_EQ(0, features.chroma_subsampling); +} + +TEST_F(ParserTest, Vp9CodecPrivateBadTest) { + const int kCodecPrivateLength = 3; + libwebm::Vp9CodecFeatures features; + // Test invalid codec private data; all of these should return false. + const uint8_t bad_codec_private[kCodecPrivateLength] = {0, 0, 0}; + EXPECT_FALSE( + libwebm::ParseVpxCodecPrivate(NULL, kCodecPrivateLength, &features)); + EXPECT_FALSE( + libwebm::ParseVpxCodecPrivate(&bad_codec_private[0], 0, &features)); + EXPECT_FALSE(libwebm::ParseVpxCodecPrivate(&bad_codec_private[0], + kCodecPrivateLength, &features)); + const uint8_t good_codec_private_level[kCodecPrivateLength] = {2, 1, 11}; + + // Test parse of codec private chunks, but lie about length. + EXPECT_FALSE( + libwebm::ParseVpxCodecPrivate(&bad_codec_private[0], 0, &features)); + EXPECT_FALSE(libwebm::ParseVpxCodecPrivate(&good_codec_private_level[0], 0, + &features)); + EXPECT_FALSE(libwebm::ParseVpxCodecPrivate(&good_codec_private_level[0], + kCodecPrivateLength, NULL)); +} + +TEST_F(ParserTest, InvalidTruncatedChapterString) { + ASSERT_NO_FATAL_FAILURE(CreateSegmentNoHeaderChecks( + "invalid/chapters_truncated_chapter_string.mkv")); + EXPECT_EQ(mkvparser::E_PARSE_FAILED, segment_->Load()); +} + +TEST_F(ParserTest, InvalidTruncatedChapterString2) { + ASSERT_NO_FATAL_FAILURE(CreateSegmentNoHeaderChecks( + "invalid/chapters_truncated_chapter_string_2.mkv")); + EXPECT_EQ(mkvparser::E_FILE_FORMAT_INVALID, segment_->Load()); +} + +TEST_F(ParserTest, InvalidFixedLacingSize) { + ASSERT_NO_FATAL_FAILURE( + CreateSegmentNoHeaderChecks("invalid/fixed_lacing_bad_lace_size.mkv")); + ASSERT_EQ(0, segment_->Load()); + const mkvparser::BlockEntry* block_entry = NULL; + EXPECT_EQ(mkvparser::E_FILE_FORMAT_INVALID, + segment_->GetFirst()->GetFirst(block_entry)); +} + +TEST_F(ParserTest, InvalidBlockEndsBeyondCluster) { + ASSERT_NO_FATAL_FAILURE( + CreateSegmentNoHeaderChecks("invalid/block_ends_beyond_cluster.mkv")); + ASSERT_EQ(0, segment_->Load()); + const mkvparser::BlockEntry* block_entry = NULL; + EXPECT_EQ(0, segment_->GetFirst()->GetFirst(block_entry)); + EXPECT_EQ(mkvparser::E_FILE_FORMAT_INVALID, + segment_->GetFirst()->GetNext(block_entry, block_entry)); +} + +TEST_F(ParserTest, InvalidBlockGroupBlockEndsBlockGroup) { + ASSERT_NO_FATAL_FAILURE(CreateSegmentNoHeaderChecks( + "invalid/blockgroup_block_ends_beyond_blockgroup.mkv")); + ASSERT_EQ(0, segment_->Load()); + const mkvparser::BlockEntry* block_entry = NULL; + EXPECT_EQ(0, segment_->GetFirst()->GetFirst(block_entry)); + EXPECT_EQ(mkvparser::E_FILE_FORMAT_INVALID, + segment_->GetFirst()->GetNext(block_entry, block_entry)); +} + +TEST_F(ParserTest, InvalidProjectionFloatOverflow) { + ASSERT_NO_FATAL_FAILURE( + CreateSegmentNoHeaderChecks("invalid/projection_float_overflow.webm")); + EXPECT_EQ(mkvparser::E_FILE_FORMAT_INVALID, segment_->Load()); +} + +TEST_F(ParserTest, InvalidPrimaryChromaticityParseFail) { + ASSERT_NO_FATAL_FAILURE(CreateSegmentNoHeaderChecks( + "invalid/primarychromaticity_fieldtoolarge.webm")); + EXPECT_EQ(mkvparser::E_FILE_FORMAT_INVALID, segment_->Load()); +} + +} // namespace test + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/sys/libwebm/testing/test_util.cc b/src/sys/libwebm/testing/test_util.cc new file mode 100644 index 0000000..8789b33 --- /dev/null +++ b/src/sys/libwebm/testing/test_util.cc @@ -0,0 +1,215 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include "testing/test_util.h" + +#include +#include +#include +#include +#include +#include + +#include "common/libwebm_util.h" +#include "common/webmids.h" + +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" + +namespace test { + +std::string GetTestDataDir() { + const char* test_data_path = std::getenv("LIBWEBM_TEST_DATA_PATH"); + return test_data_path ? std::string(test_data_path) : std::string(); +} + +std::string GetTestFilePath(const std::string& name) { + const std::string libwebm_testdata_dir = GetTestDataDir(); + return libwebm_testdata_dir + "/" + name; +} + +bool CompareFiles(const std::string& file1, const std::string& file2) { + const std::size_t kBlockSize = 4096; + std::uint8_t buf1[kBlockSize] = {0}; + std::uint8_t buf2[kBlockSize] = {0}; + + libwebm::FilePtr f1 = + libwebm::FilePtr(std::fopen(file1.c_str(), "rb"), libwebm::FILEDeleter()); + libwebm::FilePtr f2 = + libwebm::FilePtr(std::fopen(file2.c_str(), "rb"), libwebm::FILEDeleter()); + + if (!f1.get() || !f2.get()) { + // Files cannot match if one or both couldn't be opened. + return false; + } + + do { + const std::size_t r1 = std::fread(buf1, 1, kBlockSize, f1.get()); + const std::size_t r2 = std::fread(buf2, 1, kBlockSize, f2.get()); + + // TODO(fgalligan): Add output of which byte differs. + if (r1 != r2 || std::memcmp(buf1, buf2, r1)) { + return 0; // Files are not equal + } + } while (!std::feof(f1.get()) && !std::feof(f2.get())); + + return std::feof(f1.get()) && std::feof(f2.get()); +} + +bool HasCuePoints(const mkvparser::Segment* segment, + std::int64_t* cues_offset) { + if (!segment || !cues_offset) { + return false; + } + using mkvparser::SeekHead; + const SeekHead* const seek_head = segment->GetSeekHead(); + if (!seek_head) { + return false; + } + + std::int64_t offset = 0; + for (int i = 0; i < seek_head->GetCount(); ++i) { + const SeekHead::Entry* const entry = seek_head->GetEntry(i); + if (entry->id == libwebm::kMkvCues) { + offset = entry->pos; + } + } + + if (offset <= 0) { + // No Cues found. + return false; + } + + *cues_offset = offset; + return true; +} + +bool ValidateCues(mkvparser::Segment* segment, mkvparser::IMkvReader* reader) { + if (!segment) { + return false; + } + + std::int64_t cues_offset = 0; + if (!HasCuePoints(segment, &cues_offset)) { + // No cues to validate, everything is OK. + return true; + } + + // Parse Cues. + long long cues_pos = 0; // NOLINT + long cues_len = 0; // NOLINT + if (segment->ParseCues(cues_offset, cues_pos, cues_len)) { + return false; + } + + // Get a pointer to the video track if it exists. Otherwise, we assume + // that Cues are based on the first track (which is true for all our test + // files). + const mkvparser::Tracks* const tracks = segment->GetTracks(); + const mkvparser::Track* cues_track = tracks->GetTrackByIndex(0); + for (int i = 1; i < static_cast(tracks->GetTracksCount()); ++i) { + const mkvparser::Track* const track = tracks->GetTrackByIndex(i); + if (track->GetType() == mkvparser::Track::kVideo) { + cues_track = track; + break; + } + } + + // Iterate through Cues and verify if they are pointing to the correct + // Cluster position. + const mkvparser::Cues* const cues = segment->GetCues(); + const mkvparser::CuePoint* cue_point = NULL; + while (cues->LoadCuePoint()) { + if (!cue_point) { + cue_point = cues->GetFirst(); + } else { + cue_point = cues->GetNext(cue_point); + } + const mkvparser::CuePoint::TrackPosition* const track_position = + cue_point->Find(cues_track); + const long long cluster_pos = track_position->m_pos + // NOLINT + segment->m_start; + + // If a cluster does not begin at |cluster_pos|, then the file is + // incorrect. + long length; // NOLINT + const std::int64_t id = mkvparser::ReadID(reader, cluster_pos, length); + if (id != libwebm::kMkvCluster) { + return false; + } + } + return true; +} + +MkvParser::~MkvParser() { + delete segment; + delete reader; +} + +bool ParseMkvFileReleaseParser(const std::string& webm_file, + MkvParser* parser_out) { + parser_out->reader = new (std::nothrow) mkvparser::MkvReader; + mkvparser::MkvReader& reader = *parser_out->reader; + if (!parser_out->reader || reader.Open(webm_file.c_str()) < 0) { + return false; + } + + long long pos = 0; // NOLINT + mkvparser::EBMLHeader ebml_header; + if (ebml_header.Parse(&reader, pos)) { + return false; + } + + using mkvparser::Segment; + Segment* segment_ptr = nullptr; + if (Segment::CreateInstance(&reader, pos, segment_ptr)) { + return false; + } + + std::unique_ptr segment(segment_ptr); + long result; + if ((result = segment->Load()) < 0) { + return false; + } + + const mkvparser::Cluster* cluster = segment->GetFirst(); + if (!cluster || cluster->EOS()) { + return false; + } + + while (cluster && cluster->EOS() == false) { + if (cluster->GetTimeCode() < 0) { + return false; + } + + const mkvparser::BlockEntry* block = nullptr; + if (cluster->GetFirst(block) < 0) { + return false; + } + + while (block != NULL && block->EOS() == false) { + if (cluster->GetNext(block, block) < 0) { + return false; + } + } + + cluster = segment->GetNext(cluster); + } + + parser_out->segment = segment.release(); + return true; +} + +bool ParseMkvFile(const std::string& webm_file) { + MkvParser parser; + const bool result = ParseMkvFileReleaseParser(webm_file, &parser); + delete parser.segment; + delete parser.reader; + return result; +} + +} // namespace test diff --git a/src/sys/libwebm/testing/test_util.h b/src/sys/libwebm/testing/test_util.h new file mode 100644 index 0000000..f50d259 --- /dev/null +++ b/src/sys/libwebm/testing/test_util.h @@ -0,0 +1,87 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_TESTING_TEST_UTIL_H_ +#define LIBWEBM_TESTING_TEST_UTIL_H_ + +#include +#include +#include + +namespace mkvparser { +class IMkvReader; +class MkvReader; +class Segment; +} // namespace mkvparser + +namespace test { + +// constants for muxer and parser tests +const char kAppString[] = "mkvmuxer_unit_tests"; +const char kOpusCodecId[] = "A_OPUS"; +const char kVorbisCodecId[] = "A_VORBIS"; +const int kAudioTrackNumber = 2; +const int kBitDepth = 2; +const int kChannels = 2; +const double kDuration = 2.345; +const int kFrameLength = 10; +const int kHeight = 180; +const int kInvalidTrackNumber = 100; +const std::uint64_t kOpusCodecDelay = 6500000; +const std::size_t kOpusPrivateDataSizeMinimum = 19; +const std::uint64_t kOpusSeekPreroll = 80000000; +const char kMetadataCodecId[] = "D_WEBVTT/METADATA"; +const int kMetadataTrackNumber = 3; +const int kMetadataTrackType = 0x21; +const int kSampleRate = 30; +const int kTimeCodeScale = 1000; +const char kTrackName[] = "unit_test"; +const char kVP8CodecId[] = "V_VP8"; +const char kVP9CodecId[] = "V_VP9"; +const double kVideoFrameRate = 0.5; +const int kVideoTrackNumber = 1; +const int kWidth = 320; + +// Returns the path to the test data directory by reading and returning the +// contents the LIBWEBM_TESTDATA_DIR environment variable. +std::string GetTestDataDir(); + +// Returns the absolute path to the file of |name| in LIBWEBM_TESTDATA_DIR. +std::string GetTestFilePath(const std::string& name); + +// Byte-wise comparison of two files |file1| and |file2|. Returns true if the +// files match exactly, false otherwise. +bool CompareFiles(const std::string& file1, const std::string& file2); + +// Returns true and sets |cues_offset| to the cues location within the MKV file +// parsed by |segment| when the MKV file has cue points. +bool HasCuePoints(const mkvparser::Segment* segment, std::int64_t* cues_offset); + +// Validates cue points. Assumes caller has already called Load() on |segment|. +// Returns true when: +// All cue points point at clusters, OR +// Data parsed by |segment| has no cue points. +bool ValidateCues(mkvparser::Segment* segment, mkvparser::IMkvReader* reader); + +// Parses |webm_file| using mkvparser and returns true when file parses +// successfully (all clusters and blocks can be successfully walked). Second +// variant allows further interaction with the parsed file via transferring +// ownership of the mkvparser Segment and MkvReader to the caller via +// |parser_out|. +struct MkvParser { + MkvParser() = default; + ~MkvParser(); + mkvparser::Segment* segment = nullptr; + mkvparser::MkvReader* reader = nullptr; +}; +bool ParseMkvFile(const std::string& webm_file); +bool ParseMkvFileReleaseParser(const std::string& webm_file, + MkvParser* parser_out); + +} // namespace test + +#endif // LIBWEBM_TESTING_TEST_UTIL_H_ diff --git a/src/sys/libwebm/testing/testdata/accurate_cluster_duration.webm b/src/sys/libwebm/testing/testdata/accurate_cluster_duration.webm new file mode 100644 index 0000000000000000000000000000000000000000..fffe83d7d6dc99a35e159619f07a88f86018391a GIT binary patch literal 376 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~YMh`*X*(Ixd zcXtP`ZV~ldnHIdJF%QBM3t5*9;>y1mjGF@OY8c^W_~9Jm(CW4 z0}Kql4U==T%W_LAQj6kC^D;}~OHzwVio+eTiGtiTXWgvpjf}-d8yTA$8QWUJ;==+g z9<*<0VszNmxCP`)h|d@#o;NZqn7pvB5yh>u8<~*QXg_acT8yS*!8DK_CL~?I8<|kG L2|sUSL)QiXqj_gR literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/accurate_cluster_duration_last_frame.webm b/src/sys/libwebm/testing/testdata/accurate_cluster_duration_last_frame.webm new file mode 100644 index 0000000000000000000000000000000000000000..8104bfcc8a8430f2edba000c83782e600b530810 GIT binary patch literal 384 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~Y#sERz*(Ixd zcXtP`ZV~ldnHIdJF%QBM3t5*9;>y1mjGF@OY8c^W_~9Jm(CVP zpgFz`lXJ7na!V^xi{eZ3GE3r1Qj1H9!yU1Sg4{G`-K^`4jKxPA8Jim!+giio!vZWG zv~Or)blBCn1>{VK&ln`0H!>`kys)nk#jUd&nUK_IKW}7OjHY72G>{%9BwfE7nNYP! SKW}7%C__@k@Vk)(s0;vbpK4?P literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/accurate_cluster_duration_two_tracks.webm b/src/sys/libwebm/testing/testdata/accurate_cluster_duration_two_tracks.webm new file mode 100644 index 0000000000000000000000000000000000000000..cf6985910621cc87d27b61d22334342593784e9c GIT binary patch literal 533 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~Y#;1b5vrAU_ z?(Pm=-6HC_GA(#bV;+Pj7P2lI$Xg5H$vbZ=1@hj$*$dW3E&;M)m)7--&HPRdE}bn- z3m6!D8z$#wm*tjLq!z`O=4F<|m!uY#6o)%v69u_x_qtiv8ySm_HZnFhGPbpb#fJr0 zJZRt0#OScAam%{7*BhCDa!k#QOl@tB@%{m!!4EsPwm5!ZV3^;?1o8#M;|vAQ8yOb& zH8C(WApEkpuMv&k#K46j-^3t-#9uIZA?3w literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/bbb_480p_vp9_opus_1second.webm b/src/sys/libwebm/testing/testdata/bbb_480p_vp9_opus_1second.webm new file mode 100644 index 0000000000000000000000000000000000000000..c3657a74df59e00c813e923a0fa6a243737c8932 GIT binary patch literal 45863 zcmd42gLhh*LRrOTm zIRpJci1z}6K)psSxBoj9r8WRewLJi2Tlt@c@;|Nr31hJA5BfI@=>IQFh@hUFyo!=) zd7u$pu4+dR_+TR-&>wW?zrm1y`9n5^2^`t~duoQp{scz(nR50nP7)>t#vqU!Ai$1) z_JDwc0>D8)!65L3n_d3%)7sS|e?Wl9qKI9s`Gon+~u=QYH&QW3*nEJ9P7n95Zv_^ z_@*2qHTo`si~z+pNqEL@os6Q^Vr0$Lm+QDetw$Ao$WLm~#XvUtkBfaVm;v={7h;0e zNMD7Mf(WJZ(4A;dJJ>qNUbf=W%jD+ohFp^6QqUL-lF>H5IE#yT9hj>J9h;(9m%|9L ze;-ArGnMEM79&m`^d910#e5uY5e?l@2tqfs)uNd5Z^qoPnvUdxKYYC#oe5aXPm92i zUkZpldtrE(QACHlI^~u2r1}c|9tbav_pDy9ij(VNKsH5!W|0oj6OERmEmL@y;M=4p z$`j626}T063KoGtd$BLPL03O~7LK_Qy;!A8<&S(dS)!XHh2c-ane8+#F}FXyg|8e^ zG_ai^_dU`hLBec&l(3SGnap~7lX zzs4HF{JV1X{fo)(ZDmvbuq>lHvoiWPq0SX!9>3>%mMF(Q7= zuxJHz5pUf$>qVFs?j<>c?kmBsZ6SZGV%i68&ocS45z%JOt(WClFzdTAg8><;&PVDj zv~%-sG^JH!)St{wS9)q$JIP(-*WHRAqk;4Q)#1&8MdOiFu0q;oA-Q_Y_3^Q9V*1R5LG@NpfvZ&O3I*K zB`I;0$3VozAA}qEOV|)&2X-GAVbcoOz=fi$Fw}4NN5Tre6Nyc2k^7elp*qD&t=*Vs zI03VrP`q@}xy*w|3ydJn)|)V5vxQob`*xMzwRJB@mOfuzj`_P}f(;!_sK?<33WHd^ z2}j#rbt6-#_rf)5>KXx;mufYS>f=-P?7KU}6t?hZ6j1J*nqN~thnqrwK+~eNtVoy; z)<}aIhtQ~3K%ajiHWXNcJ0HlIWIxA5>1H??i3d5yAr@f>C0f!MOGlR)=Ny=`t~mPE z8GRdp+!eupxoEW@n`#Y&Eo7q^6CgUz!(;@Try;I23rk z@_UX(N8zGRz2JD6ZZy-oEKa8BMwUrhsp8Fc-uMpw{Tte(^gt91y=OexuLjsoBAXtM ztN}ZCL2f6?GNpoKtq`ENh0cn@f>EE#MQr7m&uGpJpc+swOxIhIbJ3v4@(VtbgDK2lJ_?C8CJPqaBjpD zl_u>5Td5pv<_Cg{!G^>wvuKk(U9;;Mn9mK7VzLF$m7FsG8slQy#5>3K$Q?jpePziQ zRJRFR>S4!|KkaPCMI7OYt@Wz+cT<Bm;#2tn#>z01gry zOlKs3y1^s=UcEWQ6yEkf1cr$+$(NrNk9o5&5{k#-ezG?ZTO=Hd{1fo+_YG$VN8*IS z@ysIwdy}*K3YH@7p#lZMGy#C`f4PmWNx~cAreU=rYBt00ln^dY%r0cW!58Un(TQ`{8<~Q7S@G5^sy@_~kA!x4{OXFz79s+NMn`5z( zBe;S#HPnnE+AcX2BtZ;?P7adH(YSDn4s&Aq{&fZc(=VMn=9gB%W z6gv0kF|nDrq26E(u$6#+FTZN1?Fi_li0e_A)e8@?t8la_*~p^T8CKK#`)7v@XJ!4;XnF zWh-&in}eR4vrEZF#KJrm&d}|I2&Gq&ERgKizmCTnwC*c4-&F!$O;R|>pnxJwWF!za z0@DLu*fcDzkX~tGZ5q46Zexx*py7Gz6_kcNZX8VflwVedR7j@hccTU{8-eKWM+Qs3 zJjjrgKYL_AJB8~yVs2yWD}u#4F(YBR8#1gRUYaME$XAS??fk+Zp-)(E%qKf#$>6_3 z9o|~2RdK>7RE@Bs`bBAqk{jmW_@LsL9#c;Y_Q40XBVyUK&KoTJGNxe3BzpXzD^qUG z@7=KMriF;8e>sU*e`91=(m$Y5y5;3_jj3eiuW$PyCEO;*Fgy(;*s1)qG}+3R>&scSSI>|%#ecSAFG5&CdG1N3|pOh*DC1QEzCRaN8l@~Og z86d8?+pC^|C%Ulq&T8NHh2mB~J-HWoQyd$jSu z+;#KR^J6HyL6GGNY-Ud^K$D{LbCCK6{iqRvnLek;0Xps&+*PZ3#RV6mr<~gRtwG;o zFOX+ff&?1pO4jd}%?f2-6t^I1520HD^49(cnCrX1v=nPa>SKpZgNHns?$+xsL*lpC z=LGCwoC#pIj}4jdK|BdtoK7+{%26iHMCY{L*#g#WWBtlNI{#akv|OUqmlCnW>?%Yn z4IQbbL{Ew+O+LIYqiRf>HEHgu_-xzggI7cn9-%DZ;I2S#LS`pjymcn|04Zdnc*67<7Kore&0p6(YS9kn1MHu&B1cB5$?*($9)(fJ}i^9FRY0ggb} z>~Q&Y>fL~W4o%xdwz^c9PrFL2=9vzIuD@EGKoLMKBB`8 z#+US?H|(%wwvo+I;@Ivmh?}-rC$qMHFKBYF57v!i5Bb%V3H?yOK|m8p;Z;`$OZ6XU z3uF2N7y&^5prj`tydS{t7k_DXcs^6|!e8*)cB|mSt7mEV`iQ?rA^=vC-2Fpe?Ezy- z;{8hQgvTwuXg{HlVPwB4-$-g3nD2J6_|I|#*wr-r`g)bnNIOxr-N9Hc{o~xy?Bl#f z@kAXVf(4C_&7(%OM5uc9T9b}PrBORBlef%rxL(yZdF4QnOo(*1!Bh^8rLMkgcS^|+ zRP^M51zwR2*YsS59MwAF_Kq&Is#ctC^%~^Y{(}C{g_Ux@`WpkKI;jvZ-+^;ZAT8Wj zMqH#u%tmF`V)Go-j0n_D!3w_aw7t0OFyZ8P4Sfq~`z(EebrrID_mU5?mw2z8Q%ZOB zQ>pH*p=%1^Ht|T{e}X4&o*Y~>=hvTTU1GaZNWDCFt1=z2 zBVHcH%wT%Dt{NYx1VjG)PSm1s;&Wi3H|}#l7Q(EVSO!J{J$Zir4Gub}O@?4p9VfUm zD&%^pl_##1GOkU|9V4->lK`^MoLB*L!{tb}m-h*n8`y}IsNxv6v6auRJDVu2=MZDf zmAk9Mda9N=F*4?W2W(H5VP;7G3E%44L>XDwe#wi#+c!~^OXbgt#nUY?mJ!^g8Cfla zoTTJeS~mwFTPHTd5%!3Lvnfjv;DtcE>jTpU(0Vn-%B_IW9zn*K?{ZG!vMfWdyb?uS ziX1O7@buMKOPf8h)A|j?m<5b9bJa@Irc$xmK-l^4jN#r$W_VuFs({9F1bhX-Ztk3* zCz{j1#5;i7$E%!o@@~pP^m{F#-D$Il_4RF&e|NqYzFX@*hKge|a5v0cmmhJ=b{*)_ zR<%$$OZN!HyzJkh&L|UPeHnPiubIH+6I{FlokeFRM&+HIVx19i+pa6W0MhWsyD70* zJli^V$=J{usOfSjd?Ua~K-z~i?L654ga8CmvH-IF05Bj~r9$S^zp#bSfP-0**N7FL zgB`mBB>;>S2t5S=c!BSq_>Cs3v+DA+ok_FJaCezEwYsuq(iMa$i>@7p^0bKff2q*UuNc_F&>oc=-DMxH_T z0-Q^J274HZwVM*Yp7z4BVTyu7hi4Se-Iocv9*T?F#SMCD{Qkycj<}vML%I?pw?@IhGCa=n`b_|`iZQAc%6=LPs$^=Hv7ZJ@NfHnRSS$&&o@8g7#_@DPo`X$K|F8;gn|zPnioc`*hTy zmtc1DFYYRT3elTDhP787_}}9BNopGGzDd|OtbzT}yLnyA_H8;D+iIcRB|EB{O!y=a z5u9wB!h=_ECycH3ThCfP9}JC;6sDTbBiM6gt1^_K^0B9$qmD&qW{9CV*Un#jyXbG% zFGA=VLnpFJ6;*#Yk{_eV>cjC^N2GHdL+59nVmKXL_JgpY)&EGPzi?t7$h6!{=5T>< zZ(6!Jbp7I(Z++q&e_>9*c+xs$+(R_FJiii2N{*F5J?Cu!#v^+TRkQl$m z!5xrAkZ5A2L+x$?2llhQ5KQ4oUn%d-wEEm*2MY3wKBgcaw7X30U%m4u0H6STe}}AZ z$m+(5vYpV@@v?zKv2)cHOHWt=0@;RhF)n=|A}te?%wK<%uB{6Z*rm=A`2pc>$)hsf zmz6YE(H8+Ox_QQp6|`r*$6i5$m9?4W!*9oYU)Z4IwEJFXQ=fo+Z+QRHguDc+)ac`b z^BzJjbOZ_G^3p&l~v(xzXuEbX7V7d#Z`OE zZNOdkTyYr#OmPUaX%9<6$bo#}Re${C$eZ2hlZY;Cq8wBaLtS-XmhtS|Mom(y>Wh?) zKk78FX>jyUN@tb|x!U`YzBl7AT2O`61AXZkt>#Uv0%Pl+to66Pj$Os=ako=wtFt^0 z5tdBM=ZHnkO6qJGXwwAQWSL^&Zlyo8mhvjP&hA*W_7nQL)lO`WxQOH~{_`co5YWr> zeulFX8?`~ebP@UElS$nYMb$Qwy^MSTe3!{R9;_f8ISWK~dV_-Yw%zK?4}oM0L_EK86RWrk_|0gj19T2 zP<7ExSyHsOF{V+q?8l@dh&cF-zO0+Sxv~kj2mpB0H1Ca@|ijmQ1o) zw@KFq#sCiGHg>6PVQGWu^XuDs(mw~k`sBCpc8@U^e`Fg_g=S^Ug3HomaQAuLQtO5G zR(a~xHM_SrxLDDrp{FiMFd&+C611ZPhYt_-#_5%YREdRNyp~P+N^jrQ4y&;x^kz`ITb?T-B@z@ zGiLOQxaoHj{1fXb$vA?|U5%w|&lL=v*lK?Ya2p?$xSP#(5UOA^A7V92j(HAVLI}!O5N=4nrH&{AzZ@UzUxg^EN#5BrPRkVI2B~eQvL|^i`>Bph#eK$+JId7G;WXau; z=F85UqH^rA^d^lM2zgb~KcvDH;;ajNKd&y!D>&^&ukD_FPD5mxRQ!qJ#Z!*Fmka4m zm`B+SB(us&BeSok&?Cl_y`%=Q;+2_ekL9)ZmVa2<5_xxAs&{zk=R4RJICT>xD7qsi zMsz)Z1h+^mGuTnOUXFpr%+GY@5ofl(cu@^wycd=|b?*X3ceUTCC&uvh>ERLLRZx}RejPO5cD9pW+W z4EQxtOA}af7qAN%QKSkCdGs-Ie5Nwn=p8rtRQ&|eeRAV2v`c@IHkxrs26i%!9pFW4 zeXFa+e&ml#$hIrzHOMPqIdd9H5X3CAZM+}u&RA9+kHk0KiFRW@j?sA>!+BauR4}Bx zdlj$eGsvAF?7-~8y-@l_(9%o@fD;2Z7K0ZQ{ukInWdQ(>zs3%9y)f$ZLBJ3%S&$Vw zn{tLfpWLWQ38xpDz$Z;Cx5luN?eCOIivk=qV2J=EW6vj@+VuM{M zOug+XWue6sX0j0-XWp5vONy_-qxBH&3#D)_z^X+MLl(aam1eztop^d~0v|%X5q1q( zg;{1gS-P19pcN0FXoE4{uMD`e)+FA-R@*ZuLNH3Gz&(ZY( zbi4D->S|IxmLIexd#vh0s-6Q4e0N~X)^qon#kdgm<9qdfDYOU<_s&aJOsM`@J2IU{j6pbstVT@(L9!a@HfVL8G7I|+9O0HXhr zFhad#Ua`L$zPu~_S|>{*GRRR=QEq&B(Q79+T4;#@wxTlbqsvNJkC~CpnpiA#9*xV! zAEnAlaejNJ)Y_HLRnqHA<#a?MB!?U3^-E0ROUjtqry==~(cA%%_mrA znt&ubOKZ-vUIo_f!e?LcW!)R*;BAA)4yCa5i~K>jW7E*|9+B*4>&x;APIH}uxy-~0 zvTwpCnwrN2S4R34uOSC`3mVRaBf`2i7 zt?x}b;3ukawSnCE8dqk6?R=BG9ki|={c~Qqzy=RqC|~N*zE;M$@Q1D{4^7(6w$i>2 z1^e3C07>8l(?g!+4^GGGG7UPom;lSdIg^DOH zO9r~!Da0Ug6{6DbY#7h7{*EaLiTIlB^5F&Zc;l(eJMYCw$vc&p`ld?uLr&OdKW1!b zyuu&OilcBa<8Ep!_O=?!L7}Y%TGUv6xO>(|r)rol&NZ7)Sw_n;8S;6HD%_v$ycf8x z?2sXknR(vcJP(**{0tv(0giP&s#%>q6C}Kt0?_ z3fD6J);3*27S2oX}sZ`7-i1L24qZ2TNR&~Dh}$ft&8gYieheAf5i6OWTk;bN|p|Lk@NPad&CB?{SYM zG6g^J*rZtFr^%`BUWp@9$Fd23DZz4Hin47*}%F z>z;&p1s;9P`?cq`KRDU?;l~b8L77B&bCZSw1J29i`6!c}p2O#avIv<$BX7H4==U-8 z>-BI&?aur9>dXOqhP;s+EaUDf^KczwNHI#cuhj&s6^syNHks5kWCm;0 z{Rj)N8+!IZQ?t8l0-EO%V`&_mcV%31elaij>|^GkOV0=;WZWebXdv|5G;vd|3>8bs z(!dRCs+_)--*=b@4J9v%%gSsd;dZo2yFW{oG>ai-OT%Q{PKd1Tj&B$jLiN<7Pip9| zY`r`O*OSvo>^6l>&%0%f(tSr(g$s&Uhti<1X2N9GMS`miH>%4w6bVal`-8S?$315M zdLkq-kbckE4V&uWv8Qp)p$+qY?w_viiUL*Iexp-kT^k3Az_yel{L(E8WgaAmO!2_v9 zQXw4Ib8#2&AE8X5y|R)@w*XTb+q8?F;C*@D=Q|EM9;DpG0H%*(PJg2ATA&Tkj+x}~ zOp7(=l|rjiy@ZDaVR?@W`ewYW<(Y4R+eIZ-6$ti{I6a!<22@aC>MkzVO%)FY6bR)9 z0Gj@0p3rsWw-pp<7?3V>9518j$EE+IMI;_n0%~eJ1H4MrTs{$IKc;9T5}C*MIrP6#6MBJkZEj ztA5YsTm+$5Q-JKrCxA+BWHCispN)>uL{^AE@INO&QC)Xcqn{fh-Me_hAdTuhMlLAy z5)!oU5i^pQRjg5sOLAeFL&`o-IJ{wQEb`HvcYgr}A7F7r zv(50@K_EcDX2LDI{%HeIn$?PFeGtd#bIX(Jz_o8;&}kY(O0PB?-03&U>Eljx1C!dt zD-MWq5D5UHk^bsZew&DWxb*z4=-OW1yndIHNRswfdUJRDpdF!m+SrME5j^>Da4NBm zPOd!GW{!|`GcmIML;fs(f(#w4cF}i&d*M&uN#df)RM&QZ@yg)&QmAM2_|rEF{HplP z0C`?h?)!d1)@>m)wr+3MwF+-7Yrb0`^f<4*kP+uR?rA!MZlr@{q^LO5=H5D8J3%4Z zj`MbcMglKWacIJ(T!hgv=tI9C2bd9x>&8}Cv!xV%0N8;VbNMC=3S(P2E$7P(@fRv^ zQwd<#$Luko)^s=Gxyfu{tWtcU(NSLWEt|5xyD0}8!WlKPzo8jQ1#vJ6N)!o}GH8nS zvN_6iq?`OXran4*+McfeoDAt_zSU3CHgD-ZPReFGpI4YTgY8mELX|?%N!0mkLP%T` z?D4u3ls;y-OA^cC8Su6#3|csj*&RPDi3b(#IsSH&H3=d5S}^y(t@TuE;GPQ4F!E;2 z_8S5*tIRi4eYO)oTQT9@KBa_t18MB!0z_#BchyY7SM7+?OhwDt`9!I9D^c3NtX>%a z82c+rVCyAP9N1vBd;b8Q?`hJ zvmB?*i@HPb$emvw4{x=5VC`~3?JYd*Zl7UaI!s&l!1GvY?f>53Bwr~+A7@T^Ga-fa zwWQ+MWcbBoh`CZ-Qaf-?(ssiyjOdO~JowGT3ZPv#shS;{)h?B{26A=mI+pa9iNG<6 zf!>Z*$8_MN)DF$~;8)yR6TWL^-1Gf@t-<~oeIxy}1(twBBIp}09Lh4g0 zY|eaIG_tOHX|NeLwuWqa;Kusd-FdYlOJ~wSAm8OczGUbZ|JJNrQI7IN8J_a;Oj9;L zr>xcs-o}(|ODgiQjE!HSf%joE$&7BP8C^5PeCE!Mm1fs2Tn zfvQoPj=Tn)_25a9-w!x^5ph@v#4x-=&o~(*Jj6gC4Wx$~G!<2jKr7({l!+m3jY>Xb z+DLA6sxuw@j^P@3GxpjUNe#X$y}f;YDyis)gzN5;yYxGbE1^G0iR-VLh9F)`GoFY5 zU|d$uPV71+fWMr`53|FjW~TlXA%ViOpci8-9iiAxd3H4|h3-&VgF(RU&%uwWMst%i zvzR#0#RtoJ(_5KT57S5p1LsV4Q7^>%A<0Nd3EfAFjvF*8$OrsUeh^rk+6ph9=dp_B>Y za>&1M75L>3SpF}c%kBWc0Q%1^F8}a2fRgKh^nj4LxZj$&HDrKCO+9F5CBgnO-3CH$ z11o-6Oa%P?1k<)g^ilqwfn|t^@S;^V72WK9B=ZM=n+w(+- zeM!UXX?-H6Wn&v0e9b)hf$lk3pP>l4)0KEPQmRhLRT%|Y?)|W60@pDOs5_~QV2}>Y zBftWok^sQwU)G1MkB2i1;abeWi`7@u$$>a;LFUh+tdmfRhwnCEn-gwXGOE?H_s;mv z{kQOM#@Kdz?JZ)OACXsgl-WTQWne4O{5Zl;{WR_~@ z>L(f~?+vU;?~HDIods zmneqzb7!yOpC~(59X49BO57X#EveT>okaPAUdwwJ)m*CRyV^Xra1;*sZPh_|yUa}o zowZL!Qs~j>VE`3TM1rKJfk;NWD9sL7s-v_7A&L$tmx<78bnkvTf6c*1(P1AfH|$&# zu|u-Ls-d~dR(8vm6&c@~3b6{I2Z9q$#oc|oY|t)0H7x9n3$Md ztb#n>oTT%h{X$$>l6jZix(*|^2Arj#R;;siPSbP!NOphBW6ix6i3ag03lzc#`Z14W`*%FECnm{cb*&D66leW#1#((jJv3^U_abW+1s_LI|Kb zOjC4Ap-PcI@XNY*ByP>K8?d%(s#R+Zc<(Z@K4y|juUD>eBMbU)Cm%B+BfEQuH8EZ zq07hOo{i+t7393kcIQc1MgTKtPh2*2;pX{b83_GTzf|L1UAHfz-eb}PZJ%UlD#izV zss9RsX|Z#6tL~Y2&(O(Kc`pkVn-BUmh5wdWqoddK2s60FLMQopPHeb(iPxL8pZ90QU^_hb6$&s!l9 zDd-IeHph3?QWU3~3dkHiBlYJ%T`xFi?=i}rnEdgnyB;A30-XU5!47W>(y&L3L{1ly z;5Lc;{UWUIECMcUtKRobq zjQY%F6#JWt6(hO)?i#M>e(F`Cl^St0KEV3{6+I^_qqqyCa?ot`Z24pA#w4WxU$?@F4qIG04lah zTxpfNhzi87w6r@i_iocI-cWAayFCd#EKgWwP~`?D!6h9X*;on6MKV>D-@TRZvl(r<1wzFEAP|4EU6_$fORjv+6Y()u2ECIa;S8LId`N=e!MbE*Twc6j*i&K`@6z$jOPkQZjQrkH1@Op+J@H%`|MC^sa zmtO?#CH^J}n`k}o+Bo~sTa4?42^PgOr`VB+P)vSUQm2fc@@*+tR%dc-X^@wA!`OngU(O=RuNcSpi_4RkU=WCEA!_T23TUDSTviC{&z>;d@nmS#B zAf@|A#i3Zqtbel1k?b`2j*{CF!c{Y?>qt;{w)MhCaN}i}+Q3!|NCgZyj;~C`ZX;2-?sk#XhhTvJBIR>!gwl87iI-*02nEgFjC`l3VJQ zUyeqs_&k+J*$NG8m));@otSQ4p#)DNCHvZ0UHbAGpQm-vQSj?ZxIsJ*(@$|V`Z zBC_d<=?pK}X8TEU9O2!kpAhl<1hP>5W}Sc5%j5U$ZXH{6)U)Vcs&JFO^k0A=aq? zs~^8Pn(U{>XSJ`my7X6JFx65U{nYw7ZknyDy*5c;7WyCqA)f$Yz9Q=l$w5=iKO8=u zY+xH4pG~XGySvq&?JRkKt{8sK-fyns3NGH+I#X3^yIA9WDm!4;QM_DTex32N`Qk!; zm_l47vc)s);M$c>7KzV4eNP|qQlWoJA<9FRVwD186~uX4E129TM4&1`CpUEbJFXgg zbrzj0`H^&f)p2^spX4BcgL|J zOZZRVtls@C&HkiXG}DB?g-`Rjn}?qxMpj~nNeH-KNEzX4>YTtd1i)%5qs<+ly{REy zARgX}OO~E)mBE^8No7=ftFZYnY5lXEz4>^@6r4)YYrnBm7YFEuB79MPw<6#QDP@6B zx=MO*BqV9c7?#A_@?&xS6T!Wyl6~bO{A2KiK#|Hr;N4rY?vkp%w1|K+5c9zwf-MMU zsvj|!K%@E}e4hJ*Q2*B%m;J{X*Z-Hsi9K>Df_Z;}H7_x0K&6}3 zU$$arKwME#nFDZri_pn~w;Vdu2n|K9G8Ewz?FI|K4t9kKH>lL%z^Qv;>NPg_&;lCf zqCP1r$nGm;3ClSh^N)&uGS?vUNAy414B^F73}#a)=a|UZ1OjOro?xF5JL^xxEe)D@ z^4LTmNXHd0Xr|3V8U3m*>e%dEj=X}tLVxm2@g~()hnK>{{TQlVy-4>-P2TBZS>FCA zr3wE-4^@X6fjy zKE@%3kWUvpQmB!?;7l=WEyTJ2no(0WBZ0G&J(In%rlIAJ6&v+PNb>-Pu~vBOk3s3( zm=poQ^%-YBRHDE!BbJ6y0jrbPj{SuyA@f>0CUUVwS+(oEuDoSaLZpcZigKyi$In%0 zg`oNY6muHm^*if&>F6{Ae&oz8dZ#8w*;E-=TTyJU$9l*)*{}2?<3I_AQ z{p5l%+j|ZlSy6h1jGNvh3L=5K*8deT2NEL_vg7L!u4#d+Ipm~}M7x#Ll2wIJmy6tA zq1A2&Y&s?i06|{;u5l<`rru~ReuX|oT$0eCRVBMstet(9o?KTOO|n6(h|CmR5gwL0 z*f}Ggs$22~_nGAw$fYC-=MDaxE7$~uskf=lT)21w^)-%@Du&-j|1U%51%L?t#Uz}v zfLm#2drX6#z2yE<Gf;wPE<5EeO7WIra$eF=IPA#*U;qguGFPn3fmJVV)^_E$u1L zF-$a&7a?rJ1rwG#N~W$8ZuKE}fz_aE4yyQ4j46E8jJ<_h8bk^IU*o6F(SLw9 z-U0Y;6);RgZ&EN_zEupXuGl-2&dKYeI0Wox0;}zV`$pQE4L&YzW52sI_sRiUI$?{R zi3%1G7%;Q)=e}uMxtxuZZj8Qie(ZK&2dbFy0_X1b@4~+LP$cQUo~0=9Hy>LTKeQ5u zmo!qyrn_HXBxT_p{z zB`@?9$jVZOCSky_ytIMu-qOKX{jCkL_Z_dL4}p2#=irXme;4{MVS8?+{}r<3`M@cD z5J1H#ZPLR#zZrp$qwd;s7?LyyF5;qKKB2lFDBMyhBCU6|Atom~uYXcs5@b(V(sRG( zGS-g|91QeD2C~qN%1(JiHj{->+eVf=hbMmYZ^KsnLC_z?w;^aV@EeFt(wZVzN&WOr z68d!(^jA!6_ryJUz4=>Pyoij^41vNc#xxaoI_XPv^w>PBf0F7u5#Ftpw{4B-3gpUF zDgSgT<4zA+4jkGcCDP6lyYDZeieLU2+Q#Hb}M)Bppf<5hH2H(2) zV2W68%aY-6_xbo~`0(sE;vKJ4z=NW*j))5d#=HT}LAOrGa3xZ!W^M?<*E%44OzQ=0 z;WgUzE2~XA`(dFB^npyE*dF7+&+SH^j9IUvz$qTQtc6cjqi9$YE436e$+M)?#VIcv zb17#s^4HDm+@otxBfSVVf4v8|z#;E#eiA_0AAXL8Fp5ykh45dD3e5V0DF0V*|J(sU z0}QS|D++zEe)-ti(op_Kc`JJ0virW|5O3A{s$%bg6bFDBM7Z7M-H;+D=>2QI#{__={JrhK|Jv_mp0(uX zf!RZ$iO@F-j|t8bHsg4KWoocFjnp+cSOzd3IxZ02Tz8(5|IFmZKW z>^vXz24A8rN71uM$pgCSx3L>971uzk zSXDPBOyR{6e6x|1GQRTGUD6=|?rH@q3vXKZ5sRrTO0t-5p4u$2%$VA3ClO2Ss$Iuk z8Yo&d5iCXIWhx8@z~+2%z$NJMy*&!K$B`xFsJ+I zo8{BqPjvTCG0IXT3J$<_P+?nvqe7IMJr;>}@^I}pG9SVbMps162%1GS3g4FPD-XK# zlM+r9i_^yr6t*gU>v!3mNn*bR{kXt4U_lNGb#C4xjxf(k<$81PutGs ztSFH>wA&$#D|OI8(qCRaSJsCp(0lUE?eAh}J0nK@nQ}C}^dq|HfRj79L0zV^B)bx_ zwzIz7J!fj{t!F>~D6VwOw7!jY`M`!01j4s^tJv~6OqcCUwQctpzE65a`>&P2?8k}c zS*(CM;}_Ied-$E;ar@n0hgov2Owt6V6z=7lCqj%E*VWTPgotTt-Rz7U^yoR#8SGN6 zP0$~iB~eAC6)ct^HSldJH71`oPvX|l!c9oblav|4uHE>bFWfU7wWZn1b?qQGZ(JJG z7}7`t+51C%3C*-lhX1YusR1AsfBhDizs{h63@502`B2I3dz;DP4u*b4-GT0Royi)ya!KTPAUbeJtzCP;B-hv)nscS*zvlf6r&3q+{Om?e#`y4)b>)-6|% zI|1^ly0>;V6_rj&u}`-5BW0zWn;csp)}rLR7P|gP)=3tX3-4v2Grw&6$B{ZN6{6 zG^YI{RYowavrLcDPFJ3bC7Ndt7<9!2`YNl0VpecVQz`2mf+}QnoCPBdY~fs1*ba_f zVp{v>N)c?&^x;m*9##dcqcfkRr6Olpn$aw#`}!*rQQo(E>)8)Or^|#S8b#&Lw#8lP zZJ<%Ueu3h?JLV0(F%hG zW|J+ye_@4Q)zdQo#p;&QCmGTB{rlK$)X_GIB(a~-lLsoD;21sY*zK$Y#e{W)3S1U6 z`k)k7SEX8`ak3??>RSVZp6viVPktZl)#~LlP&1EfM8!(CsaPfIrpfP*6r|gU{v@+L z*&b2&+7IMxaV4vZ$t4f;Ayv>x(n5AFxVZavIM5y&I*>_(be=#PZ^ix-&}^H+R_jR} zfneAWVC7x`X0Q}4)XNqNtiPHWGUs)^!1N@fRUF4ruF<<3j~(QUpM<>xv?&vl6)hFz z@xRDS4*>D`n?pir8KQwI7fp05>Ep!M4#x1mf<)gX4tpP0us@deHTPS-=KnzDzQ!Y3 zs4!!S;aua5Ez_VO6o<|$25(}y79)hsLEmHW=p-t|NVk2WsvS-Bg((}-QO>T&z6`dM z$O92mGnSUXRQ5Dmm0ViBgHz^p+)-<7taJ_aZ~$oKH1&!5x75bAlUie{1+&{G-(0(9hstGwDRrCzC~m znHITET=03l;HxF3FD_9Ry=N7rdWjK!4{~1{v(m$>NQ@6Srd%0sfz(}}2qI$t`Vkc! zo#e;_oiD~Qr$-SABJx<3NSS_=sLjgXhjI0Lu<)k6SJQ5 zaxZw{4=d?pv*~~))4ser&jI>o;pMd~3H>SvzP2%bU85I_gNhWjuIx+S>pf-}$9H{# z{=nl4tRzr-9!esajZ{1|p?pXyX$pbRT_(PJZhBJ_xsdBqQbfO@7OWX~8A>c6aQ5|n z@O-&cMKST<%_#{q^l;;^O2p=)I%^h6d>;Rp`ut_M&7KpEecx0PP0gh6uS+eE=MUoh zKguNU|4Sg*DDzCTw}4DK8oo#C;!Y@N&_-H)MxNNAh^JrAeK=^` z$wd&eI115u71!P}=iybx9lv^I7$d=#`PIW5_N@)!y%UOGW{OoXx1GEyqET^h^+owj zgcVBj*)OG^7Zvskn5FO>3lMjA^_Y02g)R`wonM4D7jN)StLOun>;91%zyOf=zeQB2 zkt|FP&&J(M8p|IAhwTdJM$f;SNG%5F>aY4z@UihU_NbLMYxioN5)*v_W=-1KOgi#b z-o*m@ix@Y(@ia8QK;@_cV912<=i$Iov?2*V@)YU5h-E)!!nFWWhHMTzU#D@x&8O^R zBkKZhL2GfIKv{1R^|UmZVNQQ?Lsx1Y1MoKV4Sf0xSrUD6+YF4$oJh&HVHU;)2F8rW zf{|2ghQR8od%D;^u19pR7`Ok6rEhExY;Bs2ZQHhO+qUgYY-eKIwr$(CZEJ#)XTN9t zf%T=Ys;;i;zQv5y*eb$ws+fY0anYVd3#J?WDnY{3=9BM}CkIYI8QHOZe(t#~Do$vI z{t@nioJ||(l^jtuIrB!qtk~zc_4ZDfU_7q|%ua5Me?pG7sz{P{UWx`AGCk+1+jEn; z&r)zp^@GS?4&va}eje#7>jj@CMU++e}Vx$oV<~CUHoNE4WDyN_x!Q> zx>u8RD=@{V<9UP6BsIzrA$y#p_+QDiG77L?2aKX1G#wyf98c1=`9{bO498S*?Lo1I zGZHdkc)%@SU*$D#aee#3-hsg)t)mvH3Wl*5++C3l^z7eUG?Uvj78lJbSKFyWJ@js3Q~Wf;Ujh~R2rnYx`OK}#3{TE1h+pFx9Nn+nRd57%}Wgd2d; zO5_dnZhV~0E7EcPp@!XqO+I0TABjS{>|nBG2Vx*DWDXXzDbF4UZrGA-%B|-ED*OlG zL4kn9zs&`(wpKtl_zg5Vt{*|`0&t-_PEckl7JqVPLkpj@Mar`A__k;~J7vq{TQbg! ztrS@np{HRo=>{`7j!JEJ2Vs%U9eZTofUf-kfLa<+4aK403cE(EUHn4;;DMd@MK%5t zbIZ`xbYnBG?`zRMPga&DfxzEwQ?DlSr&(w#blAk;%$0cP5r>t|0QJgjy713a%ZOeR zgidr|yzg_dxdoreSwYKyie7?J19{y-E)b&)$%VP&SSU*uytYsK zR(6M@LEiSlyH4_m8#qeDOk@{DbWK@WujcwRM6yk1%}6NoaNd8Jc)G?`GIw7_2bWY0 zy9%sIrIz#EUsU)>- zdKN(6Y@GznR*_Y5SY-*Y{nmA#Ycy^G=3qjb^Qgs?wUpi`dQ zY2*K#HW(&*-NuII2wTE;Zv3wbn*spK073x){oK7?+^XK;|v-HJ%yUc#to`U5F@rL$$QYClqa$o5`-cSUE&G zf%~1saUy5NmPSsEL7%xxFxatpnEfrA$v>t6ZcH{Omj2!fp*fz+9b(p86#MvJ%;@(X z>3~|Y3IlXnDf({VM)5m>NzB|IQpV!-Fq9x%a~n13@Dd?yV&ex zA|EIb9c`~EH{tb!gSdveleoAKF){c$wtI8_Cp)G|@LZ1W!C(o@-Ekc+jfFZz>q72= z4I+o&Ry0V;*YeqI{<>~*vh#_2*ut)v^OL%-vCp7}#4i}+!Ot_jEphx4ftZ1-Cg`WJ z3IA3CA1Y(2PcLBv*O52RJHQQL+_@OU@UGfpkE>W<2V%do-Bz3MB;BZqgO^^i(tXSX z>S~?g5H)g^N~0RP!}q5h7l`z)?Zb(C?fUNY0cybyOjc%(TRZQs2M!X z2`msyvRMweC}EwNv*3xMseDCplbyXdOtDh}y?4lr5QG+O-RzGQ=Ot8K#yg?UoFyBZ z`6BAiQG0vVzNw;#+iEfxOy)KUU6q_umi1RCQ5hTG1tJLDdvJ`VP>-?zE{@hMX|_Y_ zPmB)Xc=9cw19*)$H?3JzeB1Em!~&gmlDvi0>BqAfdD4ra&p)Qgi+3!Ep5x(McrrL? zVF83ZLrfz64K79?!4l}?&l$Lm>gAtEmbquT*5is_iZrWL8DglY3%n}A%aL@YU#yAm z#S}|5%Nt;Sd%(@Y+AU|*`vCu$Y2AoVYc!N${|B62fq>J$zzH-8fH-8k_9pCi$?9t& z=>Ek$$CsmXeQpA(jT~9WS??`y|P_QIJ^nKya zfoZ_wrJk_N&8H)~A8r9N?n;(I5@hC3!&`QoQi^d0z>DXpGf<2g$6B#80N?hWoKBGO z%uG+Aua}B#zICSuPv8dj+5jn?pF~lc1(`^SF?+lpo=pW5a9jPXnm0-8e~gKRtf>W3 z6LQ2+SETxEbv_r5o+$glH->a44kSAnvkcT2D8SKQGU{U8ixq08L=Q zBmCMBv{DLo%q`Lr{cf3>TvF4KcVtM>&#`?T7PMoLdxi*A!^7l}CRrCyt5@MW=#5ej zr?t)fOE z*NJ5xM5RPcBOTcRh2?L^YsBt|JT4(JG4OOgT9%}>z=K8jc0?}#9yWt04Qqm<6 zua-g7kV0wj5WQQh#2*wyIw0H0tBLPb^~bmqHLTytM{0JKpyOI>8@J=|L?RtSWpTiH z#j!S()8ggH-lr^s3(Rtwng222%|nm!<~46zO%isq@WpEE#&dl25-3hcB*W2UN#c3bS~0ef z>%xy=ZR;z-@RVn|frI#%aSG)I`7BX*&LcS4n%h4>1V*y@Q*HkLRiB(^0O0)Z%DO;^ zCqS4GfT)kin|$OupV-mc?qFwk7`i7td4gv!lKx$SHREGV(9NmP%N!vM0bj(qIh(5l``(^eK9@y+odF}lNq&c8i( zVj%b7kGu@SRl1PL@@0{G<%yo~GcJrrlYuvSQ_-$h-=S%R5vQm12(S`Rd1b-}eupTv z;GAY}aH-JD%rRmNQ3wXGN|{+&b`0u>BEkad|H!lk9lxfEQpj>CePQ^Qi=fVyPm96e zP{NH1nNk4h%J!swE2JKg_JcetV!!Fka{I&i#G4%$xuL`rT~93|fx*saxj*=`7Z^5E zt3|h5sY(oT%#~VXZ(nW)zSztk%vIX?M;m2Ym%AB@ye>Uy9nIBAC;wkDw8d+)soMKt z583u}-_&yk%d76d3QO6uzmM*=fH1InFtD;0DR*L8D}&fh+7>t>(~H6x!YT<-JlDUY zZ;-7yHgXel;hL<&*&74gITwyX1gY08r^U%jg7<(u-~6N$BJVB-M>F4-W&Y191&6)t zFw-{rAmu~S{Ta?8p<NUj_7~qYEV)!r#xv3WLN~wwhx|}qjnO}o((OrwK#bU zkX@8-l@ibsr>xIY4iMNZYdC#5m^-`Ct21!XhtOD2#oym(MxHqoM)(?7T;Mg*s_a49 z|0)>(m*G#8Bkz8LBfFt+vGvQApL1UYnA<@|Z^cW|IL(HWwW?4v<>}!uX zoBv11W+c(XPZ;iQYZ#bm-(U8CGonwgf6tKgXn0lgd0$deV1hc_^Qu z@=|nSEjWOo;Y5fWhmw~vy$);8YGuG!cLJ4caY+Y}L0>lY)p&Lx8z&A*1ORXY6v}dG=@7;mN(6vc z2|>Z_&cm`Y#Ux*9ao)M+WJYJ->bTDZ{Si8ZNfyzwZ6dWyox8B6?Gl0`Gh5;13W(@S zUlMGA|54l)W3djat{7YFMt65FKO1}(oJ(*@5Y@=1@Bj}>;rPOoOTy822o;bjKUagU zdNm19E3R;nAI+*(XhXp@U`x(0A$FHYJAl zrV_^KoY<`hIMn~hAHr>2#oYl3XQxs1+)zQa@6V zMV;;Bc&oI7bh>_Ew-0y^9bbW(7qw0^B-bjC01y_^MxJjwdUVV1 zN|Aczvj(Cf!iZwZoR}K6ELgb76V#A@*;G1xD^gagf2Y}DjD2(OXASR@5clg4!g76i z&_^D2-bzJ3G$6)viG})-@4dN=V`>E-wEVjMz+xZONI&#Fy z|BA`KbxDdD9`TF$6R0COk40eSKg}9d>iV*q#ziLMH5)vEE)qJ8TK^QjaQkbZBCcql zd=#AXc?!Ei`}74v3-jlgbp88Ct0E>Ds|4qocp3#09-u$XWOdHe&4qXRwzN;iUxdZJ&VmcIee7dLrt z5ciU>mvvR554xnRh*hWcfY_ZUMT1I+D?frjp!gmPwz+Pz+(ToO{`VEtTBX-1Bwy-{ z+6|m`_E^ll!T!KU`4S|jj?7hy<`$eioPx!p4zz2Z1gjA>pn0X6Vy3f5;uYc60ri8{ z2|4y_3o^gW*Q>KETp0CdidH%MQnPkdbpc4J{RA=Hx&9+g@NOJCLgW-n+iSHiuq>S! z#svgy@6lNTnvj6}DIJ>Z{rRJI!Avl0v$dF;M$d(@soPrG9VGYw3IM1^atHGyFCJ_+ z2ZpLC$AT`!rSkTwxtS}QZK_1jfXD?(E# z%^JIN6X+a3`EH2#EiuYj6$Kun=UpDX72TvLGzWe?yZGWm8P>JU6kO236JQyC=At@9 z7GKav_f;!1eePWv(j;-Qb`40jes%aDY7)Z_&AMkSr|!!>QtqrgCY`4Fp^w-)3VI;u zqV_zCkdY1*-W2z5%wP&3lnao3zJQM0ghnc)twJOi{h}%I`ca8m&vH}MW_##~NytvH zRWbJ@#_FiB@{F<5YA(3X$!tegRXDSuF%le*{112>hz`@-2H5ninej@c{G{i@ff~_l zwc_G#89;0lx-M=2c9M4xxkqaBR2{=29mXJvB2nk{$lgrb<+IA6ID7P)1RBe4F&@rf z6tNy3gvE5tu~M^26yAoq0dR2pZF{LVDQXL7YXuW?6Og$1EEdK{qWL!vUYumWu&e5( zMmJ?FLzi8zFc^*x06Gh@)&u}xN2Tz*82Lx?fB{!Xh$BbYtc7F5ywKZ1hCXys6*_(k zE*HESHi6L5YkE}a4M`9%q0%e^)}^_aJAv>pKf54=gYuthOkhcWjB^8OO$~Odj5}?6 zWKGgQ=9+m!l@77*{0kO%szK<^pHhysEFq2I2mET}HIlHje8mQrX<8P4B@|pXtGS;I zQBL>po`&62e$CPlyazYTO4@)4;$RY^MABH3?>-?t!IdJR?aBc!<@**COhF#FQ=8I% zrMv0{XSG>)d89&M>J!?mFM-`Oo@b_PqDGS)I4YDgNhR|fFfXkdcni4(Q~y94Z~SNX zLnEgF%>MlxQ^ci$NQ<}pyM;yFz};-5Sabq%`2*DXuV6Jp8207_j6ZKItl{sZE$F|RJ%#EWZ3T~D3Q_3l)HO(7jRFEe~GTQM6I9dgh9X=NDY(wNM4Ln?Y;xpc&DKDZ~b5R|Lcw5kH zG6`qmNn9n}jFJgp^Ynbm!gSBR*Q!)t_D}EmPT!)wJM%EsW#3^Q z$U$m#pwUa~_Z57TgoYg4tnw`^@rNpk&6V=gh}}~jh3$nCKPMo;%y~56)Z)7LssH%x zouv{8z@gSJ0lY29jgd1bjkQJY5+d@p=inGLZ#88#N8Ppfj+=oRASkXEv zshvbWf?UU^ArhTUmfs2Z7jb&L3Ik7cdR8|if)j8T@CmH zn3}fY`MIAbf?$AbnX|y@Zw3E5y%Ivc9$~87>CPf&ibyYeI9W6?MX>%BoLh||=5uWy zu&rHS$)aJZ>+=xO0m-ty)`nF3@pHa1l44qsR|H~q+n(#gzCq7Xu#D{BXDCbOv3wk< zG)4YUu?x($u!z;DPw$So0Fj-fE_r)=yz@AuyZ5l6xY)2$;Bq;$5*rs-BUVkibqU@_ zhCH``^F-$&Iw1_2V(bh25=4})HVqVg{i2cd;DU0I_pdo22$zK*YxuvM^0NUbTi>q& z1CR!&{rS0}+F2l~*=(}OZMv_uwQ*(ySd>ONEWHoY7IZ;^IjZYmep_arkOLsgTVSSE z{)?TogE4|u1PW#@P$$~zZK}oJ-U)BJ2S6?0qd~PdKTe(Bnz7FL=PrZPfO4VnFP@&g z=iumTMM-~sR&u)jDX~jI3p+18KAVL@09>KwbLqm)A3fY!A??OF$t1c(cB0ur8jljc zK7jFF*!uq+g$fS@-2b)xKu1puM6h~u{V<)p$M0O|qkMZ>AxEOdGFZqri&?^^{I6sDZ!tMgwGT*T~RuowBSIB+8 zWu`(;?DY=%_kziVK-Q9Oot0DxMSds6 z*p!_soe+$AS9pu&&l7|AhDl{|`4h%vQH6G$X9lle;!;A~BR01OqS*`{c6-#gbdr92 zqAJ*B_?wFEWDwRBR6!?(>nh7}dP}f{dUK)W|Hei2ww>n*IJ$>%A^{Pcl+{sNLJ_}p z@SV<#;?{5t0L)EbVpoJElAbZR{}BWxhDDT>|M{a~gy2O9=K)bliPod*HgrRGzEqL2WE71f#E zk&6Kk6iK%|M(a@t+hj--PUnTs55T``b`|YO6N+KWv0y}I@ru+_p?pv`?AAQrkAapL z-=IqCwzmKS6TN|YTF9~RL*BqYgoGQ61+M+)R2oM0m2T#rmzvx>RN&=nY3|q+5Sb^Y zHImN3@?g zc-$sYvWTWHoN=eP_|~8vdMKJep|NF!WT;Y_mRxU5nGIsyc-2M$d~38_(8F_@>;2*O zh*v=e*P#g9JaFZcT0gxsmS~A;n_0(gTic5=)%MehUi_`Rkou8&7l{5oW9{dq-VO_Y zC804vXtn~^%;N=V`cT<{ksEq>(C-{*K%_uw5p5Rpgx6{ey0;(#pMe$pTrTJ7T77+N z#gSTchuz|V@`O8f=LYswxQ~Y#XXU7}`q&1p(!n)KL!&eC;A`dT`isQ*>ZxB`2^dd2 zwq~56^PvYbGEdPZlY{|el{gI;+*emv#a7hxFn2@8pLc0k%&s2u-)m>Uew<>E*wJNZnJ^c z#K~n3O-8iWD`9trJC6K`pQ8zYWi+O~q|_rd1dr@pEx{%{x1ek3O2z@o(e4e+oByjp zf%yQyfB%7b6of1x04RWApO%NSV=!zvRPtN{uw>kSqYz4rQ>>dfy6I>DTVk<=h#c<9paPQ9q3+4i?(EzHHbhPFAZ+jYv5T1^n=;{ z>HvTW)_i$^e0G4Sucw5|EE?Ya5=dq^JA#R?&2HFy=KVF3ES?>cGj0-OJ`RkI3opL> z&SF~Oa27|#<9W0cJBc<~x%|>1ytTX_qUD4#eoe#A_Ov4*E!ok3qoQwurRacIr*}N-VLcaXI{UF*yqBmS0X&g{8Il6+3CGR4HBnIyC^{G)qqEaGSWJ~)2S z(M^GrD)j%kflxJWwEOzjJ&I*1RejQaX{;(IazxKu0JLA*+#O_~`^IwSxIQf}g7;Y! z9Sx9`a~#&$1Th;b70iD$$hk4E8)Xf=RF2i2G`>ts&w71>g+)&H#SQDEg>7 zw%W!{7$U}W;{)*La5N)t$Qup|r(?XbW&AptwDEd6Uk7Q+F0Pj53cIYIVgffd@BK5s zVD6sl^!DxZR_{PXb6b(%0h!SyONy_e1sng~u}q7kc*+h_we&)|sR4A)l;Zc0FQmjg zrMo{GkppoSwuuqa>l-}%aGu`Urfd_R{{#(}BQ6r8c*@uKtp|fX!yAdsBaKOoMCiU}6Ylk2U{H>~LOrAFevfCfMZq%BWTb{cT+XRmSo#gDy7!na4Hz9vP`LBGxKbSpuI^Xik z4-d!&4O*gl9yS%Hr8#0+I%lg)OyBuoRIrtL;ZEL35uHMg-oiE+exs#6x~wdbE5Y+F zEQC)^1bcaHPdgqC>|I;DQWfv_S(PR_CAJg=B&(x!cwdGhWlqFVyVb4Pw3>Y-z8= zF0q#YvFY|A5V;?K|F@v>FAxa#7utzNkKK=kuhBFHN_CJW#%r_Z=L+T8&G%LL*GB?l zkqyPNGitNXdb1ojOryaD3ApLrJbbz~>7kF$K-FwMXkBUQ7|W^zmlrz#uzI0M!Qw^I z5BlX!Va>=IUS`|}Llk^k3~Mdw#2sfs(t7-7E&(U7V8vTKNKM6yII&u(>B&s}0*PMn z7}yP2)VBa4=RU{#}3>%dT^SgUfG6 zr`^@0pxAoP(Bw26uROg$)!-+(Ae$u30~-Vb3UeDv#s%BURHR{g1k1ZAX<&ZTV59py z*4v6%nrhp=jRT{=UWg`n+w}YB1iov*OXcL>e!Syx%g?@~x24HuoK3pVno z+g@4BJ)WV;35og#pn2YDf4_~(<|W7wFy^x8F-rh4owU2}%xSSzRyxJ$9?zE$id8~O zYmZ|EszQY&dG$?th7sdoz0uDJg6kcUHUloaWALP~drRVNLScUVK)|&24JGw=*<#Nd z*vGHZIO{;dciaVnuFSb~+0Kkd-}9GL4iZ@4)alvel(hKGQB>AQb|Q}zL)j5Qkj8sn z?v?MMIqt!hP<`rDC;%Uw!buPwSTh`b-O#s zU`oO`?-MV~S}R>Xs>V+lW_QJhLOv!m7>qFK;?3i2V2Kp)oumQ4OM`NGvUye)a|A7a zUNwp|qRtT98Nl_^b90lenOtUEoVkq)YcY5Ep;oR-h%X|)|KZ5-UTq3>7y}%o>sl+f z6Qx|w^T*h}Z*i2`=e}eE+oso)AslE*l=e)P;rCliaqiJ)EpiE%21u3bcon!){-R^bU2)5hz*-9uUC|<#R%ZBYN?LB|D53#(6I}p5yKho$$~J_PPFr`R(TOb zVhma8b*XDqu+{?(HAcV7v48)0ZQy>X37r!Z87gIwqyr?kUT8M0hP>K#sXl$+FGOo8MqUl^68c1!ju#}KEO+b*E*8B!EomRDJH3l6Qsl=$hlVuc0ZgRw{MQDFpE z#osxq+lZ&J4|bucdK2QUczc=-=)H$?0}LsQvOw7Y{x@vFeUx^o7!=jsL>jv3BG6R8$>5k}9kQXgN8!l|U!AvQ9Ij+bzX2>H)VXcJ8KmE zy~IPkP;4u({JrbZ&Kc+V<^i*g9@oBO=(&WdZ9&j*l|nJ(lCJ~Uzg-dk`veW_Wtq2N zy(*vp?@z3F-m-BMb=9o{%LH0AHsCASs5msEd78Wh9LHr;&qgI-fgG;naEQn`#df^} z>sItZEa@X}c6GfnK`MH(ZaW2Ih>Bc~hoE-TF(bVtt5j?0`UlDm(u=QA%2(M8{3NIQ z{B%6P^1j^Wou$y)7Bft55-VFRZUE7k3kvU9wQ0ZfINk+9t%A+|4D&u=M9? zGbr=((V>!0aHbB>!C~z(Kxmpyr8@)dv-E9I&EiaVEV6WvIAemiL}y`RMwP~D4(TyM z9}u5sQ-s`-Ddkm=u}h>7fEDgBP=F_fFr^O+{ zEcptts^k%vGm9h%F)8J7)K32?+L)4=G)<8uiu<5f69S!<$(BcwA5?L+zD+~(=ef3P zwbjbvXLp-O@=&kAu)DrjAs>!FWe!4|k_*blu^{+WcUXeuSt=bRF2rF5hBq#Ys2xb0 z0_`^KyhtD!t@#EBxB@|yZNw0N!9tOuWsITu_GuHU;>0~dbT(Q)+ZJ1mU>YB0`BK1Q zV(yTOha#G#>ZH2`%U^frC$blg(Bu4FZyfb5+}&&+1P0r15R!_N(}H~RlrQyei!23N z5nDvAdLixPa+ff@H^dSsiZqg(xf`G=1zcwV6AL^lubr_`!MW zn{a@qZeRhE;Rf<%Yj0MfmzNh%Ep83jw!(!oKN$H7K6M#emN(r67{^z;m~XC~yEB7# z6~u#h9q*&ZF7O4+tAPHk+=dbW6V%fRE4jM)1^$Im5)-oE=&jQ!H%Dj6|Es}YJ_M5c zKZ1af>Hpt_s?HLzDtULy-=c;a#N*b|j=3|#ng-+a7JeJ=HE#$KJKG;=b9e%Vv;y!3a$(x^z=VpEX&a$=YYbB=y77yOVk861NI(~b*lo{ z+ndrIc8x1={bZVP5y8<4nlo){bv~Qb8lp!WWCyzcprd!CLF=gOo4Eo zvm&-N_09<~P({j;ibt6+naK3k1nhy0bC-dwTwW{|9M(y?ZpS*nG~vMLsJ1^C`>%0Vu4wDxXW5ajcs;-0Y3)Isr*=p0=i zPDD0CDWb->rjjG&4S%LcU5E<1SZCIte>(ZRpU*q?y-R~=#>%nSW|UJ zSeZp`(_Ktq5=AV=`@3;ojq-@333tN438XjrkKVlX8rU`rqX5%=1H$v)O->gBdegc< zwj4SXu|pd276T$(c6O&g6#mGj|1mAm!?l|$u4&Q`*N%N2Jm`FKH_W{r2$emdB@pv$ zpk81FwED8vURyauW>i%Fo^-?d%}d@TpO$&%H15v2pDux_G?G>3O(K8S2xe%TbDFUI z#~sOmK(@c!0p1YLZ*c>WcI#S-NCf+@o*^a)&`4su<4srF!{OjjKYu8%DkUGL_zYPE zniA5nc*hI9Ppab9SUA_;qr_DRAEWa2U_AqT;@|kQUqNc0w{WT|;IR3D%~A|98&6Wh zcuEc*(*Ew~q!G_4x>k{xnc=@Kqm~f}*Xo2aU5A43yoM$$G$D`2XSGLz{y3I*3Uj&bS+w56|uc$1Tj9+hN zkshpe&zJFA1OC+_wxOn=52$r6ouNhqALNZ&m;jhMRd=*z8t(m?W6?6$fMhSuBXY(8 zq+oi(K?L&)M!~8u8z-iz-&4a;o%9GFr*;cGGo!^1slSbl=NUsK+YXj08T`!m625=s zj!W5iTeK+6#GO{ctWNOG(Vi6fhHm~VrWOK*1KT8RvZpv{bo$mgT_w zD7i#f)tU`{F$VWYrl7;TsBhh?h)^F3e)_Owt>(Ewh)Eb|D?4SN;f(aBZbm zdqTx5xoA6^(9|@Qfc+9Bv}s!?*G;@TewE|jfSMzB)Gjd;CV^3m$tOKf2;t^ns_5xv zh0i&J`?IObU&s8i>ziioCoDLRCo3S)PC^8R4m+4y5^-$%{{)9?0Fe9t@d=1b!2dQm zx3khRq)x*sizzN%r&rR^NE7pTPR>`M>pr-${c~E2?>I< z@{&D*d7CofEHZ|<;qiLG))%uD&cvi)>-C@;Kh)<5IdnaW8gU6KQH4^pp&mwmP<1U1 zpN>J3*`ahaFmBml<`f$PXK?Ci9;x9jJ(e_aSdcfNb-aPph*CYQcV-3uDw~Wzpn%^X zDY)KZ1QltnA&rCZmtX2?sCB&hX4pAp&1O49wftuP9&ita(T}G+IJdk3R3;e zXCISwo@0W+`j49~6UvK1yh4P)(12huNCR;&PR&ZIE045{=&dTv%*Z@O^|i8iSiKn_ z9Xz5dE5-t{Vbhry7IW{@oPk0;#yplEs8J}2+%BmUcAozll3apWopNn*AZAm=D7t4W z@=QL01LG)Ir3uEu=x^b%;Nx=yhbb|sjTP%=v8pF42{9r|i{rT4J@4Fp2XWP&{$uL) zuYk*2XosTBYYrtIZvo}#f|GhiIKNiX{k+rLp^>-%Y=)-g3Y8`{@V;#zAWe1Xo153<=<6QS~h;z%0H!G>P;%|bSRMz9oLi6W4X{=khC7T~Jue|H6H zC-6tHEq$>-Fb<~P{cu_^mt=H5%YqD3iKsfUK}TEX+?Mw>kb2w_t)5)0;b0`lKg>&TeL;8WT-zpSA9d z9TPMp!3R>D3=N^dUk-p$_;F|ugc`bn%^~B`6pk6^l@%4765oFuDaeo|T=s3-jPL@D z4O0b1!6ZqGLp)srZ#O_a{Ep|-Gm zfYkX5N zb4RK5rFYj8`mt8DAM;w{HNN&Ya=$H$OiPx~e%{0;M>Jq*>LoAAYb54>3$P?z5e|7uX{Grz!*!nrX@>I%L1fx{S63Aa%5reiqIZd1BY5{ zb^uQi%)Z*ccOm5!!zeqpavWhFgQbR8r7^X$WT>ZAt&L&BNzcQk`>DD#>McME_@I13 zrvDMFa7CVBv05ck4-tkyZSN=h1*X=X7P!9GQ`2*YZ5kJ5KNU|^4W~r(;W9+iPSC{8 zipttTc+k`A^H5!*Z5)2#6u3SCkQG8BZWS-plv=gp{gvJuiN>Vcx-*?i8bk~0Df{!4 zO+Gv5_pw86y1bpmjOQK2IPr`RB0z=y!Ya(og5+kxPA!;xp?Oa5np78tvl4Ap(||s zgaSTKdZG|S;m*drFFA7wg=jGFVR?&e&c5(G5n|HakL=OG+AmQQo@Nh2(uGMWs|The zO@1vYmdATpvmF{P)iCp0ug9CTy1{$`b$lBGNrYOV+`>l~cLK<)Kr;&$A4*{*yd50u}# zV7t4{psL@pQS~4%M3ZD#A^f%VW@O)m5W8T=^AV7Gq9~&Es)bw&!*x|`#DEc^(Eln) zW1iCVGpBr?z*?h+mZ?uE$Vat16brPHdb?yS04~|uE9$vrnI)%1wxjdNPyU3wHm968 zdg#Hxy7YP#R$!a5)}Uat@>DV(#(rssO#V76aor9B$?*P4ADGoC;Wiv#-DIN{Kb(DA zwh>*lBOG#OB3@0CGu(F79I8xe+?vxwe=QD*oxVO0MiJsbnTC%s+qINS7)E?-E%Gp-rKT7N_JXp|Hed3zOQVK-8yn7r}pG z+EEUbgKIqIl3h3eWWx2r&yr`kI+9IH=1j%9C@lHkP&pqjg^V7d-|IR>agUDLvA-XE z**#K0e(rp$r%X1`N7$(mpt!P4LM>v{41{RJ)hi00S1|?BmbPQJ136-wC7WqD+&bYEfrJ>D8iBS2v5$oQG|#0ldI=XO4p{L02UT> z@fUinEB$MvmvkEhhh={o)akz4%Jdz8NQr5|bIUrg8KVaPa5zTeiofchSJdZJ@5ZpV z*06*W?-ys2Ajn3)a^U!+^gW{9L=`&6I(;YepaGK(P>H+%_pt{|gA41pxC)h<&!vjHmBCkS z0VHm*C6_V&#S%KL*|a`LWnfW>{t1@{*+hYZu9N!H1{26WoveH>M&ADm7Q_Ssb^mX@ zM_W687R{p~mqQXFx;hFhIpLP*!cTZqwjH|oU2Uv=SxhJYvI4Gnr!W*;!ms0$KK8zAPFQIF217Ggl_&`KFpf2NAcH4ms9w|jX0D~nGB{WmQV`4 zH?7#Nw#7D%9ca?-+!xjzDmWbccq&nTz3WaVAjfdBh}6Lpc6jL3VHgs8SW_K}G|GX% zYnkuQ3%xDj>RNa*@SsGH*O4=wI#q(@r;MOv+CfBn=y0PDV)dbk_zzjfu2R>0nx|m5 zX6Hw?TKBpRU6g4)fIBe-daVYP1kmI3I=|v%vgdI1hkA%JlFP)kTX*?dqt+RVLO2bJ z8=@8jhp8jb{(GTe(7TxZM&hQPDTv)sgo9{y#^{1HFK8+$-4YnoyxG?Fc3J-+NbBX- zBU!lok_>a)c6Bhd(y#Gl8v?ZkQUdc`4Q`1`;uylc0ZLeSZ<$I9k_f-`%H}!@=LyQ_ z10d3YF8r#`Xa&B~$K}Sftgg_`A+Qa-cQk47ZouKUIK76Q;F5NzgD>(?3{VA~LV8$g zz9fvNZZn7asaOH4kC9mb=54={xVnXq;+VQIb|}Q>gxy_?LA~M1{zZ?{gA+7(XndHD z%@ZhuR?TIdRjUDQgG4Hdlh$6K8l8f?ARdkY<$kvitCO z`wtP8``m=>vuFql38cj>#`y*gjsGZbFaT)s|MVGv4B;>38F8*VOLQ(Thlhn!{g3pj z$!D7(78d%@1W-n7rMWH;2loT9XawDHsf~+hC$l7UuEjymn>}RoJ=<2KJ1ZmFZ+!*- zzzGmG;T|5@$kVy>rhkg-W@jMWBm9nKG;w&b^mD*aMRxx{k}SrAsiO&X7dGc>rPmqn z39QaR7kA|mifM@-4U$IKy}rIC1p5u^uOL6KQcfO>1TY(DlUIl+F&mB65Wv~F(ys%N z8VhxKEB5rCEv-(H(2DVg8IXHe7z9nO&sV_E=#>)^FmPi4f=%dLYmNaJ6F9YboFg2S z6u(+OjQDjYrT|R2T7)m^1_V3NH?W^ciyY8>ce=TtudU3|&c4dgy_0JD9}gr}Ug#Kc%q5GYN@^uE@`kO* ziFyz8C{r${kF%je!~*iPGxv!Es_QwEgAnzKmM<@zTGhAOX^Ok!&YT&YXb*c;dP3ku zt&EmToEeq&B>H_{;7}^S5RxVgC4-tR&}3!zH;!&0u`Oc2AFj3;WjB6*w8E{d5=fPp zz0WUDD3lopH2+I`klI0b!`$#D*ltH|BVu?0l6|~G6RuX!3+cpLOkjUa@F#$(?p#zE zA$663$=tHOS!eT_t79CO+}tZ1^wOmr$?12P)xL8)V9Os|+2^q(HI(8qXs4J#x74$A z-=SPuz<6KuLw0GmrMm#woq+sjkrJR^N5bx|K9a3q6}4ZI!ZnLa~g%`!oe zY~MwhugUN|YojwxA%{YRHW}uOE7(~_!tp-j^X7Uj?I+u8rf>a2S}Nj^d0{912;3eb z59E8ahm%nvG5W1&Oz&6vrjxorH|~(1;TQR@>3&bpw93rslg5Tq2DiD+O*>X~4J(*w zETP8II5&Lg&;7%XN}G`Y9&}f2;I92wQcdTm1Ys#%6O7J@uiEVS_bo|^;PXmvYaZ<6 zoN&`;e^jhT^&HWIKVx3 z{Cf4mA^#Of(6|v;ecZlgg86v%>oN!_gw?b+v#bNIfl+Ri)zG|JJ)n0Q88km3h+bdk3lvIK3q zpP{+zV1ZM`)D66G+J$QjUc4*Bamuf-+lt8G+9jMd)mO+;)dG0}e2&_c*St(XyKXAO z0cR96h=w(??$-@J@1o&n2ITwAT*08`b>7V0IY%`Jhu9B3iEtcBmTEP{|FK-e27ny= z(hIRy<+ zxE^f3u2^Z^b%Y*jEWHAt5V%y*KK_`c@mg4==CsgeN*yf%6<)b6Y)Lxx4HyI@dgnk02 zDS}BFB?gbYJ4d1@IfNgyJND*+6+ft$c&wW<7;Y`_2`emaHR5Ge{+3&@sln!$g+tor zvZGNCn`dQJ;^sak?-OV<+ZC(0Azl^n0oMI1@X)J@;JoUPxXoq2-e%@+^tPeWM?BQk zz~I>NP~6hn2_G1=pE`1_RTmVK8{K2Ej8h?_S7>B)ImnCj2g1v4ia(kVJ3pstVlQ?` zYU^7quaggs>@Y;TCD_v_Un28!lsCUYX)B$diUt>DBhV(u3xASt`E8V|{ifl*f95&t zwOVwyCAVy)pW8T=?^x?vs4dMMEgaGY^D)=Era2JCEC-YcBDlAnUIV1&VK4Y|@pLY( z3-Wb_uWram5B`R-0I@JvUEoWHKHwnsKi2E;2YLA4DVKELx3|tGjcG&nXMFzDKgt`R zAL}`V^q@|;@+&UcI!_-m zSAoDd5dW7z6G%J9Mr?c?>9WnkGbS$Y5pK22(!uP95D+|KN-q#ivL3#|BH(6VWm!)6 zT~wo&JtprCRPDOCtZ0@5lo{js#mLmo3)*PGOO_{`ii&1VB*yZdsA zP{n5{x8W;o4GnGb8l0wuB418}pZ;|BI0(W`6{l4oy1f1OF>9;Ie&qX4!APCU28!rW z6PBt%s=ja)mWlL5@`^`c*k>iKJ7+2*YIJZp7y08m=5o@XyNG1G9*BI10p|R^+c8%C z`cjOt*3H^k2MN861DT*qtNeb%!%^r|vMA9ggO1=p&RgX|K$|+8OyJHtj z`OJFM<&l5@bBs>Aq)6!RBxM@@K=dK-dDPThi{7S@o(|`R8GqTiGI+@Mj4HPy=f2-6 zluB5aeUXMUj-MHWr%9wREzTfByk*KoKf9Yee6emu^}Y!>aMN16OBs{G3UVX00?X(J=xdl=xFO9XZ|e^Yy~&Ja9;ceu0P| zAMecYHltPZ+Ip(2Q=$In?fapYRvL**l&1qKdczJ4jb6Edv+GC(TgDSb)JRF0eqi8P zVn#x-L!|w5Xn9R4CO7)_Is|+4`i6H2CLApS$%S`}_J&=pUBZ;ezH;#HGKTAM&?g>S zG*!(EH3^H_i98nn!%CzCZROEdvV(Z!m3h)*y5_GS#$Q1UFHw92J675zkTC?9JI6!U7uS zpL^^8nY})P$&n`xr1>~fv-S319h*5owmh35?`QSTNsBag2F@!YB}5S#_z1>ZcJ)foSRMU z6+z^V2@FeP5^er|8R8qVEez}qwf&Q;HiKIK>6r-upz!}7sk=GE4*}y3j1HCn5{VFj zmKh(x=LYP1ptdW5AIk3G^FrM9x60b@qE+%IrNF!Ccx9H{=f+r-7q@S-^^ad=x52J9 zXg;tKLo;qgTiTJ3zp=?0y=OjcORD?=hs}M{rCJBfmFa0OjUmG>{eGurc>nlCzM$e6 zUsBq|V{ydY$=cFqPee8-cX`4%Fp}LNattiGiVR3L0F_lY(3ZM zIGZgN*Z@8n5tVUy2t%Ad$!0=Oj|4wGWuNGgXG)gJ>)!y|XO6pI8yw89)0ekz|tx z5XR3D@s>pRIX0Mt)>jN6Mk1d_!eEFjeLgIH=D>5Sl&>Jo>fud0Dc&-* z?UW??z`vZ`<6~r>O));!8D={iFBhm-`S^XG^@$*tg>5x9yZ5SP5Hjg8mb-}N`GEBa zCittDCT{*bt=;sy-avambcAK)bGpUmKS$|SLF%Tjt5%{c2x9fFlo}Y%=!E6LR0$Ce z;7PrvAQX1Z25^vAL8u=70(JF1eL5wXnYErokSPn`6+)?DXHh%i2~3Vv>dn-H#_P6_ znET0%zh|WnG)o1($nk#QDb!|p}MJug`1Vkei!r0~< zMnvdSr^Ok3*s7ft&eM#U%32XqZ<8b?D@8~HkKuNH3SbPku|aiuLL|z~nrmPQUhFO| zgDg2?y>V=b-7vmUdOImXsyu0S;H=S)9f}y7N*zUXjjCO1@})G16`FDY_tA zhpZnHcQXpr(5L?UHpJ$cd-0`VpEQVC*dfY8dby~dKIf%l7CmA1uFjSgROL~xO7LwJ?*Xwb5?$5yiKCImKO?=IIy_LO8oX3vUYSI3X{=^s`ygCZCXp8V zCxG5R#ed#|OR3hAn`z6|;#-nt-qnvQ3^jI&r0~Jn9ZP16 zqo4Q(=7`BX0)AXK{k*hCv>XX^Ebz2uWLcdw6K-c!#ehHAu}AMypyAORsAwH4kg^JY zarM0HjoF@k5>iO<41J<==Mua<*v|AT6bcLgCHkI=fa=b3YRdb3$L+=TDO(z`p3h1B z5P{2m%f_csm-4H_|16!m&5-gyK4r``tpF~*_83!>z9ZQR)tm+?sd2=D9#VPnYSH5` zxZ@gmz;AqGfv);tQyh%>Y9&bR|EDdNN+khkEea|;VN#Y$!DXri_sXO~R9;4(k%Y?J znB4Tna6de(O`ZB?jN!{d?*#p@PrAOUtojh(Is0B9$OPy1y zLS8Hqb3a?P>dbhCPX1a%O75rRW?pe; zp?fE}2N%CsRt*;mSELq=6X(N;LLHag$8+BHr}1>Ht{IyAI%mhN0+~s2D0I8}eS~_} zKNaKbiVs3tvqlJTqo5N=+rxE%M)^#6bS_cqPGX})`d(XNYnrFEgKX-R1qgJ`VE*_S|X2X^sJB?Ve#dtD6Fe?(_Y5X<`@4RPA;=w{`gI%x^wb5kWZ5I!P+Ce~0&*Ny46x%?`w&!4p zvbZCgk20jpZZt+SpE5{uBe0^pJPUC3iKAD#cxZ`j7)(cb+_{D&myvx5G(o<2i)IiP z9AB;r(@P=<3%2WRBp#Yl;bh~UMb!T z_Z(cKZdH~px)j|4egbti`@nifG!JM_vCW{9qwh)vi}MnW8_=?aI~XE3E=F!eT8Af_ z1G?D)z_k9wUyX-Banlh-f#5XUryJ@O@~HK>4hBZlx*4pvM1;7AkYY#_8ck+ZJ=6c? zm8aEN3}+dW8w}xYk_n$=9)V>$6okYcy_vk>^lu8$zhJH@tJ$t}r?ZEQ%q6B&gnn@c zGlrnj|66ZAzSy@j%Ssz;92+~>Ls;89>dR^fO)2VMB5Q0ZDV8Zr-7Brr_Gl_`InZ@D{h&2IdUGidTop5b%Q6v%6w`HYZMzL2-$y`czw&>pm7K zv}PFHbQ?|CqIIhQfgaS)@@DT9c#(7pYmIH_e_F#l#EG(3h+m$n^Ce z_)7diCB8|^A0Z1&sqg!u8u^Us$iJox2*T>lBS}@?8jE0karwIo_y(!uzf~gLzrcy- z@OB-&?6TU-e2{rFeW!Z(yMj-XU}|iH3FeuNgK*P#Lu?*r;80Hv`Gphb2tCgHS#d4I za*6_ETLob6MYO;nT2)wZqSGinE|`L%M7dI^tqW%Jv$3)?WQb^{`r^`J#n<7IUb!mX zvLV6D<-d;ZDq?q8_AuzS9;I^VcrH}b-Wgpzl+NxN@V9%aMuSIN5(ZsVC;T&}jAN*t zpwEyG+k%E$uf3eR*){kEg48pckmui+*L;X+Q7?*P^O+em44uDxACQTr_hCV6FeP|b zuL{(TMje0clHtH94&vJBQx!Y6CDP<0d_5gYNotJOpq(>E9PELN5kNrlqPM7iuM%yt z%lQuYPwLcvz;XZfub_G3l9qKH+<_5O2Qw)u9UD;ndrFkRr~ljM0YW5~O#5=rGpNh~ z$Um?Wywzc8n=BBjR%O`Q@>;QykMGXJUScEfAWBMr`^7JrTWR1c-3E)+Y;_>cEYn>lwvI94$x9uVW@t2?>&e+KMT#s$0LmEC83Wri&t@R9?2A`zmqM>Xy z2YG(zkyCUmMbYl6IplIC(FAi|+lcS6{MBW@$FqCZ!joW&%m8+pqiGn$qWVd-+a9KO z3lQ}e&LIh&fFgj50xvIEG@$MZCLnVzr^vcrKg2sgQVS9FObAJryoeQ8PCAP}KNXj! zI$G>jO=();$o}dQd!RH(T7qdOUk8vRUPfUW|P1S4<|oVy`t8TfB%%quDeCvAP`eqT$+Hx z^%YP4>0BZBOIJazf7SG%9A?zll7R=}uqFegm$oJ$A`ebCL(EjI2RsT#z?N@gT(&iz0;ei z-MEB#bb2cNF@-W7WR=->henpiAiE7ZYiL;0O(9`-Rn1RF>0VmTKN8U+7;}z| z(!$k46MNFO$vut`F;y?joav^h^sE0fy|L3+F$lnx z#-z)YGD-KU1^?Z7YBHCdHM9yL&Rxxy?PWmvqc5N{S{p+CB{!~5FNkLa0}d|Fo?7po zJP56Ur<^533a5}qPU^YTB-lT7X@{-*%zZ~3DTmH7aue!|got;<=@`9tAL`XnIh26+ zLnoaY1Dh&`E0sv`w#gqxK43xds90QAs1ZVcSe+JPongVd6 zYD-xf%BN(ecc+_j<6?S{_l+~cE#JNU1XN0Fwn1Gw5Mnogl9KTG@SRdxL&{gobJ=np zr<|UnZ!J@*S$;P8J~tEUvEsbseDw)wT)%D4O3l#fmp{AevIC_A?JsPVJFFvYca;mg z%SWjyDUyc~jf6ypm%~F;60@aMkTg`|!-=fmRXD{Cd7k4~$@wz$o;sYke4bFb*m4&$ zWGDF+ZB2U>F9MuQ%y2AmEyTR&G3)W`sA^uqbGB%1wG|9l6L|mr`Ykt3sH9nISm*s8 z=z;=3?Y}_>mZfSYNcn6PhW-vQH6YQ6rwPaXlTS#Y+^Ee;Io_WAKFkVEpTdAvYC$E> z=-K2lM|!GOIV-3F5lrg9r80-wCag3;ox&R4tcAXewp%QtZ1s36iBaG#rmzceiWs?? zJq@~|Zj27{xHq(=c2`|`A-LIzb1KcVk0CHeGb)2%ARW6o)hW9WVhF8Y5k=52lGxA- z_Q$tBZN}v@xJx+d5^UANfs8bg=h@#;pc9|n%mQ(uq8%e*0O0}F=Jl3`9+`r7?xhLFGpa?3R5v`O2Wd8ggKoX{ds z%Po6`d!9`|%yIsNWZ%m`Bx%|p>kA?fnj%of)KpI|oAU~AoDb2GRFr;y9`aZH>SICu zZ=()b@)!C*Gxjy?_lfy$q2|FKA*B7FpQP9&?|sUu z9wU@pQ;Wn~qBa^wprc2QuQ#n?&&u5B#2A-2y1osHF@|)HWi=O>7)9S7n zFbPil8(^t@9lEzwM)*d0fr^s(w9Msh{kGX@>l8E{-Cq1;E%%{7It#r-dPB$c1K-$l zCjqHpFpeRuQ=)A*Pk`6WJw%Wh8t_5V6ek0A3wMNqbdsj{_vMYhO$%7r{!yU*y}Kfb zxt9`e(w^{MrZRsuHqkF?viWZQ!BFtPAJpNSp#@T+Fuykhp#2OEcz?U5uYq~(@u3%G zxb}?Y{iEyke}NOHVYgWq`G=b7_R%wAor5<6r3P~gS3!IBN4(VD_k-{EV~mqiWECHSX1=9MNa zT_MN^xDuJiWq@}3&lePgnNkC>fUAa~ZvW~St`|q3YFAaUCau|dP3{xqG--@%%pqr* zBrxDY4kvOctLZm-di){S&0=rcb)F!|m;patD(U3+HkC}z9+0~9{8gr$uXQP_qk)R4 zYI0UPMejHaApMzd5)EH*f7|h~e&5$%`6IU8t-@XgmAgkV3mD7@?H8&-gnoxaCm13T zFWtiJc?5Mc{h$|9}vHL4>`_S?MU+F=3u2mA)RLb8Bm ztMmCP4C6-fX@4W$huX?9sdljiM!oQU9D*|q>d5P-)oy_#)6HL!C!T9PHdEQv5FWu| zRCG%=rFXhq9#y#RlR-7M{M$TqqADZZ;$ZVpzN5W-C==ApYP;l`c7u0EbwY`POLgkO zv!&B&S!CqH$(NQ89_Nwiig%{hkjZ9N3Cj+AF?{+{-w+OV@^*EY9o#!WfIncJQQ-Sn@3X^ycZ2oO4B;h;^>*y}= zP5M_rMPmiu*q&(g5D~_?ZRCsrKsaB9J!$&-ycFl z5%tf3MF|%HaN75xeX^v$8uCU4K2IVNPlSZ6_pKCyQ4FP%c&E6iXy-3%YvzOI3B$IH z$(AQn@`Kdwy*^uE_1!i)1 z@H#uklKc_f=<82Uv|qZT-5=w~a3x%O6a-vBkFALMOrsr}p0mZtP1a2kS|zv(ZWvtU z(RQWewFv(182^{|(!YTS_U-AC<)&Kz>+d|3w8=lJDtMD+fFwiO7bJ*)WKzj+l&bLF zbvx`YqWe@qr#hO^x2qa+eWskN56#0eX-Z!=g2=PiglxRx|F-fb5jIQk% zYv>>+)D19$3GWpK7DJfER1hBcd)b#gSVbPTLHENR)2Q1mk<}f$h>&7>Spp7`Mh z5mCavF3s{YsS1Z~q9>q|<|2C_Cf+*`LxlTMy;b2nB2?9|vJtRGy3m?RoQr5ohyo4K zr6!O86EWE*jp?<-^N%sKvnyhBu^VBF7@-fv*0E8nc`^Kk|1)L?!PTUVi zAm`ZFSdFopxl~<$pyXS7vx5&34H5dxY8SFp3R1X}U z{jz5DiKpe^Vr6w@THH-h;1!hfpawqhlmkWT#W>27e=EV;nmQi~*_+Y604*km3esMY zo%YugvHQe3BG6B!thm0(QrXf4cT!4BF)~IqrarYvcLQOXl@8jFa@cTDt)Bf|NVTgl zIuMB+d2f==NMrJnVU8rZI1#3eLX+z``5%oR#2+;4e|Qf}CLajIPha5qAJGA=F*)8| zq8~p+LVNtIbQY>#yt7i>x+}6K+GZO*0VY~%MIz!u56kjzi_X@cvv3>wiZ@T!hQIRfoHt5E^SG%EYqM|fLe44Z%5c2!U{^Y|b%Kj0KmVfRc z!ZzBAZr7yqVX1k6{` ziIk}x#viP%n?jQS&^-DAD)D)ggyS;TFPn4I@aY^w`CB-T3C@n=@Zcj%go{P3Hd#nz zXL?kh{_-5Hr*shB2~^$$A4b^qmM=%>3r)+kb2sLJF?;ol=73c@0$hWcob6d%g#2nX z)6M3vFF#UDqBWa1v2?Z(~xLPrLagPoY1%UJ|(0;29)!zaw$nb+H#rLeW&m)aTJ#DGh`$MyzW#`NT zT+D~n1vl5Ueuj3ox|W`Y3Df?K%yMNHG1UTFj4rfKDPvsE!^ZpCJUeUQT4A?tVF*|W zbGDhy6ZI{ge^D?>DHwyb# zQ$f8@D)N#=(Nt+aU}(lnqAhu3$(DHDujn<)9)~T)gk}+(dDO?K?t0X3EWKeo!lk36 zH)1i8*d?1xZUS3l>d%U?M5BmwpdRW?8D==&&iT*$j#@rB&_bSJr88rwX2)rl9|R|@ z4tJDFpy+TMz8C@d1RNY6Qm{0&tjtDn!AjSaO7#DB{3;ScRjSnZ6+iP$NVtFkuBGx% zDAUsA!qEgA*GcXJi9`NgoTqR7q-Q9gQsiY%!&hD9$(E;qF*%$%v)63_Rv>A zkoVyk93O<~<6cj6C)ku`AAKpEaOoa-Ru^e-KsCRM-)-xy87FK(+MuzOoBP3BeH7&| z`x{=I_odg_f?z_(B(uxaVZ=;u+=A%RVTj;I@8m&g8*9^mVb)J&Cs8f)-{%;ImGRg+ zAcT@4r~9kP^_PW5FA ztxsznVHuMIi~dZwRhjWvG}mdQo2@ zJBKL0syQvc_!aYbB7X(o8HPOVZkb#9#E-Tw%lt=#ZULZu|G@X1N+q#d2q>5_im@P9 zJWg51TXh!j$mu?<=%m2`(F*;lNW;Wfu&zt2p|gF5!{FLSbf6u(y~{%KVPo=^bLQ|u zX)dD!S({ZV-X_ztPc-qvRcu_Kq*N^e+_tv1o82Lj=LVVu(LQky`RW67!eEc)sZ_gu zaQ1HTpm*9B-oAE-#ykgu2%dfRfv&y;hz@jK${EWN30yL;85gZ6n2r}t$@6IfUcG{j zA=O%z*H|4^DXaz=k%HvOT2itrVTB*+&Y?d>7X$EfiIlDsSTOh7Yg6kyQr(8GHy&ZA zIq7+8UgE8*ot|Yg0TS@-r)9w(pT3%UTOJfWJ5w+Sid)V(0xdA%Uy^fT2 z6exa8_PFYBaI@PB0_$_*arx$kW^~d<{_KCH(|iTsfR>H&x!GwjU?cfG4>IqS}CcZAV}BGbr-glmPjdI2jer*JtllK za6j06Lb>im`gll!n_y^S`~Tpt*Vc|_*D_p-AT+gSD76_ks`O6HboCO^EX#O!Ar^_f(2lEw&yp*=k75J6+*RCf12#IpO5;8!OmihFG zK0O-Z>#NS)Y3Rip(YfwqaElsx_Y~Om&sxNVPKj@|5TOr2jc9}WyRIKr=W94C^bLOl zU-f!DVHqGW#3@ERdYz{+Cgji)=J~`mwA@YcNFI%}X-!cihzM;o$L}ixIZDCubpjn77 z$eb%e;ySBR7}A8tVb`b3X~II2xhd`HU!NdC5uB-;=c# zu-rg^FMgm};51g?7qMb(5Tc1hHd({Nwq{FtI#&sf(g;2)unFyz8)Ge&an4qbaH<BF4QF z9z&2HhYSiB1{J^mT+63YH$$yQVIqXhI1^q?cEe@!7Km#(4kKBJ#U#K*6&&=v8U>!B zCm*VKP`rQ3)nx89QNAhJy!9*&?i^kgUhrc)KV6?&>~~+7V`FVnaQZQ~AoI$^V6G?F zADJOM(`n4tVd6qIWz}^O5F(n|t$f8SWyB=EFkOk9Xas`t8YJiYGDi7iENw}StvA(*&_H7?jF&)J-9G=16cv@`S!^T zdvz&^rxe5|9+;mA*tr%ts7l2EffaqYyUiCK;8~28;oK?`qe( zzHkRJ<(KTR{z>a?S0$~s&(xjr%ySMY>D#b ziKso1+FO%k?19_Q3*U#z{t(sDBV@BgojY~l#+(1jyrKM&Jpi?ry-ldX$@qI@5Gw+Q zD^86UTuGf4`&YP26z3KYN!*vN!q&2xGDO{1{nWVPH6~Ph=aLa3_BuU0 zj8w3jwORH`2ID`VZ=1gshm@9fKK+lrqI6~GR)iN%tF|>DMjbaGptFsSKiMs_{U$Mz z6!+zil;`aCt8j1r&?~ZQ)mE^7XD%>dH8CZB3$RW!0VhWs$Sg(GyPQi2XHB+wG(qBC zNZgJqq+vFIZT3E`Kb@zOvH+SAoU@;Ag>%HbS4355;JOEiF+_)b6}>u7a^Tt2nH-W` zlbqOT!QpwcczFU)x}`rLEF_=L0lYJ1+Hch0Qrf^cL){(IZO zeo8?zSmC^y>L#QNl~|G*90&d|`mYGxIY5NS_+WYPxiZW#vz@IQq=d4GM1uE~@0Q2U zVc*wj#i2sedsfT@7j8d=SMEi>SQT|Yo;jfgJv$s;781~(W9;3e6D5w6# zd!Ij3tzrp}2W_f=`fhAIiAjwOz(Ov!ZfKFaYE87b9HTvnQ1N99U_dpb=;S*zBF1Ps zMD(6R^YEH58!v^js3OoYy%h2H`|Pk`Rv zDcmQZ3}lj0hOqBVYutZm7Z~`)z>K(evB?MUzA-b~z_~!tu%7v|;qQJ;e)#XquRz5x z<#sf)`-|oSdv@`M8!FR`5Vfx(r!R%pN&bfAnK(mXSkRm>A}_dkD(bWmxY(;sV8%{| z!LXbzPG&()i!uv2{k%nm2+gt7$KR48R?{V;RG|}xcoV$Q5RwK5mE)zYDpCXJSWb}= zyM)+9*R)kE0eCBGF1c*YCfC{suPi!BIp!Rpt;d}BKdI0t{(GPQ?*nv@@4&^gazcW* zYT9tgi5;5?n1hfMHB#$znWRNcU>~`RvHc_|%XgokSb0H*F(hzczvy$t?;%`lFB!WdNV|n|(RKzoeyc zCltV)Wwte0a2~vHX1`FGv*iy_bySDE?m0UprtQDaL0B6?dYcucUBX+AwXI_nBQ@lC zk$0G0?dXG;Mb9@h?GCMzu6oc1`h-Bw{r-vX`Dj3a#D5TolXpGyG|w`I+?{W7e#yiL zo$Ea;j(fs>0v<11t&pKsS-?w76sys_w+C7EyV0}My(EUQ_iK(loveooGYM5)V#d#= zEN`~z5n@?mv?L}A{)(54#zGPu@!Q$SU3>SimtxVnY`)lU@k$bd*YNHlwoQ7(^G?kp zZZ=b$+FaYGtt~=b=NWJ?V|)eFP1qnjzqN^9Kw$U({PMs>m!;eGSDa*NZd+ffqbHY- zrG!v3VCKtb zL_iW|Qxa}A>jEHOZhR>ErIi>q`tcmO40u5#@TvzMwT7ViLVL(abSxAGK2Gg^G%3L< z3Taps|31BLS!0j%?>7wU6^ehU3 zkjXM)wsI7PvvoCIB%<}mW`t>tar8$lb$kvbnXtx&?spk*E(ije{M5%)?zH-!f&hfl X8Q16!*&6xe4}22`pw!2|l literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/block_with_additional.webm b/src/sys/libwebm/testing/testdata/block_with_additional.webm new file mode 100644 index 0000000000000000000000000000000000000000..2f1b22cc9169f5c437af71aee0ae5f7fcbb527e5 GIT binary patch literal 348 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~YMjb)l*(Ixd zcXtP`ZV~ldnHIdJF%QBM3t5*9;>y1mjGF@OY8c^W_~9Jm(CUk zpgFz`lXJ7na!V^xi{eZ3GE3r1Qj1H9!yU1Sg4{G`-K^`4jKxPA8Jim!+giio!vZWG zv~Or)blBCn1>{VK&lrN9H!>_(vaqia#jT|aCob!M*T}fE3n9E4PMj4$o*y=*chS- zkQKYMu5WDScXDv)Y_V@(VDN32oSR*iTUwD?6knQ`SrT88T3k{b?ubnk-0HAZPAy-MMw!=CF`XglR__87DR}Olo3&(J-qO kA?{q$o|>1QlUbbMT-Q`u4DuBuSQvz#H!>{lYeexE0O-zk{Qv*} literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/colour.webm b/src/sys/libwebm/testing/testdata/colour.webm new file mode 100644 index 0000000000000000000000000000000000000000..580cb50aad5e262b9a80ffd04199c9760e7cd629 GIT binary patch literal 416 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~Y#sWd#*(Ixe zcXtP`ZV~ldnHIdJF%QBM3t5*96{)TRBWC-2V$QZi0ktuXbBXj81MwZZRjjW;Dfnqy= zcqdSNS0iWW?nbWAJ&oLy4YfS=FHj9OD%RjKJ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/cues_before_clusters.webm b/src/sys/libwebm/testing/testdata/cues_before_clusters.webm new file mode 100644 index 0000000000000000000000000000000000000000..c634b179d97144cae2c776ae343a2db5911d13c9 GIT binary patch literal 380 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~YMjt`n*(E!C zcXtP`ZV~ldnHIdJF%QBM3t5*9;>y1mjGF@OY8c^W_~9Jm(CVz zm)XmF8z$#wm*tjLq!z`O=4F<|m!uY#6o)%v69u_x{<^u>8<~oaHZnCgGPSii#`_0^ z20!fF+T!?ufnk0l6Ue0y&oOvBZ)8|7ePLe{igQaBwJ;nm7g#U_Q=+jRt7roNjM!yI literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/estimate_duration.webm b/src/sys/libwebm/testing/testdata/estimate_duration.webm new file mode 100644 index 0000000000000000000000000000000000000000..c7547414d478801c213e036c825215b064d30f3a GIT binary patch literal 365 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~YMq5GO*(Ixd zcXtP`ZV~ldnHIdJF%QBM3t5*9;>y1mjGF@OY8c^W_~9Jm(CVP zoik^B8z$#wm*tjLq!z`O=4F<|m!uY#6o)%v69u_x&bnFG8ySm_HZnFhGPbpb#fJr0 vJZRt0#OScAaSO;>y1mjGF@OY8c^W_~9Jm(CW4 z1_lP-hRM0vWx1slsYUUnd6^~gC8@;>y1mjGF@OY8c^W_~9Jm(CW4 z0}Kql4U==T%W_LAQj6kC^D;}~OHzwVio+eTiGtiTXWgvpjf}-d8yTA$8QWUJ;==+g x9<*<0VszNmxCP`)h|d^=pEoir?rTJGDU!7E^F}6gX%L?YNduB{plNLA$^nK3VF&;K literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/invalid/README.libwebm b/src/sys/libwebm/testing/testdata/invalid/README.libwebm new file mode 100644 index 0000000..f9e9413 --- /dev/null +++ b/src/sys/libwebm/testing/testdata/invalid/README.libwebm @@ -0,0 +1,24 @@ +Why the files in this directory are considered invalid: + +block_ends_beyond_cluster.mkv - + File containing a single cluster with two simple blocks. One valid, and the + second reporting a size that would cause the block to end far beyond the end + of its parent cluster. + +blockgroup_block_ends_beyond_blockgroup.mkv - + File containing a single cluster and two blockgroups. The first blockgroup is + valid. The second blockgroup contains a block reporting a size that spans well + past the block and the end of the file. + +chapters_truncated_chapter_string.mkv - + File with a Chapters element that ends with a ChapterAtom whose ChapterDisplay + element contains a truncated ChapterString. + +chapters_truncated_chapter_string_2.mkv - + Nearly identical to chapters_truncated_chapter_string.mkv, but with a void + element and a partial cluster. Causes mkvparser to fail in a slightly + different manner. + +fixed_lacing_bad_lace_size.mkv - + File containing a BlockGroup with fixed lacing, but reports a total laced size + that is not evenly divisible by the number of laced frames. diff --git a/src/sys/libwebm/testing/testdata/invalid/invalid_vp9_bitstream-bug_1416.webm b/src/sys/libwebm/testing/testdata/invalid/invalid_vp9_bitstream-bug_1416.webm new file mode 100644 index 0000000000000000000000000000000000000000..ac76dce86be63a13600d01d598f3dfbf563acfa7 GIT binary patch literal 12847 zcmeIzF-yZh6u|MO-#|erF8u-yZ*_5K+QC5(EO8VSbZ{*0eN8Pcg1dslxwsS^bnqMa z3F4+sE`ErYZ$JGm zz4zbC%GUj{&$nZ_##XoGvXu4SRKF)zrTf-t%SAD?+8v+zfRAH;v6*PlGrJqD*|cE|MbC@ZdIOsQaiL1 zj^sLD@@v}+pU?88B3~-5-M1Vl2q1vKp9r`_tJ&9u>wMd)p(X0#3Aol9ugl^+R!$`1 z!bU~^7<3VsQ-Rks@2r{A1CTZX2q1s}0tg_000IagfB*srAbGe|^iJb=w~A(aqU&_W0(rc9?r%Ef-)u8L(2V7F-mBUTpPASXzf zbZI<bJ*)lqxa+OQ zZr*#HHPO|VMLzX&aS7!u&z$!_mc^qw+`hUmx?6W?eHlMgt(Eb#E&FvbAH9s89unj0 z!?OLj-pVc(IT#sezeY6Fv(es9^Kw&ujiev8l$9@ubaPF68id!hUorqa2q1t!slaEJ zwOeVKBmxK^fB*srAb5M-?O4)3E zcSAJ^1+Q)q^<0@&TAUi6oLgXNU}`BAvMw7cYqJi@FuvZ%SbVhQ^t*z^&5ew0tzq$D v0hSM-l42VgId(P9E-PSUU}OQAUsl|aniq4w^W6Xc3``6R2_Oq*FfafBm1;6r literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/long_tag_string.webm b/src/sys/libwebm/testing/testdata/long_tag_string.webm new file mode 100644 index 0000000000000000000000000000000000000000..e8d665300a45b8d7d162586df521105ef3739a56 GIT binary patch literal 474 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~Y##Ms8vrBgR z?(Pm=-6HC_GA(#bV;+Pj7P2lI$Xg5H356U^2lCGO?(PAqly}}%8oZ{7vHQ(BurWjv zAS-rhUEkQu@8sap*<#+!327$W3$B&AQ&m zSbVgRvAL14tu-t@EWqMH`-Ub)hh2?ZK+bg7UR><3IsJsgde_ArIr(|%@g<4rF6|Br X3g(@Uk7=)iUGA!;>y1mjGF@OY8c^W_~9Jm(CVP z0R{%&hRM0vWx1slsYUUnd6^~gC8@;>y1mjGF@OY8c^W_~9Jm(CVP z0R{%&hRM0vWx1slsYUUnd6^~gC8@E-Y3Zj@G6bl0bk{adbjckkiz-r(=0`Y;0;Q&dw K@bgAabmaiqEn~R= literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/metadata_block.webm b/src/sys/libwebm/testing/testdata/metadata_block.webm new file mode 100644 index 0000000000000000000000000000000000000000..a9c686e00176aaa08629a07d34359515a98f7e89 GIT binary patch literal 314 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~YMlM0$*(Ixd zcXtP`ZV~ldnHIdJF%QBM3t5*9;>y1mjGF@OY8c^W_~9Jm(CVP zpgFz`lXJ7na!V^xi{eZ3GE3r1Qj1H9!yU1Sg4{HJ-Q4Sq%*96=nVTCG+a|iihr2q3 sg@ow)x`sHqIEFZaTnh0VgYNT2h6R%s_BEq8cXlHaM34zdcy=Qj0I^+K761SM literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/output_cues.webm b/src/sys/libwebm/testing/testdata/output_cues.webm new file mode 100644 index 0000000000000000000000000000000000000000..49e2126139be5f2aded6a0e960ddfdb87658370f GIT binary patch literal 394 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~Y#wbDG*(E!D zcXtP`ZV~ldnHIdJF%QBM3t5*9Fn-?1u(+?0fuRB6IuM@;!3E2+An}p3 s3qNmUL)Q-S_R8Jen;RLnw*f=gO^m!C9t)fY0DEeDrvLx| literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/projection.webm b/src/sys/libwebm/testing/testdata/projection.webm new file mode 100644 index 0000000000000000000000000000000000000000..0f13e8a6573b2494fb38220563b305a560593891 GIT binary patch literal 317 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJh~YMqWYR*(Ixd zcXtP`ZV~ldnHIdJF%QBM3t5*9;>y1mjGF@OY8c^W_~9Jm(CXZ z1_lP-hRM0vWx1slsYUUnd6^~gC8@;>y1mjGF@OY8c^W_~9Jm(CVP zpgFz`lXJ7na!V^xi{eZ3GE3r1Qj1H9!yU1Sg4{G`-K^`4jKxPA8Jim!+giio!vZWG zv~Or)blBCn1>{VK<R)H!>{lYeaD=h|h#10^+kE@fS>62ozyM68YW8GP{up0G9M# A9RL6T literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/segment_info.webm b/src/sys/libwebm/testing/testdata/segment_info.webm new file mode 100644 index 0000000000000000000000000000000000000000..0fde8f0687bfb5ceba15cf0255ce4bbf64a14e94 GIT binary patch literal 284 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJi0_H-f&iOIG>r z?hanvBI>y^EqG019)u?rvMw9QTLaba`W|!rbR-_iim*!=b#FwNNmlTIPViN_qY0kP?*BiNt zk2W$kH!`-hhQ)^kSUhOo(8TDlt8oj+nGl~b7(Z`hSlrjez|eqj9f;3_;DY5@koc(D o*@)53jHDeDEVFlaZ*FAR-uAtb>to}&-94Kd*|xWXI8BVa0R0AeKL7v# literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/set_pixelwidth_pixelheight.webm b/src/sys/libwebm/testing/testdata/set_pixelwidth_pixelheight.webm new file mode 100644 index 0000000000000000000000000000000000000000..e81c8bcd4f22f3b2844aaceb84929b1c34f5455b GIT binary patch literal 302 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJi0_e}cZVOIG>r z?hanvBI>y^EqG019)u?rvMw9QTMOaIJ8vrm^3K263(-d=39@3B*7c3e{7w!ooh=SP zV|*JX=Vq7XmR6(|#h2z~mc*B&7MB!0JMWx9RL6T literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/set_segment_duration.webm b/src/sys/libwebm/testing/testdata/set_segment_duration.webm new file mode 100644 index 0000000000000000000000000000000000000000..100684bfe66394ce10e356d19c83c629088c11b2 GIT binary patch literal 301 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJi0_zkr z?hanvBI>y^EqG019)u?rvMw9QTMOaIJ8vrm^3J{43(-d=39@3B*7c3e{7w!ooh@!E z0t~(llXJ7na!V^xi{eZ3GE3r1Qj1H9!yU1Sg4{G`-K^`4jKxPA8Jim!+giio!vZWG gv~Or)blBCn1>{Vq&y=4xGA!R literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/testing/testdata/simple_block.webm b/src/sys/libwebm/testing/testdata/simple_block.webm new file mode 100644 index 0000000000000000000000000000000000000000..c311e681162cb971db6fad8b79e703a03c7114d4 GIT binary patch literal 301 zcmb1gy}x+AQ(GgW({~{L)X3uWxsk)EsiizMDc7kT$Zc(8k_c`{XJi0_zkr z?hanvBI>y^EqG019)u?rvMw9QTMOaIJ8vrm^3J{43(-d=39@3B*7c3e{7w!ooh=SP zV|*JX=Vq7XmR6(|#h2z~mc*B&7MB!27$n_m4Rme zsM4dL$YwYT(8;z%D3=9dNS2r?mxDHB+afy2F!y-%{|; z%l`kq{^ioY_OjC~)&w943CIG2#qI3OtiP)Z{yT6gh$W=<&tD96cNNwJL$;EcC>03{ z7040z+qb{s@b457mH!U-7eQc7{UESR5P-BHGr+~xBsfS-Urm8C00c(16A%c|R}a|y zR~N0?9}Lh6idAj~fvHr3fGQtjBH>1te{R#7?SlaM6(9fr=r0){1VFlgxdCvH<74vx z016Jti~xY;=mqoVRIHen(N&%}gbulTV179WpzuHHH2+t9obe$ITOA?Wrl1b-IS6>Wlt(v-cPik05Hc8Pl05_F$>Uj2Q(V75NTi*rRB z(Det>&@+$p$x~A!y=UcmVtKtOlb;jqw)Gt3Gy_8^KLC$hf7r%s~pZBz`7TxB&CaA|>87~O`y zXod-2ScW&y@E!zQHf;&C;@Q)uve%v7eaNJy%#Fd}K2 zAk8wrU>J)GbsoZ)IG)DH5c3^ze!@~tGl;-(C?lpN#AhF_t)WikRB}!eEzfKzF4&$z zxwU5;1O*wQQL5u;IH!CJB^1itihV?ECCkO2>>I;FdcQekYqnV{^tv#}0h@{=Dek-l zeaQe8{SX@wpidd|vo^fv5Q=#h6>S5v}Jc`nE)lxmCVVoW9cC7i$?a6>P#< z{Al<%jF4?*JtH7Q(yoa~h`p48Qg(#wIcX`99J(zh3YXm-OE%&JcWy1==XQ{pWT4~c z%6qQch~q~Y7O9uvDZd>3T=2tCCMn39%9Tczv32~rwied3X~s%K(1TOn?az4vRtlLx z^nS-&3XSbW-o(@EbtDtHZ^;XeEY%SBRi?PaF+@YfmmNt5bUWC*h14i6704+0HJ3$t z)j>GH&^-lkBF>g@=7kDIf;B)>B)NdydswkA@gAr-nB0=T(Cdm z$oc1ek#tH$esEh&J73Y|3s1Nv%i&|X@xj+KhQzF@Po!!-bx{2I+;lpqG(em)W!xTa zhen>XpY}(nHm%hE!5KU@pG{~+C-XdhRv4iH)6Oh|cV=U-X#H22tW@Am9>xL-Y16ri znWv3Zr!-A4Y2~Lee1iTnC-M}BU)rME1-v`5OkDn0)F&3g2fL|u_Y-l5IBI-{L_1+x z7+>IQR+Dcm>?DlcYpWkMX9zfkcjoXoD@S)3o~f!LJg!jE8)w} zw(P|_L2@U#K2}(A8}W2?PY{^!_yeDT!2p5eRDieu;1e+bpv7{cK%UzT7*>J601W3R zg8&zR|0+0TJS%+QU;_Vx-^&#M@{>SdvHydM@euz7Z~hOgApyuw1c5XD7uHm``A`N2 z{ufnW@BUkP>c6m>2JmBw53B!Uph~5{U#R_mQDsJ8zQ8Q#Q};hG@`t;K4%6_TsIY20 zyU`#9i2)v^s)sJ2+55k)1mc%#>htbA&SL8{t{n?1o638P%zK44_qdNLL>GA^vJefE zguE!Lk#L%EH@46l?d^jOFP$Qp_K93#%updHTfpn}C`ewDYlo8tkHnKJm}t8Bu%iWU z!ug_dJ$3lumHjTjLHOx{bj@np;^Hh9tg%M73Ogdst-TA;0$y(62~nRPlysW~pSx#S z`lYC_u>`>iZlge9q&Pn$r1g3(PtM3}nW7jF7 zs`C|}KoABWD~v#pOgJecfClJCRQ&tET~GS)jdFKw1MliZe)5u^60+m+oYzl5cZR{v zWkL7E$4%?jQoWx+5W0hieoejKn{mWM#98lh-T#yL(A*SQ2X&zw?@!Q%KGKP|Vg)h4 zw^B8@_)6(HGS?QGZ@{=7(rj9om3i{I3Fzys!nYCUoX&j}S<<$f&q``zCmeCf%ic)D ze+DQigr(q`*7sOpIv8bizTmrFx%3p)y>oOR=^oic*WANhk!r!(Tpbyfqf2&sp#~II zL=!HqiP>zf;HBQ=EW9~xEYt**ucq{9LQXfCHl>#_n^Xr**`U^|uNChYn`cg0s3_sb zM>NX^H55XfrCRji8L)(<1%!&db0cJsAfOq(3OeNHsrlB1e_NF#|G|zN-8pG^ULuW$ zD8(lgB8y}-W=44f0oApCmAlAK#f}YC{$0FN&Wp(1pL<~uzL?+(VOoNj<%@h2pM1so z8_iSLw)f+Xs?y%r1A`-|eSTV-JHPwnK_wj%v3B&LW% z@ku)My~FPevurSCl-~K^Wc8ayQta1&*8sD=cC^~wA1yp0UmkvBN!PuQyR<$5y`OQO z71rdv;SLjjT%LEX8h)lRZ%Pwn8d02p9miTE&0B@bul*KQ2%-`w2!4+isU+8`))Dhq z>JNx0(MQuh%$8rtmajNIw1r`9C^O%-uuz8@65FK^=;a$8hJT_Y#mG|gtKvkZXlUzlR+?&5uBCQd)Bp$in?uN<}=TjH(qfwZ9G&l<8XI| zW`A2AzR98|fCd*wIpU@AtLhCS!02InNU$Z{nyqIYS}9&nexyT)e|!#jTZZ{XYWC?~ zYLshT4U+04!tQ*h<@q)FSE&c)uhVH}hI-XxR|5#s6u^mg_K#M#cdSn-B%fkfLv2Wg zy$yHezo1$!`fOx;C7G$2Eh9;5cidOVI~ssM5cb0$2&V-q-vRW$<%+xweeeD$Yeub% zK1So;sC13zVW9#I*L=Rrzj!QFZIO9nkv?xIVRFjJv0E-5ED)cCCQ$m~l zpi=M`Pi-(OcVoXyQ<@mXdU*W0aE>({yns`E;A2S8R??5Q{ghIw%K-A|p$la!h4F6) z8{ngKe!C@M659zbYhB;olkB7MW#85MOX#cnef+nA@o^SnyB|P%4jJ?1mhVp??b2{E z#L@@X6lr;+r?R}^xQ@Nvk z!=X#gOSyS`9$@+O*4?&|d&til-|&ZdYsq3Ca?^$F^EFxYv>yeJH#n-cUB~ohXc_86 zLE;bOh?yZTMYCPthV>j!M=k-;<{M`v4w>Nsc?8OBL{${KPS0OM)RjAB!jB~64K>x7 z?y9J(mmo$X1TMAEIg3QpMwfy$c`jg>mG4+p)60uIC^Z@GcA=wHpea)TOPMkpxn9Hm zQ(T|soY~%|Ir*)>)y~FCaIT~6Ltl{ME<+EtdG}8~1KMK3z`Her4b2yjGMlj)BIFwEbG$<556pimq;u}abs6k;L?4q0^E+5P@{g+NhyF7O;RxKq4nrqQ8&VETGA zp@+~SI*(OOOkd(~(kMVWI=#f-FmtUawCsS{P{q^hjf%*p-yd7F)mfFo;wkI?9SKh> zHU3g8t?ydodLpQ$$e+~^$^m_qdI%X)zbvz>>6>%s`2YuJ2Desjhcsz3lpupXZC6tu z7-N^yF+jDCa?rUg^lf6 zqV#bkVG^7O8fTRObtD#~uyf?rE;Kw-uwXdemStKU1Tj#X`)2NQd+hMt;S5s8>IKy? zgv(+iva{3{->MFLo9IgGvFIwM(NrW(aWj&mk}iA%^1GjtB6ZLFx{&G3j|#`nlMGw$ z)AuQXxQFu(%r)DEQ$tZ=Ws__Kod^x?Lyd}0o^ni%xy`-0dDLDINzyCSNek^r`-n_k zK^P?0K%wgl)k**UZgS{~R}^pRYikbnWnNSmuk8uvIKxDN7S0n3^%V8T`17r|4E(3a z#6Dm@kWj)824{``Duz9S!P1|^{f0m%muWB=eNVgoU6y$n(EDHq>j z7FO98Xn?sRbR@9}_bQW+5d`>2Qgo1KAWkGcISd&Nmoc{y_sE6Fcy|Y%yBkBfVI-@l zjy&(7qxff$RU9A!KGF&vQWtecH#vBMqW^eWjf6E9z5oo&KVD-ai{%j4Li7yLr)fKf z$%JhhcJnORrJ?pMAAqC^+*2asovA8n@_|JZ4-X@UviA~2{1O{M(EU4a2qI230FfzF zxO=9k?lCukBTfuEmG3n)>y137dJy;X?tD6#f-z$+dZ9IA2%*hlQ`1Siu_wE{vQ_Tb zg%i8z>;+URulN*!6xAWtE0Y(a8*{!eTk3n`@@O68J7W%5ip&tMe^Z8fG&Dn4Q-WGr zaFgxMw#|Mx!4f`ctNa6Er|YIV3cK6)<4Q&|#`pd^>r9d4cLC>=g3>S-@vrk44h7i$ za@ezJXfDp}aElLY?$)Y5wY>4hjP)NrpgW?kNM z95KT^?&U%rj~3Z|;1Fecr|68id!Cks92)lVjFU7eQgNzCR-B zWNJ_)j41=FD3GD413CGGZ(EEt8_^~*qhHjW;`>PFM(eNoetz>W%dV97#TT`_3EFhu zN{gn@-agrjb^$^)>xj9#1oN#66U4siDmKW__KA=7)RyEQbshGiT&DUuIQANZN(G+8 zrvvd5kuWLx(~2r%@Tw&O73QGk+0zdnLT!!pwnD;vgja=nk#c2d25Mtgr5MWl=^`dR zyA`SWM)G#JE+UW!pWnz@qo3+n1UE}}mA>|B7OOn7MONzYLCz3`?a;LMa-RD5l42Dc+P@*$@m&A>27k+lvOlB0z0`bTTD`JD+*^) z_BmZCC4a);Fh)MH3Hf{5tTs0unt(@0u4$v%b>H1+gXavr$6MbZXG)jA!(`3c$+8gFKlK__T#sqkVEFW> z-y7r=FvBawC^oQl>=Lt9w30ZzrvGvv+AcO0FO{NBMMCiE^3-Kkv1$YvSm%Mb7$drSgnQe_5y2#x7HnVXYQe#hB5Z64t&A#kjp8YATo zW5B74q%b1GQEaNAvQ7`mg0ajL&Q8jg%lKMbBgWf66{8c;Pxz_PJ6ds_f-j}kFcFvT z1tgYTMbK#h={ujFoZJarbcZzClYnTsa@p@>P?fOOkrRFVzcpd_)EwV*E^$`GNDw1P z=#gT5C53qT1*H}$(D9q=5P}c(Yy{p8w&1M;g?1Tx&INAicWW-1XGhla@5p>p#MGzq z2s_{D+n3F|31jI`zpx*Ed+ZjXGxZ5RnZlJ@m~IooGqFA=ujJ=mMHp2)k(uYLw^MVC zc}YyPS{_%L`CC5%Ag@r!0fyaYtPGA$^gW7?1S2_0Veq_8CbDma zW8TeVc{*Xea4 z=Bw_uY3Rk$K+hn51H`hd<$;_Kk0}c1&>Er|d>)gBD-?VoTa^~x>lOyV+!($Ia~Jd8BEIlg{!&=?;NG^rn~Kw=9foOwJ6OQNyS6eT3MWjPPbV?p-ucfCz| z=wb!yD1RmqDc{8t}wbWi7KpQ+_3v32?l0^V%I5Cf_Z+ITleOW#uF*M z=U%H8W3N&3(+`yW8}+&nX(A2bnJ|(8#-w2(3JtzPg%=@PMj{6J-P+QR+zja^oWH7S zH}yC;aw6Nv{TjF$kn&H*-$0WXN&eEn8 zAzsRMixNWyb|SS#*Qk!8J7>xxL;C!V*0#(jKjJdU#_te);|+(vsl~^js!Tv3|Gq=Q za5~JT>}g0{EbV9tGjM}!=L&weu^s=L2H3^RH$Zc6KIV1G{du{Lt2ZcXgBb;zd@lr+ zb02fr>*!HBRn2k5Ss`sr1eTY`TDt*ypzJGR_Y3+%fqs;Fj@{hwgVQ79sz$9d?)vhP zC>i7q?W(-j0x1Gy(T^7!I6*Y*$h6I9)Pr(nx-5-h+-F0_c!tPjeDXi8d7nalhN^i7 zA3>9SG4_b8VS&j`|k42@+obILDMZjW~~|v$lZF+BbQ~nFA%iza|=g*Im5Xl zvIb+P+bJ>*xx2r53SBjy*KS`Ol?#_&d_@m0V>FjOvlmu1`pIM$=A%j)pA6_EsrxzS z!t-@e&Pqlrq2R=|85UEQeu#l@d5o=Lg(oznamFeIm%&1VGx8|vyq?3(eEL@zxy9uH zQ#dE6f(SY5!QI;} zeMK+tEbY13&&U!Be-v5|x!lPb+2~peF!@zR33AmTmWAIn+68TF+%JOr+Aae%wbBD% zIjAWLY89VQ#qI0kjee_~h{R66L>!94`$eS`veV~VaP&jeRT#Th9xM9jb;Q@yaBbWF z_(eBz0V=N2ZJvFd7xqvzspu$O$3@Da0H+s2dnBDadr*m36=99zJtV$GBqFCl8=7B` zNp2Zr$BZ?h^Oi2Y7l{?L5i;)aBwb~WxjTZwyBtdWSzd!DoPAKPA!&vY4_T0O9~bH! z10f`cf$cJ*M18o#0#v0HGPRrjpsLyDSR)=_Q?b0v>`Xsr`!3GCrLRt33N3ka!`$k7 zmQ!Iz-=k385_6%Sd{LSHr z)_$ouyvZYbOA}IC>8AxIfh<(Di=wV^aw^u$?M@kiE5e2)>l_zCxXw8wmnnzgjX{4t z_3knkUt&_IQ5;h3J&7h|M_5Rt{@PSz!lg7IHokO5Qgzuw=mi~{$d;r{6CGqrROzf+ zv)lG9zPoT-SB_rRHGzjno_#%meQo=UwHMIsf{zavzCZ$i59bRtfgq~?Ap`aY8StFB z&-t&qe7}MPo1S|k6$7g090=NNPY_Q402_ug_5{>}&%8zb;y$KDwuX@OSp-mVlDO_A zK@c&QwT?BxLH14_fXXhGJ;oXq27NfftJ7}7LP>V%AScYh!`t`#GbMf?mdqH_RYl$f z*+C|;W?ijLQKa~(DxvFSvbzy2y3{QJ7Jv8wt%bH(yb730!Z+}eG>PW$_eA6kMnz4d zRv_`8Y%czr+(BttCr4RUfQ|mmkjcrhMXNcPaRgq>^5X6t$xr%nj*IOxNY{Ly^w`eehjguD!`V+6H2JzeHM zU*J&;7aJ-=k2yOdTb0Cm7n_zRiCnHQpc3X7)Tl&yCFcyckr;+Kn@xpiZ^U1z6e$N& z!`;1Q%b~nBe{>gptlc%};0+cb;l?pRG!Y?IBjhg>A!6=LA@DYiNOv-n4_kqrZ?9~J z5&b-R2?2Q^9E)YE>`BbEbeRjLWpBKKDfQjo`g{bcN*_HuBy^^r1)esz#dcIV|Ab;E!sF8 zHI5$oI#&g=>i6U=ytl?Qby2{lb*t4(k)7zxxRcHXj^xpD0mUI`Gjb+Te6sY|Pu_|v zxiB)6yHj%DZ-X`H65cax-0$dt2U(1h{k(rz2n$9J8RqK5j`2sgDncy`5qFPxN7|fe zzl1vj@`YMKkbu9LTa5p~TvVq<=psN>{im*C$V1f`cV+;NYOpKZK%OB4E!dP^rTZ`ng(x`|h~|SxGOi)beF-%Z zFz=8ZLq<&{kwxEKe9_OAO~VCp7s%P6e2emUPfRqLzKAUQWbs5h>nC!k|Ed=9mCHPzwt z^>aWj5w?S)7HrQE*FS4lD2_=Ew&sESt|VYo4^ybmPJS?Cnttf5x4?gOxJIk}J=2%J z-G;;AvUbh-TL!|9NhKsK({@(b42K8#DusUid-5x4I%%QH<;o15DZRV_5StQ5P!C3b zMMLKb*D!MfIi0r~O=JnXygy5POyB-EMeWV3Q4?>e9zvdv_`$tArPOFMHjT}ipZk$m z8)^>Y0l=wvrX z&yy8G;#H+H)Nr{0meAoIN3N^us zi_*Is3nM~9L?>aNJH}&Kd9sq47d!hiS?-u!U*NcGPr9(~sF|_`gQcr6UKo7>F8+ng zHWL%Vw!Nr}jwnf}2VIyx*2U=LrgPF$&%Busf3EQA3m=%6C@c?b*J8asx0k znzn8cBB!VvIq5WHgIDX=iH26@c-iZ>_0@xEAkD}cO{Wq-jL{>A8Dg%_@H3~9g5sX%OF&&-yn5_ zbOuBFN2_!gTgio=Rlj%fD$(Asj|R!Oyh-T^?uplkPzNlmE)#cx%_tIWvT??#sjGwG zP#UO}h0~>uvPM1PJ$_LGE&3^9~E_ZV<$STP@WdZYr z0zr^D|B#;e?~L8>vatfX5Agz`PYnfrzAymz`E@k}g0WeM8Z;_pCLyjryRlw(lt)WnprK8^m{^+iLxUtU|og`*Y(Q zerEJIqQe7*b75wyz}cd6<;I@WV`A;khC=Ev{q_(XEVfZSHzz=EeQ;$2u9?u<7boiE zfMH#*=FSfLhUcNK)XE4xCHXiPRgW4s>O2Pgh9)gX-c@$jLaFu=X4CuqCA%CV_r_=* z!)+<=LZ1vTPK1c}M^7mO9$aZD2N#}0Y|>N=$)8j9b%c0XOr&+W-bWB4V!2-YDV1?Z z81B`e9GrSAfwc9NZ^c$Q34u6|fZFkMmqLjJNnf{#r%W!x)s_R!1_;YB^i;{&`tj;d z1=R3M5BW2u7s9G}QniaMozJa#{r&Ymk|L=*RY_4%y_J@^Md89VmP69&V;Fuj4)c5= z#YagR=T;-tL{p;%PI-#F<9e^Ikv4No8fZ+3L-;=gOGOGn>>R3{&T$8!j(CbooA>Qe z-3AuAiG~V#=2>4USIjNeOI;t&ciD~K&A)n8<@YfMqcMuLOnfCp$?3PGW}C3(2m{mw z>+Z^T{BbgQ{EPwyMNV{P+6<5r84?>F2vE^S?{~IFaBhTC z9RlA<`K@yY3B+86hbT(*bs5jdU3(@q0ZQBFtK@!d(nojVqdAVt8&l+wB-@G*ePk|h zKW+>7Mr!$jQ#_5RcVNSo94t$0=Zta~U0HnL4xbVFC176{gFTb4Sr0z-aLTo6F=3R& zv?OpT-H3*%ngrw=m(6u_^8?Z!BoWxWn^zOONYHyjtH-yVZc z(ImhjiVbAiTrAg7pxS$+0D-iK$A=9F$Q`Y70*XD(=H%qW+4944ZXdOV6#-%z$RF7B zURpY9-woj%tBxgSSJW&jcFKC_*rnRPeQzO&V1ev7w3Y_aq zFFjNU<5R@xH3!4?bgGp4_3NS5)v5W2w(}610E=j3mg$~;3PA-Mhg<$9)U`hT_Ki18 z$JV1yt-mbIQsBVmEyDSIzAE{U#?ZQc(V|m_!SS^8Fv^8DR}gzkGYq8TEL6*>lG=iL zC02swvR31G3o#cHeWH%U1*CH@Ea9&I+hL^gi3iglXY!$6^h7mcV*#_Rlo<@(fIL`{ zqkr!n`JX7MjKw&v6aI|}k1^OGFTTS0sMscx7^`YXpB4}x;@EpW27I@l7W0!k8Vv8B z341)p@rkzmKa#J{zPDxQL5;A(8Yos7jz6;KOveUTsSL!m^qDPt%dn6av&89zSp-{} zjF2M~UzOhp_roqw60^jOAT!wA?jxcNSnqB)Rh=Mtz3cqwyHmqY{&c*ZpYm5L^R6#r{p0;=d{q z@D9J>W&z4Px^y2s9uD&ncNB0@(-@Gj;N6o71dU3wVRyi*iML-4?XVR0HSRFf2icKI zxQooVsIFfS_UqOmpV{(i+m);a~B7bS>dv}ttk99 z@yj9CEaPn*;5FM{H4`@l6q08II{HaGNbEaHSxIgyX%u9Ryh@;lpRy~k#G-}h!%c+O-V^*SGbu!dFl`5h# zt48s8C*+PI3rMGw*NGb-_SMA9b5Gacybz=rA?DTJw!{_n{D=mHOPaum5?8?7!7>W$ zBb=_h^5RAidLP@cSujF7K{3If;KFQ=RElaFvFR*o`Q3%VP~ynF#`Rot z(xDt-wze0-lsPhg01?uxv?6dquEK~fJaZj9j_)>Z1!YUr+`F zwfRpzQ2fXT*!HIeVC?|6i>|l9hN(F!=J1(p*d_2+QWT_AhCpSZNd<3=bNmYt00N#^ zC8D>}gj(DeCbg6Z^$d9W))tO-gkO6%?Ea}rLFheI&|&As4Iwz6ARXR!POFoDz({ak zrol}klgqSyqb6^#%etE>Ze#gLYur|!gLztf>*s&$I}w9uANXh@-&6+u+$Ok@yQ}pMw0nDW#69TJAyt~??vHx#DtAy-ihBKeap3FJU z&{)b2;mDk~7Q=;7K+yO_?fJNFvH7G{8_%!0VGl}0`{^|=d?iy#zsIjD0lUu9WWs4r zO9yk8SUvFeAKHA9G+{oD0 z8WtZGU=f_x3D^2y#)c+Fhh2?ZLV&bc$gaj!%FT~k?12tmxBhw~6Hp^lb0bq*hhu!0 qe~^=BFtXlr z?hanvBI>y^EqG019)u?rvMw9QTMOaIJ8vrm^3J{43(-d=39@3B*7c3e{7w!ooh|ka z3=F;vlXJ7na!V^xi{eZ3GE3r1Qj1H9!yU1Sg4{G`-K^`4jKxPA8Jim!+giio!vZWH bv~Or)blBCn1>{Vq&xD^hGA!(frame.buffer().data.get()); + *write_ptr = 0xFF; + EXPECT_TRUE(frame.SetBufferLength(1)); + EXPECT_EQ(frame.buffer().length, frame.buffer().capacity); +} + +TEST(VideoFrameTests, OverloadsTest) { + const bool kKeyframe = true; + + // Test VideoFrame::VideoFrame(bool keyframe, int64_t nano_pts, Codec c). + libwebm::VideoFrame keyframe(kKeyframe, kPts, kCodec); + EXPECT_EQ(kKeyframe, keyframe.keyframe()); + EXPECT_EQ(kPts, keyframe.nanosecond_pts()); + EXPECT_EQ(kCodec, keyframe.codec()); + EXPECT_EQ(kEmptySize, keyframe.buffer().capacity); + EXPECT_EQ(kEmptySize, keyframe.buffer().length); + EXPECT_EQ(nullptr, keyframe.buffer().data.get()); + + // Test VideoFrame::Init(std::size_t length). + EXPECT_TRUE(keyframe.Init(kSize)); + EXPECT_EQ(kKeyframe, keyframe.keyframe()); + EXPECT_EQ(kPts, keyframe.nanosecond_pts()); + EXPECT_EQ(kCodec, keyframe.codec()); + EXPECT_NE(nullptr, keyframe.buffer().data.get()); + + // Test VideoFrame::Init(size_t length, int64_t nano_pts, Codec c). + EXPECT_TRUE(keyframe.Init(kSize, kPts + 1, libwebm::VideoFrame::kVP9)); + EXPECT_EQ(kSize, keyframe.buffer().capacity); + EXPECT_GT(kSize, keyframe.buffer().length); + EXPECT_NE(kPts, keyframe.nanosecond_pts()); + EXPECT_NE(kCodec, keyframe.codec()); +} + +} // namespace diff --git a/src/sys/libwebm/vttdemux.cc b/src/sys/libwebm/vttdemux.cc new file mode 100644 index 0000000..186783b --- /dev/null +++ b/src/sys/libwebm/vttdemux.cc @@ -0,0 +1,1004 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. + +#include +#include +#include +#include +#include +#include +#include + +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" +#include "webvtt/webvttparser.h" + +using std::string; + +namespace libwebm { +namespace vttdemux { + +typedef long long mkvtime_t; // NOLINT +typedef long long mkvpos_t; // NOLINT +typedef std::unique_ptr segment_ptr_t; + +// WebVTT metadata tracks have a type (encoded in the CodecID for the track). +// We use |type| to synthesize a filename for the out-of-band WebVTT |file|. +struct MetadataInfo { + enum Type { kSubtitles, kCaptions, kDescriptions, kMetadata, kChapters } type; + FILE* file; +}; + +// We use a map, indexed by track number, to collect information about +// each track in the input file. +typedef std::map metadata_map_t; // NOLINT + +// The distinguished key value we use to store the chapters +// information in the metadata map. +enum { kChaptersKey = 0 }; + +// The data from the original WebVTT Cue is stored as a WebM block. +// The FrameParser is used to parse the lines of text out from the +// block, in order to reconstruct the original WebVTT Cue. +class FrameParser : public libwebvtt::LineReader { + public: + // Bind the FrameParser instance to a WebM block. + explicit FrameParser(const mkvparser::BlockGroup* block_group); + virtual ~FrameParser(); + + // The Webm block (group) to which this instance is bound. We + // treat the payload of the block as a stream of characters. + const mkvparser::BlockGroup* const block_group_; + + protected: + // Read the next character from the character stream (the payload + // of the WebM block). We increment the stream pointer |pos_| as + // each character from the stream is consumed. + virtual int GetChar(char* c); + + // End-of-line handling requires that we put a character back into + // the stream. Here we need only decrement the stream pointer |pos_| + // to unconsume the character. + virtual void UngetChar(char c); + + // The current position in the character stream (the payload of the block). + mkvpos_t pos_; + + // The position of the end of the character stream. When the current + // position |pos_| equals the end position |pos_end_|, the entire + // stream (block payload) has been consumed and end-of-stream is indicated. + mkvpos_t pos_end_; + + private: + // Disable copy ctor and copy assign + FrameParser(const FrameParser&); + FrameParser& operator=(const FrameParser&); +}; + +// The data from the original WebVTT Cue is stored as an MKV Chapters +// Atom element (the cue payload is stored as a Display sub-element). +// The ChapterAtomParser is used to parse the lines of text out from +// the String sub-element of the Display element (though it would be +// admittedly odd if there were more than one line). +class ChapterAtomParser : public libwebvtt::LineReader { + public: + explicit ChapterAtomParser(const mkvparser::Chapters::Display* display); + virtual ~ChapterAtomParser(); + + const mkvparser::Chapters::Display* const display_; + + protected: + // Read the next character from the character stream (the title + // member of the atom's display). We increment the stream pointer + // |str_| as each character from the stream is consumed. + virtual int GetChar(char* c); + + // End-of-line handling requires that we put a character back into + // the stream. Here we need only decrement the stream pointer |str_| + // to unconsume the character. + virtual void UngetChar(char c); + + // The current position in the character stream (the title of the + // atom's display). + const char* str_; + + // The position of the end of the character stream. When the current + // position |str_| equals the end position |str_end_|, the entire + // stream (title of the display) has been consumed and end-of-stream + // is indicated. + const char* str_end_; + + private: + ChapterAtomParser(const ChapterAtomParser&); + ChapterAtomParser& operator=(const ChapterAtomParser&); +}; + +// Parse the EBML header of the WebM input file, to determine whether we +// actually have a WebM file. Returns false if this is not a WebM file. +bool ParseHeader(mkvparser::IMkvReader* reader, mkvpos_t* pos); + +// Parse the Segment of the input file and load all of its clusters. +// Returns false if there was an error parsing the file. +bool ParseSegment(mkvparser::IMkvReader* reader, mkvpos_t pos, + segment_ptr_t* segment); + +// If |segment| has a Chapters element (in which case, there will be a +// corresponding entry in |metadata_map|), convert the MKV chapters to +// WebVTT chapter cues and write them to the output file. Returns +// false on error. +bool WriteChaptersFile(const metadata_map_t& metadata_map, + const mkvparser::Segment* segment); + +// Convert an MKV Chapters Atom to a WebVTT cue and write it to the +// output |file|. Returns false on error. +bool WriteChaptersCue(FILE* file, const mkvparser::Chapters* chapters, + const mkvparser::Chapters::Atom* atom, + const mkvparser::Chapters::Display* display); + +// Write the Cue Identifier line of the WebVTT cue, if it's present. +// Returns false on error. +bool WriteChaptersCueIdentifier(FILE* file, + const mkvparser::Chapters::Atom* atom); + +// Use the timecodes from the chapters |atom| to write just the +// timings line of the WebVTT cue. Returns false on error. +bool WriteChaptersCueTimings(FILE* file, const mkvparser::Chapters* chapters, + const mkvparser::Chapters::Atom* atom); + +// Parse the String sub-element of the |display| and write the payload +// of the WebVTT cue. Returns false on error. +bool WriteChaptersCuePayload(FILE* file, + const mkvparser::Chapters::Display* display); + +// Iterate over the tracks of the input file (and any chapters +// element) and cache information about each metadata track. +void BuildMap(const mkvparser::Segment* segment, metadata_map_t* metadata_map); + +// For each track listed in the cache, synthesize its output filename +// and open a file handle that designates the out-of-band file. +// Returns false if we were unable to open an output file for a track. +bool OpenFiles(metadata_map_t* metadata_map, const char* filename); + +// Close the file handle for each track in the cache. +void CloseFiles(metadata_map_t* metadata_map); + +// Iterate over the clusters of the input file, and write a WebVTT cue +// for each metadata block. Returns false if processing of a cluster +// failed. +bool WriteFiles(const metadata_map_t& m, mkvparser::Segment* s); + +// Write the WebVTT header for each track in the cache. We do this +// immediately before writing the actual WebVTT cues. Returns false +// if the write failed. +bool InitializeFiles(const metadata_map_t& metadata_map); + +// Iterate over the blocks of the |cluster|, writing a WebVTT cue to +// its associated output file for each block of metadata. Returns +// false if processing a block failed, or there was a parse error. +bool ProcessCluster(const metadata_map_t& metadata_map, + const mkvparser::Cluster* cluster); + +// Look up this track number in the cache, and if found (meaning this +// is a metadata track), write a WebVTT cue to the associated output +// file. Returns false if writing the WebVTT cue failed. +bool ProcessBlockEntry(const metadata_map_t& metadata_map, + const mkvparser::BlockEntry* block_entry); + +// Parse the lines of text from the |block_group| to reconstruct the +// original WebVTT cue, and write it to the associated output |file|. +// Returns false if there was an error writing to the output file. +bool WriteCue(FILE* file, const mkvparser::BlockGroup* block_group); + +// Consume a line of text from the character stream, and if the line +// is not empty write the cue identifier to the associated output +// file. Returns false if there was an error writing to the file. +bool WriteCueIdentifier(FILE* f, FrameParser* parser); + +// Consume a line of text from the character stream (which holds any +// cue settings) and write the cue timings line for this cue to the +// associated output file. Returns false if there was an error +// writing to the file. +bool WriteCueTimings(FILE* f, FrameParser* parser); + +// Write the timestamp (representating either the start time or stop +// time of the cue) to the output file. Returns false if there was an +// error writing to the file. +bool WriteCueTime(FILE* f, mkvtime_t time_ns); + +// Consume the remaining lines of text from the character stream +// (these lines are the actual payload of the WebVTT cue), and write +// them to the associated output file. Returns false if there was an +// error writing to the file. +bool WriteCuePayload(FILE* f, FrameParser* parser); +} // namespace vttdemux + +namespace vttdemux { + +FrameParser::FrameParser(const mkvparser::BlockGroup* block_group) + : block_group_(block_group) { + const mkvparser::Block* const block = block_group->GetBlock(); + const mkvparser::Block::Frame& f = block->GetFrame(0); + + // The beginning and end of the character stream corresponds to the + // position of this block's frame within the WebM input file. + + pos_ = f.pos; + pos_end_ = f.pos + f.len; +} + +FrameParser::~FrameParser() {} + +int FrameParser::GetChar(char* c) { + if (pos_ >= pos_end_) // end-of-stream + return 1; // per the semantics of libwebvtt::Reader::GetChar + + const mkvparser::Cluster* const cluster = block_group_->GetCluster(); + const mkvparser::Segment* const segment = cluster->m_pSegment; + mkvparser::IMkvReader* const reader = segment->m_pReader; + + unsigned char* const buf = reinterpret_cast(c); + const int result = reader->Read(pos_, 1, buf); + + if (result < 0) // error + return -1; + + ++pos_; // consume this character in the stream + return 0; +} + +void FrameParser::UngetChar(char /* c */) { + // All we need to do here is decrement the position in the stream. + // The next time GetChar is called the same character will be + // re-read from the input file. + --pos_; +} + +ChapterAtomParser::ChapterAtomParser( + const mkvparser::Chapters::Display* display) + : display_(display) { + str_ = display->GetString(); + if (str_ == NULL) + return; + const size_t len = strlen(str_); + str_end_ = str_ + len; +} + +ChapterAtomParser::~ChapterAtomParser() {} + +int ChapterAtomParser::GetChar(char* c) { + if (str_ == NULL || str_ >= str_end_) // end-of-stream + return 1; // per the semantics of libwebvtt::Reader::GetChar + + *c = *str_++; // consume this character in the stream + return 0; +} + +void ChapterAtomParser::UngetChar(char /* c */) { + // All we need to do here is decrement the position in the stream. + // The next time GetChar is called the same character will be + // re-read from the input file. + --str_; +} + +} // namespace vttdemux + +bool vttdemux::ParseHeader(mkvparser::IMkvReader* reader, mkvpos_t* pos) { + mkvparser::EBMLHeader h; + const mkvpos_t status = h.Parse(reader, *pos); + + if (status) { + printf("error parsing EBML header\n"); + return false; + } + + if (h.m_docType == NULL || strcmp(h.m_docType, "webm") != 0) { + printf("bad doctype\n"); + return false; + } + + return true; // success +} + +bool vttdemux::ParseSegment(mkvparser::IMkvReader* reader, mkvpos_t pos, + segment_ptr_t* segment_ptr) { + // We first create the segment object. + + mkvparser::Segment* p; + const mkvpos_t create = mkvparser::Segment::CreateInstance(reader, pos, p); + + if (create) { + printf("error parsing segment element\n"); + return false; + } + + segment_ptr->reset(p); + + // Now parse all of the segment's sub-elements, in toto. + + const long status = p->Load(); // NOLINT + + if (status < 0) { + printf("error loading segment\n"); + return false; + } + + return true; +} + +void vttdemux::BuildMap(const mkvparser::Segment* segment, + metadata_map_t* map_ptr) { + metadata_map_t& m = *map_ptr; + m.clear(); + + if (segment->GetChapters()) { + MetadataInfo info; + info.file = NULL; + info.type = MetadataInfo::kChapters; + + m[kChaptersKey] = info; + } + + const mkvparser::Tracks* const tt = segment->GetTracks(); + if (tt == NULL) + return; + + const long tc = tt->GetTracksCount(); // NOLINT + if (tc <= 0) + return; + + // Iterate over the tracks in the intput file. We determine whether + // a track holds metadata by inspecting its CodecID. + + for (long idx = 0; idx < tc; ++idx) { // NOLINT + const mkvparser::Track* const t = tt->GetTrackByIndex(idx); + + if (t == NULL) // weird + continue; + + const long tn = t->GetNumber(); // NOLINT + + if (tn <= 0) // weird + continue; + + const char* const codec_id = t->GetCodecId(); + + if (codec_id == NULL) // weird + continue; + + MetadataInfo info; + info.file = NULL; + + if (strcmp(codec_id, "D_WEBVTT/SUBTITLES") == 0) { + info.type = MetadataInfo::kSubtitles; + } else if (strcmp(codec_id, "D_WEBVTT/CAPTIONS") == 0) { + info.type = MetadataInfo::kCaptions; + } else if (strcmp(codec_id, "D_WEBVTT/DESCRIPTIONS") == 0) { + info.type = MetadataInfo::kDescriptions; + } else if (strcmp(codec_id, "D_WEBVTT/METADATA") == 0) { + info.type = MetadataInfo::kMetadata; + } else { + continue; + } + + m[tn] = info; // create an entry in the cache for this track + } +} + +bool vttdemux::OpenFiles(metadata_map_t* metadata_map, const char* filename) { + if (metadata_map == NULL || metadata_map->empty()) + return false; + + if (filename == NULL) + return false; + + // Find the position of the filename extension. We synthesize the + // output filename from the directory path and basename of the input + // filename. + + const char* const ext = strrchr(filename, '.'); + + if (ext == NULL) // TODO(matthewjheaney): liberalize? + return false; + + // Remember whether a track of this type has already been seen (the + // map key) by keeping a count (the map item). We quality the + // output filename with the track number if there is more than one + // track having a given type. + + std::map exists; + + typedef metadata_map_t::iterator iter_t; + + metadata_map_t& m = *metadata_map; + const iter_t ii = m.begin(); + const iter_t j = m.end(); + + // Make a first pass over the cache to determine whether there is + // more than one track corresponding to a given metadata type. + + iter_t i = ii; + while (i != j) { + const metadata_map_t::value_type& v = *i++; + const MetadataInfo& info = v.second; + const MetadataInfo::Type type = info.type; + ++exists[type]; + } + + // Make a second pass over the cache, synthesizing the filename of + // each output file (from the input file basename, the input track + // metadata type, and its track number if necessary), and then + // opening a WebVTT output file having that filename. + + i = ii; + while (i != j) { + metadata_map_t::value_type& v = *i++; + MetadataInfo& info = v.second; + const MetadataInfo::Type type = info.type; + + // Start with the basename of the input file. + + string name(filename, ext); + + // Next append the metadata kind. + + switch (type) { + case MetadataInfo::kSubtitles: + name += "_SUBTITLES"; + break; + + case MetadataInfo::kCaptions: + name += "_CAPTIONS"; + break; + + case MetadataInfo::kDescriptions: + name += "_DESCRIPTIONS"; + break; + + case MetadataInfo::kMetadata: + name += "_METADATA"; + break; + + case MetadataInfo::kChapters: + name += "_CHAPTERS"; + break; + + default: + return false; + } + + // If there is more than one metadata track having a given type + // (the WebVTT-in-WebM spec doesn't preclude this), then qualify + // the output filename with the input track number. + + if (exists[type] > 1) { + enum { kLen = 33 }; + char str[kLen]; // max 126 tracks, so only 4 chars really needed +#ifndef _MSC_VER + snprintf(str, kLen, "%ld", v.first); // track number +#else + _snprintf_s(str, sizeof(str), kLen, "%ld", v.first); // track number +#endif + name += str; + } + + // Finally append the output filename extension. + + name += ".vtt"; + + // We have synthesized the full output filename, so attempt to + // open the WebVTT output file. + + info.file = fopen(name.c_str(), "wb"); + const bool success = (info.file != NULL); + + if (!success) { + printf("unable to open output file %s\n", name.c_str()); + return false; + } + } + + return true; +} + +void vttdemux::CloseFiles(metadata_map_t* metadata_map) { + if (metadata_map == NULL) + return; + + metadata_map_t& m = *metadata_map; + + typedef metadata_map_t::iterator iter_t; + + iter_t i = m.begin(); + const iter_t j = m.end(); + + // Gracefully close each output file, to ensure all output gets + // propertly flushed. + + while (i != j) { + metadata_map_t::value_type& v = *i++; + MetadataInfo& info = v.second; + + if (info.file != NULL) { + fclose(info.file); + info.file = NULL; + } + } +} + +bool vttdemux::WriteFiles(const metadata_map_t& m, mkvparser::Segment* s) { + // First write the WebVTT header. + + InitializeFiles(m); + + if (!WriteChaptersFile(m, s)) + return false; + + // Now iterate over the clusters, writing the WebVTT cue as we parse + // each metadata block. + + const mkvparser::Cluster* cluster = s->GetFirst(); + + while (cluster != NULL && !cluster->EOS()) { + if (!ProcessCluster(m, cluster)) + return false; + + cluster = s->GetNext(cluster); + } + + return true; +} + +bool vttdemux::InitializeFiles(const metadata_map_t& m) { + // Write the WebVTT header for each output file in the cache. + + typedef metadata_map_t::const_iterator iter_t; + iter_t i = m.begin(); + const iter_t j = m.end(); + + while (i != j) { + const metadata_map_t::value_type& v = *i++; + const MetadataInfo& info = v.second; + FILE* const f = info.file; + + if (fputs("WEBVTT\n", f) < 0) { + printf("unable to initialize output file\n"); + return false; + } + } + + return true; +} + +bool vttdemux::WriteChaptersFile(const metadata_map_t& m, + const mkvparser::Segment* s) { + const metadata_map_t::const_iterator info_iter = m.find(kChaptersKey); + if (info_iter == m.end()) // no chapters, so nothing to do + return true; + + const mkvparser::Chapters* const chapters = s->GetChapters(); + if (chapters == NULL) // weird + return true; + + const MetadataInfo& info = info_iter->second; + FILE* const file = info.file; + + const int edition_count = chapters->GetEditionCount(); + + if (edition_count <= 0) // weird + return true; // nothing to do + + if (edition_count > 1) { + // TODO(matthewjheaney): figure what to do here + printf("more than one chapter edition detected\n"); + return false; + } + + const mkvparser::Chapters::Edition* const edition = chapters->GetEdition(0); + + const int atom_count = edition->GetAtomCount(); + + for (int idx = 0; idx < atom_count; ++idx) { + const mkvparser::Chapters::Atom* const atom = edition->GetAtom(idx); + const int display_count = atom->GetDisplayCount(); + + if (display_count <= 0) + continue; + + if (display_count > 1) { + // TODO(matthewjheaney): handle case of multiple languages + printf("more than 1 display in atom detected\n"); + return false; + } + + const mkvparser::Chapters::Display* const display = atom->GetDisplay(0); + + if (const char* language = display->GetLanguage()) { + if (strcmp(language, "eng") != 0) { + // TODO(matthewjheaney): handle case of multiple languages. + + // We must create a separate webvtt file for each language. + // This isn't a simple problem (which is why we defer it for + // now), because there's nothing in the header that tells us + // what languages we have as cues. We must parse the displays + // of each atom to determine that. + + // One solution is to make two passes over the input data. + // First parse the displays, creating an in-memory cache of + // all the chapter cues, sorted according to their language. + // After we have read all of the chapter atoms from the input + // file, we can then write separate output files for each + // language. + + printf("only English-language chapter cues are supported\n"); + return false; + } + } + + if (!WriteChaptersCue(file, chapters, atom, display)) + return false; + } + + return true; +} + +bool vttdemux::WriteChaptersCue(FILE* f, const mkvparser::Chapters* chapters, + const mkvparser::Chapters::Atom* atom, + const mkvparser::Chapters::Display* display) { + // We start a new cue by writing a cue separator (an empty line) + // into the stream. + + if (fputc('\n', f) < 0) + return false; + + // A WebVTT Cue comprises 3 things: a cue identifier, followed by + // the cue timings, followed by the payload of the cue. We write + // each part of the cue in sequence. + + if (!WriteChaptersCueIdentifier(f, atom)) + return false; + + if (!WriteChaptersCueTimings(f, chapters, atom)) + return false; + + if (!WriteChaptersCuePayload(f, display)) + return false; + + return true; +} + +bool vttdemux::WriteChaptersCueIdentifier( + FILE* f, const mkvparser::Chapters::Atom* atom) { + const char* const identifier = atom->GetStringUID(); + + if (identifier == NULL) + return true; // nothing else to do + + if (fprintf(f, "%s\n", identifier) < 0) + return false; + + return true; +} + +bool vttdemux::WriteChaptersCueTimings(FILE* f, + const mkvparser::Chapters* chapters, + const mkvparser::Chapters::Atom* atom) { + const mkvtime_t start_ns = atom->GetStartTime(chapters); + + if (start_ns < 0) + return false; + + const mkvtime_t stop_ns = atom->GetStopTime(chapters); + + if (stop_ns < 0) + return false; + + if (!WriteCueTime(f, start_ns)) + return false; + + if (fputs(" --> ", f) < 0) + return false; + + if (!WriteCueTime(f, stop_ns)) + return false; + + if (fputc('\n', f) < 0) + return false; + + return true; +} + +bool vttdemux::WriteChaptersCuePayload( + FILE* f, const mkvparser::Chapters::Display* display) { + // Bind a Chapter parser object to the display, which allows us to + // extract each line of text from the title-part of the display. + ChapterAtomParser parser(display); + + int count = 0; // count of lines of payload text written to output file + for (string line;;) { + const int e = parser.GetLine(&line); + + if (e < 0) // error (only -- we allow EOS here) + return false; + + if (line.empty()) // TODO(matthewjheaney): retain this check? + break; + + if (fprintf(f, "%s\n", line.c_str()) < 0) + return false; + + ++count; + } + + if (count <= 0) // WebVTT cue requires non-empty payload + return false; + + return true; +} + +bool vttdemux::ProcessCluster(const metadata_map_t& m, + const mkvparser::Cluster* c) { + // Visit the blocks in this cluster, writing a WebVTT cue for each + // metadata block. + + const mkvparser::BlockEntry* block_entry; + + long result = c->GetFirst(block_entry); // NOLINT + if (result < 0) { + printf("bad cluster (unable to get first block)\n"); + return false; + } + + while (block_entry != NULL && !block_entry->EOS()) { + if (!ProcessBlockEntry(m, block_entry)) + return false; + + result = c->GetNext(block_entry, block_entry); + if (result < 0) { // error + printf("bad cluster (unable to get next block)\n"); + return false; + } + } + + return true; +} + +bool vttdemux::ProcessBlockEntry(const metadata_map_t& m, + const mkvparser::BlockEntry* block_entry) { + // If the track number for this block is in the cache, then we have + // a metadata block, so write the WebVTT cue to the output file. + + const mkvparser::Block* const block = block_entry->GetBlock(); + const long long tn = block->GetTrackNumber(); // NOLINT + + typedef metadata_map_t::const_iterator iter_t; + const iter_t i = m.find(static_cast(tn)); + + if (i == m.end()) // not a metadata track + return true; // nothing else to do + + if (block_entry->GetKind() != mkvparser::BlockEntry::kBlockGroup) + return false; // weird + + typedef mkvparser::BlockGroup BG; + const BG* const block_group = static_cast(block_entry); + + const MetadataInfo& info = i->second; + FILE* const f = info.file; + + return WriteCue(f, block_group); +} + +bool vttdemux::WriteCue(FILE* f, const mkvparser::BlockGroup* block_group) { + // Bind a FrameParser object to the block, which allows us to + // extract each line of text from the payload of the block. + FrameParser parser(block_group); + + // We start a new cue by writing a cue separator (an empty line) + // into the stream. + + if (fputc('\n', f) < 0) + return false; + + // A WebVTT Cue comprises 3 things: a cue identifier, followed by + // the cue timings, followed by the payload of the cue. We write + // each part of the cue in sequence. + + if (!WriteCueIdentifier(f, &parser)) + return false; + + if (!WriteCueTimings(f, &parser)) + return false; + + if (!WriteCuePayload(f, &parser)) + return false; + + return true; +} + +bool vttdemux::WriteCueIdentifier(FILE* f, FrameParser* parser) { + string line; + int e = parser->GetLine(&line); + + if (e) // error or EOS + return false; + + // If the cue identifier line is empty, this means that the original + // WebVTT cue did not have a cue identifier, so we don't bother + // writing an extra line terminator to the output file (though doing + // so would be harmless). + + if (!line.empty()) { + if (fputs(line.c_str(), f) < 0) + return false; + + if (fputc('\n', f) < 0) + return false; + } + + return true; +} + +bool vttdemux::WriteCueTimings(FILE* f, FrameParser* parser) { + const mkvparser::BlockGroup* const block_group = parser->block_group_; + const mkvparser::Cluster* const cluster = block_group->GetCluster(); + const mkvparser::Block* const block = block_group->GetBlock(); + + // A WebVTT Cue "timings" line comprises two parts: the start and + // stop time for this cue, followed by the (optional) cue settings, + // such as orientation of the rendered text or its size. Only the + // settings part of the cue timings line is stored in the WebM + // block. We reconstruct the start and stop times of the WebVTT cue + // from the timestamp and duration of the WebM block. + + const mkvtime_t start_ns = block->GetTime(cluster); + + if (!WriteCueTime(f, start_ns)) + return false; + + if (fputs(" --> ", f) < 0) + return false; + + const mkvtime_t duration_timecode = block_group->GetDurationTimeCode(); + + if (duration_timecode < 0) + return false; + + const mkvparser::Segment* const segment = cluster->m_pSegment; + const mkvparser::SegmentInfo* const info = segment->GetInfo(); + + if (info == NULL) + return false; + + const mkvtime_t timecode_scale = info->GetTimeCodeScale(); + + if (timecode_scale <= 0) + return false; + + const mkvtime_t duration_ns = duration_timecode * timecode_scale; + const mkvtime_t stop_ns = start_ns + duration_ns; + + if (!WriteCueTime(f, stop_ns)) + return false; + + string line; + int e = parser->GetLine(&line); + + if (e) // error or EOS + return false; + + if (!line.empty()) { + if (fputc(' ', f) < 0) + return false; + + if (fputs(line.c_str(), f) < 0) + return false; + } + + if (fputc('\n', f) < 0) + return false; + + return true; +} + +bool vttdemux::WriteCueTime(FILE* f, mkvtime_t time_ns) { + mkvtime_t ms = time_ns / 1000000; // WebVTT time has millisecond resolution + + mkvtime_t sec = ms / 1000; + ms -= sec * 1000; + + mkvtime_t min = sec / 60; + sec -= 60 * min; + + mkvtime_t hr = min / 60; + min -= 60 * hr; + + if (hr > 0) { + if (fprintf(f, "%02lld:", hr) < 0) + return false; + } + + if (fprintf(f, "%02lld:%02lld.%03lld", min, sec, ms) < 0) + return false; + + return true; +} + +bool vttdemux::WriteCuePayload(FILE* f, FrameParser* parser) { + int count = 0; // count of lines of payload text written to output file + for (string line;;) { + const int e = parser->GetLine(&line); + + if (e < 0) // error (only -- we allow EOS here) + return false; + + if (line.empty()) // TODO(matthewjheaney): retain this check? + break; + + if (fprintf(f, "%s\n", line.c_str()) < 0) + return false; + + ++count; + } + + if (count <= 0) // WebVTT cue requires non-empty payload + return false; + + return true; +} + +} // namespace libwebm + +int main(int argc, const char* argv[]) { + if (argc != 2) { + printf("usage: vttdemux \n"); + return EXIT_SUCCESS; + } + + const char* const filename = argv[1]; + mkvparser::MkvReader reader; + + int e = reader.Open(filename); + + if (e) { // error + printf("unable to open file\n"); + return EXIT_FAILURE; + } + + libwebm::vttdemux::mkvpos_t pos; + + if (!libwebm::vttdemux::ParseHeader(&reader, &pos)) + return EXIT_FAILURE; + + libwebm::vttdemux::segment_ptr_t segment_ptr; + + if (!libwebm::vttdemux::ParseSegment(&reader, pos, &segment_ptr)) + return EXIT_FAILURE; + + libwebm::vttdemux::metadata_map_t metadata_map; + + BuildMap(segment_ptr.get(), &metadata_map); + + if (metadata_map.empty()) { + printf("no WebVTT metadata found\n"); + return EXIT_FAILURE; + } + + if (!OpenFiles(&metadata_map, filename)) { + CloseFiles(&metadata_map); // nothing to flush, so not strictly necessary + return EXIT_FAILURE; + } + + if (!WriteFiles(metadata_map, segment_ptr.get())) { + CloseFiles(&metadata_map); // might as well flush what we do have + return EXIT_FAILURE; + } + + CloseFiles(&metadata_map); + + return EXIT_SUCCESS; +} diff --git a/src/sys/libwebm/vttreader.h b/src/sys/libwebm/vttreader.h new file mode 100644 index 0000000..2e7cc4b --- /dev/null +++ b/src/sys/libwebm/vttreader.h @@ -0,0 +1,15 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef LIBWEBM_VTTREADER_H_ +#define LIBWEBM_VTTREADER_H_ + +// This file is a wrapper for the file included immediately after this comment. +// New projects should not include this file: include the file included below. +#include "webvtt/vttreader.h" + +#endif // LIBWEBM_VTTREADER_H_ diff --git a/src/sys/libwebm/webm_info.cc b/src/sys/libwebm/webm_info.cc new file mode 100644 index 0000000..7cc7272 --- /dev/null +++ b/src/sys/libwebm/webm_info.cc @@ -0,0 +1,1336 @@ +// Copyright (c) 2012 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "common/hdr_util.h" +#include "common/indent.h" +#include "common/vp9_header_parser.h" +#include "common/vp9_level_stats.h" +#include "common/webm_constants.h" +#include "common/webm_endian.h" + +#include "mkvparser/mkvparser.h" +#include "mkvparser/mkvreader.h" + +namespace { + +using libwebm::Indent; +using libwebm::kNanosecondsPerSecond; +using libwebm::kNanosecondsPerSecondi; +using mkvparser::ContentEncoding; +using std::string; +using std::wstring; + +const char VERSION_STRING[] = "1.0.4.5"; + +struct Options { + Options(); + + // Returns true if |value| matches -|option| or -no|option|. + static bool MatchesBooleanOption(const string& option, const string& value); + + // Set all of the member variables to |value|. + void SetAll(bool value); + + bool output_video; + bool output_audio; + bool output_size; + bool output_offset; + bool output_seconds; + bool output_ebml_header; + bool output_segment; + bool output_seekhead; + bool output_segment_info; + bool output_tracks; + bool output_clusters; + bool output_blocks; + bool output_codec_info; + bool output_clusters_size; + bool output_encrypted_info; + bool output_cues; + bool output_frame_stats; + bool output_vp9_level; +}; + +Options::Options() + : output_video(true), + output_audio(true), + output_size(false), + output_offset(false), + output_seconds(true), + output_ebml_header(true), + output_segment(true), + output_seekhead(false), + output_segment_info(true), + output_tracks(true), + output_clusters(false), + output_blocks(false), + output_codec_info(false), + output_clusters_size(false), + output_encrypted_info(false), + output_cues(false), + output_frame_stats(false), + output_vp9_level(false) {} + +void Options::SetAll(bool value) { + output_video = value; + output_audio = value; + output_size = value; + output_offset = value; + output_ebml_header = value; + output_seconds = value; + output_segment = value; + output_segment_info = value; + output_tracks = value; + output_clusters = value; + output_blocks = value; + output_codec_info = value; + output_clusters_size = value; + output_encrypted_info = value; + output_cues = value; + output_frame_stats = value; + output_vp9_level = value; +} + +bool Options::MatchesBooleanOption(const string& option, const string& value) { + const string opt = "-" + option; + const string noopt = "-no" + option; + return value == opt || value == noopt; +} + +struct FrameStats { + FrameStats() + : frames(0), + displayed_frames(0), + first_altref(true), + frames_since_last_altref(0), + minimum_altref_distance(std::numeric_limits::max()), + min_altref_end_ns(0), + max_window_size(0), + max_window_end_ns(0) {} + + int frames; + int displayed_frames; + + bool first_altref; + int frames_since_last_altref; + int minimum_altref_distance; + int64_t min_altref_end_ns; + + std::queue window; + int64_t max_window_size; + int64_t max_window_end_ns; +}; + +void Usage() { + printf("Usage: webm_info [options] -i input\n"); + printf("\n"); + printf("Main options:\n"); + printf(" -h | -? show help\n"); + printf(" -v show version\n"); + printf(" -all Enable all output options.\n"); + printf(" -video Output video tracks (true)\n"); + printf(" -audio Output audio tracks (true)\n"); + printf(" -size Output element sizes (false)\n"); + printf(" -offset Output element offsets (false)\n"); + printf(" -times_seconds Output times as seconds (true)\n"); + printf(" -ebml_header Output EBML header (true)\n"); + printf(" -segment Output Segment (true)\n"); + printf(" -seekhead Output SeekHead (false)\n"); + printf(" -segment_info Output SegmentInfo (true)\n"); + printf(" -tracks Output Tracks (true)\n"); + printf(" -clusters Output Clusters (false)\n"); + printf(" -blocks Output Blocks (false)\n"); + printf(" -codec_info Output video codec information (false)\n"); + printf(" -clusters_size Output Total Clusters size (false)\n"); + printf(" -encrypted_info Output encrypted frame info (false)\n"); + printf(" -cues Output Cues entries (false)\n"); + printf(" -frame_stats Output frame stats (VP9)(false)\n"); + printf(" -vp9_level Output VP9 level(false)\n"); + printf("\nOutput options may be negated by prefixing 'no'.\n"); +} + +// TODO(fgalligan): Add support for non-ascii. +wstring UTF8ToWideString(const char* str) { + wstring wstr; + + if (str == NULL) + return wstr; + + string temp_str(str, strlen(str)); + wstr.assign(temp_str.begin(), temp_str.end()); + + return wstr; +} + +string ToString(const char* str) { return string((str == NULL) ? "" : str); } + +void OutputEBMLHeader(const mkvparser::EBMLHeader& ebml, FILE* o, + Indent* indent) { + fprintf(o, "EBML Header:\n"); + indent->Adjust(libwebm::kIncreaseIndent); + fprintf(o, "%sEBMLVersion : %lld\n", indent->indent_str().c_str(), + ebml.m_version); + fprintf(o, "%sEBMLReadVersion : %lld\n", indent->indent_str().c_str(), + ebml.m_readVersion); + fprintf(o, "%sEBMLMaxIDLength : %lld\n", indent->indent_str().c_str(), + ebml.m_maxIdLength); + fprintf(o, "%sEBMLMaxSizeLength : %lld\n", indent->indent_str().c_str(), + ebml.m_maxSizeLength); + fprintf(o, "%sDoc Type : %s\n", indent->indent_str().c_str(), + ebml.m_docType); + fprintf(o, "%sDocTypeVersion : %lld\n", indent->indent_str().c_str(), + ebml.m_docTypeVersion); + fprintf(o, "%sDocTypeReadVersion: %lld\n", indent->indent_str().c_str(), + ebml.m_docTypeReadVersion); + indent->Adjust(libwebm::kDecreaseIndent); +} + +void OutputSegment(const mkvparser::Segment& segment, const Options& options, + FILE* o) { + fprintf(o, "Segment:"); + if (options.output_offset) + fprintf(o, " @: %lld", segment.m_element_start); + if (options.output_size) + fprintf(o, " size: %lld", + segment.m_size + segment.m_start - segment.m_element_start); + fprintf(o, "\n"); +} + +bool OutputSeekHead(const mkvparser::Segment& segment, const Options& options, + FILE* o, Indent* indent) { + const mkvparser::SeekHead* const seekhead = segment.GetSeekHead(); + if (!seekhead) { + // SeekHeads are optional. + return true; + } + + fprintf(o, "%sSeekHead:", indent->indent_str().c_str()); + if (options.output_offset) + fprintf(o, " @: %lld", seekhead->m_element_start); + if (options.output_size) + fprintf(o, " size: %lld", seekhead->m_element_size); + fprintf(o, "\n"); + + indent->Adjust(libwebm::kIncreaseIndent); + + for (int i = 0; i < seekhead->GetCount(); ++i) { + const mkvparser::SeekHead::Entry* const entry = seekhead->GetEntry(i); + if (!entry) { + fprintf(stderr, "Error retrieving SeekHead entry #%d\n", i); + return false; + } + + fprintf(o, "%sEntry[%d]", indent->indent_str().c_str(), i); + if (options.output_offset) + fprintf(o, " @: %lld", entry->element_start); + if (options.output_size) + fprintf(o, " size: %lld", entry->element_size); + fprintf(o, "\n"); + + indent->Adjust(libwebm::kIncreaseIndent); + std::string entry_indent = indent->indent_str(); + // TODO(jzern): 1) known ids could be stringified. 2) ids could be + // reencoded to EBML for ease of lookup. + fprintf(o, "%sSeek ID : %llx\n", entry_indent.c_str(), entry->id); + fprintf(o, "%sSeek position : %lld\n", entry_indent.c_str(), entry->pos); + indent->Adjust(libwebm::kDecreaseIndent); + } + + for (int i = 0; i < seekhead->GetVoidElementCount(); ++i) { + const mkvparser::SeekHead::VoidElement* const entry = + seekhead->GetVoidElement(i); + if (!entry) { + fprintf(stderr, "Error retrieving SeekHead void element #%d\n", i); + return false; + } + + fprintf(o, "%sVoid element[%d]", indent->indent_str().c_str(), i); + if (options.output_offset) + fprintf(o, " @: %lld", entry->element_start); + if (options.output_size) + fprintf(o, " size: %lld", entry->element_size); + fprintf(o, "\n"); + } + + indent->Adjust(libwebm::kDecreaseIndent); + return true; +} + +bool OutputSegmentInfo(const mkvparser::Segment& segment, + const Options& options, FILE* o, Indent* indent) { + const mkvparser::SegmentInfo* const segment_info = segment.GetInfo(); + if (!segment_info) { + fprintf(stderr, "SegmentInfo was NULL.\n"); + return false; + } + + const int64_t timecode_scale = segment_info->GetTimeCodeScale(); + const int64_t duration_ns = segment_info->GetDuration(); + const wstring title = UTF8ToWideString(segment_info->GetTitleAsUTF8()); + const wstring muxing_app = + UTF8ToWideString(segment_info->GetMuxingAppAsUTF8()); + const wstring writing_app = + UTF8ToWideString(segment_info->GetWritingAppAsUTF8()); + + fprintf(o, "%sSegmentInfo:", indent->indent_str().c_str()); + if (options.output_offset) + fprintf(o, " @: %lld", segment_info->m_element_start); + if (options.output_size) + fprintf(o, " size: %lld", segment_info->m_element_size); + fprintf(o, "\n"); + + indent->Adjust(libwebm::kIncreaseIndent); + fprintf(o, "%sTimecodeScale : %" PRId64 " \n", indent->indent_str().c_str(), + timecode_scale); + if (options.output_seconds) + fprintf(o, "%sDuration(secs): %g\n", indent->indent_str().c_str(), + duration_ns / kNanosecondsPerSecond); + else + fprintf(o, "%sDuration(nano): %" PRId64 "\n", indent->indent_str().c_str(), + duration_ns); + + if (!title.empty()) + fprintf(o, "%sTitle : %ls\n", indent->indent_str().c_str(), + title.c_str()); + if (!muxing_app.empty()) + fprintf(o, "%sMuxingApp : %ls\n", indent->indent_str().c_str(), + muxing_app.c_str()); + if (!writing_app.empty()) + fprintf(o, "%sWritingApp : %ls\n", indent->indent_str().c_str(), + writing_app.c_str()); + indent->Adjust(libwebm::kDecreaseIndent); + return true; +} + +bool OutputTracks(const mkvparser::Segment& segment, const Options& options, + FILE* o, Indent* indent) { + const mkvparser::Tracks* const tracks = segment.GetTracks(); + if (!tracks) { + fprintf(stderr, "Tracks was NULL.\n"); + return false; + } + + fprintf(o, "%sTracks:", indent->indent_str().c_str()); + if (options.output_offset) + fprintf(o, " @: %lld", tracks->m_element_start); + if (options.output_size) + fprintf(o, " size: %lld", tracks->m_element_size); + fprintf(o, "\n"); + + unsigned int i = 0; + const unsigned long j = tracks->GetTracksCount(); + while (i != j) { + const mkvparser::Track* const track = tracks->GetTrackByIndex(i++); + if (track == NULL) + continue; + + indent->Adjust(libwebm::kIncreaseIndent); + fprintf(o, "%sTrack:", indent->indent_str().c_str()); + if (options.output_offset) + fprintf(o, " @: %lld", track->m_element_start); + if (options.output_size) + fprintf(o, " size: %lld", track->m_element_size); + fprintf(o, "\n"); + + const int64_t track_type = track->GetType(); + const int64_t track_number = track->GetNumber(); + const wstring track_name = UTF8ToWideString(track->GetNameAsUTF8()); + + indent->Adjust(libwebm::kIncreaseIndent); + fprintf(o, "%sTrackType : %" PRId64 "\n", indent->indent_str().c_str(), + track_type); + fprintf(o, "%sTrackNumber : %" PRId64 "\n", indent->indent_str().c_str(), + track_number); + if (!track_name.empty()) + fprintf(o, "%sName : %ls\n", indent->indent_str().c_str(), + track_name.c_str()); + + const char* const codec_id = track->GetCodecId(); + if (codec_id) + fprintf(o, "%sCodecID : %s\n", indent->indent_str().c_str(), + codec_id); + + const wstring codec_name = UTF8ToWideString(track->GetCodecNameAsUTF8()); + if (!codec_name.empty()) + fprintf(o, "%sCodecName : %ls\n", indent->indent_str().c_str(), + codec_name.c_str()); + + size_t private_size; + const unsigned char* const private_data = + track->GetCodecPrivate(private_size); + if (private_data) { + fprintf(o, "%sPrivateData(size): %d\n", indent->indent_str().c_str(), + static_cast(private_size)); + + if (track_type == mkvparser::Track::kVideo) { + const std::string codec_id = ToString(track->GetCodecId()); + const std::string v_vp9 = "V_VP9"; + if (codec_id == v_vp9) { + libwebm::Vp9CodecFeatures features; + if (!libwebm::ParseVpxCodecPrivate(private_data, + static_cast(private_size), + &features)) { + fprintf(stderr, "Error parsing VpxCodecPrivate.\n"); + return false; + } + if (features.profile != -1) + fprintf(o, "%sVP9 profile : %d\n", + indent->indent_str().c_str(), features.profile); + if (features.level != -1) + fprintf(o, "%sVP9 level : %d\n", + indent->indent_str().c_str(), features.level); + if (features.bit_depth != -1) + fprintf(o, "%sVP9 bit_depth : %d\n", + indent->indent_str().c_str(), features.bit_depth); + if (features.chroma_subsampling != -1) + fprintf(o, "%sVP9 chroma subsampling : %d\n", + indent->indent_str().c_str(), features.chroma_subsampling); + } + } + } + + const uint64_t default_duration = track->GetDefaultDuration(); + if (default_duration > 0) + fprintf(o, "%sDefaultDuration: %" PRIu64 "\n", + indent->indent_str().c_str(), default_duration); + + if (track->GetContentEncodingCount() > 0) { + // Only check the first content encoding. + const ContentEncoding* const encoding = + track->GetContentEncodingByIndex(0); + if (!encoding) { + printf("Could not get first ContentEncoding.\n"); + return false; + } + + fprintf(o, "%sContentEncodingOrder : %lld\n", + indent->indent_str().c_str(), encoding->encoding_order()); + fprintf(o, "%sContentEncodingScope : %lld\n", + indent->indent_str().c_str(), encoding->encoding_scope()); + fprintf(o, "%sContentEncodingType : %lld\n", + indent->indent_str().c_str(), encoding->encoding_type()); + + if (encoding->GetEncryptionCount() > 0) { + // Only check the first encryption. + const ContentEncoding::ContentEncryption* const encryption = + encoding->GetEncryptionByIndex(0); + if (!encryption) { + printf("Could not get first ContentEncryption.\n"); + return false; + } + + fprintf(o, "%sContentEncAlgo : %lld\n", + indent->indent_str().c_str(), encryption->algo); + + if (encryption->key_id_len > 0) { + fprintf(o, "%sContentEncKeyID : ", indent->indent_str().c_str()); + for (int k = 0; k < encryption->key_id_len; ++k) { + fprintf(o, "0x%02x, ", encryption->key_id[k]); + } + fprintf(o, "\n"); + } + + if (encryption->signature_len > 0) { + fprintf(o, "%sContentSignature : 0x", + indent->indent_str().c_str()); + for (int k = 0; k < encryption->signature_len; ++k) { + fprintf(o, "%x", encryption->signature[k]); + } + fprintf(o, "\n"); + } + + if (encryption->sig_key_id_len > 0) { + fprintf(o, "%sContentSigKeyID : 0x", + indent->indent_str().c_str()); + for (int k = 0; k < encryption->sig_key_id_len; ++k) { + fprintf(o, "%x", encryption->sig_key_id[k]); + } + fprintf(o, "\n"); + } + + fprintf(o, "%sContentSigAlgo : %lld\n", + indent->indent_str().c_str(), encryption->sig_algo); + fprintf(o, "%sContentSigHashAlgo : %lld\n", + indent->indent_str().c_str(), encryption->sig_hash_algo); + + const ContentEncoding::ContentEncAESSettings& aes = + encryption->aes_settings; + fprintf(o, "%sCipherMode : %lld\n", + indent->indent_str().c_str(), aes.cipher_mode); + } + } + + if (track_type == mkvparser::Track::kVideo) { + const mkvparser::VideoTrack* const video_track = + static_cast(track); + const int64_t width = video_track->GetWidth(); + const int64_t height = video_track->GetHeight(); + const int64_t display_width = video_track->GetDisplayWidth(); + const int64_t display_height = video_track->GetDisplayHeight(); + const int64_t display_unit = video_track->GetDisplayUnit(); + const double frame_rate = video_track->GetFrameRate(); + fprintf(o, "%sPixelWidth : %" PRId64 "\n", indent->indent_str().c_str(), + width); + fprintf(o, "%sPixelHeight : %" PRId64 "\n", indent->indent_str().c_str(), + height); + if (frame_rate > 0.0) + fprintf(o, "%sFrameRate : %g\n", indent->indent_str().c_str(), + video_track->GetFrameRate()); + if (display_unit > 0 || display_width != width || + display_height != height) { + fprintf(o, "%sDisplayWidth : %" PRId64 "\n", + indent->indent_str().c_str(), display_width); + fprintf(o, "%sDisplayHeight : %" PRId64 "\n", + indent->indent_str().c_str(), display_height); + fprintf(o, "%sDisplayUnit : %" PRId64 "\n", + indent->indent_str().c_str(), display_unit); + } + + const mkvparser::Colour* const colour = video_track->GetColour(); + if (colour) { + // TODO(fgalligan): Add support for Colour's address and size. + fprintf(o, "%sColour:\n", indent->indent_str().c_str()); + indent->Adjust(libwebm::kIncreaseIndent); + + const int64_t matrix_coefficients = colour->matrix_coefficients; + const int64_t bits_per_channel = colour->bits_per_channel; + const int64_t chroma_subsampling_horz = colour->chroma_subsampling_horz; + const int64_t chroma_subsampling_vert = colour->chroma_subsampling_vert; + const int64_t cb_subsampling_horz = colour->cb_subsampling_horz; + const int64_t cb_subsampling_vert = colour->cb_subsampling_vert; + const int64_t chroma_siting_horz = colour->chroma_siting_horz; + const int64_t chroma_siting_vert = colour->chroma_siting_vert; + const int64_t range = colour->range; + const int64_t transfer_characteristics = + colour->transfer_characteristics; + const int64_t primaries = colour->primaries; + const int64_t max_cll = colour->max_cll; + const int64_t max_fall = colour->max_fall; + if (matrix_coefficients != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sMatrixCoefficients : %" PRId64 "\n", + indent->indent_str().c_str(), matrix_coefficients); + if (bits_per_channel != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sBitsPerChannel : %" PRId64 "\n", + indent->indent_str().c_str(), bits_per_channel); + if (chroma_subsampling_horz != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sChromaSubsamplingHorz : %" PRId64 "\n", + indent->indent_str().c_str(), chroma_subsampling_horz); + if (chroma_subsampling_vert != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sChromaSubsamplingVert : %" PRId64 "\n", + indent->indent_str().c_str(), chroma_subsampling_vert); + if (cb_subsampling_horz != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sCbSubsamplingHorz : %" PRId64 "\n", + indent->indent_str().c_str(), cb_subsampling_horz); + if (cb_subsampling_vert != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sCbSubsamplingVert : %" PRId64 "\n", + indent->indent_str().c_str(), cb_subsampling_vert); + if (chroma_siting_horz != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sChromaSitingHorz : %" PRId64 "\n", + indent->indent_str().c_str(), chroma_siting_horz); + if (chroma_siting_vert != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sChromaSitingVert : %" PRId64 "\n", + indent->indent_str().c_str(), chroma_siting_vert); + if (range != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sRange : %" PRId64 "\n", + indent->indent_str().c_str(), range); + if (transfer_characteristics != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sTransferCharacteristics : %" PRId64 "\n", + indent->indent_str().c_str(), transfer_characteristics); + if (primaries != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sPrimaries : %" PRId64 "\n", + indent->indent_str().c_str(), primaries); + if (max_cll != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sMaxCLL : %" PRId64 "\n", + indent->indent_str().c_str(), max_cll); + if (max_fall != mkvparser::Colour::kValueNotPresent) + fprintf(o, "%sMaxFALL : %" PRId64 "\n", + indent->indent_str().c_str(), max_fall); + + const mkvparser::MasteringMetadata* const metadata = + colour->mastering_metadata; + if (metadata) { + // TODO(fgalligan): Add support for MasteringMetadata's address and + // size. + fprintf(o, "%sMasteringMetadata:\n", indent->indent_str().c_str()); + indent->Adjust(libwebm::kIncreaseIndent); + + const mkvparser::PrimaryChromaticity* const red = metadata->r; + const mkvparser::PrimaryChromaticity* const green = metadata->g; + const mkvparser::PrimaryChromaticity* const blue = metadata->b; + const mkvparser::PrimaryChromaticity* const white = + metadata->white_point; + const float max = metadata->luminance_max; + const float min = metadata->luminance_min; + if (red) { + fprintf(o, "%sPrimaryRChromaticityX : %g\n", + indent->indent_str().c_str(), red->x); + fprintf(o, "%sPrimaryRChromaticityY : %g\n", + indent->indent_str().c_str(), red->y); + } + if (green) { + fprintf(o, "%sPrimaryGChromaticityX : %g\n", + indent->indent_str().c_str(), green->x); + fprintf(o, "%sPrimaryGChromaticityY : %g\n", + indent->indent_str().c_str(), green->y); + } + if (blue) { + fprintf(o, "%sPrimaryBChromaticityX : %g\n", + indent->indent_str().c_str(), blue->x); + fprintf(o, "%sPrimaryBChromaticityY : %g\n", + indent->indent_str().c_str(), blue->y); + } + if (white) { + fprintf(o, "%sWhitePointChromaticityX : %g\n", + indent->indent_str().c_str(), white->x); + fprintf(o, "%sWhitePointChromaticityY : %g\n", + indent->indent_str().c_str(), white->y); + } + if (max != mkvparser::MasteringMetadata::kValueNotPresent) + fprintf(o, "%sLuminanceMax : %g\n", + indent->indent_str().c_str(), max); + if (min != mkvparser::MasteringMetadata::kValueNotPresent) + fprintf(o, "%sLuminanceMin : %g\n", + indent->indent_str().c_str(), min); + indent->Adjust(libwebm::kDecreaseIndent); + } + indent->Adjust(libwebm::kDecreaseIndent); + } + + const mkvparser::Projection* const projection = + video_track->GetProjection(); + if (projection) { + fprintf(o, "%sProjection:\n", indent->indent_str().c_str()); + indent->Adjust(libwebm::kIncreaseIndent); + + const int projection_type = static_cast(projection->type); + const int kTypeNotPresent = + static_cast(mkvparser::Projection::kTypeNotPresent); + const float kValueNotPresent = mkvparser::Projection::kValueNotPresent; + if (projection_type != kTypeNotPresent) + fprintf(o, "%sProjectionType : %d\n", + indent->indent_str().c_str(), projection_type); + if (projection->private_data) + fprintf(o, "%sProjectionPrivate(size) : %d\n", + indent->indent_str().c_str(), + static_cast(projection->private_data_length)); + if (projection->pose_yaw != kValueNotPresent) + fprintf(o, "%sProjectionPoseYaw : %g\n", + indent->indent_str().c_str(), projection->pose_yaw); + if (projection->pose_pitch != kValueNotPresent) + fprintf(o, "%sProjectionPosePitch : %g\n", + indent->indent_str().c_str(), projection->pose_pitch); + if (projection->pose_roll != kValueNotPresent) + fprintf(o, "%sProjectionPoseRoll : %g\n", + indent->indent_str().c_str(), projection->pose_roll); + indent->Adjust(libwebm::kDecreaseIndent); + } + } else if (track_type == mkvparser::Track::kAudio) { + const mkvparser::AudioTrack* const audio_track = + static_cast(track); + const int64_t channels = audio_track->GetChannels(); + const int64_t bit_depth = audio_track->GetBitDepth(); + const uint64_t codec_delay = audio_track->GetCodecDelay(); + const uint64_t seek_preroll = audio_track->GetSeekPreRoll(); + fprintf(o, "%sChannels : %" PRId64 "\n", + indent->indent_str().c_str(), channels); + if (bit_depth > 0) + fprintf(o, "%sBitDepth : %" PRId64 "\n", + indent->indent_str().c_str(), bit_depth); + fprintf(o, "%sSamplingFrequency: %g\n", indent->indent_str().c_str(), + audio_track->GetSamplingRate()); + if (codec_delay) + fprintf(o, "%sCodecDelay : %" PRIu64 "\n", + indent->indent_str().c_str(), codec_delay); + if (seek_preroll) + fprintf(o, "%sSeekPreRoll : %" PRIu64 "\n", + indent->indent_str().c_str(), seek_preroll); + } + indent->Adjust(libwebm::kDecreaseIndent * 2); + } + + return true; +} + +// libvpx reference: vp9/vp9_dx_iface.c +void ParseSuperframeIndex(const uint8_t* data, size_t data_sz, + uint32_t sizes[8], int* count) { + const uint8_t marker = data[data_sz - 1]; + *count = 0; + + if ((marker & 0xe0) == 0xc0) { + const int frames = (marker & 0x7) + 1; + const int mag = ((marker >> 3) & 0x3) + 1; + const size_t index_sz = 2 + mag * frames; + + if (data_sz >= index_sz && data[data_sz - index_sz] == marker) { + // found a valid superframe index + const uint8_t* x = data + data_sz - index_sz + 1; + + for (int i = 0; i < frames; ++i) { + uint32_t this_sz = 0; + + for (int j = 0; j < mag; ++j) { + this_sz |= (*x++) << (j * 8); + } + sizes[i] = this_sz; + } + *count = frames; + } + } +} + +void PrintVP9Info(const uint8_t* data, int size, FILE* o, int64_t time_ns, + FrameStats* stats, vp9_parser::Vp9HeaderParser* parser, + vp9_parser::Vp9LevelStats* level_stats) { + if (size < 1) + return; + + uint32_t sizes[8]; + int i = 0, count = 0; + ParseSuperframeIndex(data, size, sizes, &count); + + // Remove all frames that are less than window size. + while (!stats->window.empty() && + stats->window.front() < (time_ns - (kNanosecondsPerSecondi - 1))) + stats->window.pop(); + + do { + const size_t frame_length = (count > 0) ? sizes[i] : size; + if (frame_length > static_cast(std::numeric_limits::max()) || + static_cast(frame_length) > size) { + fprintf(o, " invalid VP9 frame size (%u)\n", + static_cast(frame_length)); + return; + } + if (!parser->ParseUncompressedHeader(data, frame_length)) + return; + level_stats->AddFrame(*parser, time_ns); + + // const int frame_marker = (data[0] >> 6) & 0x3; + const int version = parser->profile(); + const int key = parser->key(); + const int altref_frame = parser->altref(); + const int error_resilient_mode = parser->error_resilient_mode(); + const int row_tiles = parser->row_tiles(); + const int column_tiles = parser->column_tiles(); + const int frame_parallel_mode = parser->frame_parallel_mode(); + + if (key && + !(size >= 4 && data[1] == 0x49 && data[2] == 0x83 && data[3] == 0x42)) { + fprintf(o, " invalid VP9 signature"); + return; + } + + stats->window.push(time_ns); + ++stats->frames; + + if (altref_frame) { + const int delta_altref = stats->frames_since_last_altref; + if (stats->first_altref) { + stats->first_altref = false; + } else if (delta_altref < stats->minimum_altref_distance) { + stats->minimum_altref_distance = delta_altref; + stats->min_altref_end_ns = time_ns; + } + stats->frames_since_last_altref = 0; + } else { + ++stats->frames_since_last_altref; + ++stats->displayed_frames; + } + + if (count > 0) { + fprintf(o, " packed [%d]: {", i); + } + + fprintf(o, " key:%d v:%d altref:%d errm:%d rt:%d ct:%d fpm:%d", key, + version, altref_frame, error_resilient_mode, row_tiles, + column_tiles, frame_parallel_mode); + + if (key) { + if (size > 4) { + fprintf(o, " cs:%d", parser->color_space()); + } + if (parser->display_width() != parser->width() || + parser->display_height() != parser->height()) { + fprintf(o, " dw:%d dh:%d", parser->display_width(), + parser->display_height()); + } + } + + if (count > 0) { + fprintf(o, " size: %u }", sizes[i]); + data += sizes[i]; + size -= sizes[i]; + } + ++i; + } while (i < count); + + if (stats->max_window_size < static_cast(stats->window.size())) { + stats->max_window_size = stats->window.size(); + stats->max_window_end_ns = time_ns; + } +} + +void PrintVP8Info(const uint8_t* data, int size, FILE* o) { + if (size < 3) + return; + + const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); + const int key = !(bits & 0x1); + const int altref_frame = !((bits >> 4) & 0x1); + const int version = (bits >> 1) & 0x7; + const int partition_length = (bits >> 5) & 0x7FFFF; + if (key && + !(size >= 6 && data[3] == 0x9d && data[4] == 0x01 && data[5] == 0x2a)) { + fprintf(o, " invalid VP8 signature"); + return; + } + fprintf(o, " key:%d v:%d altref:%d partition_length:%d", key, version, + altref_frame, partition_length); +} + +// Prints the partition offsets of the sub-sample encryption. |data| must point +// to an encrypted frame just after the signal byte. Returns the number of +// bytes read from the sub-sample partition information. +int PrintSubSampleEncryption(const uint8_t* data, int size, FILE* o) { + int read_end = sizeof(uint64_t); + + // Skip past IV. + if (size < read_end) + return 0; + data += sizeof(uint64_t); + + // Read number of partitions. + read_end += sizeof(uint8_t); + if (size < read_end) + return 0; + const int num_partitions = data[0]; + data += sizeof(uint8_t); + + // Read partitions. + for (int i = 0; i < num_partitions; ++i) { + read_end += sizeof(uint32_t); + if (size < read_end) + return 0; + uint32_t partition_offset; + memcpy(&partition_offset, data, sizeof(partition_offset)); + partition_offset = libwebm::bigendian_to_host(partition_offset); + fprintf(o, " off[%d]:%u", i, partition_offset); + data += sizeof(uint32_t); + } + + return read_end; +} + +bool OutputCluster(const mkvparser::Cluster& cluster, + const mkvparser::Tracks& tracks, const Options& options, + FILE* o, mkvparser::MkvReader* reader, Indent* indent, + int64_t* clusters_size, FrameStats* stats, + vp9_parser::Vp9HeaderParser* parser, + vp9_parser::Vp9LevelStats* level_stats) { + if (clusters_size) { + // Load the Cluster. + const mkvparser::BlockEntry* block_entry; + long status = cluster.GetFirst(block_entry); + if (status) { + fprintf(stderr, "Could not get first Block of Cluster.\n"); + return false; + } + + *clusters_size += cluster.GetElementSize(); + } + + if (options.output_clusters) { + const int64_t time_ns = cluster.GetTime(); + const int64_t duration_ns = cluster.GetLastTime() - cluster.GetFirstTime(); + + fprintf(o, "%sCluster:", indent->indent_str().c_str()); + if (options.output_offset) + fprintf(o, " @: %lld", cluster.m_element_start); + if (options.output_size) + fprintf(o, " size: %lld", cluster.GetElementSize()); + fprintf(o, "\n"); + indent->Adjust(libwebm::kIncreaseIndent); + if (options.output_seconds) + fprintf(o, "%sTimecode (sec) : %g\n", indent->indent_str().c_str(), + time_ns / kNanosecondsPerSecond); + else + fprintf(o, "%sTimecode (nano): %" PRId64 "\n", + indent->indent_str().c_str(), time_ns); + if (options.output_seconds) + fprintf(o, "%sDuration (sec) : %g\n", indent->indent_str().c_str(), + duration_ns / kNanosecondsPerSecond); + else + fprintf(o, "%sDuration (nano): %" PRId64 "\n", + indent->indent_str().c_str(), duration_ns); + + fprintf(o, "%s# Blocks : %ld\n", indent->indent_str().c_str(), + cluster.GetEntryCount()); + } + + if (options.output_blocks) { + const mkvparser::BlockEntry* block_entry; + long status = cluster.GetFirst(block_entry); + if (status) { + fprintf(stderr, "Could not get first Block of Cluster.\n"); + return false; + } + + std::vector vector_data; + while (block_entry != NULL && !block_entry->EOS()) { + const mkvparser::Block* const block = block_entry->GetBlock(); + if (!block) { + fprintf(stderr, "Could not getblock entry.\n"); + return false; + } + + const unsigned int track_number = + static_cast(block->GetTrackNumber()); + const mkvparser::Track* track = tracks.GetTrackByNumber(track_number); + if (!track) { + fprintf(stderr, "Could not get Track.\n"); + return false; + } + + const int64_t track_type = track->GetType(); + if ((track_type == mkvparser::Track::kVideo && options.output_video) || + (track_type == mkvparser::Track::kAudio && options.output_audio)) { + const int64_t time_ns = block->GetTime(&cluster); + const bool is_key = block->IsKey(); + + if (block_entry->GetKind() == mkvparser::BlockEntry::kBlockGroup) { + fprintf(o, "%sBlockGroup:\n", indent->indent_str().c_str()); + indent->Adjust(libwebm::kIncreaseIndent); + } + + fprintf(o, "%sBlock: type:%s frame:%s", indent->indent_str().c_str(), + track_type == mkvparser::Track::kVideo ? "V" : "A", + is_key ? "I" : "P"); + if (options.output_seconds) + fprintf(o, " secs:%5g", time_ns / kNanosecondsPerSecond); + else + fprintf(o, " nano:%10" PRId64, time_ns); + + if (options.output_offset) + fprintf(o, " @_payload: %lld", block->m_start); + if (options.output_size) + fprintf(o, " size_payload: %lld", block->m_size); + + const uint8_t KEncryptedBit = 0x1; + const uint8_t kSubSampleBit = 0x2; + const int kSignalByteSize = 1; + bool encrypted_stream = false; + if (options.output_encrypted_info) { + if (track->GetContentEncodingCount() > 0) { + // Only check the first content encoding. + const ContentEncoding* const encoding = + track->GetContentEncodingByIndex(0); + if (encoding) { + if (encoding->GetEncryptionCount() > 0) { + const ContentEncoding::ContentEncryption* const encryption = + encoding->GetEncryptionByIndex(0); + if (encryption) { + const ContentEncoding::ContentEncAESSettings& aes = + encryption->aes_settings; + if (aes.cipher_mode == 1) { + encrypted_stream = true; + } + } + } + } + } + + if (encrypted_stream) { + const mkvparser::Block::Frame& frame = block->GetFrame(0); + if (frame.len > static_cast(vector_data.size())) { + vector_data.resize(frame.len + 1024); + } + + unsigned char* data = &vector_data[0]; + if (frame.Read(reader, data) < 0) { + fprintf(stderr, "Could not read frame.\n"); + return false; + } + + const bool encrypted_frame = !!(data[0] & KEncryptedBit); + const bool sub_sample_encrypt = !!(data[0] & kSubSampleBit); + fprintf(o, " enc: %d", encrypted_frame ? 1 : 0); + fprintf(o, " sub: %d", sub_sample_encrypt ? 1 : 0); + + if (encrypted_frame) { + uint64_t iv; + memcpy(&iv, data + kSignalByteSize, sizeof(iv)); + fprintf(o, " iv: %" PRIx64, iv); + } + } + } + + if (options.output_codec_info) { + const int frame_count = block->GetFrameCount(); + + if (frame_count > 1) { + fprintf(o, "\n"); + indent->Adjust(libwebm::kIncreaseIndent); + } + + for (int i = 0; i < frame_count; ++i) { + if (track_type == mkvparser::Track::kVideo) { + const mkvparser::Block::Frame& frame = block->GetFrame(i); + if (frame.len > static_cast(vector_data.size())) { + vector_data.resize(frame.len + 1024); + } + + unsigned char* data = &vector_data[0]; + if (frame.Read(reader, data) < 0) { + fprintf(stderr, "Could not read frame.\n"); + return false; + } + + if (frame_count > 1) + fprintf(o, "\n%sVP8 data :", indent->indent_str().c_str()); + + bool encrypted_frame = false; + bool sub_sample_encrypt = false; + int frame_size = static_cast(frame.len); + + int frame_offset = 0; + if (encrypted_stream) { + if (data[0] & KEncryptedBit) { + encrypted_frame = true; + if (data[0] & kSubSampleBit) { + sub_sample_encrypt = true; + data += kSignalByteSize; + frame_size -= kSignalByteSize; + frame_offset = + PrintSubSampleEncryption(data, frame_size, o); + } + } else { + frame_offset = kSignalByteSize; + } + } + + if (!encrypted_frame || sub_sample_encrypt) { + data += frame_offset; + frame_size -= frame_offset; + + const string codec_id = ToString(track->GetCodecId()); + if (codec_id == "V_VP8") { + PrintVP8Info(data, frame_size, o); + } else if (codec_id == "V_VP9") { + PrintVP9Info(data, frame_size, o, time_ns, stats, parser, + level_stats); + } + } + } + } + + if (frame_count > 1) + indent->Adjust(libwebm::kDecreaseIndent); + } + + if (block_entry->GetKind() == mkvparser::BlockEntry::kBlockGroup) { + const int64_t discard_padding = block->GetDiscardPadding(); + if (discard_padding != 0) { + fprintf(o, "\n%sDiscardPadding: %10" PRId64, + indent->indent_str().c_str(), discard_padding); + } + indent->Adjust(libwebm::kDecreaseIndent); + } + + fprintf(o, "\n"); + } + + status = cluster.GetNext(block_entry, block_entry); + if (status) { + printf("\n Could not get next block of cluster.\n"); + return false; + } + } + } + + if (options.output_clusters) + indent->Adjust(libwebm::kDecreaseIndent); + + return true; +} + +bool OutputCues(const mkvparser::Segment& segment, + const mkvparser::Tracks& tracks, const Options& options, + FILE* o, Indent* indent) { + const mkvparser::Cues* const cues = segment.GetCues(); + if (cues == NULL) + return true; + + // Load all of the cue points. + while (!cues->DoneParsing()) + cues->LoadCuePoint(); + + // Confirm that the input has cue points. + const mkvparser::CuePoint* const first_cue = cues->GetFirst(); + if (first_cue == NULL) { + fprintf(o, "%sNo cue points.\n", indent->indent_str().c_str()); + return true; + } + + // Input has cue points, dump them: + fprintf(o, "%sCues:", indent->indent_str().c_str()); + if (options.output_offset) + fprintf(o, " @:%lld", cues->m_element_start); + if (options.output_size) + fprintf(o, " size:%lld", cues->m_element_size); + fprintf(o, "\n"); + + const mkvparser::CuePoint* cue_point = first_cue; + int cue_point_num = 1; + const int num_tracks = static_cast(tracks.GetTracksCount()); + indent->Adjust(libwebm::kIncreaseIndent); + + do { + for (int track_num = 0; track_num < num_tracks; ++track_num) { + const mkvparser::Track* const track = tracks.GetTrackByIndex(track_num); + const mkvparser::CuePoint::TrackPosition* const track_pos = + cue_point->Find(track); + + if (track_pos != NULL) { + const char track_type = + (track->GetType() == mkvparser::Track::kVideo) ? 'V' : 'A'; + fprintf(o, "%sCue Point:%d type:%c track:%d", + indent->indent_str().c_str(), cue_point_num, track_type, + static_cast(track->GetNumber())); + + if (options.output_seconds) { + fprintf(o, " secs:%g", + cue_point->GetTime(&segment) / kNanosecondsPerSecond); + } else { + fprintf(o, " nano:%lld", cue_point->GetTime(&segment)); + } + + if (options.output_blocks) + fprintf(o, " block:%lld", track_pos->m_block); + + if (options.output_offset) + fprintf(o, " @:%lld", track_pos->m_pos); + + fprintf(o, "\n"); + } + } + + cue_point = cues->GetNext(cue_point); + ++cue_point_num; + } while (cue_point != NULL); + + indent->Adjust(libwebm::kDecreaseIndent); + return true; +} + +} // namespace + +int main(int argc, char* argv[]) { + string input; + Options options; + + const int argc_check = argc - 1; + for (int i = 1; i < argc; ++i) { + if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) { + Usage(); + return EXIT_SUCCESS; + } else if (!strcmp("-v", argv[i])) { + printf("version: %s\n", VERSION_STRING); + } else if (!strcmp("-i", argv[i]) && i < argc_check) { + input = argv[++i]; + } else if (!strcmp("-all", argv[i])) { + options.SetAll(true); + } else if (Options::MatchesBooleanOption("video", argv[i])) { + options.output_video = !strcmp("-video", argv[i]); + } else if (Options::MatchesBooleanOption("audio", argv[i])) { + options.output_audio = !strcmp("-audio", argv[i]); + } else if (Options::MatchesBooleanOption("size", argv[i])) { + options.output_size = !strcmp("-size", argv[i]); + } else if (Options::MatchesBooleanOption("offset", argv[i])) { + options.output_offset = !strcmp("-offset", argv[i]); + } else if (Options::MatchesBooleanOption("times_seconds", argv[i])) { + options.output_seconds = !strcmp("-times_seconds", argv[i]); + } else if (Options::MatchesBooleanOption("ebml_header", argv[i])) { + options.output_ebml_header = !strcmp("-ebml_header", argv[i]); + } else if (Options::MatchesBooleanOption("segment", argv[i])) { + options.output_segment = !strcmp("-segment", argv[i]); + } else if (Options::MatchesBooleanOption("seekhead", argv[i])) { + options.output_seekhead = !strcmp("-seekhead", argv[i]); + } else if (Options::MatchesBooleanOption("segment_info", argv[i])) { + options.output_segment_info = !strcmp("-segment_info", argv[i]); + } else if (Options::MatchesBooleanOption("tracks", argv[i])) { + options.output_tracks = !strcmp("-tracks", argv[i]); + } else if (Options::MatchesBooleanOption("clusters", argv[i])) { + options.output_clusters = !strcmp("-clusters", argv[i]); + } else if (Options::MatchesBooleanOption("blocks", argv[i])) { + options.output_blocks = !strcmp("-blocks", argv[i]); + } else if (Options::MatchesBooleanOption("codec_info", argv[i])) { + options.output_codec_info = !strcmp("-codec_info", argv[i]); + } else if (Options::MatchesBooleanOption("clusters_size", argv[i])) { + options.output_clusters_size = !strcmp("-clusters_size", argv[i]); + } else if (Options::MatchesBooleanOption("encrypted_info", argv[i])) { + options.output_encrypted_info = !strcmp("-encrypted_info", argv[i]); + } else if (Options::MatchesBooleanOption("cues", argv[i])) { + options.output_cues = !strcmp("-cues", argv[i]); + } else if (Options::MatchesBooleanOption("frame_stats", argv[i])) { + options.output_frame_stats = !strcmp("-frame_stats", argv[i]); + } else if (Options::MatchesBooleanOption("vp9_level", argv[i])) { + options.output_vp9_level = !strcmp("-vp9_level", argv[i]); + } + } + + if (argc < 3 || input.empty()) { + Usage(); + return EXIT_FAILURE; + } + + std::unique_ptr reader( + new (std::nothrow) mkvparser::MkvReader()); // NOLINT + if (reader->Open(input.c_str())) { + fprintf(stderr, "Error opening file:%s\n", input.c_str()); + return EXIT_FAILURE; + } + + long long int pos = 0; + std::unique_ptr ebml_header( + new (std::nothrow) mkvparser::EBMLHeader()); // NOLINT + if (ebml_header->Parse(reader.get(), pos) < 0) { + fprintf(stderr, "Error parsing EBML header.\n"); + return EXIT_FAILURE; + } + + Indent indent(0); + FILE* out = stdout; + + if (options.output_ebml_header) + OutputEBMLHeader(*ebml_header.get(), out, &indent); + + mkvparser::Segment* temp_segment; + if (mkvparser::Segment::CreateInstance(reader.get(), pos, temp_segment)) { + fprintf(stderr, "Segment::CreateInstance() failed.\n"); + return EXIT_FAILURE; + } + std::unique_ptr segment(temp_segment); + + if (segment->Load() < 0) { + fprintf(stderr, "Segment::Load() failed.\n"); + return EXIT_FAILURE; + } + + if (options.output_segment) { + OutputSegment(*(segment.get()), options, out); + indent.Adjust(libwebm::kIncreaseIndent); + } + + if (options.output_seekhead) + if (!OutputSeekHead(*(segment.get()), options, out, &indent)) + return EXIT_FAILURE; + + if (options.output_segment_info) + if (!OutputSegmentInfo(*(segment.get()), options, out, &indent)) + return EXIT_FAILURE; + + if (options.output_tracks) + if (!OutputTracks(*(segment.get()), options, out, &indent)) + return EXIT_FAILURE; + + const mkvparser::Tracks* const tracks = segment->GetTracks(); + if (!tracks) { + fprintf(stderr, "Could not get Tracks.\n"); + return EXIT_FAILURE; + } + + // If Cues are before the clusters output them first. + if (options.output_cues) { + const mkvparser::Cluster* cluster = segment->GetFirst(); + const mkvparser::Cues* const cues = segment->GetCues(); + if (cluster != NULL && cues != NULL) { + if (cues->m_element_start < cluster->m_element_start) { + if (!OutputCues(*segment, *tracks, options, out, &indent)) { + return EXIT_FAILURE; + } + options.output_cues = false; + } + } + } + + if (options.output_clusters) + fprintf(out, "%sClusters (count):%ld\n", indent.indent_str().c_str(), + segment->GetCount()); + + int64_t clusters_size = 0; + FrameStats stats; + vp9_parser::Vp9HeaderParser parser; + vp9_parser::Vp9LevelStats level_stats; + const mkvparser::Cluster* cluster = segment->GetFirst(); + while (cluster != NULL && !cluster->EOS()) { + if (!OutputCluster(*cluster, *tracks, options, out, reader.get(), &indent, + &clusters_size, &stats, &parser, &level_stats)) + return EXIT_FAILURE; + cluster = segment->GetNext(cluster); + } + + if (options.output_clusters_size) + fprintf(out, "%sClusters (size):%" PRId64 "\n", indent.indent_str().c_str(), + clusters_size); + + if (options.output_cues) + if (!OutputCues(*segment, *tracks, options, out, &indent)) + return EXIT_FAILURE; + + // TODO(fgalligan): Add support for VP8. + if (options.output_frame_stats && + stats.minimum_altref_distance != std::numeric_limits::max()) { + const double actual_fps = + stats.frames / + (segment->GetInfo()->GetDuration() / kNanosecondsPerSecond); + const double displayed_fps = + stats.displayed_frames / + (segment->GetInfo()->GetDuration() / kNanosecondsPerSecond); + fprintf(out, "\nActual fps:%g Displayed fps:%g\n", actual_fps, + displayed_fps); + + fprintf(out, "Minimum Altref Distance:%d at:%g seconds\n", + stats.minimum_altref_distance, + stats.min_altref_end_ns / kNanosecondsPerSecond); + + // TODO(fgalligan): Add support for window duration other than 1 second. + const double sec_end = stats.max_window_end_ns / kNanosecondsPerSecond; + const double sec_start = + stats.max_window_end_ns > kNanosecondsPerSecondi ? sec_end - 1.0 : 0.0; + fprintf(out, "Maximum Window:%g-%g seconds Window fps:%" PRId64 "\n", + sec_start, sec_end, stats.max_window_size); + } + + if (options.output_vp9_level) { + level_stats.set_duration(segment->GetInfo()->GetDuration()); + const vp9_parser::Vp9Level level = level_stats.GetLevel(); + fprintf(out, "VP9 Level:%d\n", level); + fprintf( + out, + "mlsr:%" PRId64 " mlps:%" PRId64 " mlpb:%" PRId64 + " abr:%g mcs:%g cr:%g mct:%d" + " mad:%d mrf:%d\n", + level_stats.GetMaxLumaSampleRate(), level_stats.GetMaxLumaPictureSize(), + level_stats.GetMaxLumaPictureBreadth(), level_stats.GetAverageBitRate(), + level_stats.GetMaxCpbSize(), level_stats.GetCompressionRatio(), + level_stats.GetMaxColumnTiles(), level_stats.GetMinimumAltrefDistance(), + level_stats.GetMaxReferenceFrames()); + } + return EXIT_SUCCESS; +} diff --git a/src/sys/libwebm/webm_parser/README.md b/src/sys/libwebm/webm_parser/README.md new file mode 100644 index 0000000..f3d37ff --- /dev/null +++ b/src/sys/libwebm/webm_parser/README.md @@ -0,0 +1,325 @@ +# WebM Parser {#mainpage} + +# Introduction + +This WebM parser is a C++11-based parser that aims to be a safe and complete +parser for WebM. It supports all WebM elements (from the old deprecated ones to +the newest ones like `Colour`), including recursive elements like `ChapterAtom` +and `SimpleTag`. It supports incremental parsing; parsing may be stopped at any +point and resumed later as needed. It also supports starting at an arbitrary +WebM element, so parsing need not start from the beginning of the file. + +The parser (`WebmParser`) works by being fed input data from a data source (an +instance of `Reader`) that represents a WebM file. The parser will parse the +WebM data into various data structures that represent the encoded WebM elements, +and then call corresponding `Callback` event methods as the data structures are +parsed. + +# Building + +CMake support has been added to the root libwebm `CMakeLists.txt` file. Simply +enable the `ENABLE_WEBM_PARSER` feature if using the interactive CMake builder, +or alternatively pass the `-DENABLE_WEBM_PARSER:BOOL=ON` flag from the command +line. By default, this parser is not enabled when building libwebm, so you must +explicitly enable it. + +Alternatively, the following illustrates the minimal commands necessary to +compile the code into a static library without CMake: + +```.sh +c++ -Iinclude -I. -std=c++11 -c src/*.cc +ar rcs libwebm.a *.o +``` + +# Using the parser + +There are 3 basic components in the parser that are used: `Reader`, `Callback`, +and `WebmParser`. + +## `Reader` + +The `Reader` interface acts as a data source for the parser. You may subclass it +and implement your own data source if you wish. Alternatively, use the +`FileReader`, `IstreamReader`, or `BufferReader` if you wish to read from a +`FILE*`, `std::istream`, or `std::vector`, respectively. + +The parser supports `Reader` implementations that do short reads. If +`Reader::Skip()` or `Reader::Read()` do a partial read (returning +`Status::kOkPartial`), the parser will call them again in an attempt to read +more data. If no data is available, the `Reader` may return some other status +(like `Status::kWouldBlock`) to indicate that no data is available. In this +situation, the parser will stop parsing and return the status it received. +Parsing may be resumed later when more data is available. + +When the `Reader` has reached the end of the WebM document and no more data is +available, it should return `Status::kEndOfFile`. This will cause parsing to +stop. If the file ends at a valid location (that is, there aren't any elements +that have specified a size that indicates the file ended prematurely), the +parser will translate `Status::kEndOfFile` into `Status::kOkCompleted` and +return it. If the file ends prematurely, the parser will return +`Status::kEndOfFile` to indicate that. + +Note that if the WebM file contains elements that have an unknown size (or a +seek has been performed and the parser doesn't know the size of the root +element(s)), and the parser is parsing them and hits end-of-file, the parser may +still call `Reader::Read()`/`Reader::Skip()` multiple times (even though they've +already reported `Status::kEndOfFile`) as nested parsers terminate parsing. +Because of this, `Reader::Read()`/`Reader::Skip()` implementations should be +able to handle being called multiple times after the file's end has been +reached, and they should consistently return `Status::kEndOfFile`. + +The three provided readers (`FileReader`, `IstreamReader`, and `BufferReader`) +are blocking implementations (they won't return `Status::kWouldBlock`), so if +you're using them the parser will run until it entirely consumes all their data +(unless, of course, you request the parser to stop via `Callback`... see the +next section). + +## `Callback` + +As the parser progresses through the file, it builds objects (see +`webm/dom_types.h`) that represent parsed data structures. The parser then +notifies the `Callback` implementation as objects complete parsing. For some +data structures (like frames or Void elements), the parser notifies the +`Callback` and requests it to consume the data directly from the `Reader` (this +is done for structures that can be large/frequent binary blobs in order to allow +you to read the data directly into the object/type of your choice, rather than +just reading them into a `std::vector` and making you copy it into +a different object if you wanted to work with something other than +`std::vector`). + +The parser was designed to parse the data into objects that are small enough +that the `Callback` can be quickly and frequently notified as soon as the object +is ready, but large enough that the objects received by the `Callback` are still +useful. Having `Callback` events for every tiny integer/float/string/etc. +element would require too much assembly and work to be useful to most users, and +pasing the file into a single DOM tree (or a small handful of large conglomerate +structures) would unnecessarily delay video playback or consume too much memory +on smaller devices. + +The parser may call the following methods while nearly anywhere in the file: + +- `Callback::OnElementBegin()`: This is called for every element that the + parser encounters. This is primarily useful if you want to skip some + elements or build a map of every element in the file. +- `Callback::OnUnknownElement()`: This is called when an element is either not + a valid/recognized WebM element, or it is a WebM element but is improperly + nested (e.g. an EBMLVersion element inside of a Segment element). The parser + doesn't know how to handle the element; it could just skip it but instead + defers to the `Callback` to decide how it should be handled. The default + implementation just skips the element. +- `Callback::OnVoid()`: Void elements can appear anywhere in any master + element. This method will be called to handle the Void element. + +The parser may call the following methods in the proper nesting order, as shown +in the list. A `*Begin()` method will always be matched up with its +corresponding `*End()` method (unless a seek has been performed). The parser +will only call the methods in the proper nesting order as specified in the WebM +DOM. For example, `Callback::OnEbml()` will never be called in between +`Callback::OnSegmentBegin()`/`Callback::OnSegmentEnd()` (since the EBML element +is not a child of the Segment element), and `Callback::OnTrackEntry()` will only +ever be called in between +`Callback::OnSegmentBegin()`/`Callback::OnSegmentEnd()` (since the TrackEntry +element is a (grand-)child of the Segment element and must be contained by a +Segment element). `Callback::OnFrame()` is listed twice because it will be +called to handle frames contained in both SimpleBlock and Block elements. + +- `Callback::OnEbml()` +- `Callback::OnSegmentBegin()` + - `Callback::OnSeek()` + - `Callback::OnInfo()` + - `Callback::OnClusterBegin()` + - `Callback::OnSimpleBlockBegin()` + - `Callback::OnFrame()` + - `Callback::OnSimpleBlockEnd()` + - `Callback::OnBlockGroupBegin()` + - `Callback::OnBlockBegin()` + - `Callback::OnFrame()` + - `Callback::OnBlockEnd()` + - `Callback::OnBlockGroupEnd()` + - `Callback::OnClusterEnd()` + - `Callback::OnTrackEntry()` + - `Callback::OnCuePoint()` + - `Callback::OnEditionEntry()` + - `Callback::OnTag()` +- `Callback::OnSegmentEnd()` + +Only `Callback::OnFrame()` (and no other `Callback` methods) will be called in +between `Callback::OnSimpleBlockBegin()`/`Callback::OnSimpleBlockEnd()` or +`Callback::OnBlockBegin()`/`Callback::OnBlockEnd()`, since the SimpleBlock and +Block elements are not master elements only contain frames. + +Note that seeking into the middle of the file may cause the parser to skip some +`*Begin()` methods. For example, if a seek is performed to a SimpleBlock +element, `Callback::OnSegmentBegin()` and `Callback::OnClusterBegin()` will not +be called. In this situation, the full sequence of callback events would be +(assuming the file ended after the SimpleBlock): +`Callback::OnSimpleBlockBegin()`, `Callback::OnFrame()` (for every frame in the +SimpleBlock), `Callback::OnSimpleBlockEnd()`, `Callback::OnClusterEnd()`, and +`Callback::OnSegmentEnd()`. Since the Cluster and Segment elements were skipped, +the `Cluster` DOM object may have some members marked as absent, and the +`*End()` events for the Cluster and Segment elements will have metadata with +unknown header position, header length, and body size (see `kUnknownHeaderSize`, +`kUnknownElementSize`, and `kUnknownElementPosition`). + +When a `Callback` method has completed, it should return `Status::kOkCompleted` +to allow parsing to continue. If you would like parsing to stop, return any +other status code (except `Status::kEndOfFile`, since that's treated somewhat +specially and is intended for `Reader`s to use), which the parser will return. +If you return a non-parsing-error status code (.e.g. `Status::kOkPartial`, +`Status::kWouldBlock`, etc. or your own status code with a value > 0), parsing +may be resumed again. When parsing is resumed, the parser will call the same +callback method again (and once again, you may return `Status::kOkCompleted` to +let parsing continue or some other value to stop parsing). + +You may subclass the `Callback` element and override methods which you are +interested in receiving events for. By default, methods taking an `Action` +parameter will set it to `Action::kRead` so the entire file is parsed. The +`Callback::OnFrame()` method will just skip over the frame bytes by default. + +## `WebmParser` + +The actual parsing work is done with `WebmParser`. Simply construct a +`WebmParser` and call `WebmParser::Feed()` (providing it a `Callback` and +`Reader` instance) to parse a file. It will return `Status::kOkCompleted` when +the entire file has been successfully parsed. `WebmParser::Feed()` doesn't store +any internal references to the `Callback` or `Reader`. + +If you wish to start parsing from the middle of a file, call +`WebmParser::DidSeek()` before calling `WebmParser::Feed()` to prepare the +parser to receive data starting at an arbitrary point in the file. When seeking, +you should seek to the beginning of a WebM element; seeking to a location that +is not the start of a WebM element (e.g. seeking to a frame, rather than its +containing SimpleBlock/Block element) will cause parsing to fail. Calling +`WebmParser::DidSeek()` will reset the state of the parser and clear any +internal errors, so a `WebmParser` instance may be reused (even if it has +previously failed to parse a file). + +## Building your program + +The following program is a small program that completely parses a file from +stdin: + +```.cc +#include +#include +#include + +int main() { + webm::Callback callback; + webm::FileReader reader(std::freopen(nullptr, "rb", stdin)); + webm::WebmParser parser; + parser.Feed(&callback, &reader); +} +``` + +It completely parses the input file, but we need to make a new class that +derives from `Callback` if we want to receive any parsing events. So if we +change it to: + +```.cc +#include +#include + +#include +#include +#include +#include + +class MyCallback : public webm::Callback { + public: + webm::Status OnElementBegin(const webm::ElementMetadata& metadata, + webm::Action* action) override { + std::cout << "Element ID = 0x" + << std::hex << static_cast(metadata.id); + std::cout << std::dec; // Reset to decimal mode. + std::cout << " at position "; + if (metadata.position == webm::kUnknownElementPosition) { + // The position will only be unknown if we've done a seek. But since we + // aren't seeking in this demo, this will never be the case. However, this + // if-statement is included for completeness. + std::cout << ""; + } else { + std::cout << metadata.position; + } + std::cout << " with header size "; + if (metadata.header_size == webm::kUnknownHeaderSize) { + // The header size will only be unknown if we've done a seek. But since we + // aren't seeking in this demo, this will never be the case. However, this + // if-statement is included for completeness. + std::cout << ""; + } else { + std::cout << metadata.header_size; + } + std::cout << " and body size "; + if (metadata.size == webm::kUnknownElementSize) { + // WebM master elements may have an unknown size, though this is rare. + std::cout << ""; + } else { + std::cout << metadata.size; + } + std::cout << '\n'; + + *action = webm::Action::kRead; + return webm::Status(webm::Status::kOkCompleted); + } +}; + +int main() { + MyCallback callback; + webm::FileReader reader(std::freopen(nullptr, "rb", stdin)); + webm::WebmParser parser; + webm::Status status = parser.Feed(&callback, &reader); + if (status.completed_ok()) { + std::cout << "Parsing successfully completed\n"; + } else { + std::cout << "Parsing failed with status code: " << status.code << '\n'; + } +} +``` + +This will output information about every element in the entire file: it's ID, +position, header size, and body size. The status of the parse is also checked +and reported. + +For a more complete example, see `demo/demo.cc`, which parses an entire file and +prints out all of its information. That example overrides every `Callback` +method to show exactly what information is available while parsing and how to +access it. The example is verbose, but that's primarily due to pretty-printing +and string formatting operations. + +When compiling your program, add the `include` directory to your compiler's +header search paths and link to the compiled library. Be sure your compiler has +C++11 mode enabled (`-std=c++11` in clang++ or g++). + +# Testing + +Unit tests are located in the `tests` directory. Google Test and Google Mock are +used as testing frameworks. Building and running the tests will be supported in +the upcoming CMake scripts, but they can currently be built and run by manually +compiling them (and linking to Google Test and Google Mock). + +# Fuzzing + +The parser has been fuzzed with [AFL](http://lcamtuf.coredump.cx/afl/) and +[libFuzzer](http://llvm.org/docs/LibFuzzer.html). If you wish to fuzz the parser +with AFL or libFuzzer but don't want to write an executable that exercises the +parsing API, you may use `fuzzing/webm_fuzzer.cc`. + +When compiling for fuzzing, define the macro +`WEBM_FUZZER_BYTE_ELEMENT_SIZE_LIMIT` to be some integer in order to limit the +maximum size of ASCII/UTF-8/binary elements. It's too easy for the fuzzer to +generate elements that claim to have a ridiculously massive size, which will +cause allocations to fail or the program to allocate too much memory. AFL will +terminate the process if it allocates too much memory (by default, 50 MB), and +the [Address Sanitizer doesn't throw `std::bad_alloc` when an allocation fails] +(https://github.com/google/sanitizers/issues/295). Defining +`WEBM_FUZZER_BYTE_ELEMENT_SIZE_LIMIT` to a low number (say, 1024) will cause the +ASCII/UTF-8/binary element parsers to return `Status::kNotEnoughMemory` if the +element's size exceeds `WEBM_FUZZER_BYTE_ELEMENT_SIZE_LIMIT`, which will avoid +false positives when fuzzing. The parser expects `std::string` and `std::vector` +to throw `std::bad_alloc` when an allocation fails, which doesn't necessarily +happen due to the fuzzers' limitations. + +You may also define the macro `WEBM_FUZZER_SEEK_FIRST` to have +`fuzzing/webm_fuzzer.cc` call `WebmParser::DidSeek()` before doing any parsing. +This will test the seeking code paths. diff --git a/src/sys/libwebm/webm_parser/demo/demo.cc b/src/sys/libwebm/webm_parser/demo/demo.cc new file mode 100644 index 0000000..47ecbb0 --- /dev/null +++ b/src/sys/libwebm/webm_parser/demo/demo.cc @@ -0,0 +1,1161 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include +#include +#include +#include + +#include "webm/callback.h" +#include "webm/file_reader.h" +#include "webm/status.h" +#include "webm/webm_parser.h" + +// We use pretty much everything in the webm namespace. Just pull +// it all in. +using namespace webm; // NOLINT + +template +std::ostream& PrintUnknownEnumValue(std::ostream& os, T value) { + return os << std::to_string(static_cast(value)) << " (?)"; +} + +// Overloads for operator<< for pretty printing enums. +std::ostream& operator<<(std::ostream& os, Id id) { + switch (id) { + case Id::kEbml: + return os << "EBML"; + case Id::kEbmlVersion: + return os << "EBMLVersion"; + case Id::kEbmlReadVersion: + return os << "EBMLReadVersion"; + case Id::kEbmlMaxIdLength: + return os << "EBMLMaxIDLength"; + case Id::kEbmlMaxSizeLength: + return os << "EBMLMaxSizeLength"; + case Id::kDocType: + return os << "DocType"; + case Id::kDocTypeVersion: + return os << "DocTypeVersion"; + case Id::kDocTypeReadVersion: + return os << "DocTypeReadVersion"; + case Id::kVoid: + return os << "Void"; + case Id::kSegment: + return os << "Segment"; + case Id::kSeekHead: + return os << "SeekHead"; + case Id::kSeek: + return os << "Seek"; + case Id::kSeekId: + return os << "SeekID"; + case Id::kSeekPosition: + return os << "SeekPosition"; + case Id::kInfo: + return os << "Info"; + case Id::kTimecodeScale: + return os << "TimecodeScale"; + case Id::kDuration: + return os << "Duration"; + case Id::kDateUtc: + return os << "DateUTC"; + case Id::kTitle: + return os << "Title"; + case Id::kMuxingApp: + return os << "MuxingApp"; + case Id::kWritingApp: + return os << "WritingApp"; + case Id::kCluster: + return os << "Cluster"; + case Id::kTimecode: + return os << "Timecode"; + case Id::kPrevSize: + return os << "PrevSize"; + case Id::kSimpleBlock: + return os << "SimpleBlock"; + case Id::kBlockGroup: + return os << "BlockGroup"; + case Id::kBlock: + return os << "Block"; + case Id::kBlockVirtual: + return os << "BlockVirtual"; + case Id::kBlockAdditions: + return os << "BlockAdditions"; + case Id::kBlockMore: + return os << "BlockMore"; + case Id::kBlockAddId: + return os << "BlockAddID"; + case Id::kBlockAdditional: + return os << "BlockAdditional"; + case Id::kBlockDuration: + return os << "BlockDuration"; + case Id::kReferenceBlock: + return os << "ReferenceBlock"; + case Id::kDiscardPadding: + return os << "DiscardPadding"; + case Id::kSlices: + return os << "Slices"; + case Id::kTimeSlice: + return os << "TimeSlice"; + case Id::kLaceNumber: + return os << "LaceNumber"; + case Id::kTracks: + return os << "Tracks"; + case Id::kTrackEntry: + return os << "TrackEntry"; + case Id::kTrackNumber: + return os << "TrackNumber"; + case Id::kTrackUid: + return os << "TrackUID"; + case Id::kTrackType: + return os << "TrackType"; + case Id::kFlagEnabled: + return os << "FlagEnabled"; + case Id::kFlagDefault: + return os << "FlagDefault"; + case Id::kFlagForced: + return os << "FlagForced"; + case Id::kFlagLacing: + return os << "FlagLacing"; + case Id::kDefaultDuration: + return os << "DefaultDuration"; + case Id::kName: + return os << "Name"; + case Id::kLanguage: + return os << "Language"; + case Id::kCodecId: + return os << "CodecID"; + case Id::kCodecPrivate: + return os << "CodecPrivate"; + case Id::kCodecName: + return os << "CodecName"; + case Id::kCodecDelay: + return os << "CodecDelay"; + case Id::kSeekPreRoll: + return os << "SeekPreRoll"; + case Id::kVideo: + return os << "Video"; + case Id::kFlagInterlaced: + return os << "FlagInterlaced"; + case Id::kStereoMode: + return os << "StereoMode"; + case Id::kAlphaMode: + return os << "AlphaMode"; + case Id::kPixelWidth: + return os << "PixelWidth"; + case Id::kPixelHeight: + return os << "PixelHeight"; + case Id::kPixelCropBottom: + return os << "PixelCropBottom"; + case Id::kPixelCropTop: + return os << "PixelCropTop"; + case Id::kPixelCropLeft: + return os << "PixelCropLeft"; + case Id::kPixelCropRight: + return os << "PixelCropRight"; + case Id::kDisplayWidth: + return os << "DisplayWidth"; + case Id::kDisplayHeight: + return os << "DisplayHeight"; + case Id::kDisplayUnit: + return os << "DisplayUnit"; + case Id::kAspectRatioType: + return os << "AspectRatioType"; + case Id::kFrameRate: + return os << "FrameRate"; + case Id::kColour: + return os << "Colour"; + case Id::kMatrixCoefficients: + return os << "MatrixCoefficients"; + case Id::kBitsPerChannel: + return os << "BitsPerChannel"; + case Id::kChromaSubsamplingHorz: + return os << "ChromaSubsamplingHorz"; + case Id::kChromaSubsamplingVert: + return os << "ChromaSubsamplingVert"; + case Id::kCbSubsamplingHorz: + return os << "CbSubsamplingHorz"; + case Id::kCbSubsamplingVert: + return os << "CbSubsamplingVert"; + case Id::kChromaSitingHorz: + return os << "ChromaSitingHorz"; + case Id::kChromaSitingVert: + return os << "ChromaSitingVert"; + case Id::kRange: + return os << "Range"; + case Id::kTransferCharacteristics: + return os << "TransferCharacteristics"; + case Id::kPrimaries: + return os << "Primaries"; + case Id::kMaxCll: + return os << "MaxCLL"; + case Id::kMaxFall: + return os << "MaxFALL"; + case Id::kMasteringMetadata: + return os << "MasteringMetadata"; + case Id::kPrimaryRChromaticityX: + return os << "PrimaryRChromaticityX"; + case Id::kPrimaryRChromaticityY: + return os << "PrimaryRChromaticityY"; + case Id::kPrimaryGChromaticityX: + return os << "PrimaryGChromaticityX"; + case Id::kPrimaryGChromaticityY: + return os << "PrimaryGChromaticityY"; + case Id::kPrimaryBChromaticityX: + return os << "PrimaryBChromaticityX"; + case Id::kPrimaryBChromaticityY: + return os << "PrimaryBChromaticityY"; + case Id::kWhitePointChromaticityX: + return os << "WhitePointChromaticityX"; + case Id::kWhitePointChromaticityY: + return os << "WhitePointChromaticityY"; + case Id::kLuminanceMax: + return os << "LuminanceMax"; + case Id::kLuminanceMin: + return os << "LuminanceMin"; + case Id::kProjection: + return os << "Projection"; + case Id::kProjectionType: + return os << "kProjectionType"; + case Id::kProjectionPrivate: + return os << "kProjectionPrivate"; + case Id::kProjectionPoseYaw: + return os << "kProjectionPoseYaw"; + case Id::kProjectionPosePitch: + return os << "kProjectionPosePitch"; + case Id::kProjectionPoseRoll: + return os << "ProjectionPoseRoll"; + case Id::kAudio: + return os << "Audio"; + case Id::kSamplingFrequency: + return os << "SamplingFrequency"; + case Id::kOutputSamplingFrequency: + return os << "OutputSamplingFrequency"; + case Id::kChannels: + return os << "Channels"; + case Id::kBitDepth: + return os << "BitDepth"; + case Id::kContentEncodings: + return os << "ContentEncodings"; + case Id::kContentEncoding: + return os << "ContentEncoding"; + case Id::kContentEncodingOrder: + return os << "ContentEncodingOrder"; + case Id::kContentEncodingScope: + return os << "ContentEncodingScope"; + case Id::kContentEncodingType: + return os << "ContentEncodingType"; + case Id::kContentEncryption: + return os << "ContentEncryption"; + case Id::kContentEncAlgo: + return os << "ContentEncAlgo"; + case Id::kContentEncKeyId: + return os << "ContentEncKeyID"; + case Id::kContentEncAesSettings: + return os << "ContentEncAESSettings"; + case Id::kAesSettingsCipherMode: + return os << "AESSettingsCipherMode"; + case Id::kCues: + return os << "Cues"; + case Id::kCuePoint: + return os << "CuePoint"; + case Id::kCueTime: + return os << "CueTime"; + case Id::kCueTrackPositions: + return os << "CueTrackPositions"; + case Id::kCueTrack: + return os << "CueTrack"; + case Id::kCueClusterPosition: + return os << "CueClusterPosition"; + case Id::kCueRelativePosition: + return os << "CueRelativePosition"; + case Id::kCueDuration: + return os << "CueDuration"; + case Id::kCueBlockNumber: + return os << "CueBlockNumber"; + case Id::kChapters: + return os << "Chapters"; + case Id::kEditionEntry: + return os << "EditionEntry"; + case Id::kChapterAtom: + return os << "ChapterAtom"; + case Id::kChapterUid: + return os << "ChapterUID"; + case Id::kChapterStringUid: + return os << "ChapterStringUID"; + case Id::kChapterTimeStart: + return os << "ChapterTimeStart"; + case Id::kChapterTimeEnd: + return os << "ChapterTimeEnd"; + case Id::kChapterDisplay: + return os << "ChapterDisplay"; + case Id::kChapString: + return os << "ChapString"; + case Id::kChapLanguage: + return os << "ChapLanguage"; + case Id::kChapCountry: + return os << "ChapCountry"; + case Id::kTags: + return os << "Tags"; + case Id::kTag: + return os << "Tag"; + case Id::kTargets: + return os << "Targets"; + case Id::kTargetTypeValue: + return os << "TargetTypeValue"; + case Id::kTargetType: + return os << "TargetType"; + case Id::kTagTrackUid: + return os << "TagTrackUID"; + case Id::kSimpleTag: + return os << "SimpleTag"; + case Id::kTagName: + return os << "TagName"; + case Id::kTagLanguage: + return os << "TagLanguage"; + case Id::kTagDefault: + return os << "TagDefault"; + case Id::kTagString: + return os << "TagString"; + case Id::kTagBinary: + return os << "TagBinary"; + default: + return PrintUnknownEnumValue(os, id); + } +} + +std::ostream& operator<<(std::ostream& os, Lacing value) { + switch (value) { + case Lacing::kNone: + return os << "0 (none)"; + case Lacing::kXiph: + return os << "2 (Xiph)"; + case Lacing::kFixed: + return os << "4 (fixed)"; + case Lacing::kEbml: + return os << "6 (EBML)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, MatrixCoefficients value) { + switch (value) { + case MatrixCoefficients::kRgb: + return os << "0 (identity, RGB/XYZ)"; + case MatrixCoefficients::kBt709: + return os << "1 (Rec. ITU-R BT.709-5)"; + case MatrixCoefficients::kUnspecified: + return os << "2 (unspecified)"; + case MatrixCoefficients::kFcc: + return os << "4 (US FCC)"; + case MatrixCoefficients::kBt470Bg: + return os << "5 (Rec. ITU-R BT.470-6 System B, G)"; + case MatrixCoefficients::kSmpte170M: + return os << "6 (SMPTE 170M)"; + case MatrixCoefficients::kSmpte240M: + return os << "7 (SMPTE 240M)"; + case MatrixCoefficients::kYCgCo: + return os << "8 (YCgCo)"; + case MatrixCoefficients::kBt2020NonconstantLuminance: + return os << "9 (Rec. ITU-R BT.2020, non-constant luma)"; + case MatrixCoefficients::kBt2020ConstantLuminance: + return os << "10 (Rec. ITU-R BT.2020 , constant luma)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, Range value) { + switch (value) { + case Range::kUnspecified: + return os << "0 (unspecified)"; + case Range::kBroadcast: + return os << "1 (broadcast)"; + case Range::kFull: + return os << "2 (full)"; + case Range::kDerived: + return os << "3 (defined by MatrixCoefficients/TransferCharacteristics)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, TransferCharacteristics value) { + switch (value) { + case TransferCharacteristics::kBt709: + return os << "1 (Rec. ITU-R BT.709-6)"; + case TransferCharacteristics::kUnspecified: + return os << "2 (unspecified)"; + case TransferCharacteristics::kGamma22curve: + return os << "4 (gamma 2.2, Rec. ITU‑R BT.470‑6 System M)"; + case TransferCharacteristics::kGamma28curve: + return os << "5 (gamma 2.8, Rec. ITU‑R BT.470-6 System B, G)"; + case TransferCharacteristics::kSmpte170M: + return os << "6 (SMPTE 170M)"; + case TransferCharacteristics::kSmpte240M: + return os << "7 (SMPTE 240M)"; + case TransferCharacteristics::kLinear: + return os << "8 (linear)"; + case TransferCharacteristics::kLog: + return os << "9 (log, 100:1 range)"; + case TransferCharacteristics::kLogSqrt: + return os << "10 (log, 316.2:1 range)"; + case TransferCharacteristics::kIec6196624: + return os << "11 (IEC 61966-2-4)"; + case TransferCharacteristics::kBt1361ExtendedColourGamut: + return os << "12 (Rec. ITU-R BT.1361, extended colour gamut)"; + case TransferCharacteristics::kIec6196621: + return os << "13 (IEC 61966-2-1, sRGB or sYCC)"; + case TransferCharacteristics::k10BitBt2020: + return os << "14 (Rec. ITU-R BT.2020-2, 10-bit)"; + case TransferCharacteristics::k12BitBt2020: + return os << "15 (Rec. ITU-R BT.2020-2, 12-bit)"; + case TransferCharacteristics::kSmpteSt2084: + return os << "16 (SMPTE ST 2084)"; + case TransferCharacteristics::kSmpteSt4281: + return os << "17 (SMPTE ST 428-1)"; + case TransferCharacteristics::kAribStdB67Hlg: + return os << "18 (ARIB STD-B67/Rec. ITU-R BT.[HDR-TV] HLG)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, Primaries value) { + switch (value) { + case Primaries::kBt709: + return os << "1 (Rec. ITU‑R BT.709-6)"; + case Primaries::kUnspecified: + return os << "2 (unspecified)"; + case Primaries::kBt470M: + return os << "4 (Rec. ITU‑R BT.470‑6 System M)"; + case Primaries::kBt470Bg: + return os << "5 (Rec. ITU‑R BT.470‑6 System B, G)"; + case Primaries::kSmpte170M: + return os << "6 (SMPTE 170M)"; + case Primaries::kSmpte240M: + return os << "7 (SMPTE 240M)"; + case Primaries::kFilm: + return os << "8 (generic film)"; + case Primaries::kBt2020: + return os << "9 (Rec. ITU-R BT.2020-2)"; + case Primaries::kSmpteSt4281: + return os << "10 (SMPTE ST 428-1)"; + case Primaries::kJedecP22Phosphors: + return os << "22 (EBU Tech. 3213-E/JEDEC P22 phosphors)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, ProjectionType value) { + switch (value) { + case ProjectionType::kRectangular: + return os << "0 (rectangular)"; + case ProjectionType::kEquirectangular: + return os << "1 (equirectangular)"; + case ProjectionType::kCubeMap: + return os << "2 (cube map)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, FlagInterlaced value) { + switch (value) { + case FlagInterlaced::kUnspecified: + return os << "0 (unspecified)"; + case FlagInterlaced::kInterlaced: + return os << "1 (interlaced)"; + case FlagInterlaced::kProgressive: + return os << "2 (progressive)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, StereoMode value) { + switch (value) { + case StereoMode::kMono: + return os << "0 (mono)"; + case StereoMode::kSideBySideLeftFirst: + return os << "1 (side-by-side, left eye first)"; + case StereoMode::kTopBottomRightFirst: + return os << "2 (top-bottom, right eye first)"; + case StereoMode::kTopBottomLeftFirst: + return os << "3 (top-bottom, left eye first)"; + case StereoMode::kCheckboardRightFirst: + return os << "4 (checkboard, right eye first)"; + case StereoMode::kCheckboardLeftFirst: + return os << "5 (checkboard, left eye first)"; + case StereoMode::kRowInterleavedRightFirst: + return os << "6 (row interleaved, right eye first)"; + case StereoMode::kRowInterleavedLeftFirst: + return os << "7 (row interleaved, left eye first)"; + case StereoMode::kColumnInterleavedRightFirst: + return os << "8 (column interleaved, right eye first)"; + case StereoMode::kColumnInterleavedLeftFirst: + return os << "9 (column interleaved, left eye first)"; + case StereoMode::kAnaglyphCyanRed: + return os << "10 (anaglyph, cyan/red)"; + case StereoMode::kSideBySideRightFirst: + return os << "11 (side-by-side, right eye first)"; + case StereoMode::kAnaglyphGreenMagenta: + return os << "12 (anaglyph, green/magenta)"; + case StereoMode::kBlockLacedLeftFirst: + return os << "13 (block laced, left eye first)"; + case StereoMode::kBlockLacedRightFirst: + return os << "14 (block laced, right eye first)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, DisplayUnit value) { + switch (value) { + case DisplayUnit::kPixels: + return os << "0 (pixels)"; + case DisplayUnit::kCentimeters: + return os << "1 (centimeters)"; + case DisplayUnit::kInches: + return os << "2 (inches)"; + case DisplayUnit::kDisplayAspectRatio: + return os << "3 (display aspect ratio)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, AspectRatioType value) { + switch (value) { + case AspectRatioType::kFreeResizing: + return os << "0 (free resizing)"; + case AspectRatioType::kKeep: + return os << "1 (keep aspect ratio)"; + case AspectRatioType::kFixed: + return os << "2 (fixed)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, AesSettingsCipherMode value) { + switch (value) { + case AesSettingsCipherMode::kCtr: + return os << "1 (CTR)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, ContentEncAlgo value) { + switch (value) { + case ContentEncAlgo::kOnlySigned: + return os << "0 (only signed, not encrypted)"; + case ContentEncAlgo::kDes: + return os << "1 (DES)"; + case ContentEncAlgo::k3Des: + return os << "2 (3DES)"; + case ContentEncAlgo::kTwofish: + return os << "3 (Twofish)"; + case ContentEncAlgo::kBlowfish: + return os << "4 (Blowfish)"; + case ContentEncAlgo::kAes: + return os << "5 (AES)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, ContentEncodingType value) { + switch (value) { + case ContentEncodingType::kCompression: + return os << "0 (compression)"; + case ContentEncodingType::kEncryption: + return os << "1 (encryption)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +std::ostream& operator<<(std::ostream& os, TrackType value) { + switch (value) { + case TrackType::kVideo: + return os << "1 (video)"; + case TrackType::kAudio: + return os << "2 (audio)"; + case TrackType::kComplex: + return os << "3 (complex)"; + case TrackType::kLogo: + return os << "16 (logo)"; + case TrackType::kSubtitle: + return os << "17 (subtitle)"; + case TrackType::kButtons: + return os << "18 (buttons)"; + case TrackType::kControl: + return os << "32 (control)"; + default: + return PrintUnknownEnumValue(os, value); + } +} + +// For binary elements, just print out its size. +std::ostream& operator<<(std::ostream& os, + const std::vector& value) { + return os << '<' << value.size() << " bytes>"; +} + +class DemoCallback : public Callback { + public: + int indent = 0; + int spaces_per_indent = 2; + + void PrintElementMetadata(const std::string& name, + const ElementMetadata& metadata) { + // Since we aren't doing any seeking in this demo, we don't have to worry + // about kUnknownHeaderSize or kUnknownElementPosition when adding the + // position and sizes. + const std::uint64_t header_start = metadata.position; + const std::uint64_t header_end = header_start + metadata.header_size; + const std::uint64_t body_start = header_end; + std::cout << std::string(indent * spaces_per_indent, ' ') << name; + // The ContentEncAESSettings element has the longest name (out of all other + // master elements) at 21 characters. It's also the deepest master element + // at a level of 6. Insert enough whitespace so there's room for it. + std::cout << std::string(21 + 6 * spaces_per_indent - + indent * spaces_per_indent - name.size(), + ' ') + << " header: [" << header_start << ", " << header_end + << ") body: [" << body_start << ", "; + if (metadata.size != kUnknownElementSize) { + const std::uint64_t body_end = body_start + metadata.size; + std::cout << body_end; + } else { + std::cout << '?'; + } + std::cout << ")\n"; + } + + template + void PrintMandatoryElement(const std::string& name, + const Element& element) { + std::cout << std::string(indent * spaces_per_indent, ' ') << name; + if (!element.is_present()) { + std::cout << " (implicit)"; + } + std::cout << ": " << element.value() << '\n'; + } + + template + void PrintMandatoryElement(const std::string& name, + const std::vector>& elements) { + for (const Element& element : elements) { + PrintMandatoryElement(name, element); + } + } + + template + void PrintOptionalElement(const std::string& name, + const Element& element) { + if (element.is_present()) { + std::cout << std::string(indent * spaces_per_indent, ' ') << name << ": " + << element.value() << '\n'; + } + } + + template + void PrintOptionalElement(const std::string& name, + const std::vector>& elements) { + for (const Element& element : elements) { + PrintOptionalElement(name, element); + } + } + + void PrintMasterElement(const BlockAdditions& block_additions) { + PrintMasterElement("BlockMore", block_additions.block_mores); + } + + void PrintMasterElement(const BlockMore& block_more) { + PrintMandatoryElement("BlockAddID", block_more.id); + PrintMandatoryElement("BlockAdditional", block_more.data); + } + + void PrintMasterElement(const Slices& slices) { + PrintMasterElement("TimeSlice", slices.slices); + } + + void PrintMasterElement(const TimeSlice& time_slice) { + PrintOptionalElement("LaceNumber", time_slice.lace_number); + } + + void PrintMasterElement(const Video& video) { + PrintMandatoryElement("FlagInterlaced", video.interlaced); + PrintOptionalElement("StereoMode", video.stereo_mode); + PrintOptionalElement("AlphaMode", video.alpha_mode); + PrintMandatoryElement("PixelWidth", video.pixel_width); + PrintMandatoryElement("PixelHeight", video.pixel_height); + PrintOptionalElement("PixelCropBottom", video.pixel_crop_bottom); + PrintOptionalElement("PixelCropTop", video.pixel_crop_top); + PrintOptionalElement("PixelCropLeft", video.pixel_crop_left); + PrintOptionalElement("PixelCropRight", video.pixel_crop_right); + PrintOptionalElement("DisplayWidth", video.display_width); + PrintOptionalElement("DisplayHeight", video.display_height); + PrintOptionalElement("DisplayUnit", video.display_unit); + PrintOptionalElement("AspectRatioType", video.aspect_ratio_type); + PrintOptionalElement("FrameRate", video.frame_rate); + PrintMasterElement("Colour", video.colour); + PrintMasterElement("Projection", video.projection); + } + + void PrintMasterElement(const Colour& colour) { + PrintOptionalElement("MatrixCoefficients", colour.matrix_coefficients); + PrintOptionalElement("BitsPerChannel", colour.bits_per_channel); + PrintOptionalElement("ChromaSubsamplingHorz", colour.chroma_subsampling_x); + PrintOptionalElement("ChromaSubsamplingVert", colour.chroma_subsampling_y); + PrintOptionalElement("CbSubsamplingHorz", colour.cb_subsampling_x); + PrintOptionalElement("CbSubsamplingVert", colour.cb_subsampling_y); + PrintOptionalElement("ChromaSitingHorz", colour.chroma_siting_x); + PrintOptionalElement("ChromaSitingVert", colour.chroma_siting_y); + PrintOptionalElement("Range", colour.range); + PrintOptionalElement("TransferCharacteristics", + colour.transfer_characteristics); + PrintOptionalElement("Primaries", colour.primaries); + PrintOptionalElement("MaxCLL", colour.max_cll); + PrintOptionalElement("MaxFALL", colour.max_fall); + PrintMasterElement("MasteringMetadata", colour.mastering_metadata); + } + + void PrintMasterElement(const MasteringMetadata& mastering_metadata) { + PrintOptionalElement("PrimaryRChromaticityX", + mastering_metadata.primary_r_chromaticity_x); + PrintOptionalElement("PrimaryRChromaticityY", + mastering_metadata.primary_r_chromaticity_y); + PrintOptionalElement("PrimaryGChromaticityX", + mastering_metadata.primary_g_chromaticity_x); + PrintOptionalElement("PrimaryGChromaticityY", + mastering_metadata.primary_g_chromaticity_y); + PrintOptionalElement("PrimaryBChromaticityX", + mastering_metadata.primary_b_chromaticity_x); + PrintOptionalElement("PrimaryBChromaticityY", + mastering_metadata.primary_b_chromaticity_y); + PrintOptionalElement("WhitePointChromaticityX", + mastering_metadata.white_point_chromaticity_x); + PrintOptionalElement("WhitePointChromaticityY", + mastering_metadata.white_point_chromaticity_y); + PrintOptionalElement("LuminanceMax", mastering_metadata.luminance_max); + PrintOptionalElement("LuminanceMin", mastering_metadata.luminance_min); + } + + void PrintMasterElement(const Projection& projection) { + PrintMandatoryElement("ProjectionType", projection.type); + PrintOptionalElement("ProjectionPrivate", projection.projection_private); + PrintMandatoryElement("ProjectionPoseYaw", projection.pose_yaw); + PrintMandatoryElement("ProjectionPosePitch", projection.pose_pitch); + PrintMandatoryElement("ProjectionPoseRoll", projection.pose_roll); + } + + void PrintMasterElement(const Audio& audio) { + PrintMandatoryElement("SamplingFrequency", audio.sampling_frequency); + PrintOptionalElement("OutputSamplingFrequency", audio.output_frequency); + PrintMandatoryElement("Channels", audio.channels); + PrintOptionalElement("BitDepth", audio.bit_depth); + } + + void PrintMasterElement(const ContentEncodings& content_encodings) { + PrintMasterElement("ContentEncoding", content_encodings.encodings); + } + + void PrintMasterElement(const ContentEncoding& content_encoding) { + PrintMandatoryElement("ContentEncodingOrder", content_encoding.order); + PrintMandatoryElement("ContentEncodingScope", content_encoding.scope); + PrintMandatoryElement("ContentEncodingType", content_encoding.type); + PrintMasterElement("ContentEncryption", content_encoding.encryption); + } + + void PrintMasterElement(const ContentEncryption& content_encryption) { + PrintOptionalElement("ContentEncAlgo", content_encryption.algorithm); + PrintOptionalElement("ContentEncKeyID", content_encryption.key_id); + PrintMasterElement("ContentEncAESSettings", + content_encryption.aes_settings); + } + + void PrintMasterElement( + const ContentEncAesSettings& content_enc_aes_settings) { + PrintMandatoryElement("AESSettingsCipherMode", + content_enc_aes_settings.aes_settings_cipher_mode); + } + + void PrintMasterElement(const CueTrackPositions& cue_track_positions) { + PrintMandatoryElement("CueTrack", cue_track_positions.track); + PrintMandatoryElement("CueClusterPosition", + cue_track_positions.cluster_position); + PrintOptionalElement("CueRelativePosition", + cue_track_positions.relative_position); + PrintOptionalElement("CueDuration", cue_track_positions.duration); + PrintOptionalElement("CueBlockNumber", cue_track_positions.block_number); + } + + void PrintMasterElement(const ChapterAtom& chapter_atom) { + PrintMandatoryElement("ChapterUID", chapter_atom.uid); + PrintOptionalElement("ChapterStringUID", chapter_atom.string_uid); + PrintMandatoryElement("ChapterTimeStart", chapter_atom.time_start); + PrintOptionalElement("ChapterTimeEnd", chapter_atom.time_end); + PrintMasterElement("ChapterDisplay", chapter_atom.displays); + PrintMasterElement("ChapterAtom", chapter_atom.atoms); + } + + void PrintMasterElement(const ChapterDisplay& chapter_display) { + PrintMandatoryElement("ChapString", chapter_display.string); + PrintMandatoryElement("ChapLanguage", chapter_display.languages); + PrintOptionalElement("ChapCountry", chapter_display.countries); + } + + void PrintMasterElement(const Targets& targets) { + PrintOptionalElement("TargetTypeValue", targets.type_value); + PrintOptionalElement("TargetType", targets.type); + PrintMandatoryElement("TagTrackUID", targets.track_uids); + } + + void PrintMasterElement(const SimpleTag& simple_tag) { + PrintMandatoryElement("TagName", simple_tag.name); + PrintMandatoryElement("TagLanguage", simple_tag.language); + PrintMandatoryElement("TagDefault", simple_tag.is_default); + PrintOptionalElement("TagString", simple_tag.string); + PrintOptionalElement("TagBinary", simple_tag.binary); + PrintMasterElement("SimpleTag", simple_tag.tags); + } + + // When printing a master element that's wrapped in Element<>, peel off the + // Element<> wrapper and print the underlying master element if it's present. + template + void PrintMasterElement(const std::string& name, const Element& element) { + if (element.is_present()) { + std::cout << std::string(indent * spaces_per_indent, ' ') << name << "\n"; + ++indent; + PrintMasterElement(element.value()); + --indent; + } + } + + template + void PrintMasterElement(const std::string& name, + const std::vector>& elements) { + for (const Element& element : elements) { + PrintMasterElement(name, element); + } + } + + template + void PrintValue(const std::string& name, const T& value) { + std::cout << std::string(indent * spaces_per_indent, ' ') << name << ": " + << value << '\n'; + } + + Status OnElementBegin(const ElementMetadata& metadata, + Action* action) override { + // Print out metadata for some level 1 elements that don't have explicit + // callbacks. + switch (metadata.id) { + case Id::kSeekHead: + indent = 1; + PrintElementMetadata("SeekHead", metadata); + break; + case Id::kTracks: + indent = 1; + PrintElementMetadata("Tracks", metadata); + break; + case Id::kCues: + indent = 1; + PrintElementMetadata("Cues", metadata); + break; + case Id::kChapters: + indent = 1; + PrintElementMetadata("Chapters", metadata); + break; + case Id::kTags: + indent = 1; + PrintElementMetadata("Tags", metadata); + break; + default: + break; + } + + *action = Action::kRead; + return Status(Status::kOkCompleted); + } + + Status OnUnknownElement(const ElementMetadata& metadata, Reader* reader, + std::uint64_t* bytes_remaining) override { + // Output unknown elements without any indentation because we aren't + // tracking which element contains them. + int original_indent = indent; + indent = 0; + PrintElementMetadata("UNKNOWN_ELEMENT!", metadata); + indent = original_indent; + // The base class's implementation will just skip the element via + // Reader::Skip(). + return Callback::OnUnknownElement(metadata, reader, bytes_remaining); + } + + Status OnEbml(const ElementMetadata& metadata, const Ebml& ebml) override { + indent = 0; + PrintElementMetadata("EBML", metadata); + indent = 1; + PrintMandatoryElement("EBMLVersion", ebml.ebml_version); + PrintMandatoryElement("EBMLReadVersion", ebml.ebml_read_version); + PrintMandatoryElement("EBMLMaxIDLength", ebml.ebml_max_id_length); + PrintMandatoryElement("EBMLMaxSizeLength", ebml.ebml_max_size_length); + PrintMandatoryElement("DocType", ebml.doc_type); + PrintMandatoryElement("DocTypeVersion", ebml.doc_type_version); + PrintMandatoryElement("DocTypeReadVersion", ebml.doc_type_read_version); + return Status(Status::kOkCompleted); + } + + Status OnVoid(const ElementMetadata& metadata, Reader* reader, + std::uint64_t* bytes_remaining) override { + // Output Void elements without any indentation because we aren't tracking + // which element contains them. + int original_indent = indent; + indent = 0; + PrintElementMetadata("Void", metadata); + indent = original_indent; + // The base class's implementation will just skip the element via + // Reader::Skip(). + return Callback::OnVoid(metadata, reader, bytes_remaining); + } + + Status OnSegmentBegin(const ElementMetadata& metadata, + Action* action) override { + indent = 0; + PrintElementMetadata("Segment", metadata); + indent = 1; + *action = Action::kRead; + return Status(Status::kOkCompleted); + } + + Status OnSeek(const ElementMetadata& metadata, const Seek& seek) override { + indent = 2; + PrintElementMetadata("Seek", metadata); + indent = 3; + PrintMandatoryElement("SeekID", seek.id); + PrintMandatoryElement("SeekPosition", seek.position); + return Status(Status::kOkCompleted); + } + + Status OnInfo(const ElementMetadata& metadata, const Info& info) override { + indent = 1; + PrintElementMetadata("Info", metadata); + indent = 2; + PrintMandatoryElement("TimecodeScale", info.timecode_scale); + PrintOptionalElement("Duration", info.duration); + PrintOptionalElement("DateUTC", info.date_utc); + PrintOptionalElement("Title", info.title); + PrintOptionalElement("MuxingApp", info.muxing_app); + PrintOptionalElement("WritingApp", info.writing_app); + return Status(Status::kOkCompleted); + } + + Status OnClusterBegin(const ElementMetadata& metadata, const Cluster& cluster, + Action* action) override { + indent = 1; + PrintElementMetadata("Cluster", metadata); + // A properly muxed file will have Timecode and PrevSize first before any + // SimpleBlock or BlockGroups. The parser takes advantage of this and delays + // calling OnClusterBegin() until it hits the first SimpleBlock or + // BlockGroup child (or the Cluster ends if it's empty). It's possible for + // an improperly muxed file to have Timecode or PrevSize after the first + // block, in which case they'll be absent here and may be accessed in + // OnClusterEnd() when the Cluster and all its children have been fully + // parsed. In this demo we assume the file has been properly muxed. + indent = 2; + PrintMandatoryElement("Timecode", cluster.timecode); + PrintOptionalElement("PrevSize", cluster.previous_size); + *action = Action::kRead; + return Status(Status::kOkCompleted); + } + + Status OnSimpleBlockBegin(const ElementMetadata& metadata, + const SimpleBlock& simple_block, + Action* action) override { + indent = 2; + PrintElementMetadata("SimpleBlock", metadata); + indent = 3; + PrintValue("track number", simple_block.track_number); + PrintValue("frames", simple_block.num_frames); + PrintValue("timecode", simple_block.timecode); + PrintValue("lacing", simple_block.lacing); + std::string flags = (simple_block.is_visible) ? "visible" : "invisible"; + if (simple_block.is_key_frame) + flags += ", key frame"; + if (simple_block.is_discardable) + flags += ", discardable"; + PrintValue("flags", flags); + *action = Action::kRead; + return Status(Status::kOkCompleted); + } + + Status OnSimpleBlockEnd(const ElementMetadata& /* metadata */, + const SimpleBlock& /* simple_block */) override { + return Status(Status::kOkCompleted); + } + + Status OnBlockGroupBegin(const ElementMetadata& metadata, + Action* action) override { + indent = 2; + PrintElementMetadata("BlockGroup", metadata); + *action = Action::kRead; + return Status(Status::kOkCompleted); + } + + Status OnBlockBegin(const ElementMetadata& metadata, const Block& block, + Action* action) override { + indent = 3; + PrintElementMetadata("Block", metadata); + indent = 4; + PrintValue("track number", block.track_number); + PrintValue("frames", block.num_frames); + PrintValue("timecode", block.timecode); + PrintValue("lacing", block.lacing); + PrintValue("flags", (block.is_visible) ? "visible" : "invisible"); + *action = Action::kRead; + return Status(Status::kOkCompleted); + } + + Status OnBlockEnd(const ElementMetadata& /* metadata */, + const Block& /* block */) override { + return Status(Status::kOkCompleted); + } + + Status OnBlockGroupEnd(const ElementMetadata& /* metadata */, + const BlockGroup& block_group) override { + if (block_group.virtual_block.is_present()) { + std::cout << std::string(indent * spaces_per_indent, ' ') + << "BlockVirtual\n"; + indent = 4; + PrintValue("track number", + block_group.virtual_block.value().track_number); + PrintValue("timecode", block_group.virtual_block.value().timecode); + } + indent = 3; + PrintMasterElement("BlockAdditions", block_group.additions); + PrintOptionalElement("BlockDuration", block_group.duration); + PrintOptionalElement("ReferenceBlock", block_group.references); + PrintOptionalElement("DiscardPadding", block_group.discard_padding); + PrintMasterElement("Slices", block_group.slices); + // BlockGroup::block has been set, but we've already printed it in + // OnBlockBegin(). + return Status(Status::kOkCompleted); + } + + Status OnFrame(const FrameMetadata& metadata, Reader* reader, + std::uint64_t* bytes_remaining) override { + PrintValue("frame byte range", + '[' + std::to_string(metadata.position) + ", " + + std::to_string(metadata.position + metadata.size) + ')'); + // The base class's implementation will just skip the frame via + // Reader::Skip(). + return Callback::OnFrame(metadata, reader, bytes_remaining); + } + + Status OnClusterEnd(const ElementMetadata& /* metadata */, + const Cluster& /* cluster */) override { + // The Cluster and all its children have been fully parsed at this point. If + // the file wasn't properly muxed and Timecode or PrevSize were missing in + // OnClusterBegin(), they'll be set here (if the Cluster contained them). In + // this demo we already handled them, though. + return Status(Status::kOkCompleted); + } + + Status OnTrackEntry(const ElementMetadata& metadata, + const TrackEntry& track_entry) override { + indent = 2; + PrintElementMetadata("TrackEntry", metadata); + indent = 3; + PrintMandatoryElement("TrackNumber", track_entry.track_number); + PrintMandatoryElement("TrackUID", track_entry.track_uid); + PrintMandatoryElement("TrackType", track_entry.track_type); + PrintMandatoryElement("FlagEnabled", track_entry.is_enabled); + PrintMandatoryElement("FlagDefault", track_entry.is_default); + PrintMandatoryElement("FlagForced", track_entry.is_forced); + PrintMandatoryElement("FlagLacing", track_entry.uses_lacing); + PrintOptionalElement("DefaultDuration", track_entry.default_duration); + PrintOptionalElement("Name", track_entry.name); + PrintOptionalElement("Language", track_entry.language); + PrintMandatoryElement("CodecID", track_entry.codec_id); + PrintOptionalElement("CodecPrivate", track_entry.codec_private); + PrintOptionalElement("CodecName", track_entry.codec_name); + PrintOptionalElement("CodecDelay", track_entry.codec_delay); + PrintMandatoryElement("SeekPreRoll", track_entry.seek_pre_roll); + PrintMasterElement("Video", track_entry.video); + PrintMasterElement("Audio", track_entry.audio); + PrintMasterElement("ContentEncodings", track_entry.content_encodings); + return Status(Status::kOkCompleted); + } + + Status OnCuePoint(const ElementMetadata& metadata, + const CuePoint& cue_point) override { + indent = 2; + PrintElementMetadata("CuePoint", metadata); + indent = 3; + PrintMandatoryElement("CueTime", cue_point.time); + PrintMasterElement("CueTrackPositions", cue_point.cue_track_positions); + return Status(Status::kOkCompleted); + } + + Status OnEditionEntry(const ElementMetadata& metadata, + const EditionEntry& edition_entry) override { + indent = 2; + PrintElementMetadata("EditionEntry", metadata); + indent = 3; + PrintMasterElement("ChapterAtom", edition_entry.atoms); + return Status(Status::kOkCompleted); + } + + Status OnTag(const ElementMetadata& metadata, const Tag& tag) override { + indent = 2; + PrintElementMetadata("Tag", metadata); + indent = 3; + PrintMasterElement("Targets", tag.targets); + PrintMasterElement("SimpleTag", tag.tags); + return Status(Status::kOkCompleted); + } + + Status OnSegmentEnd(const ElementMetadata& /* metadata */) override { + return Status(Status::kOkCompleted); + } +}; + +int main(int argc, char* argv[]) { + if ((argc != 1 && argc != 2) || + (argc == 2 && argv[1] == std::string("--help"))) { + std::cerr << "Usage:\n" + << argv[0] << " [path-to-webm-file]\n\n" + << "Prints info for the WebM file specified in the command line. " + "If no file is\n" + << "specified, stdin is used as input.\n"; + return EXIT_FAILURE; + } + + FILE* file = (argc == 2) ? std::fopen(argv[1], "rb") + : std::freopen(nullptr, "rb", stdin); + if (!file) { + std::cerr << "File cannot be opened\n"; + return EXIT_FAILURE; + } + + FileReader reader(file); + DemoCallback callback; + WebmParser parser; + Status status = parser.Feed(&callback, &reader); + if (!status.completed_ok()) { + std::cerr << "Parsing error; status code: " << status.code << '\n'; + return EXIT_FAILURE; + } + + return 0; +} diff --git a/src/sys/libwebm/webm_parser/doxygen.config b/src/sys/libwebm/webm_parser/doxygen.config new file mode 100644 index 0000000..f2aae8a --- /dev/null +++ b/src/sys/libwebm/webm_parser/doxygen.config @@ -0,0 +1,319 @@ +# Doxyfile 1.8.11 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "WebM Parser" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 2 +ALIASES = MatroskaID{1}="[\1](https://www.webmproject.org/docs/container/#\1) ([Matroska definition](https://matroska.org/technical/specs/index.html#\1))" \ + WebMID{1}="[\1](https://www.webmproject.org/docs/container/#\1)" \ + WebMTable{7}="| Type | Level | Mandatory | Multiple | Recursive | Value range | Default value |\n| ---- | ----- | --------- | -------- | --------- | ----------- | ------------- |\n| \1 | \2 | \3 | \4 | \5 | \6 | \7 |\n" +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = README.md include/webm +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = README.md +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/00805c2543756a5fd85652d03bfbbd2eb6192ca5 b/src/sys/libwebm/webm_parser/fuzzing/corpus/00805c2543756a5fd85652d03bfbbd2eb6192ca5 new file mode 100644 index 0000000..d78507e --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/00805c2543756a5fd85652d03bfbbd2eb6192ca5 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1�S�g�T�k���m��b@�P5�G�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/00d120eb143bb02c48d7c863e5826d2ad1a6da4b b/src/sys/libwebm/webm_parser/fuzzing/corpus/00d120eb143bb02c48d7c863e5826d2ad1a6da4b new file mode 100644 index 0000000..2d4403c --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/00d120eb143bb02c48d7c863e5826d2ad1a6da4b @@ -0,0 +1 @@ +S�g�T�k���c��! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/018dee8285e9e20ca3996bb2dc0284b5c57ba75a b/src/sys/libwebm/webm_parser/fuzzing/corpus/018dee8285e9e20ca3996bb2dc0284b5c57ba75a new file mode 100644 index 0000000..2920522 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/018dee8285e9e20ca3996bb2dc0284b5c57ba75a @@ -0,0 +1 @@ +S�g�C�u� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/020edb59637c1e6439f19aa3a5a9d50c3377dbe9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/020edb59637c1e6439f19aa3a5a9d50c3377dbe9 new file mode 100644 index 0000000..c194606 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/020edb59637c1e6439f19aa3a5a9d50c3377dbe9 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P3� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0247ce2b1a71752a3af11e1065ca90afa0df9d30 b/src/sys/libwebm/webm_parser/fuzzing/corpus/0247ce2b1a71752a3af11e1065ca90afa0df9d30 new file mode 100644 index 0000000..42b8525 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/0247ce2b1a71752a3af11e1065ca90afa0df9d30 @@ -0,0 +1 @@ +S�g�C�u������̃ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/028b19f7d79f5da7a2af13a0c1e2d13f7eaf24cd b/src/sys/libwebm/webm_parser/fuzzing/corpus/028b19f7d79f5da7a2af13a0c1e2d13f7eaf24cd new file mode 100644 index 0000000..863b42b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/028b19f7d79f5da7a2af13a0c1e2d13f7eaf24cd @@ -0,0 +1 @@ +S�g�T�k�ஈT���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/029ab55b16df41881f8de2351205201da334550a b/src/sys/libwebm/webm_parser/fuzzing/corpus/029ab55b16df41881f8de2351205201da334550a new file mode 100644 index 0000000..27523d4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/029ab55b16df41881f8de2351205201da334550a @@ -0,0 +1 @@ +S�g�C�p�E����VT�! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/029be5e90913b19cf5890559cf3f98aa909f0a84 b/src/sys/libwebm/webm_parser/fuzzing/corpus/029be5e90913b19cf5890559cf3f98aa909f0a84 new file mode 100644 index 0000000000000000000000000000000000000000..75abefb3957f55eaeabd6182c18423924b4f04b1 GIT binary patch literal 5 McmZ1^b>Ec%00zDR;Q#;t literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/02fb96539b84bbd12de84ff05cbc9dc3faa96b7e b/src/sys/libwebm/webm_parser/fuzzing/corpus/02fb96539b84bbd12de84ff05cbc9dc3faa96b7e new file mode 100644 index 0000000000000000000000000000000000000000..f6d373818e5f7363f27e6e530ef091b7b25b496f GIT binary patch literal 58 zcmYd3wPAyl>;1(YPVN%H4e1j^Jy)i6yF6kkPfg7Q3gl0fcivVy;kg4t*z}OZ4u-|8 OLMCAqv-ULJ`v3spz!`7= literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0349f5632d21faa36b85520ad0b524d561f5e13f b/src/sys/libwebm/webm_parser/fuzzing/corpus/0349f5632d21faa36b85520ad0b524d561f5e13f new file mode 100644 index 0000000000000000000000000000000000000000..f3df0a462649d7548105f209addcdec9b4f74954 GIT binary patch literal 35 ncmWGxaF7UYNS`4VvMzh_x{0|BeMt=etsGhc3>z7fz!Vbz>$nWt literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/036fc9daf7fb1b4274dd668cfd883248ebbad967 b/src/sys/libwebm/webm_parser/fuzzing/corpus/036fc9daf7fb1b4274dd668cfd883248ebbad967 new file mode 100644 index 0000000..5d97ec8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/036fc9daf7fb1b4274dd668cfd883248ebbad967 @@ -0,0 +1 @@ +S�g�S�k��������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/037a4edc18e475ec81081e47277cbf51f1316680 b/src/sys/libwebm/webm_parser/fuzzing/corpus/037a4edc18e475ec81081e47277cbf51f1316680 new file mode 100644 index 0000000000000000000000000000000000000000..3109c3157447173a710f49210c32c5c44db8712c GIT binary patch literal 20 bcmb0LZbHAapzrLGE55r07#P@t*8oXIMvzD^OeBQ?B*rA_ zxiYOo>-t7PkOCM7EF2o8?8wUobCI^=C)TCUe_QwBCt&L1?ni!ct#{C!c zon6xHySpQJbt7Z&nnos3&y{IgwXSazU|?Wmbm?sI?fZPlC9&f_6jZMSN-(DZ01E3x A761SM literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/056b83ab2457979ea021e7118ab847eba265df15 b/src/sys/libwebm/webm_parser/fuzzing/corpus/056b83ab2457979ea021e7118ab847eba265df15 new file mode 100644 index 0000000000000000000000000000000000000000..ef730c6298b5cbe6f82d56a9d68d675289cba7d4 GIT binary patch literal 36 rcmb0LZb;uC@4T&a^@5cPTbmdpg2Q$uN* literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/058326151c1d4a490964d495d35adcf15178030f b/src/sys/libwebm/webm_parser/fuzzing/corpus/058326151c1d4a490964d495d35adcf15178030f new file mode 100644 index 0000000000000000000000000000000000000000..e6d60cc489522cef25f4c6101e9e8a6ba892adda GIT binary patch literal 28 kcmb0LZb+XY6TCZn^6rV-`@cIde02EWz_7`IA-JLe0Jn$?dH?_b literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/05847b5be0eb200d6a6b340c939c7a654b55003e b/src/sys/libwebm/webm_parser/fuzzing/corpus/05847b5be0eb200d6a6b340c939c7a654b55003e new file mode 100644 index 0000000000000000000000000000000000000000..c9282128dc6d97d8f6bbefb765e49ed364694a6c GIT binary patch literal 33 ncmb0LZb+Xa6mmFydU5fTPkLwKg)iw062AH!`-SpP1>=-q_*-7HUj( PX>D&zOFz*96iWvHb?qCg literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/08af8d91bb21835c50330e997d973cac8ff67766 b/src/sys/libwebm/webm_parser/fuzzing/corpus/08af8d91bb21835c50330e997d973cac8ff67766 new file mode 100644 index 0000000000000000000000000000000000000000..7fab9be0b7740e7daa6403ec116145f28cbd83ad GIT binary patch literal 60 zcmb0LZb)A&@4T&a-hw#`TP1+JUa^pnMg|~Q#L&{nP+YvQVYUOqZwH3bb=e*3+8(ro OENa-$nA_*j@E-uqP8oCn literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0a18f05bb16402756202160225aec9c5a654f1ae b/src/sys/libwebm/webm_parser/fuzzing/corpus/0a18f05bb16402756202160225aec9c5a654f1ae new file mode 100644 index 0000000000000000000000000000000000000000..11f4d8c0ec2a6b05d4711f9ab457abd742f435be GIT binary patch literal 192 zcmb1gy}!7_smXz*JT)m-BDf*l;h3QB?2=yJ-2w~@?7?e*BqJk+2$QJi%Crux>l?w+ z$Q&kl=WV5J&%xpdCX-mmy6o~4^iY@5OI0?x||dR=z{*$nl2 Zz#>8+htnq)7X#V6$p?TWd&Vh{H~@H9GI#(0 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0b60823983971ee17a2590678f0fc0762c21bb73 b/src/sys/libwebm/webm_parser/fuzzing/corpus/0b60823983971ee17a2590678f0fc0762c21bb73 new file mode 100644 index 0000000000000000000000000000000000000000..14fc6def90c1d0ae325b7194eb13511d8bb32681 GIT binary patch literal 84 zcmb1gy}!7_smXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfuJ}ZDi1s(!&lI7#J3}HUUWn R<`*op9qutKZ~#(_OaNX;7l!}< literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0bae7f0976af0f75974047b5f2cf4c9645412066 b/src/sys/libwebm/webm_parser/fuzzing/corpus/0bae7f0976af0f75974047b5f2cf4c9645412066 new file mode 100644 index 0000000..beeec12 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/0bae7f0976af0f75974047b5f2cf4c9645412066 @@ -0,0 +1 @@ +S�g�C�p�E����ĀaT���������������́ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0c1862b4065eefab2535ecc6951295e38069a82e b/src/sys/libwebm/webm_parser/fuzzing/corpus/0c1862b4065eefab2535ecc6951295e38069a82e new file mode 100644 index 0000000000000000000000000000000000000000..95342c8b12d93c6a8958ae3ab785e7adc88050b5 GIT binary patch literal 79 zcmb1RXlQC`S`5T9nwnC9R8v#%Y7ohg0wRGl0|V3B|Bs(M30{5h$&-su+3R01G%zsi YW_ruO^!L(Dv{~Qe085phu0P~P1D*ylh literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0c2f51d5ffc69e69680bf3d6edb91d76c353ad14 b/src/sys/libwebm/webm_parser/fuzzing/corpus/0c2f51d5ffc69e69680bf3d6edb91d76c353ad14 new file mode 100644 index 0000000..f0ad094 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/0c2f51d5ffc69e69680bf3d6edb91d76c353ad14 @@ -0,0 +1 @@ +S�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0c3af72d69f18103383c9cd41a7f2676a9d28a40 b/src/sys/libwebm/webm_parser/fuzzing/corpus/0c3af72d69f18103383c9cd41a7f2676a9d28a40 new file mode 100644 index 0000000000000000000000000000000000000000..74f05504c850033d3b9513e85d34f4e5916be494 GIT binary patch literal 20 bcmb0LZbPE)kHH}Q7 zo-5O~YF*zbz`(%B=+fEZ+xPiUN@B--YLkG+a zAP045Z2>!oN#1#RZQFCOHjuv{OeV3Ab=lqPfTC>I!BS{^CXmazK~}PD2NDd70swuZ BUKaoW literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/0f5741483be8f4f6eddcb70ea418fb0c08da9443 b/src/sys/libwebm/webm_parser/fuzzing/corpus/0f5741483be8f4f6eddcb70ea418fb0c08da9443 new file mode 100644 index 0000000000000000000000000000000000000000..34838b0cbaec462c36272ce1b6f44553eea51688 GIT binary patch literal 20 bcmb0LZbZg+q6)mJ~Bx&P#PcY5d1>ldf1H>YFs z_^J61Ub|_Y{o6hb-n@3d58$N#XgCi3@ZvE%s=;4={>AgtvHdGiM#DucaWA0kB)88oJSrFz!-MArAd+7;<0>6 zVCC+%L*xTTbq5C`5{hN;J{lS5r1=8>efW z-d|+`*KqJa7C;+-V>-8ENg7^t>@3n+CDX%sOJWvaQgN!D&WW5+(pc%JOpl44Je`$O z`V3v4Oka&vibRA8%bFGwyCXQ|0JBWJYp`>ww^fQV>!LHL1Xfz5SP^(FEnpNKDYHnA z3NV*dicvC-C$+&JnLgKgNHbccNJ!{i2|9x)9<6gU5RT+CU9(xGSTj6gWZ)py&x3vc41)Qks0u^l_HrSun%3QXYG+M>mzgB z3|>pOjWi&pQOmJ3UMH_dY9L&au7~kqub>PS9xY(IEzi- zvho)2NDrg2uAN{rYw$TssID#LLmMsybB7o9dP_eX$tFizO2M;Akr|!sV*PM*Sw;k& z6YW%)gp)>QKyIY}D7znCfz_>7HNT(1i3bfO#WRAR23sCnnX#c|U2F$)D%oG!NLr>< zL8|mFBxYKsg}y1XOH^Z_U$zeYnd7F+gBc0ZsNvYwC7N!&8joZfkLBgpmTDzCH<8Iw ztyPoWT8?tSYNtc2UnI3nKntc?(X;RcxYah&bGQULZ_++T(3~-5GS16{Bd|DWWc&)M zrmD+IkuM?YLXIlGKZd$i50p_4q%+D=MoD{pkL*c456G)|FmK>udZ^y8Om4m53pNL* zm0AkKGv>tk+#9IaZ4TOpS?t3sju$#%O^48B2l6gBDdH4ze{%Z5>H(c5v@z1P%~eSe z>3IYP^2|bD!?92%Wvyd<9C{H>^UG+4);43%WsX}pRmG9D++IO*k$3p4AoDdfGg~&0 z`&+vhVLD%stLVhGDf`ZRfOM?kkt|&(3fni;YDOv&2UIOAp9|<6>}HU(QiZ$Wf&nm* zB1)dDF3&71n7r0)vavl5a9NYY2^ z<+Ib(V(i*MuDb@X=AJe8953{Ial^4X_f3Wo0j999tJ9>bYtgL}8b}<3;~G)PlX~Tu zr4-CK$o1->@|t_Hcei_={}E2_WpRt7xjicvRtAweWtF1b zIR#67c}BN>c(QL(F*q^*WC1s0Rx546JXnr} zmT5KKP2>{O10avod9q9kT})<|2<2OqY1uc`*uT16($(kJmTDzC_rxIEkOePnsg?)G zV0;41{CZ|^fE3UWcrV$pR108j>`>R|!BnfAR1u=WEd18G)6?GedEte%Cm3hnQ^M99 zduI?qB1OdO!E5bTqI(;Tc{rn-Ya!{trRDdVTr6T1xDL!>omU4!1014{f7ewHq%$ff zr=uB6v|=Cw!U88P`xeZHGL3F^0$Ok&@c3pX#j=(xqOww@!(_$k z1fp&urLk2}Lb65IusT5!1&M=mj{{~>=RVCXs7 z!(t60(gu%xX{0t2yl|@418<=D0`a|P?Zm(a-q5U#PQ-|o{lVk;slp17nsc-nlpHr@v g)v~TdIN$_y=WyMfnKT2}@mmAM*`M4V7IC=xALxY<`Tzg` literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/15366a3aafe2590c2e3183c088dde4cc100cb956 b/src/sys/libwebm/webm_parser/fuzzing/corpus/15366a3aafe2590c2e3183c088dde4cc100cb956 new file mode 100644 index 0000000..acb4e59 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/15366a3aafe2590c2e3183c088dde4cc100cb956 @@ -0,0 +1 @@ +S�g�C�p�E����sāVT�A�@�@B�@�@C�@sā�@sā�@sā�@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/15feeb939fa90b25f57622a0abd9155ca88ad08b b/src/sys/libwebm/webm_parser/fuzzing/corpus/15feeb939fa90b25f57622a0abd9155ca88ad08b new file mode 100644 index 0000000000000000000000000000000000000000..e8c0a654e695292780bc3e92b7f31b5fde8010b0 GIT binary patch literal 88 zcmb0LP7hhva7`?G-TCVZ3=G9bfkZP9?*!rwAP!x{z%U0$D?e^-2+jjCl(t$mv;pbl aML)ZY)%-&I`P4ip0FR|Ej=#3QW$ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/18fd762b91406d37b85a7b342a91434a15f17290 b/src/sys/libwebm/webm_parser/fuzzing/corpus/18fd762b91406d37b85a7b342a91434a15f17290 new file mode 100644 index 0000000000000000000000000000000000000000..26c44c98a73a43f7ceb0808aa1657bcdaa033740 GIT binary patch literal 25 hcmaFU5OSu$sZDF;JBD}f-nGAB5MW@iy7cbd8vwAQ4YvRQ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/19334eee05eeb18c549498e7ca2e792a2a4e04f3 b/src/sys/libwebm/webm_parser/fuzzing/corpus/19334eee05eeb18c549498e7ca2e792a2a4e04f3 new file mode 100644 index 0000000..cc25e67 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/19334eee05eeb18c549498e7ca2e792a2a4e04f3 @@ -0,0 +1 @@ +S�g�C�p�E������C|� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/1a9a5df35779dd6e9e1de171b9bb0d316d2b64a5 b/src/sys/libwebm/webm_parser/fuzzing/corpus/1a9a5df35779dd6e9e1de171b9bb0d316d2b64a5 new file mode 100644 index 0000000..7293974 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/1a9a5df35779dd6e9e1de171b9bb0d316d2b64a5 @@ -0,0 +1 @@ +S�g�T�k�����#��@� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/1ab3d30f60743c2a1d3043773aae3a04f83c07c0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/1ab3d30f60743c2a1d3043773aae3a04f83c07c0 new file mode 100644 index 0000000..9682a0f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/1ab3d30f60743c2a1d3043773aae3a04f83c07c0 @@ -0,0 +1 @@ +Sg��I��@D��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/1ad84ed46f3fda305150bac93958a5a390e23a67 b/src/sys/libwebm/webm_parser/fuzzing/corpus/1ad84ed46f3fda305150bac93958a5a390e23a67 new file mode 100644 index 0000000..7e0f66f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/1ad84ed46f3fda305150bac93958a5a390e23a67 @@ -0,0 +1 @@ +S�g�C�p�E�������@helloC|�lang0C|�area0C|�lang1C|�lang2C|�area1 \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/1b40a997150aa03c23ecc6efe445a2d7c3dd8368 b/src/sys/libwebm/webm_parser/fuzzing/corpus/1b40a997150aa03c23ecc6efe445a2d7c3dd8368 new file mode 100644 index 0000000000000000000000000000000000000000..b5d9ab5ff318fcd361ed0e8592579006a23cfcd7 GIT binary patch literal 17 Ycmb0LZb{V0RgK(0RpXp0EGYm0H8n+ Lb)o;J|L#BmEzK0U literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/1bb8f5f81b7f6c1d58e1f7bb13fa561fe1a146bc b/src/sys/libwebm/webm_parser/fuzzing/corpus/1bb8f5f81b7f6c1d58e1f7bb13fa561fe1a146bc new file mode 100644 index 0000000..b3204bc --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/1bb8f5f81b7f6c1d58e1f7bb13fa561fe1a146bc @@ -0,0 +1 @@ +S�g�C�u���u����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/1c56068c6dd17e9a824db6da78d64f933267a8c0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/1c56068c6dd17e9a824db6da78d64f933267a8c0 new file mode 100644 index 0000000..bd3b28e --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/1c56068c6dd17e9a824db6da78d64f933267a8c0 @@ -0,0 +1 @@ +S�g�T�g�ss�c��hg� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/1c8db8b9d88dd3483b6f81e4224c4f985046e6ac b/src/sys/libwebm/webm_parser/fuzzing/corpus/1c8db8b9d88dd3483b6f81e4224c4f985046e6ac new file mode 100644 index 0000000000000000000000000000000000000000..57d98442b6c5f48f3adbed433baffd83cd40fcde GIT binary patch literal 85 zcmb0LZb-i%7P2n;^tzJ|j?YqHU=uI6)Wa0Byh)nnFXU3l>lvDnofN zhLTWJ9Qh3e@C81>JIIFT@EGnx8r*=Za1j#V6dZ#?5DmLwJ8Xt9SOY6y2?WAimZyUZx{n3U?8RlyX>L1`!s1|sGce1rcW z7v924cnTSC4{pIVNP-J+22MaM9E82F6Cz*}tbFavyHB6z_laEHOrA9{lmbb$`g25g}zG=#cf0o9>0lm}xd z2}Q+$-%tQw;1j%qY=m>40CD=eCs0X#c9I8MC_#2F%nAraZen39_3-94IWWf`70Cyl2 zlHn4ZgLpU&hhaZN!4B908z2-`!ctfW0Wb@u!6fj8F)#v#fGhNcp3oH>pdGY=W?&8V zp*H*jW>68zLMbqWA|m=He1$yt0B_(0WWqzZ3pXJJF2i{^4RLS;4!|CWgsrd<)fQxBzG11jNEY*b6%$0ye=qSOvkb80N!l@PjEZ0mgy{41+u?1U;VhhlqYwl8 zU>9tIa99tkVL1fB0+<6cz!xTh7mNaT7!3WPH#k8T=m2fN7Memss0$WQ9V$b4Fou#) zRP6Z;1@Hwv!8^!?=kOTrLmJ$Gt8ft#;1nE#Ll6zSVLNPwFjxaCUNAQ#@k zOLz(ya1U<5HAsRBa0X65EF6TruoEI+6Rd+(5Dbf9KFkI`m;w`EEO@{$7zF*m8M;Gf zXb*PK0-8Vru!NdW4Jv^Nlz|fPm)Kbd-{CWSgdBJU&)^ZH!)>?@S0EA2!bvy^F|ZGI z!8Qno^{^V2Ll7*0IWPl!VIp|JC~$|t&>wn(6Lf(N&<1RwDKvz-U;)*kGL#2nC<#SH zeBXoqe&=PE*5!8cPU=CHF0{jg|P)zLj13w@i{)PAO8nWOCJb*ip3dwK@ z&OtmJhr_TRqF@JXfejD}D`6=tgaDWY(_j*K!x$I=L%K+%*h6b*4voPI>Oc*s3Z_sFN<(ol5ZiviH~0^7;Vry` zr;q{n;1*niB)9-)-~`0NLD&mBAp$nRI#>n4uo&jUZ196AFagGb2MmKj&<~uUJ9LKj zUO!3#!#I}C>Y&>Nhf3v_@sU<*y5A=Cv6s1B8(JQzbsC@Qx8 zh64BkpWq#2!*h5H_aO~#z*V>i32+LI!6Ar--LM@tLl~@q6|e*XVJ^&sso(?SU^EN| zHy8kYpa(cYM`#Nz!3G*ZJ*WldPz5T$-(UpA#Fjts1M=Ztcn_~33!cCOxC5z>442>> z#KUno4ErGpcEA?c0HLrFmcl{^fLSmNCV@AMfe|nST%j-Ygs$KK?VuGj18b-cwc#Hy zgNjfVN`WC15u1O)SIC18@CIH$COm|@a1&DCGMtCg5C=!#0PKNC*a{nAErh@_SOoLH zAEv`(7!RH>5{AM+aDiUX4LX56w1(!;7_6WU)PSmB3gw_Q6bAzl{tLdre~=4r;UzqU z47dlk;2I>s1vmpIAQle7Uf2l{unE?|DhP(fFdt@vA54J>Fcv&u7z~1b;0)cNGqeXg zXaP;20a!v!s0Nk51j;}O_)BamgzxYfK0*$>f@kmu(&08-hbxc>XW=9qg&5ceyI>oH z!+KZ^%OMCBz#NzXzAzEIU=+B+VCWCM!3nxR2WSJf&=eX%U9f=aP#MaDF_eU&V&iWp zfG_X~-a$4zhsSUq(%=SMg^Q2?r{EYIf@s(c+hH?=!5UZrOCS*D!c3S7J}?eO!*Fne z0ni6}fFpE-w$Ku6pb^xAT3`-UpaT32Mo>&__ya#6AO3~+@EWq<2|R#1kP69g3C=-0 z9EZcOAEICfY=I3B3M*kLEQA1<1=C;>c*7VN0YktQ`a)0W3J%Z?T0t|ghWbz&{sA+n z2xXxZ7(x*d_7lEB9(;f|@B%X7A>4(VkOG(CJe-C&I06S?4@AON*a&MO1eU=fm67u1$CeXR0UHg2c@An7>M=1;2Zo0x$qWV!c)kA zdvFV`K@wbmGjIZ8;UMgVoe%+=U>&T2U|0G!2^cDAm|6q&>cEMd$5BR z&;%NQCDep!Pzg++43vPs#JWQG4xiy8eZo_rB0*P=IPQp=$fqk$Gwm~?o zht;qgf?xs6ff?Wn6Tu5cfjbO_{?HqopbK<>Hed@)p&`@-3#bm2p*$EvNhm7T{)Phh z0-xX=WW#fK4EG@oZopNz2nlcsj=>>_hTX6oHbWS!ffcX>0%0!9gsI>I<6txl2R9f1 zeV_+8LPux|Ex`sFK|QDi=1>JHz~5j5#YE^I_yPIwFT97>kOfcR0o;L9NQO&r4&vcB z9ESZ61v_91Y=BT$2}@xi1i&nq29v-W#=r;|0(dO}xlfOgOdnt?UchuZKDm_bD- z3#GsiiikBo;Vb092Y3T7AQK+KUAPG;a2d|SX^4X(Z~*o|By5F^uogmK87zW%;1APb zGK>dL7zsmRAhFR7e&7tQEWVgE5qZq9Wus6u=kw z1n(dlp2K6f4{2}%uEIq~fKzY`4nZ{RhV8H!!e9-ofF%$Jb73Y-1s@m(qhUC>!2sw3 zJ-`tkPrXDdw305@B|*f9Y}>_xCG}Q9*)Cd z*bh;#1Gc~h2!)lf6c$1N%z|k!3A|wpjDR8F3Vop`bOi@!2d$tPSVMiN4gY`{RD`ln z3Jjr$Sn(6SLLPj8H}C>7;UV0Gn~(yR;XIs%I5+|aU=KvXR@ew@Aq1AeBA5sMFdZht zc<_XgFcb!Y3-p3+&oLx1QEPS6E9KpU`yrqB@Tf(2BE%1|DRp(GR)%YH)ve1T8! z4zl4nJcj#_1~=d;T!aKT1;^kJM8j^_4x1qi*1!r_0)a3WX2MkPfpIVzhJzanfIiRz z9HAq$g_d9gji4UX0&}PW72t0$f?{InANT?J@GrcF*N_EI-~rr$R7i$Pa1P?(I2?xk z5CuD63v7T;SP4sEAq2oIm) z5Q>N;KjACn!3TH)FCY^h!dPiedEgJzVKR&d zPZ$Y9VIa6bFX#rHz#dvdb7%}!PzP#2RWOBeP#TJZfe88q-{3#Ug}3k$otGcG!(x~Zv%wFhzyufz9xx0BK|gSY?$8<9gB`ShCeQ#Z zp(a#=N?-zIpalFS78k;I_zWK*2VTK5cm(Ni8?M6@NQAR+5{^O)?1Npf4Z>kPtcK+f z1Pfpe%m81Q2wpG>++i^Ehu+`>U7!QB0b6Ja4WTYrKy|1L<-r(ALQ%2kHx$4Z_yq4D z8=k{sxDRP?1FphFNPtst3=Tmw?1t^I8Ny%On0qhbmA3{sto`CKmpIACM3K!h3iPS?~lNz#T}1WVi(9ARdmxVb~8* zumiTh1_*_fuoMEUUW3YlcPy?!hDU^fKP#g@zf?x0r{)1e23oqd*WWYVR1=k=6 zF2ET$0kLop_QFnxfK9LtRzWZVgGShssbMjG-hH74v>W0epc^@D8%! zIXs5@kOnv4DqMsFI0eVx5Jban*bbW^4A#I3SOS4C7iPj#@PTnK8is=#41hk+1010v zw1t*n1C5{_)By(qXa&u{8tOxB_y^3OB9w(vUfL5$c4A?5}rZ^+=E+i4U*sj zoPiS%3kP8@?1Tu|1nXcG1jAyO53|7!roaRk3mz~G20=e?hVIZA+JhamfF{rYETJY; zgGyimWuOH7C1w}GclZn+AqQT;Gk65)a2u|}6-b1$a1xF}4D5qlunodtJ*jDyiI9Nb_4^no7W2pyp< zv;-Sy1ofa6m_rq)0DprK6ce-lzz@iWf8jm6hAemj58w`@LNZ)}a}W>5;V|rnDA)m8 zU;~80N>~aDApmB`P(oh@>#Ef6?4gP~%cndG#DP+JsxCPfB2`<1H zI03P65ca}Oh=5J74pu=hEQa|o8~k7jOn|ZA0mEPr^aE$;4xOPr*g*?u0u8_tYC<)r z1SU`hO2A*juMob&XZQ#?@Cu&6BS?qaa2>8dBAkVja1>%-AMAo{5Dx2MH7ti9SO9Zi z2Kd56@Pbj`4uhdT^adyB0v(_Y*g{ii2z9{%szYTc55`auii+vKp#Z+XCwK?h@Ejh) zeMo~Fa1|~>0-SSSLh2pp({8*J7@*Xz#8g9ZTJVwpdyroQeX&0#MGbg z74qN%ynz>x2@l~e+=LXk4CmoA#K93b0DB-3w!%hO3n8!!7QsC5hv_gG#)Bt}grP7H zT%Z?pgHB)%t)V$I1}mroHJ~b(LOCc6#lb-M{(^7tALPPYcnMD-1Ma~sxCTjZ0nWe) zh=qf&7j{AfY=U*L3W8xV%!k?F2UB1Ij0F!E27{m?8RlyX>L1`!s24dnb_y+$$F1&@8@DwuO9^8U!kOUXt44i;i zI0$=TCq%#|SO=>h7#72Pm<@g~1t!2)@PJ`32>O9DbcfE+9_*k6G=TIaGlP@HZGiG2#6Oen39_3-94IWWf`70Cyl2lHn4ZgLpU&hhaZN!4B908z2-` z!ctfW0Wb@u!6fj8F)#v#fGhNcp3oH>pdGY=W?&8Vp*H*jW>68zLMbqWB4XT6_zHRO z0p7q1$b^S*7j8ldT!!;-8sgvx9DqF#30q+!tc4I*28&=G_``IV4CBEQM#4}S2rkeI zx8iN(off`U1Oraco#ynewq_z!a7Exd%MkOBAL7F>fQxBzG11jNEY z*b6%$0ye=qSOvkb80N!l@PjEZ0mgy{41+u?1U;VhhlqYwl8U>9tIa99tkVL1fB0+<6cz!xTh z7mNaT7!3WPH#k8T=m2fN7Memss0$WQ9V$b4Fou#)RCxY|0{8--;2mVcb9fB*Aq{T8 zRk#QVa0-sWA&7?EupKr-7_5O6uml2OF3g0f-~;1eGzNAQ#@kOLz(ya1U<5HAsRBa0X65EF6Tr zuoEI+6Rd+(5Dbf9KFkI`m;w`EEO@{$7zF*m8M;GfXb*PK0-8Vru!NdW4Jv^Nlz|fP zm+&Zr@9-HuLJquwXYdHp;Wk`{E073h;UpY|7}y89U>k(PdRPt1AqW=09GC&VFcG|9 z6u84+=nuWY3A#WBXaly;6dFQZuz>1N8Onn(l!T&UeBXoqe&=PE*5!8cP zU=CHF0{jg|P)v;Y13w@i{)PAO8nWOCJb*ip3dwK@&OtmJhr_TRqF@JXfejD}D`6=t zgaDWY(_j*K!x$I=L%K+% z*h6b*4voPI>Oc*s3Z_sFN<(ol5bnR=8~g{k@D^UeQ^O!3#!# zI}C>Y&>Nhf3v_@sU<*y5A=Cv6s1B8(JQzbsC@O~jh64BkpWq#2!*h5H_aO~#z*V>i z32+LI!6Ar--LM@tLl~@q6|e*XVJ^&sso(?SU^EN|Hy8kYpa(cYM`#Nz!3G*ZJ*Wld zPz5T$-(UpA#E?Jm1M=Ztcn_~33!cCOxC5z>442>>#KUno4ErGpcEA?c0HLrFmcl{^ zfLSmNCV@AMfe|nST%j-Ygs$KK?VuGj18b-cwc#HygNjfVN`WC15pF->E9AikcmppW z6CT1{xCtq68P3CLh=U_=0QNv6Y=w=m7D8YdEP{F957S{Xj0aB`2}5BZxIi!H2A#kj zT0?Va3|3GFYCu&mg>q0Dii3d|{0qLpe~=4r;UzqU47dlk;2I>s1vmpIAQle7Uf2l{ zunE?|DhP(fFdt@vA54J>Fcv&u7z~1b;0)cNGqeXgXaP;20a!v!s0Nk51j;}O_)82b zgzxYfK0*$>f@kmu(&08-hbxc>XW=9qg&5ceyI>oH!+KZ^%OMCBz#NzXzAzEIU=+B+ zVCWCM!3nxR2WSJf&=eX%U9f=aP#MaDF_eU&V&HEmfG_X~-a$4zhsSUq(%=SMg^Q2? zr{EYIf@s(c+hH?=!5UZrOCS*D!c3S7J}?eO!*Fne0ni6}fFpE-w$Ku6pb^xAT3`-U zpaT32Mo>(+{(&Em5C6h@cnw+b1RlU0NQGp$1m_?gj>BQt4^glKw!j7mg_W=r7D52b zf@v@bykQKCfFa-teW53G1qWyct)LlLLw%?X|9}}(gtAZy455e^@Dsj59(;f|@B%X7 zA>4(VkOG(CJe-C&I06S?4@AON*a&MO1eU=fm67u1$CeXR0UHg2c@An7>NGA;2Zo0x$qWV!c)kAdvFV`K@wbmGjIZ8;UMgVoe%+= zU>&T2U|0G!2^cDAm|6q&>cEMd$5BR&;%NQCDep!Pzg++43vPsM887# z4xiy8eZo_rB0*P=IPQp=$fqk$Gwm~?oht;qgf?xs6ff?Wn6Tu5cfjbO_ z{?HqopbK<>Hed@)p&`@-3#bm2p*$EvNhm5@enSC#flu%bvf(*AhWn5PH{dEkOfcR0o;L9NQO&r4&vcB9ESZ61v_91Y=BT$2}@xi1i&nq z29v-W#=r;|0(dO}xlfOgOdnt?UchuZKDm_bD-3#Gsiiikcx;Vb092Y3T7AQK+K zUAPG;a2d|SX^4X(Z~*o|By5F^uogmK87zW%;1APbGK>dL7zsmRAhFR7e&7t!2sw3J-`t_xCG}Q9*)Cd*bh;#1Gc~h2!)lf6c$1N%z|k! z3A|wpjDR8F3Vop`bOi@!2d$tPSVMiN4gY`{RD`ln3Jjr$=7;UV0G zn~(yR;XIs%I5+|aU=KvXR@ew@Aq1AeBA5sMFdZhtc<_XgFcb!Y3-p3+&oLx1QE zPS6E9KpU`yrqB@Tf(2BE%1|DRp(GR)-F`y>e1T8!4zl4nJcj#_1~=d;T!aKT1;^kJ zM8j^_4x1qi*1!r_0)a3WX2MkPfpIVzhJzanfIiRz9HAq$g_d9gji4UX0&}PW72t0$ zf?}fUANT?J@GrcF*N_EI-~rr$R7i$Pa1P?(I2?xk5CuD63v7T;SP4sEAq2oIm)5Q+%LpYRp(-~+sY7mx`L;V#^S z6u1oM;WWg-5jX&QAQHC1Mpz3WunZQ#Jn)C!Cya!lFc4gz7j%P8U=OXKIWz_< zr~@^iDwsk!C=JEIKy>*9-{3#Ug}3k$otGcG z!(x~Zv%wFhzyufz9xx0BK|gSY?$8<9gB`ShCeQ#Zp(a#=N?-zIpalFSIv2us_zWK* z2VTK5cm(Ni8?M6@NQAR+5{^O)?1Npf4Z>kPtcK+f1Pfpe%m81Q2wpG>++i^Ehu+`> zU7!QB0b6Ja4WTYrKy|1L<-r(ALQ&D_Hx$4Z_yq4D8=k{sxDRP?1FphFNPtst3=Tmw z?1t^I8Ny%On0qhbmA3{sto` zCLI3256Fjq;XS;DEO-JB;0~lhGF*al5D&-UFzkmY*a2H$1BAj#SPBav0A|57m;~N1 z21dXTaD~3m6S{%}w1ZaA46LC()P{e+3@SodCEUUW3Ylc zPy?!hDU^fKP#g@rlKKBXzd-5!^R<6|uF6r_O81|y{qr+ax=K^J|9tJApQI91f{It# zKR;H*sAv_Xw10kt3Rht&RB8YGU=^eSReWvMKbxiV9x%0w9}BW0)zyprb?ssfd-@>H(MQQ0a>WvUF7uF_PhN>NEF zQ6;E&6{liVjEYuKDpEzLa22LPRfq~!K`KxMD1YUre3g&#R-Vd3xhps2s$7(_a#D`U zLD?%iWvgtIwX#x{%0ihdGi9nwl(8~WhRVPzIiOG#sC<>Da#fDXR#_@jWvFzOrczak zN>Yg`LB*>$6{})Yw2D%ZDnf;;FcqpoRImzCfhs`xD?jC{e3ZBHR36G*xhYrWqMVhJ za#Rk=UfC&IWuvT>m9kV8%3PT#Q)Qxzm60-3242Z?3sr&2S9vN|<*00xr7~59N>^zr zRi&sTm8cR_yoyt?Dn>=CC>5z9RJaOLp(;cLs~{Dq0+heCwmUAZY& z<)WOGlX6rJ%3j$iTV5vQ=uwE1*;$xr~;I~@>9ObM|mqx<)Pe_ zn{rhy%2_!nN9CaGm7TIxHp*IADNALc%$1okRVK<<87V_$;FauOs0viR%2T;2M`f!l zm8mjRx=K^2Dn%u!M3tc8Rh)`dF)CU`sYn%}!c~|GRUs-^1*t$4p!}7e@>M>{TX`xE z<*wY6t8!7!%1JpY2W7A9l&!K+*2+p*Dhp+<%#^7zQO3$h87c#>#qJmYB3RD5gU->Ct<)gfn zr}9wl%1yZ{7v-#+l%sM`_R3D#DjQ|3tdym)Q0B@^nJN=ytc;YQGVn^CS*QwBzRFX% zDo16jES0G;RJux2sVYS!sYI2a;#HiARWT}BMX5*?p~6*|3RNL0SOuv-6`=f;pYl~c z%3FCV59O}hl&f-4&dNzSDhFk+?3AstQP#>zSt<)vujCnpszBwd zJe8|*RJO`enJPo2t2C9WQdE*kR0%3x#i>{oqoP%mic}FQT!pDn6{3PwkP1`*%3t{@ zU*)5`m8bGh?#fNMDi`IfoRp(-Q1;4B*(w`lt*n%#vQXyAOqnVZWvq;pp)&AF_A68c zDqrQPT$Q7;RhG(B87f_+sZ^Dsl2oEfQ1L2G#i|$;t)f(EzS9Z!)*(hser7V?&GFN8GRGBDaWuy$1fmibM zLRFyhRi4UKIVxLasZ5oj(p8#DRVgY-C8`7!ui{j!ic!%jN=2#&6|TZms0vZRDo6#Y z0Ohazl&|tp-pW&XD0k(iT$PJ*R!+)MIVgK&r)-stvQ}2gQduZ-Wu{D(i85A3%1{}2 zB~L3<1u9?Vsa%z#vQ?JKR2eE=rKwbvqLNgiN>K4CPQ|Ji6|JIFq>51CDoll{5EZO~ zRGo4JDj(&oJe7xXS8mExxhQAlq#TulvR8J>R@o?PWu+{Yg)&!W%2b&sV`Zca zm4R3C)IwFD@>QP7RXHkKWvNV+q0&{FN>wQ;NhPWT6|dq{tcp?5DoRDF2oH(MQQ0a>WvUF7uF_PhN>NEFQ6;E&6{liVjEYuKDpEzLa22LP zRfq~!K`KxMD1YUre3g&#R-Vd3xhps2s$7(_a#D`ULD?%iWvgtIwX#x{%0ihdGi9nw zl(8~WhRVPzc}k%wQ28oP<*FQ&t+G_6%24SlO{J<7m823?f{IshDptj)XceU*RfGyx zVJcLGs9+VO0#$(WSANP@`6zGYsXUasa#OC#ML8=c<)|E#y|Pob%0^i$D`lxHl({lf zrpiPaDzr+k%<@>ZV8L%AzA<*HnivvN|7%0byHJ7ueEl(n)_mdZkz zD>G%POq8)QQijUFD|u3(Dp2_hP!SNSM!<*7WByK+;m%0)RVC*`Odl)bW3w#r6XD=THG zER?x2Q>My987m`Ys0_T4eF{~9%2#5vQ=uwE1*;$xr~;I~@>9ObM|mqx<)Pe_n{rhy%2_!nN9CaGm7TIxHp*IA zDNALc%$1okRVK<<87V_$;FUbFP!*_rm8Wu5j>=Y9DpO^sbd{!3RfQjsb`g{v?XszOw-3Q~b8K=~^_<*R&@xAIgT%3ZlBSLLFdm6LK*4$5BHDO+Wu ztd*6rR2IrynJH6cqKuW1GE@d$$rB1yfy!5TDp%#GY?Y-lRfbAeX)0Bvs3euB5>&j3 zQ?V*WMXM+ksUlRk3R9sfLUUdi5tszBwdJe8|*RJO`enJPo2t2C9WQdE*k zR0%3x#i>{oqoP%mic}FQT!pDn6{3PwkP1`*%3t{@U*)5`m8bGh?#fNMDi`IfoRp(- zQ1;4B*(w`lt*n%#vQXyAOqnVZWvq;pp)&AF9#^OeRKChnxhh9xt1OkNGE}-sQ>iLN zC8{+M^RKChnxhh9xt1OkN zGE}-sQ>iLNC8cRs!~*vN>m9dUd5?c6{Dh6l!{alDqMxBP!*zrRgel)0m@(bDPQHIyp^Z& zQ0~f2xhfasteljia!~flPT49OWv#4~rLs`w%1oIm6J@N7l%X>4N*-OP3RJ$zQ@JWf zWveWesWMc$N>iySMJ1_3m7wBPoQhR3Dq2OUNEM;NRhSA@Au3n}sX!H={FR^bRX)mF zc`6U(uH2NXa#7C8NjWM9Wv}d%t+G+p%1T)(3uUg%l&LaN#>z+;Dg&?NQH82N<*PiE zt8!Gf%2JssL#3-Um8w!yl1fwwDqh8@SQVq9Rg{WU5h`4TsZbT7f>n?TQ~}Cg`6*xJ zqr8=;@=)%|O}Q!;<*b~PqjFI8%1+rT8)dDml%=vz=E_W&DidX_jFh1=@JjY5R0S$u z<*8hiqq0?&%2XLDU8Sj1m7fXiQ2xqK z`6?gftvr>7a#wE3RkygR)n4%2wGZYh|S@m4z}_X3A8VC}U-$43&Xb^2kC} zpz>9o%2hckTV<(Cm7&sAno3nEDoG`(1QoC1RIG|o(JD$sst6UX!c?dVQNb!m1*!n$ zul$s+@=@N(Q+X(N<)&Pfi*i;@%27Eedu69=m5s7iR?1RYD05||OqGc;Rz}KD8F(d+ zC{zV1U*)M>m7}s%mdaEaDqW?iRF$HVRH8~y@hVQmsu&fmqEw`cP~j>}g{lx0tb$aa z3Q+#aPx&ez<*huGhjLeL%2l~2XXT_Em4mWZcFI=SC~IY) zP#Jh7yBDegm9O$tuF6r_DobUm43)0ZRH{l*Nh(n#sCe~%19#}E001C%7=yuJFc=I5 z!wUw3;RS;*Z|8RI&fDDP-Ml-4LB#Na!SI4`1`iB!7=$x85GKQ5kl}%F1`h<~FbMa8 z17R`@1{od*d%>|UeEIhu{8lVkFlWY;31dbK8PKOkmk!^wY4JsqIyI_PC{v3s&AxwxMfyVwX-~968$%8vL zu3R|t!-*pYc5KF`aP7GE@}Q=>|SG9`)>$de;WhELL@ zNb*5~I5DC`2ooYmpt1jpH^01i^5D*mD;LiEaN@{;9a}c6S+QinoEcLlj2SUxK%X96 zI(*Zn#TQNL)TmOSOo<`|^5n>p;gd8el6;ULPK+oK!h{GCXzVL*etGfa!JQjdE}Z${ z#E}C#wrp6lV#$IzGp0-!Gh)bqK0Ug0_@+&ZFPhY;QKdqe5=9E+$&n?)Cuve7`5-}@ z7*QgG2@xdF*#DO|zr1+z;LeRJ7tZ`};>dv=TQ;m&v1GxV8B->V88Ku)pB`O0eAA}I z7ftHas8XR!i6RB^CvUbH*H#c(WFj| zDiz9m+MH?CYb^TUZF2X<`Pux7=Q1#@OhnJ{L=kO6&qbm{O-n-*U*sZ*m$g)$|I6v&e! zONLLrB}abiS?5GF*BKx6+O-u&|7$%8vL zu3R|t!-*pYc5KF`aP7GE@}Q=>|SG9`)>$de;WhELL@ zNb*5~I5DC`2ooYmpt1k=Z+?045mgoET9egb5KO(AfX!n_pf$d2r{(l?!Kn zIC12_jx8J3tXQ&O&WtG&#*7#;pihr39lmMP;)^DAYE-FErbLkfd2(dQ@JX5!Nj^vr zCq|SAVL}86H1@?ezr1+z;LeRJ7tZ`};>dv=TQ;m&v1GxV8B->V88Ku)pB`O0eAA}I z7ftHas8XR!i6RB^CvUbH*H#c(WFj| zDiz9>|^yt#zn>H=JXi}#}l?r7_6e*A=N0tnqq)CzFg9LG6M2Qe4M36vZ zUwHG&izg56+_-Y#%nv7y9N4jC!m+MH?CYb^TUZF2X<`Pux7=Q1#@Oh znJ{L=kO6&qbm{O-n-*U*sZ*m$g)$|I6v&e!ONLLW9_c=F)RjVl+<{BYvPfgM{mtXZ*S!JHXWCX5*| zWI&%DT{?Wzro|Uc>eQ%Gp-hP)1@h#`lHrpyDUy7UAWn=Z5yFHB5@_u6Z+?045mgoET9egb5KO(AfXsn_pf$d2r{(l?!KnIC12_jx8J3tXQ&O&WtG&#*7#;pihr3 z9lmMP;)^DAYE-FErbLkfd2(dQ@JX5!Nj^vrCq|SAVL}86H1_}c%`Y#WJh*e?%7rsO zoH%k|$CeFiRxDXCXU3EXV@3=a(5FY24&StC@kNt5HL6r7Q=&+LJUOyt_#{n=Bp)P* z6C+B5Fd>2j8v8$Z^UI4T5ANK!a^cJmCypH0v1P-W6-yS(nK5O;m=Qw;^y$&1!#8bO ze9@#%jVcw&lqgalPmU}ZK1q`z$p;DI#E23hOo$+X#y8mMoYvW6FdvBZds<)1ym=Z`!o@qDh?^RVtJzQKUeg99c4ak|srx4-&+Q5hX&H z5J3Ws{l9wi%Zn!u?%cR?;mi*wjvUyrWy6{kOBT$TF=fJ-5km&_>CtWM|6gP8Kk$DW zd;NcD?Eg<=??0gLzwo~s`~TJ0>;KQj-hbhr8+(2Kfq!c3{TKBAv9b3b_=m<`|L+_7 u|Iyg{59s?Z{P)KGzcu#y|FyCAU--MmUf+M literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/212ee7d21a8cb25249644cab4f959db111f3a3c0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/212ee7d21a8cb25249644cab4f959db111f3a3c0 new file mode 100644 index 0000000000000000000000000000000000000000..0474655b121f0ee9fab71f67c89ca7a368be343b GIT binary patch literal 106 zcmb0LP7hhva7`?G-TCVZ3=G9b|1vO01UIDj3OFw>=x}WYitPmA4j>L)#lSEJNGm^X yZV1i;GL*JjHSB5wGLjbo3DvfahOkvY#%>^f0K^X!TDLVbFyuBUOk!wcs0RR9z9Cis literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/224ce7b415f7950118880fce0594734aef489fec b/src/sys/libwebm/webm_parser/fuzzing/corpus/224ce7b415f7950118880fce0594734aef489fec new file mode 100644 index 0000000000000000000000000000000000000000..35aedfe3fa41fe68f36914a3cc1de5cd28781fd1 GIT binary patch literal 45 zcmb0LZb+Xa6mmFydU5fT_PyeNl(ajI; z-z$3Pe-saezx(2QI(*?@e|h)Q?IpdBPn(s~gK^*JGc`&_X!I}lKi9KxN$$Gq_ufI) zwRgd2Cz}K_yxbC>(nZ-a-gJ_E*{K@)UNBw;<^kT_ge99NZ(GB>51JX66Md8;^@)(Q zmy%)(em%wa1M@C{sh;_@c&b3<-!q~&X@dGJv8xXZpE5P<+CO_0I^GkN$T|;9DHCT2Z)3U%80x=dstA@D@jWtS{7~xj0dI?G+}`h-nao3N}fDLfaa=C z6bZ@dW3MH)(YeOVFe50S>T;$3uLc3s*T(TOzRm@G9=Zr;;2x+$zFXcGB8s)lh*s%C zZGCEiG3mTBa;`#Bfj((efKe7EvC;>|9#~Vwp6<`YhDrxHI+Uo~voz?@9nEtxNY7jj z-5fdQCoH|(nlgZk{Kz(CTqg1)7)BO`SrSqDf*va%V=4DuZjCb_Qw>d+xr1nsaj70{ zISww++nk`!)t`kZ^szkAcsAfoH8=}x?F?!0WT>3rrbOils$nBjS&WbckT3K~LmLrP zJ0JS`k5n=ku|$2#zT#Or>wE95L)FV!ZYJXjzOelSk0W6{l)x*wa{RfkYDN>Iu24Y9 zxHI$^==l|_@h!L!U&}!@L@^bqXr+cFuI4yKQ{aDm4kCO=`pUwW+;qqqDU4EV*<#d_ zvs>ZlkLijW$>Cn~+C9hU8GU!Yi~;Q(@H)qWT|G_?Y}BGd($&h0r&uwpwG~3Zw1PwU z#8_%x@5e(Gast6{NNQ{7M-1pq3reCK6pg~_1wRywDPlyc^nppAS}wKOz|OIqn2k5# zh1DI~i7~1oJ^^vhdGi6NipG^$Sn@-T_Fq@SXO1;hC7^@NvsCtU2l6JC6@Bp3rxvOA zBj&aJsI;A!;Oh~++aJrq1pktmDL9}sQ$SzwES)R)!qx^BHrvk^*@P*%a{PUSf>II7s?svX zh*KNJ*(!tYg|w7!#}}eIWk)&Igk@bH_%lOBPH5=JodHZQ%WUOWgh@ZJQT23SJ@C$u z)RU_0H#%hIQO95fD(#(GA9WGy$AP#ffl@uOo-8}1RRgA^5w};+6{pia3E?Tx*QHy0OZ@i4d zEL&;G2FQ?H`qz;j4W&ovcZ?FJ$Ig}LDO(P08FovbJa@M*aat^f_GL7Ku zo=P7Wd*Bro;x;80MjqAT$xt~Z5G5*;4PQA63XqpQn2C|h<&fimgn@bTi8THj2cFnn z_BV%;_yBd;`XB@o& z2Ek7OrGC9FS!fA`yQxa5j`X5Lecaz*3p`8bO6ySd8-1?GVz!^)%=usuiu{rt))IAv z0!qfsHYEka1M2{L)t|{6*&XN#(2tMk%%&XNE!ni_sW#nXTa^=T+oL zDjJT06YA=}T8HpJu)-B%t!$gtzB?PP8nLhA*w=A^5T=7RyA#kM`89|Lx&u$gvZ4>3`qU!ze#E@CAC<}e^iB!1zc)g3<$2m> z9s#BmUK1wxxoOD(?+r3OzyYP10{V()>0HSdLoQ|N$I!Zt6JQ~6EPG%zb$iY%RxpU1 zr3wX}(}ET3BO$VXzOG>j`Yp)un{~aJ{uBNZOIcF)V z7*ODXl0@UD>#4m}+(;_WHmPir%EvgtPy(z?6)Bu^Q@tc9Ht4xKlM4A2gP&O0l?-|qO65#$OJ3hitVs! zf?Kz2#mY`$PcmFR(hhjh$Fi04MAl)khQb8LvK6s{w_3q+bc-h`maW)ioUO=4d_4=o z)Rdu6J$JM&iM6)3;;KT1Sbno#+&9=0i&b!igLc|DPMpeA%wcjgFy`8wX$8%g{V`X?xwaHBbpP_I1lJ0eUP zNWB$S6dLTYBC|3+w6(z4abIUnn2=OIhBic@FH(D};p5?pe<0wuh(f)&3JH(8To^|H H%d6XGTQCI{ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/281b259280ada5d07b07a22cbe9a78c7b0fba94b b/src/sys/libwebm/webm_parser/fuzzing/corpus/281b259280ada5d07b07a22cbe9a78c7b0fba94b new file mode 100644 index 0000000..d59afe9 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/281b259280ada5d07b07a22cbe9a78c7b0fba94b @@ -0,0 +1 @@ +S�g�C�u���u�������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/299ed12b98673c6c4adbcf886cb70db8adde6aa1 b/src/sys/libwebm/webm_parser/fuzzing/corpus/299ed12b98673c6c4adbcf886cb70db8adde6aa1 new file mode 100644 index 0000000..2afc785 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/299ed12b98673c6c4adbcf886cb70db8adde6aa1 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P3�G�G�S�gg�T�k���m��b@�P3�G�G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2a40feb7480d0b31c36d5626761e948d0ae52792 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2a40feb7480d0b31c36d5626761e948d0ae52792 new file mode 100644 index 0000000000000000000000000000000000000000..6828d16aeaaa3ab1120c9338fd4d51b0fad84414 GIT binary patch literal 179 zcmb1gm2$nmxWlQ*fu%e(DOV!6A>HAa;OW^VSA2I1FfgzOuK|*bjDo(iOL}1^<0_Op>=(uAV{MqlmpfQl5BepHc2>cQuLCp~mLKH|89N-t+;`h)~tONz;;Rci;9>?({@i?Bz zWHY;KMg06tG82#e-m_c^Mv^{?(UZja+{aO~Uo>F@M1IQh{3dkz=< zqvqK7&6BsVg~ne$eg4p$rswI?YUglaY#V%ro5F@S{n`K4TZV^Z(|fzO4l?h42aI;` z3A*9bO=1cMWzPiHN&e-aTKs#!co~>GM0XXI?4Go59rJ-SBQOW~(3yHeNZKk%F$P}@ z{Jvt{1u*3+zZFjzsQf)5dQ~RCW=UNGF+$3;sB8V~r5Iilm6Ua^7?qazSuqHx;O)rj z=6di!BiW%y$dHUEs$+zOYWmocmRu#&go-G<><6T@Jo6NRYOef5F%eli_e!`;#ua9U z5kZKm!z=wi76gE;h2v#>?Lgup=n|c&F`kD}BP)71va8r0XlOqq2t_Y(`XWSsD!Jj^;TDq$duenJsgEz|yHJ$^bp{ zBj4z_oRlZ%n9LPDV=Uk@1sU^l@6;8}fV^rb!psG*LB^$dv^ozCsJA&mpSS*0SQxlG z$hcPxsG{H#VuxKc?@4+S}wLfQV@*EFMvQKvL8D((n92Kt#7U+KpAS-8F?Wblv7 z<~mPwWsXYJ9}nXL%uNx4hQe24Ea)>9;Z4ey=yO8SE^DOZ6!p%|(IC$K3P*iRJ4cbP zgz^|`x^GHj(Z_Oele<(cQ#InGTCiW3khH+7EeRWnaCxn;lEo!|>Rhv~5CF1QCIv`$ z{7HuFlG+OFh)Jmc%wBt#7yK^8D|KK}r)l>3)Q~@ zse*AO7M8-0qvx-S;j_kiRVAQ<-7|mg0%xeaiOY&Qc&gKjWPOWyZ96LcNesri#pu?@ za?b3!bQJ;pDKVVUN*W+7-!u169q3xvXX-_hOPTgD>=}VY+Plpx#*kb%M9xx5gWL4r z#>IrAHSYc71^HfLHjan!LAs@B9AAxkNuL{j665k!29jM048n^~V@xla)=#KM%h%SN zGcT$bP$lw}Q=pZ`LaGA&A(gg_v5WFlOOuPbYb&IseB1sjK^y&9PlpN&xiEnFLn=AO z=5_9RV1pz>i3au;hNPNO<$t5&e5mwyY6I&QsW+{R)&vS9Zghs29vo^=Z+P%Z;X`6t z@MH;NJo__Lb8ewnz<%jcJWI!q1X`UOXzT@soggcmiv2(s78-cAVu}myVZ5O~V+6(? zHpYzEA3`)p%Xr_6UOZa`=OqZRWx6*fj~wnn>-j4eAf zbyED8+G7IdQxY8SgZdCm?PEA=jxeHf0-6Gn#-mrjXtX9707;mym?MRM7zJRf1RG}=2yZ=y4*E`T8%ocNUc6=xuJf8*hB6nJ z^7*7l0v@?&;>Nzh#4bh7vbH2ZICUj9A{nx4NBxAKp)zPR{9KH-PA_}|sYq(aXYugK zX0JyCSdepIKLz{pNX-i69B{l3DQ7w=%NXiYIELe-`d0sV9z=jzPFk_d$Cs!%A{H>} zQ)u8EVV4W;nRCQ~CTlSXq2w)&m(G%O}=T-XK}E}X0J!G>Je}oh1jmI zEy2-ib~%DEIVN)f^9&+c&Put?*V$2lGBSHB6%A>C6jqW|MpM38l+HJ#lFz@Vp}oe{ zdXjb>>M{M;eIJTfAQuxWF|i02nV-j5Gc)v>Ayq{B3j^5tS_JCbA_%uzNAE~c|9*nR NxI6p*?V_Rb*?)8?I2!-} literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2a9588e6fab82016b545462cff2ed014c0345551 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2a9588e6fab82016b545462cff2ed014c0345551 new file mode 100644 index 0000000..0140636 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2a9588e6fab82016b545462cff2ed014c0345551 @@ -0,0 +1 @@ +S�g�T�k�����T��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2b1d57a8e8fa7164c9ba00957c9486010754560c b/src/sys/libwebm/webm_parser/fuzzing/corpus/2b1d57a8e8fa7164c9ba00957c9486010754560c new file mode 100644 index 0000000..298598f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2b1d57a8e8fa7164c9ba00957c9486010754560c @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G�G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2b475d1a8f2fe4fbba92e1424f0ea96d95b12fb7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2b475d1a8f2fe4fbba92e1424f0ea96d95b12fb7 new file mode 100644 index 0000000..7e8be98 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2b475d1a8f2fe4fbba92e1424f0ea96d95b12fb7 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1�b@�P1� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2bb80c6d0e2eadd73018eb2a8cae37d41602ee79 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2bb80c6d0e2eadd73018eb2a8cae37d41602ee79 new file mode 100644 index 0000000000000000000000000000000000000000..8f07d6cb7b32238aea8fcd2f3c36497b65894ecd GIT binary patch literal 18 Zcmb0LZb)#y?1^`9{2dMx6 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2c1389f882e256e260e37e8a67af7e32d0f4e0fc b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c1389f882e256e260e37e8a67af7e32d0f4e0fc new file mode 100644 index 0000000..6710408 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c1389f882e256e260e37e8a67af7e32d0f4e0fc @@ -0,0 +1 @@ +��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2c1f94c76e4eec607cce5311323620f349912e73 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c1f94c76e4eec607cce5311323620f349912e73 new file mode 100644 index 0000000..26995d2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c1f94c76e4eec607cce5311323620f349912e73 @@ -0,0 +1 @@ +S�g�S�k������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2c962c7fbceaacf8247ac9b70c8eeb1f814e435b b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c962c7fbceaacf8247ac9b70c8eeb1f814e435b new file mode 100644 index 0000000..856cb5b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c962c7fbceaacf8247ac9b70c8eeb1f814e435b @@ -0,0 +1 @@ +S�g�M�t�M��S��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2c9aaabacf3a3b48dec4a85767cc5d38a1736aff b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c9aaabacf3a3b48dec4a85767cc5d38a1736aff new file mode 100644 index 0000000..28edff6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2c9aaabacf3a3b48dec4a85767cc5d38a1736aff @@ -0,0 +1 @@ +S�g�C�u�����y�̀ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2cf086299f983d0afc7f95c5e0c86b657448af33 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2cf086299f983d0afc7f95c5e0c86b657448af33 new file mode 100644 index 0000000000000000000000000000000000000000..13f182651c52ad51d29cced172d6655989304382 GIT binary patch literal 40 qcmb0LZb)A&@4T&a-hw#`TN@iTIxzfpU?^SG(Br@`8^-Q)U;qGO_YjT% literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2d0d96b95e9a3316d1ff0ef019ada509bbde4c9d b/src/sys/libwebm/webm_parser/fuzzing/corpus/2d0d96b95e9a3316d1ff0ef019ada509bbde4c9d new file mode 100644 index 0000000000000000000000000000000000000000..adcb9e1bc6b01befbfaafa7958240dfef5411231 GIT binary patch literal 41 xcmWF$aF7UYNS`70rX^$@L-yo#6LTBX`;r*`TRF4@7&kH|IkYe`T`+891^`G;4+sDN literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2d414d5dfd20055393df3208009840da9cfabca9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2d414d5dfd20055393df3208009840da9cfabca9 new file mode 100644 index 0000000000000000000000000000000000000000..8e5d23f1644f6073d164607f522edfca80a16bfc GIT binary patch literal 24 fcmb0LZb+XZ@4T(Fe{pXkLklwl10y376EiaaXC4Me literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2df967edcc00ac5c8e00037f1a43680600af5cba b/src/sys/libwebm/webm_parser/fuzzing/corpus/2df967edcc00ac5c8e00037f1a43680600af5cba new file mode 100644 index 0000000000000000000000000000000000000000..fb0e9b1cf79d446a592be2c1c379804fbc5ec676 GIT binary patch literal 166 zcmb1gm2$nmxWlQ*fu%e(DOV!6A>HAa;OvqszPkk&7}$f?2(U0PG79?6F6o7dq%Z(w z7@0(+T>qnL{J&D(d0VOH%Crux>l+1uY8WBxg#wDMARQptw&x(t^7j|FI|=*;ib(*) ffOfV*#6>+k=S iZv;sr*g&%w7@6dqFO{}E2Wymf-UekdiG{4o?gjuD@FJ=J literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/2f6e92a71918d01c16762d5ca59b328f1341d326 b/src/sys/libwebm/webm_parser/fuzzing/corpus/2f6e92a71918d01c16762d5ca59b328f1341d326 new file mode 100644 index 0000000..3393c8d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/2f6e92a71918d01c16762d5ca59b328f1341d326 @@ -0,0 +1 @@ +S�g�k \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/306e2cf9aebe012cb0769b1b2a6ea68af2e8ed44 b/src/sys/libwebm/webm_parser/fuzzing/corpus/306e2cf9aebe012cb0769b1b2a6ea68af2e8ed44 new file mode 100644 index 0000000..60a0f48 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/306e2cf9aebe012cb0769b1b2a6ea68af2e8ed44 @@ -0,0 +1 @@ +�Eߣ�B�@webm�S�g�*M'�t�I�f�C�u�TSkk����C�p�T�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/30f7348d35de0c47d2044736cb115972b800569d b/src/sys/libwebm/webm_parser/fuzzing/corpus/30f7348d35de0c47d2044736cb115972b800569d new file mode 100644 index 0000000000000000000000000000000000000000..d992dbe02907cc1dec120daeb7a6e24b3d75bc0c GIT binary patch literal 173 zcmb1o=X!r}hf|XSOL=Nit`vfkD-qm~K2_d%Tj_-74h*Xu7#6oSG62B>2L`w*kP?Su zg1)m$dVO~bFfgzOuK|*bj2I$JqMj?$I<&5D1WO}xn1D8b%xjPcE^T`bl5R+61ligE T<}itctjq3R2NY+!F2Dc)@JTjw literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/310798b8d94a3a2fe649a4c871458b4d74fdcf32 b/src/sys/libwebm/webm_parser/fuzzing/corpus/310798b8d94a3a2fe649a4c871458b4d74fdcf32 new file mode 100644 index 0000000..e3c32aa --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/310798b8d94a3a2fe649a4c871458b4d74fdcf32 @@ -0,0 +1 @@ +S�g�C�p�E������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/31ea606a9859bb29d7f98162d254348021e0d932 b/src/sys/libwebm/webm_parser/fuzzing/corpus/31ea606a9859bb29d7f98162d254348021e0d932 new file mode 100644 index 0000000..038f1a9 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/31ea606a9859bb29d7f98162d254348021e0d932 @@ -0,0 +1 @@ +S�g�C�p�E����sāVT�A�@�@�@�@B�@�@C�@sā�@�����@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3230fc31ab8d408c484aa28bbe36431f71101243 b/src/sys/libwebm/webm_parser/fuzzing/corpus/3230fc31ab8d408c484aa28bbe36431f71101243 new file mode 100644 index 0000000000000000000000000000000000000000..cad0aa0757408781be3d0440f1feb48082e2eaec GIT binary patch literal 59 zcmb1gy}!7_smXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfuJ}ZDas~#jXGA!4!hW$OHg} C5EKCb literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/328b7c92996e480d1f11efe847c3be4b5dc0f8eb b/src/sys/libwebm/webm_parser/fuzzing/corpus/328b7c92996e480d1f11efe847c3be4b5dc0f8eb new file mode 100644 index 0000000000000000000000000000000000000000..b229bcb7d68ada960850496dc15d3d0f4a1f4c22 GIT binary patch literal 207 zcmb0LZb+Xh;JmzGg6q!SZQTu>tqu&%bqzoy0hE~|6mmFydU5fT1_u@(<-E;72q?s|&4H!(Nh2$Wg7S{Q zcx+Ox_ZRrh|Ns9G)7d0~ E0rl?w+ v$Q&kl=WVHN&%xqAW+{ZpBo?wRyL%l_ll+1x7#Nx4owt>?JqL>;m`q|J>$1Do0Y%xa1BpOJvAlKJjVQn+u|o>v765?d BE$;vT literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/35b2f81c573b15304cb9b13f00008b460da78942 b/src/sys/libwebm/webm_parser/fuzzing/corpus/35b2f81c573b15304cb9b13f00008b460da78942 new file mode 100644 index 0000000..85f4be2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/35b2f81c573b15304cb9b13f00008b460da78942 @@ -0,0 +1 @@ +S�g�C�u���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/35d9256a4d7ef3ee54384616178af3a8092d0981 b/src/sys/libwebm/webm_parser/fuzzing/corpus/35d9256a4d7ef3ee54384616178af3a8092d0981 new file mode 100644 index 0000000..42f1817 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/35d9256a4d7ef3ee54384616178af3a8092d0981 @@ -0,0 +1 @@ +S�g�T�g�ss� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/36352efd680a747f0f2c93d760559d69399a4102 b/src/sys/libwebm/webm_parser/fuzzing/corpus/36352efd680a747f0f2c93d760559d69399a4102 new file mode 100644 index 0000000..d438e9c --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/36352efd680a747f0f2c93d760559d69399a4102 @@ -0,0 +1 @@ +S�g�C�u������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3685ffbcfe28b166ced0a783b012a446f9cfea46 b/src/sys/libwebm/webm_parser/fuzzing/corpus/3685ffbcfe28b166ced0a783b012a446f9cfea46 new file mode 100644 index 0000000..fe6660b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3685ffbcfe28b166ced0a783b012a446f9cfea46 @@ -0,0 +1 @@ +S�g�S�k�������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/36def8b2661197d594756f116a750822ae1d65d5 b/src/sys/libwebm/webm_parser/fuzzing/corpus/36def8b2661197d594756f116a750822ae1d65d5 new file mode 100644 index 0000000..50d822a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/36def8b2661197d594756f116a750822ae1d65d5 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P3� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/371950308853fb3b1b3a940c0598bfdfeb1d0f9c b/src/sys/libwebm/webm_parser/fuzzing/corpus/371950308853fb3b1b3a940c0598bfdfeb1d0f9c new file mode 100644 index 0000000..d12faf8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/371950308853fb3b1b3a940c0598bfdfeb1d0f9c @@ -0,0 +1 @@ +S�g�C�u���u��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3765e9174971dbac9cfeb7e485ca61dc4941f7a9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/3765e9174971dbac9cfeb7e485ca61dc4941f7a9 new file mode 100644 index 0000000..4c306d9 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3765e9174971dbac9cfeb7e485ca61dc4941f7a9 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G�G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/37cae036ce7ff5d0671f32d3757579f248609c9c b/src/sys/libwebm/webm_parser/fuzzing/corpus/37cae036ce7ff5d0671f32d3757579f248609c9c new file mode 100644 index 0000000..9183f01 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/37cae036ce7ff5d0671f32d3757579f248609c9c @@ -0,0 +1 @@ +S�g�T�k���m��b*�P0�G�!S�g�T�k������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/38460ea06ee847ff3d5733415c299b44b0866e58 b/src/sys/libwebm/webm_parser/fuzzing/corpus/38460ea06ee847ff3d5733415c299b44b0866e58 new file mode 100644 index 0000000..6456fa5 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/38460ea06ee847ff3d5733415c299b44b0866e58 @@ -0,0 +1 @@ +S�g�C�p�E����sāVT�A�@�@�@�@B�@�@C�@sā�@�����@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3865de2fec3f353513d86b28e43bf936d4707f97 b/src/sys/libwebm/webm_parser/fuzzing/corpus/3865de2fec3f353513d86b28e43bf936d4707f97 new file mode 100644 index 0000000..f2150f6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3865de2fec3f353513d86b28e43bf936d4707f97 @@ -0,0 +1 @@ +�g�S�g�C�p�E����sāVT�A� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3867b18060c307e0d04e0098f195d699e4b3294f b/src/sys/libwebm/webm_parser/fuzzing/corpus/3867b18060c307e0d04e0098f195d699e4b3294f new file mode 100644 index 0000000..f0cfd0a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3867b18060c307e0d04e0098f195d699e4b3294f @@ -0,0 +1 @@ +S�g�T�g�ss�gțȄ#��dgȄ]��egȄD��dgȄ]��egȄD��gȀD��dgȀg \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/391920720c3609b7c1f7b51162ce3ec99329a0b4 b/src/sys/libwebm/webm_parser/fuzzing/corpus/391920720c3609b7c1f7b51162ce3ec99329a0b4 new file mode 100644 index 0000000000000000000000000000000000000000..fb057c8c30a8643cb6093734cee16e0a0621908d GIT binary patch literal 148 zcmb0LZb;uF;JmzGyX(#^+cq_9Xmw!CNX^M9ajt32Nz6+(aIR}jEJ{r@fbtEYv=K<$ zP|EfG;tsDS2bS{Gq+AK0QGc)+RflF2P-|Ygq4OWGumn(FL%PE;LEqUWy}r8z7#IKy C20VoT literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/395027454c7d5babff9544414c04a39d712eed1c b/src/sys/libwebm/webm_parser/fuzzing/corpus/395027454c7d5babff9544414c04a39d712eed1c new file mode 100644 index 0000000..e34ef6f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/395027454c7d5babff9544414c04a39d712eed1c @@ -0,0 +1 @@ +������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit��������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit�������;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit��������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3a258c9ed48e634ed8d495f07caf21dbc6978205 b/src/sys/libwebm/webm_parser/fuzzing/corpus/3a258c9ed48e634ed8d495f07caf21dbc6978205 new file mode 100644 index 0000000000000000000000000000000000000000..a14b82b42581aa263f09a7c985969b3ba5fdb406 GIT binary patch literal 19 acmb0LZbHAa;OvqszPkk&7}&8%`od+`0F^K@3IYXsA5~H!1B27&MwT}Y3_w99kIa4Az literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3ec4ac00bb967a335b5caae0ae51488f2fda6583 b/src/sys/libwebm/webm_parser/fuzzing/corpus/3ec4ac00bb967a335b5caae0ae51488f2fda6583 new file mode 100644 index 0000000000000000000000000000000000000000..b8043e818e3446a8da0baf7602765ad78eec6612 GIT binary patch literal 9 QcmaFE^oEInfuZ3)01)H@TmS$7 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3eec38c0ac3a96856d3210a0357857e70b07a9cb b/src/sys/libwebm/webm_parser/fuzzing/corpus/3eec38c0ac3a96856d3210a0357857e70b07a9cb new file mode 100644 index 0000000..25f0273 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3eec38c0ac3a96856d3210a0357857e70b07a9cb @@ -0,0 +1 @@ +S�g�T�g�ss�c��c�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3ef82ba46238fa46b89148a230d23e741ba5f1da b/src/sys/libwebm/webm_parser/fuzzing/corpus/3ef82ba46238fa46b89148a230d23e741ba5f1da new file mode 100644 index 0000000..134a456 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3ef82ba46238fa46b89148a230d23e741ba5f1da @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1�b@�b@�P1� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3fbd43f81888ca60e5bfe49b47e23cb115d5cd7d b/src/sys/libwebm/webm_parser/fuzzing/corpus/3fbd43f81888ca60e5bfe49b47e23cb115d5cd7d new file mode 100644 index 0000000..75b0d29 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3fbd43f81888ca60e5bfe49b47e23cb115d5cd7d @@ -0,0 +1 @@ +S�g�C�p�E����sāV�@B�@�@C�@sā�@s��@sā�@sā�@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3fe56e5b06653e8a37c99da190ff8d44d14bfc06 b/src/sys/libwebm/webm_parser/fuzzing/corpus/3fe56e5b06653e8a37c99da190ff8d44d14bfc06 new file mode 100644 index 0000000..7a3c719 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3fe56e5b06653e8a37c99da190ff8d44d14bfc06 @@ -0,0 +1 @@ +S�G�T�k���m��b�P�S�g�C�u������́��G���G瀁 \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/3febffec3be8b1f4bcb76a01c1d713600d8e4adb b/src/sys/libwebm/webm_parser/fuzzing/corpus/3febffec3be8b1f4bcb76a01c1d713600d8e4adb new file mode 100644 index 0000000..5f0a13d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/3febffec3be8b1f4bcb76a01c1d713600d8e4adb @@ -0,0 +1 @@ +S�g�C�p�E���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/43380e5a9dd29ca847e9b5bfba12a0a95d94d0da b/src/sys/libwebm/webm_parser/fuzzing/corpus/43380e5a9dd29ca847e9b5bfba12a0a95d94d0da new file mode 100644 index 0000000000000000000000000000000000000000..1c630fc4cde9e55595fda6d1a211ac1243e5229c GIT binary patch literal 30 mcmb0LZb+Xg7P2mT%DPDpCTwtEWZdPz$P}`{fgxm<0|NlO)eAHL literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/435d3ff6ddc43ac582e740ead969397fd2bfc7f5 b/src/sys/libwebm/webm_parser/fuzzing/corpus/435d3ff6ddc43ac582e740ead969397fd2bfc7f5 new file mode 100644 index 0000000000000000000000000000000000000000..8d8a6f49518d666cd6a281aaf02b9d9dabb41b83 GIT binary patch literal 24 fcmb0LZb)}{DDS+j)ZzAGheig58*Qu-|AQLW)92O(04Bi&!T4G5|#h} literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/49c0e3eed81c1827e755c70c9c6d9606e7f54b22 b/src/sys/libwebm/webm_parser/fuzzing/corpus/49c0e3eed81c1827e755c70c9c6d9606e7f54b22 new file mode 100644 index 0000000000000000000000000000000000000000..cc061ed58617aa22fef64d9cea9b87d2a694a2d5 GIT binary patch literal 26 hcmb0LZb+Xh;JmzGg6q!SZQTu>tqu&%H4V;n4FHjT3j6>7 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/4a3e77f5bc061fc8121ef7ebd2b8e3ebb0bdd609 b/src/sys/libwebm/webm_parser/fuzzing/corpus/4a3e77f5bc061fc8121ef7ebd2b8e3ebb0bdd609 new file mode 100644 index 0000000..336e6fb --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/4a3e77f5bc061fc8121ef7ebd2b8e3ebb0bdd609 @@ -0,0 +1 @@ +S�g�C�p�E����sāVT�A�@�@�@�@B����j������������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/4a454e01ef09b175f3864b654cfc1104a850e871 b/src/sys/libwebm/webm_parser/fuzzing/corpus/4a454e01ef09b175f3864b654cfc1104a850e871 new file mode 100644 index 0000000000000000000000000000000000000000..f57bbfdda993be030eab9a33d500481843240efb GIT binary patch literal 192 zcmb1gy}!7_smXz*JT)m-BDf*l;h3QB?2=yJ-2w~@?7?e*BqJk+2$QJi%Crux>l?w+ z$Q&kl=WV5J&%xpdCX-mmy6o~4^iY@5OI0?x||dR=z{+3fXu Yz#>8+htnq)7X#V6$p=8<$wxur0C@T`bpQYW literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/4acd9df9a7ee34e48c6c80777159b089f417a69a b/src/sys/libwebm/webm_parser/fuzzing/corpus/4acd9df9a7ee34e48c6c80777159b089f417a69a new file mode 100644 index 0000000000000000000000000000000000000000..1df1e83120c7fe57128d72e8615733ce8fdf4df0 GIT binary patch literal 17 Ycmb0LZbr{ZrOCwE^XwCq0;uya51i=o;Gq literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/4eeb4507868732d3705d1ab10f6a31f70f579556 b/src/sys/libwebm/webm_parser/fuzzing/corpus/4eeb4507868732d3705d1ab10f6a31f70f579556 new file mode 100644 index 0000000..652484d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/4eeb4507868732d3705d1ab10f6a31f70f579556 @@ -0,0 +1 @@ +S�g�C�u������́�́S�g�C�u������΀ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/4f21f3584c99e97453ebe513ed44c86530fbebba b/src/sys/libwebm/webm_parser/fuzzing/corpus/4f21f3584c99e97453ebe513ed44c86530fbebba new file mode 100644 index 0000000..b37544d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/4f21f3584c99e97453ebe513ed44c86530fbebba @@ -0,0 +1 @@ +S�g�C�p�E������C|��C�p�E������C|�! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5103160695cd56d281faa45d9267013488cc7bde b/src/sys/libwebm/webm_parser/fuzzing/corpus/5103160695cd56d281faa45d9267013488cc7bde new file mode 100644 index 0000000..2a707f7 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5103160695cd56d281faa45d9267013488cc7bde @@ -0,0 +1 @@ +S�g�T�k���ׁ��ׁ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/521103054e395afd0f9612b47c71cfa0e62151b9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/521103054e395afd0f9612b47c71cfa0e62151b9 new file mode 100644 index 0000000000000000000000000000000000000000..5849044fca819585d552fe08c6d960ef17b34fd0 GIT binary patch literal 163 zcmb1gy}!7_smXz*JT)m-BDf*l;h3QB?2=yJ-2w~@?7?e*BqJk+2$QJi%CrYs*EfQt zL7WZ{M~H!uN#1!|Y1?zKID*L}7P2n8dmT`e?K)UWEN@+QW1~xFV`Jl+#y4+(6bkTd QXl(3m_{X@8;mcGt065P#^#A|> literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/523511e33c8788ebb1b703d7c5ad12b5da03964e b/src/sys/libwebm/webm_parser/fuzzing/corpus/523511e33c8788ebb1b703d7c5ad12b5da03964e new file mode 100644 index 0000000000000000000000000000000000000000..99e77993ee608f7043592be0df6654146a901c1e GIT binary patch literal 28 kcmb0LZb+Xl7P2mT(z*$`4ZTSYT>+-;?$2A?UoP%Er93q$S0cC}-Qk$)eL>&ZCB4481sE9EgVz8_Mn((~CQ;9oX&qYE eH-e=R9H3zgj7;**+e+J>gQXBmCb5up+1&v0ks=QO literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5466c59c9c0eff34800e19cc92faf07469865ea9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5466c59c9c0eff34800e19cc92faf07469865ea9 new file mode 100644 index 0000000..2b86b64 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5466c59c9c0eff34800e19cc92faf07469865ea9 @@ -0,0 +1 @@ +VT������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/54bf8d6f1f846243b6f4de81605779b0acb78406 b/src/sys/libwebm/webm_parser/fuzzing/corpus/54bf8d6f1f846243b6f4de81605779b0acb78406 new file mode 100644 index 0000000..9b4a32e --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/54bf8d6f1f846243b6f4de81605779b0acb78406 @@ -0,0 +1 @@ +�������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/54fd1711209fb1c0781092374132c66e79e2241b b/src/sys/libwebm/webm_parser/fuzzing/corpus/54fd1711209fb1c0781092374132c66e79e2241b new file mode 100644 index 0000000..7937c68 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/54fd1711209fb1c0781092374132c66e79e2241b @@ -0,0 +1 @@ +g \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5506797514c0b214f5faa9764a9e149cd1df9d28 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5506797514c0b214f5faa9764a9e149cd1df9d28 new file mode 100644 index 0000000..bfc5004 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5506797514c0b214f5faa9764a9e149cd1df9d28 @@ -0,0 +1 @@ +S�g�T�k���׃ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5566c6d599866f5e523c54e6575d7b9e557a2539 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5566c6d599866f5e523c54e6575d7b9e557a2539 new file mode 100644 index 0000000000000000000000000000000000000000..8578677e2113331f3e2c7a6516c3c27da6c86af8 GIT binary patch literal 53 wcmb0LZb;uC@4T&a^@5cPTNgGjb71)Gz{m*246_kzrqV@?|N9)6Uo`v&07G9DkpKVy literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/55c3d55780427eb00bde252348db1c2ede22526c b/src/sys/libwebm/webm_parser/fuzzing/corpus/55c3d55780427eb00bde252348db1c2ede22526c new file mode 100644 index 0000000..25c7cc7 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/55c3d55780427eb00bde252348db1c2ede22526c @@ -0,0 +1 @@ +� diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5600abaefe804c50a353bbfdd0f9e10ffc102f81 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5600abaefe804c50a353bbfdd0f9e10ffc102f81 new file mode 100644 index 0000000..2b5e073 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5600abaefe804c50a353bbfdd0f9e10ffc102f81 @@ -0,0 +1 @@ +S�S�g�Tk���m��b@�P1�S�g�T�k���m��b@��5�G�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5611ddd40488973ee6c64c45ad57d6eefe6da100 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5611ddd40488973ee6c64c45ad57d6eefe6da100 new file mode 100644 index 0000000..34d12c7 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5611ddd40488973ee6c64c45ad57d6eefe6da100 @@ -0,0 +1 @@ +S�g�I�f�*ױ�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/56b0ddd4e44492b45ebb7e9438b0a5556c244bfb b/src/sys/libwebm/webm_parser/fuzzing/corpus/56b0ddd4e44492b45ebb7e9438b0a5556c244bfb new file mode 100644 index 0000000..2da35a1 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/56b0ddd4e44492b45ebb7e9438b0a5556c244bfb @@ -0,0 +1 @@ +S�g�S�k������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5729395b452092152b06fbb8976e9bf1fda06439 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5729395b452092152b06fbb8976e9bf1fda06439 new file mode 100644 index 0000000000000000000000000000000000000000..df3e05b5af142d0f680d0ca0901f423bc4f9b706 GIT binary patch literal 207 zcmb0LZb+Xh;JmzGg6q!SZQTu>tqu&%DhJtL-Nrk ztIXu1jf_Cd1X8dUq;-eu&aK6rh GA{YR-R#Q0u literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/57cce6fac7c0992eb338e0e538d3e0ee3fe7f1cd b/src/sys/libwebm/webm_parser/fuzzing/corpus/57cce6fac7c0992eb338e0e538d3e0ee3fe7f1cd new file mode 100644 index 0000000..ab69784 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/57cce6fac7c0992eb338e0e538d3e0ee3fe7f1cd @@ -0,0 +1 @@ +�Eߣ�B�@webm�S�g�*M'�t�I�f�C�u��Skk����C�p�T�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5822672f068da89546838004ae59552e12e132f7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5822672f068da89546838004ae59552e12e132f7 new file mode 100644 index 0000000000000000000000000000000000000000..b5b45fedae59fc3126ae69d84ae60ba3c06748c0 GIT binary patch literal 20 bcmb1gy}x*#Q(J>mlLLcOdxKMJLjwZX1CVWR@We}>!! GAO`@!tSABi literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5a645b30948850f8efb7bdd11944bdf3112c7bfe b/src/sys/libwebm/webm_parser/fuzzing/corpus/5a645b30948850f8efb7bdd11944bdf3112c7bfe new file mode 100644 index 0000000..2d85ba9 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5a645b30948850f8efb7bdd11944bdf3112c7bfe @@ -0,0 +1 @@ +S�g�T�g�ss�c��cŁ� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5b2f727461cde3c02ffdfb300adb0b4a09734911 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5b2f727461cde3c02ffdfb300adb0b4a09734911 new file mode 100644 index 0000000..7416715 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5b2f727461cde3c02ffdfb300adb0b4a09734911 @@ -0,0 +1 @@ +S�g�T�k�����S�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5b5531d859ab5bbb034345bbaa2852e9d8a1e1ef b/src/sys/libwebm/webm_parser/fuzzing/corpus/5b5531d859ab5bbb034345bbaa2852e9d8a1e1ef new file mode 100644 index 0000000..5b800b8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5b5531d859ab5bbb034345bbaa2852e9d8a1e1ef @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5b980cb94e35769ec92a140ca00d34977e7da5ec b/src/sys/libwebm/webm_parser/fuzzing/corpus/5b980cb94e35769ec92a140ca00d34977e7da5ec new file mode 100644 index 0000000000000000000000000000000000000000..180ef6b3a4a5dae75bce7cf7d72e59455e685cda GIT binary patch literal 10 OcmZo@00D+p1_b~ZIRmBu literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5bfec2fe795176646fa0babecf97c04045bd4814 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5bfec2fe795176646fa0babecf97c04045bd4814 new file mode 100644 index 0000000000000000000000000000000000000000..9e406d3a2f528624ca1659172ecfc08b82715137 GIT binary patch literal 348 zcmb0LZb<(v7P2n;+qy5;6&M&9i;n_Hre+|az7t3=bbyG^RX~z)4v4AzxVe!fI1k8l zRN6YH(Wwo{a!y_Zl2UE!Xmkk!DP;}Y4J6qfDlo8xYyz^_fh^YfKn6!{g8~D0k^@j8 zz!1o1lmObl0A&B{bu)7trX@K{4lrzF3@~bB3NUVD4lr#Af7r+hQZxgkX!5#=xea|u z4lN)>NhTnQNy-%@y|}}v$suG@YErI5LwfK^Y3FUFZIDugvvVC70T~Ezh5!Hn literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5c28d94242e9a5ba7e7324e59e5dd12f3e31e51c b/src/sys/libwebm/webm_parser/fuzzing/corpus/5c28d94242e9a5ba7e7324e59e5dd12f3e31e51c new file mode 100644 index 0000000000000000000000000000000000000000..68b4ebc8cb661b187f2b3afa4e38266143571ebe GIT binary patch literal 63 zcmb1gy}!7_smXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfuJ}ZDe2&1_B0##jOntK(Nh$ MWj0Xq0hnR}0IaAI)&Kwi literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5c67728ab04ba3dfe4b2636cf609f9617c4a5974 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5c67728ab04ba3dfe4b2636cf609f9617c4a5974 new file mode 100644 index 0000000..f14a6f6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5c67728ab04ba3dfe4b2636cf609f9617c4a5974 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P0�G�!S�g�T�k������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5cd36053e269c97f5359b0a075d80bf1e23b5f47 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5cd36053e269c97f5359b0a075d80bf1e23b5f47 new file mode 100644 index 0000000..985bba4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5cd36053e269c97f5359b0a075d80bf1e23b5f47 @@ -0,0 +1 @@ +S�g�C�u���u���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5d6f99c2afbf68a1b15a17e07945c11db8579e5f b/src/sys/libwebm/webm_parser/fuzzing/corpus/5d6f99c2afbf68a1b15a17e07945c11db8579e5f new file mode 100644 index 0000000000000000000000000000000000000000..85a0c9302c8e4d809c6d1a38aed9bf05312009de GIT binary patch literal 88 zcmb0LZb-i-7P2n;;=1$K6&M(bj{=EiAl?bY9Y7qq3P{WWV&%up4Z(RphSJtK4Q)U= XSpZ0=wskawfs};p1`-dUn1K-hye$}I literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5dd149b1b8509f456c16c4ac6dac3c7d6aa217ed b/src/sys/libwebm/webm_parser/fuzzing/corpus/5dd149b1b8509f456c16c4ac6dac3c7d6aa217ed new file mode 100644 index 0000000000000000000000000000000000000000..102660dbf5d6908dbe3eb011a2cf1146d938ae6e GIT binary patch literal 99 zcmb0LZb)A&@4T&a-hw#`TN@b|;v|3~^BIG82rw`(G6f$1QOq*IyR*A@1DR}_fds>% umPUzSM#hHpi6EUl3%V9{_$HPVSu#AZ7rGW>R6C|%Uh=KugkBOveq literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5e84011c6b092e9f0d6ba60f12fc0fae95a622ca b/src/sys/libwebm/webm_parser/fuzzing/corpus/5e84011c6b092e9f0d6ba60f12fc0fae95a622ca new file mode 100644 index 0000000000000000000000000000000000000000..d4df4df8c4b6a47b487f4ed563cb78ce5430d8fd GIT binary patch literal 56 zcmb1gy}!7_smXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfuJ}ZDinv05J$91=PUJ$OHfx C#SfhT literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/5f56766993de2b8c2db87116090af546e1add3b0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/5f56766993de2b8c2db87116090af546e1add3b0 new file mode 100644 index 0000000..c90364d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/5f56766993de2b8c2db87116090af546e1add3b0 @@ -0,0 +1 @@ +S�g�S�k������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/60571c8be9bee3b13428613df66ff36cf54309ec b/src/sys/libwebm/webm_parser/fuzzing/corpus/60571c8be9bee3b13428613df66ff36cf54309ec new file mode 100644 index 0000000..bfd35dc --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/60571c8be9bee3b13428613df66ff36cf54309ec @@ -0,0 +1 @@ +S�g�T�g�ss�c��hʀcʀcŀS�g�T�g�ss�c��cʁ! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/60ac245f262ee1ff177d351a4fe246060fb4538b b/src/sys/libwebm/webm_parser/fuzzing/corpus/60ac245f262ee1ff177d351a4fe246060fb4538b new file mode 100644 index 0000000000000000000000000000000000000000..21219e91111dae7829f2c60fc4ca295282aec47d GIT binary patch literal 86 zcmb0LZb<(v7P2n;+qy5;6&M&9i;n_Hre+|)yc0+;bbyG^RX~z)4v4AzxVe!fI1k8l cRN6YHQ39xcCP@F3bxv(SLFY*iCM0hF0Blkk+W-In literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6120aafb0db1715400e47d0a61fb9f6d8665a736 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6120aafb0db1715400e47d0a61fb9f6d8665a736 new file mode 100644 index 0000000..2fc4e39 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6120aafb0db1715400e47d0a61fb9f6d8665a736 @@ -0,0 +1 @@ +S�g�C�u�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/61953a8f7a9f0613020d297a6d350abeeaf6e58c b/src/sys/libwebm/webm_parser/fuzzing/corpus/61953a8f7a9f0613020d297a6d350abeeaf6e58c new file mode 100644 index 0000000..478128c --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/61953a8f7a9f0613020d297a6d350abeeaf6e58c @@ -0,0 +1 @@ +S�g�C�u������́�́ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/61c0a7fef46c0c1b081b1c2b40835805e5989b54 b/src/sys/libwebm/webm_parser/fuzzing/corpus/61c0a7fef46c0c1b081b1c2b40835805e5989b54 new file mode 100644 index 0000000..b5ac3f6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/61c0a7fef46c0c1b081b1c2b40835805e5989b54 @@ -0,0 +1 @@ +� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/620d85870206e88db0bc3ee978c24c0bbc1821ba b/src/sys/libwebm/webm_parser/fuzzing/corpus/620d85870206e88db0bc3ee978c24c0bbc1821ba new file mode 100644 index 0000000000000000000000000000000000000000..4749f9c35d3e1c577cf9165027fae03d21096cdd GIT binary patch literal 60 zcmb0LZb;uP6mmFyTXFH`6YVYO$}1aF(oeL+wl}5%DVKIQ&xN6-w>|wt`iTaJU}HJ} DVP71! literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/621131d8e28a67a6b4fb03c611f4375873d69678 b/src/sys/libwebm/webm_parser/fuzzing/corpus/621131d8e28a67a6b4fb03c611f4375873d69678 new file mode 100644 index 0000000..d037403 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/621131d8e28a67a6b4fb03c611f4375873d69678 @@ -0,0 +1 @@ +S�g�C�u������́ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/624cbd42e3ebf35a3a0ba55b3b4969b99054f84d b/src/sys/libwebm/webm_parser/fuzzing/corpus/624cbd42e3ebf35a3a0ba55b3b4969b99054f84d new file mode 100644 index 0000000000000000000000000000000000000000..0b518b97103ca60382df4ba846ce636d866c56f1 GIT binary patch literal 348 zcmb0LZb<(v7P2n;+qy5;6&M&9i;n_Hre+|)yc0+;bbyG^RX~z)4v4AzxVe!fI1k8l zRN6YH(Wwo{a!y_Zl2UE!Xmkk!DP;}Y4J6qfDlo8xYyz^_fh^YfKn6!{g8~D0k^@j8 zz!1o1lmObl0A&B{bu)7trX@K{4lrzF3@~bB3NUVD4lr#Af7r+hQZxgkX!5#=xea|u z4lN)>NhTnQNy-%@y|}}v$suG@YErI5LwfK^Y3FUFZGPjUYo8!^~!x?ZDXNzz9;kz=36Ut^*?g61Z^g literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6290103200631075988aa3566d8d8922599f8b6d b/src/sys/libwebm/webm_parser/fuzzing/corpus/6290103200631075988aa3566d8d8922599f8b6d new file mode 100644 index 0000000..52f240d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6290103200631075988aa3566d8d8922599f8b6d @@ -0,0 +1 @@ +�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/62a329f65143f1571dc4a2fbb256800c8ce4d89f b/src/sys/libwebm/webm_parser/fuzzing/corpus/62a329f65143f1571dc4a2fbb256800c8ce4d89f new file mode 100644 index 0000000000000000000000000000000000000000..eca1ba98fb0f374a519138ec2af23f2e60357f7c GIT binary patch literal 52 zcmb0LZb;uP6mmFyTXFH`^b;Fg7dIxlR5d2Kv@|lLv^OTZv^FxPpP1>=-k6epqS>Xr H1;_#bX#N*p literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/62f8a53cfb4dd625dcb31ee2ba258db3916a3bd0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/62f8a53cfb4dd625dcb31ee2ba258db3916a3bd0 new file mode 100644 index 0000000..a3a36dc --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/62f8a53cfb4dd625dcb31ee2ba258db3916a3bd0 @@ -0,0 +1 @@ +S�g�T�g�ss�gȒE��gȀD��D��D��gȀ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6318dc574b3ad7291fee7e01bfeaa674eb0feb48 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6318dc574b3ad7291fee7e01bfeaa674eb0feb48 new file mode 100644 index 0000000..baa7b64 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6318dc574b3ad7291fee7e01bfeaa674eb0feb48 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1�b@�P1� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6457a079debb9b532255e3e6ddf276b29808b49d b/src/sys/libwebm/webm_parser/fuzzing/corpus/6457a079debb9b532255e3e6ddf276b29808b49d new file mode 100644 index 0000000000000000000000000000000000000000..640d4a1fc416ccab4adefa47c14fc3de049bc343 GIT binary patch literal 3 KcmdnZ!T@)8f`fki_EFCJ?p2fn_#O0zxqX E039w6ivR!s literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6714df1ac1c54d4c30add212454e9513c6880767 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6714df1ac1c54d4c30add212454e9513c6880767 new file mode 100644 index 0000000..20b7616 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6714df1ac1c54d4c30add212454e9513c6880767 @@ -0,0 +1 @@ +S�g�T�k������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/68a6f9c2f62e9f57667de9563b5d612ec2f2c829 b/src/sys/libwebm/webm_parser/fuzzing/corpus/68a6f9c2f62e9f57667de9563b5d612ec2f2c829 new file mode 100644 index 0000000000000000000000000000000000000000..d8309eadaad21768e51f3687c556830f154cb48f GIT binary patch literal 37 ccmb1gz5m96!Kn#|+Z*0AIJGvQbDJ2M02{Lp2mk;8 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/69089b76cc62fe00615702bdd1f339e259194d42 b/src/sys/libwebm/webm_parser/fuzzing/corpus/69089b76cc62fe00615702bdd1f339e259194d42 new file mode 100644 index 0000000..f925002 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/69089b76cc62fe00615702bdd1f339e259194d42 @@ -0,0 +1 @@ +S�g�T�k������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/69d8622d24c7315f344c424297986170f7ef2243 b/src/sys/libwebm/webm_parser/fuzzing/corpus/69d8622d24c7315f344c424297986170f7ef2243 new file mode 100644 index 0000000..6182f76 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/69d8622d24c7315f344c424297986170f7ef2243 @@ -0,0 +1 @@ +S�g�C�u������́�́S�g�C�u������̀ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6a700d958cb3a7565d5a6b74540486874d52b4c7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6a700d958cb3a7565d5a6b74540486874d52b4c7 new file mode 100644 index 0000000..3c4a4a4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6a700d958cb3a7565d5a6b74540486874d52b4c7 @@ -0,0 +1 @@ +S�g�C�p�E�������@helloC|�lang0C~�area0C|�lang��S|1C�T�k���m��b@�P2���G*lang2C~�G腀area1 \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6a852150c5c2a12d325e78056687a8ea97b25fe7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6a852150c5c2a12d325e78056687a8ea97b25fe7 new file mode 100644 index 0000000..ca14558 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6a852150c5c2a12d325e78056687a8ea97b25fe7 @@ -0,0 +1 @@ +S�g�T�k��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6ac8c9f754d5ff3c0cd3f3f585de99dd73944bbe b/src/sys/libwebm/webm_parser/fuzzing/corpus/6ac8c9f754d5ff3c0cd3f3f585de99dd73944bbe new file mode 100644 index 0000000000000000000000000000000000000000..a7d88f00e039c8d3dbc55416ebd2ddd617e70d35 GIT binary patch literal 46 lcmb0LZb+XZ@4T(Fe{pXk149cl1H)TJ1||Up2}}uQW&mCX4SN6p literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6ace27a48f12990e2169cc099007aa5fa11962d2 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6ace27a48f12990e2169cc099007aa5fa11962d2 new file mode 100644 index 0000000..f544930 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6ace27a48f12990e2169cc099007aa5fa11962d2 @@ -0,0 +1 @@ +S�g�T�k���m��b@�T2�P2�P3P5� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6b10397dc3bff2ccf57be4fe3ff9d8d1acb8c76e b/src/sys/libwebm/webm_parser/fuzzing/corpus/6b10397dc3bff2ccf57be4fe3ff9d8d1acb8c76e new file mode 100644 index 0000000000000000000000000000000000000000..db9ed48f183cf09af04deaf5a474b00b51071c79 GIT binary patch literal 156 zcmb1gy}x*+Q(GgG)AvRer%w({3`|a+8(H2sFgP_iu#~4JfPsOL(WSG+x9{^Im&A_$P*A-RD8ZbT ypYPiMVk9LNg*!qRRWiZ5vuE#~xw(;X`;_kvjEo;07@0meFfwm)U}OodXaoROJ3Y_< literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6c3f1d96c06b853551f685dde821142928f55acf b/src/sys/libwebm/webm_parser/fuzzing/corpus/6c3f1d96c06b853551f685dde821142928f55acf new file mode 100644 index 0000000000000000000000000000000000000000..91f4e815dc5e992252f3e1131081f7fb8e1c3df8 GIT binary patch literal 25 gcmb0LZb+XZ@4T(Fe{pXk149ct0|O%?6B9Et0BrUKO8@`> literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6c8de4d4bbb5294154c3b140d43836757b9f08ac b/src/sys/libwebm/webm_parser/fuzzing/corpus/6c8de4d4bbb5294154c3b140d43836757b9f08ac new file mode 100644 index 0000000..8aefea2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6c8de4d4bbb5294154c3b140d43836757b9f08ac @@ -0,0 +1 @@ +S�g�I�f�{��! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6cf122ee328af5cf6f18d5f9546b0fe761951b8d b/src/sys/libwebm/webm_parser/fuzzing/corpus/6cf122ee328af5cf6f18d5f9546b0fe761951b8d new file mode 100644 index 0000000000000000000000000000000000000000..56346390ca16d37bc5078685da9d23a6f3ec802f GIT binary patch literal 128 zcmb0LP7hhva7`?G-TCVZ3=G9b6&NIf8`7tUg)lS&`8$EQ1BgRcF)+*l(#nsU8-nwI z45h7e8rpz#@*)M1b=m#vdUG4Pk{sFt3|ibDH7bIP=n@NAm)*LqnL)L!qakb+Q0;CY SegMQf8y_nCXJE)}0I~tKAS%BA literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6cfbbc25caa217e22fd7ca3e92d2051c5f661bdb b/src/sys/libwebm/webm_parser/fuzzing/corpus/6cfbbc25caa217e22fd7ca3e92d2051c5f661bdb new file mode 100644 index 0000000..bc69d35 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6cfbbc25caa217e22fd7ca3e92d2051c5f661bdb @@ -0,0 +1 @@ +S�g�C�u������̀ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6d703bc900e74d1a576bebcccb63e3b2701ae86d b/src/sys/libwebm/webm_parser/fuzzing/corpus/6d703bc900e74d1a576bebcccb63e3b2701ae86d new file mode 100644 index 0000000..e0bdcf2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6d703bc900e74d1a576bebcccb63e3b2701ae86d @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1�b@�b@�P1� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6e1afa81dfcd6833705d84b45881f085c19b2211 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6e1afa81dfcd6833705d84b45881f085c19b2211 new file mode 100644 index 0000000..670dd7c --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6e1afa81dfcd6833705d84b45881f085c19b2211 @@ -0,0 +1 @@ +S�g�C�u���u������! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6e244ec3b81e0d2f8b5810854859e1b8140422d9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6e244ec3b81e0d2f8b5810854859e1b8140422d9 new file mode 100644 index 0000000..2e7c1a4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6e244ec3b81e0d2f8b5810854859e1b8140422d9 @@ -0,0 +1 @@ +S�g�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6e323b4c733df90d55c754e099fb5a13bd9701cb b/src/sys/libwebm/webm_parser/fuzzing/corpus/6e323b4c733df90d55c754e099fb5a13bd9701cb new file mode 100644 index 0000000..89e0e79 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/6e323b4c733df90d55c754e099fb5a13bd9701cb @@ -0,0 +1 @@ +S�g�T�k�����T�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/6e36720f3f55dc0cd5d585c6770572964719b5b8 b/src/sys/libwebm/webm_parser/fuzzing/corpus/6e36720f3f55dc0cd5d585c6770572964719b5b8 new file mode 100644 index 0000000000000000000000000000000000000000..376c75bf6dda4c072fb3f485354108b4331ac6bd GIT binary patch literal 56 zcmb1gy}!7_smXz*JT)m-BDf*l;h3QB?2=yJ-2w~@?7?e*BqNhp$hz$AbwDQDLm%J=k012l8mH+?% literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/745e32f46833c075c8e68552e0fbbcdd5ec52641 b/src/sys/libwebm/webm_parser/fuzzing/corpus/745e32f46833c075c8e68552e0fbbcdd5ec52641 new file mode 100644 index 0000000000000000000000000000000000000000..518d182473dd1c5e91cd6335c392ac3cd9a2db1f GIT binary patch literal 15 WcmaFU@TTDng8&1=n?{B?4C?_rBL%K&AL;79;=j8=ETz78Wwz>F7V=7}j7|{Bd7A@+ TP;n#6J_k0SLe^~#DnJSV*Tfm{ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7528086eea404dccc3ee5b214befbc2a95676feb b/src/sys/libwebm/webm_parser/fuzzing/corpus/7528086eea404dccc3ee5b214befbc2a95676feb new file mode 100644 index 0000000..40b7db2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/7528086eea404dccc3ee5b214befbc2a95676feb @@ -0,0 +1 @@ +S�g�T�k�����#���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7528f9f08f80c8e85951aa1db2dc616e992c1a62 b/src/sys/libwebm/webm_parser/fuzzing/corpus/7528f9f08f80c8e85951aa1db2dc616e992c1a62 new file mode 100644 index 0000000000000000000000000000000000000000..87b29be574d05ccba453b19a81980a7e026a7966 GIT binary patch literal 26 gcmb0LZb+Xh;JmzGg6q!SZQTu>tqu&%bqzoS0Fj6a{r~^~ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/75af94f9695c375e5eb620849f0213ad41e8f205 b/src/sys/libwebm/webm_parser/fuzzing/corpus/75af94f9695c375e5eb620849f0213ad41e8f205 new file mode 100644 index 0000000000000000000000000000000000000000..dcf5dc6230bd43e82a37793d15d9b8986c15c9d0 GIT binary patch literal 39 rcmb0LZb)A&@4T&a-hw#`TN@dGU{MQ*DqYwx+kxS?14HSehCT-XC~^+G literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/75e1ff2e016b7b80ecb7a6a1f4c3238a2a2ed130 b/src/sys/libwebm/webm_parser/fuzzing/corpus/75e1ff2e016b7b80ecb7a6a1f4c3238a2a2ed130 new file mode 100644 index 0000000000000000000000000000000000000000..9dcbbb5378a1aacabbdb810fa911dfac0075ee0d GIT binary patch literal 18 Zcmb0LZbBDf)arM&aD(k0Iw7#UYPFfuJ}ZJZ5cE^uH0QVb9Z%0pGn P3{}kl1dCgn7#NrUlt&#h literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7670db89e0c3fe492c91458de219c3be34a3dcb7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/7670db89e0c3fe492c91458de219c3be34a3dcb7 new file mode 100644 index 0000000000000000000000000000000000000000..c57ba43505f93cfa45f1a323909032b712f81583 GIT binary patch literal 118 zcmb1gy}P)>smXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfy%eZDL?x&|2UiFx!Fg?vfxsV}w M5m2bLi9wYE0G47W=l}o! literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7880e2ae55d255065ad415c4c625e1b63bfd2a93 b/src/sys/libwebm/webm_parser/fuzzing/corpus/7880e2ae55d255065ad415c4c625e1b63bfd2a93 new file mode 100644 index 0000000..e2fb6ac --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/7880e2ae55d255065ad415c4c625e1b63bfd2a93 @@ -0,0 +1 @@ +DzS�g�T�k���m��b@�P5��G�G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/78cb3d726e4f9e8bc89b399fa514c3b600bf8e5a b/src/sys/libwebm/webm_parser/fuzzing/corpus/78cb3d726e4f9e8bc89b399fa514c3b600bf8e5a new file mode 100644 index 0000000000000000000000000000000000000000..fc42e545b9c0cdbc7cbf8c829256a3924f604014 GIT binary patch literal 185 zcmb1gy}$UsQwY9{_2~I0X`Cl6T%#+V&jG6bs&+-3>C5Z8M0^DBx_hyr9>0 fCy>MLx(6&I1T}?$ffs6u2D*6q36Of1c91v#FWN7w literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/79ba60931988a5974328a73fe091bdf6f5992891 b/src/sys/libwebm/webm_parser/fuzzing/corpus/79ba60931988a5974328a73fe091bdf6f5992891 new file mode 100644 index 0000000000000000000000000000000000000000..c6837fd70eb1e2459775b9f76b88daa1d659f0a1 GIT binary patch literal 24 gcmaFUaHb)|sZDF;JBD}f-nGAB5MW@Ce)sMT0HbCM#sB~S literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/79cdb8dec1ad07b389f544a511f89b347429837e b/src/sys/libwebm/webm_parser/fuzzing/corpus/79cdb8dec1ad07b389f544a511f89b347429837e new file mode 100644 index 0000000000000000000000000000000000000000..68e6b7d0bb5a77d5cc4925adab439e5e9ac1545f GIT binary patch literal 52 zcmb0LZb;uP6mmFyTXFH`^b;Fg7dIxlR5d2Kv@|lfv^OTZv^FxPpO^_`rlg-}c4=<` FvH)fN7e4?1 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7ab8c6a65c39907f4afa4e2b294303aebb6b22d8 b/src/sys/libwebm/webm_parser/fuzzing/corpus/7ab8c6a65c39907f4afa4e2b294303aebb6b22d8 new file mode 100644 index 0000000..fddf510 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/7ab8c6a65c39907f4afa4e2b294303aebb6b22d8 @@ -0,0 +1 @@ +����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7b12a398a1860ac2f3930d5020e422aec061f177 b/src/sys/libwebm/webm_parser/fuzzing/corpus/7b12a398a1860ac2f3930d5020e422aec061f177 new file mode 100644 index 0000000..fed31c6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/7b12a398a1860ac2f3930d5020e422aec061f177 @@ -0,0 +1 @@ +S�g�T�k����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7bf1682743405f3d5b3433830eadae4ea311807d b/src/sys/libwebm/webm_parser/fuzzing/corpus/7bf1682743405f3d5b3433830eadae4ea311807d new file mode 100644 index 0000000..d8666eb --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/7bf1682743405f3d5b3433830eadae4ea311807d @@ -0,0 +1 @@ +S�g�T�g�ss�gȩȄ#��dgȄ]��egȄD��dgȄ]��egȄD��gȄD��dgȁg \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7c7ef0e305f37f833708b375271d59300d120d84 b/src/sys/libwebm/webm_parser/fuzzing/corpus/7c7ef0e305f37f833708b375271d59300d120d84 new file mode 100644 index 0000000..c9cedc0 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/7c7ef0e305f37f833708b375271d59300d120d84 @@ -0,0 +1 @@ +S�g�T�k���ᅟ� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7d06bd4a7de57953ef09c2e18ca67aa7ff367c76 b/src/sys/libwebm/webm_parser/fuzzing/corpus/7d06bd4a7de57953ef09c2e18ca67aa7ff367c76 new file mode 100644 index 0000000..6cce7cb --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/7d06bd4a7de57953ef09c2e18ca67aa7ff367c76 @@ -0,0 +1 @@ +S�g�T�g�ss�gȄE��! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7d31bd53bb7eb7b1f354c5f85d376390760ab16f b/src/sys/libwebm/webm_parser/fuzzing/corpus/7d31bd53bb7eb7b1f354c5f85d376390760ab16f new file mode 100644 index 0000000000000000000000000000000000000000..f3569497024588939604a090742b6946f6f48d0e GIT binary patch literal 32 ocmb0LZb+Xa;JmzGy6es<+a?`p2n%VL=)f?^fuX^HVVeU30N(8kkpKVy literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/7d67ef4d0c681655d4b4e93e848d56865630390b b/src/sys/libwebm/webm_parser/fuzzing/corpus/7d67ef4d0c681655d4b4e93e848d56865630390b new file mode 100644 index 0000000000000000000000000000000000000000..ca4a486f2feea1c22fecb0080a008788eecc7c3b GIT binary patch literal 17 Wcmb0LZbXkqV=Cu5L w-v$sPDX}Qr5yGgF3ErJOd-u%Ejf~r;e0N}E{OG{Q^ud9Vd6NSpOK?Ra09D^T&j0`b literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8206d92b710c04ce0bd706cec25fbb72014c79bf b/src/sys/libwebm/webm_parser/fuzzing/corpus/8206d92b710c04ce0bd706cec25fbb72014c79bf new file mode 100644 index 0000000000000000000000000000000000000000..a1233fdeb8e444d75a7b0df4bc7d06036c55917a GIT binary patch literal 64 zcmb0LZb;uP6mmFyTXFH`^b@mP7dIxlR5d2Kv@|lfv^OTZv^FxPpJ)LxQy^3-gi3=@ F=>VR^9QObK literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/822926c528d16c0a9ca4c48a25651f6a0730d797 b/src/sys/libwebm/webm_parser/fuzzing/corpus/822926c528d16c0a9ca4c48a25651f6a0730d797 new file mode 100644 index 0000000..f4269d0 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/822926c528d16c0a9ca4c48a25651f6a0730d797 @@ -0,0 +1 @@ +S�g�C�p�E����VT�!S�g�C�p�E���@sā�@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/82d80b6051f0750777bdc37319851741144b3671 b/src/sys/libwebm/webm_parser/fuzzing/corpus/82d80b6051f0750777bdc37319851741144b3671 new file mode 100644 index 0000000..43b170b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/82d80b6051f0750777bdc37319851741144b3671 @@ -0,0 +1 @@ +S�g�C�u������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/830c73748baaa10c2016d04b408a7f481882cd89 b/src/sys/libwebm/webm_parser/fuzzing/corpus/830c73748baaa10c2016d04b408a7f481882cd89 new file mode 100644 index 0000000000000000000000000000000000000000..11b45e96bd0ba5ca55b121a9b309d94a0b472259 GIT binary patch literal 88 zcmb0LP7hhva7`?G-TCVZ3=G9bfkZP9?*!rwAP!x{z%U0$D?e^-2+jjCl(t$mv;pbl aO+Z4mt)n4q6_BwTh#vs)Lml;DR E0O0%+f&c&j literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/832fad0e723027e5bd74726b1722a838183dada7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/832fad0e723027e5bd74726b1722a838183dada7 new file mode 100644 index 0000000..3545ab8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/832fad0e723027e5bd74726b1722a838183dada7 @@ -0,0 +1 @@ +S�g�T�g�ss�gȄD�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/83b78d2ad8afd0729de45b4d9fdd765a949d8073 b/src/sys/libwebm/webm_parser/fuzzing/corpus/83b78d2ad8afd0729de45b4d9fdd765a949d8073 new file mode 100644 index 0000000..5cb98fe --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/83b78d2ad8afd0729de45b4d9fdd765a949d8073 @@ -0,0 +1 @@ +S�g�C�p�E�������@helloC|�lang0C~�area0C|�lang1C|C�p�E \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/84a04bf3e15345f5c992bc6732a42b95857631a7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/84a04bf3e15345f5c992bc6732a42b95857631a7 new file mode 100644 index 0000000..e89d0d1 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/84a04bf3e15345f5c992bc6732a42b95857631a7 @@ -0,0 +1 @@ +S�g�C�u������́�́ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/84d3a72c434074ee0d810fb2357047efd23f58f6 b/src/sys/libwebm/webm_parser/fuzzing/corpus/84d3a72c434074ee0d810fb2357047efd23f58f6 new file mode 100644 index 0000000000000000000000000000000000000000..e22f95bb90bfd374c1a26435c268d5b8f3731996 GIT binary patch literal 126 zcmb0LZb+Xa6mmFydU5fT4lF>*d7A?_P>5xl155FfMph677=S!BkO|X3CQNkQ*#}X<2%(q& DM@KWl literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8659fe309298ca90f201ac7ced95b9d0de510eeb b/src/sys/libwebm/webm_parser/fuzzing/corpus/8659fe309298ca90f201ac7ced95b9d0de510eeb new file mode 100644 index 0000000..77449c7 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/8659fe309298ca90f201ac7ced95b9d0de510eeb @@ -0,0 +1 @@ +S�g�C�u��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/866cf21064b9e20eded44e2e096fd9ce6185ce86 b/src/sys/libwebm/webm_parser/fuzzing/corpus/866cf21064b9e20eded44e2e096fd9ce6185ce86 new file mode 100644 index 0000000000000000000000000000000000000000..f3a4ddd54547ba8ef656d7e09c50a189e71ee06d GIT binary patch literal 8 PcmZ>N#K6kHaOMmE3hM&L literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8864c6c9319ef120d3accb7b70c32c8f5c1ebccb b/src/sys/libwebm/webm_parser/fuzzing/corpus/8864c6c9319ef120d3accb7b70c32c8f5c1ebccb new file mode 100644 index 0000000000000000000000000000000000000000..d6f7c00cff5a3d6c26a5ed8a2cc604e1024f33eb GIT binary patch literal 10 Rcmey(ETHg*fq^mo4*(Mg1CIaz literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/88f01cffe9972bf447a21034c45f6b943ea3ec07 b/src/sys/libwebm/webm_parser/fuzzing/corpus/88f01cffe9972bf447a21034c45f6b943ea3ec07 new file mode 100644 index 0000000000000000000000000000000000000000..97754f40b8cc1dc10921db2c6bfbe6fb217fa964 GIT binary patch literal 36 rcmb0LZb;uC@4T&a^@5cPTZ0)Sn!HAa;OW^VSA2I1FfatK5ny3pWEAwBUD68{U=LoC z!T^+DWD=Ef{g0~g|4Mo1ZKa+o(>k=SZxjToVT7{5>OpdC&p}K^`TL98odo^^4Uqr} t0?5k#V&HBh%tmseP{ZmD3usrI^G*)^)D~>ST+$4gdgJIm`e6 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8c695cbcc43e37ce25194c4b61b3d87488b308a1 b/src/sys/libwebm/webm_parser/fuzzing/corpus/8c695cbcc43e37ce25194c4b61b3d87488b308a1 new file mode 100644 index 0000000..6219e9f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/8c695cbcc43e37ce25194c4b61b3d87488b308a1 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1�S�g�T�k���m��b@�P5�G��S�g�T�k���m��b@�P5�P5�Ps�P5�S�g�T�k���m��b@�P1�b@�P1�S�g�T�k�����T�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8c9dc3c5a839f90f29256ef8c8f1369bc7383817 b/src/sys/libwebm/webm_parser/fuzzing/corpus/8c9dc3c5a839f90f29256ef8c8f1369bc7383817 new file mode 100644 index 0000000..85078ca --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/8c9dc3c5a839f90f29256ef8c8f1369bc7383817 @@ -0,0 +1 @@ +WA������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8cdcf83eb89d7e5c87cfa1b8811c95f738747a6a b/src/sys/libwebm/webm_parser/fuzzing/corpus/8cdcf83eb89d7e5c87cfa1b8811c95f738747a6a new file mode 100644 index 0000000..8db4eec --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/8cdcf83eb89d7e5c87cfa1b8811c95f738747a6a @@ -0,0 +1 @@ +S�g�I�f�M��! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8d0c6e6b3d74233685c3a2c1793d1a7b0ae2e34d b/src/sys/libwebm/webm_parser/fuzzing/corpus/8d0c6e6b3d74233685c3a2c1793d1a7b0ae2e34d new file mode 100644 index 0000000000000000000000000000000000000000..b4ef3d53814af60837b8df408c239a37dc5d1bfc GIT binary patch literal 18 Zcmb0LZb=-q->WY6J?k N7avJK(E=1p2LO8E8~*?R literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8f403efbef079f1775b63bcf1061983e4c5d2162 b/src/sys/libwebm/webm_parser/fuzzing/corpus/8f403efbef079f1775b63bcf1061983e4c5d2162 new file mode 100644 index 0000000..7a0e070 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/8f403efbef079f1775b63bcf1061983e4c5d2162 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/8f8f956eaaf8f7f5e65002be888b946218f0f7ce b/src/sys/libwebm/webm_parser/fuzzing/corpus/8f8f956eaaf8f7f5e65002be888b946218f0f7ce new file mode 100644 index 0000000..7ebec69 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/8f8f956eaaf8f7f5e65002be888b946218f0f7ce @@ -0,0 +1 @@ +������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������!�����������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������!�����������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������!�����������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;����������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������!�����������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;����������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������w�������������������������������������������������������������������������������������������������������������������������������������������������������������������;����������������������������������������������������m����������݀������������������������������������������������������������������������������������������������嶀������Eߣ��������m����������݀���������������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/90a03241b5cc656b7c2a4ef55664b0320fa3bd43 b/src/sys/libwebm/webm_parser/fuzzing/corpus/90a03241b5cc656b7c2a4ef55664b0320fa3bd43 new file mode 100644 index 0000000..ac88482 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/90a03241b5cc656b7c2a4ef55664b0320fa3bd43 @@ -0,0 +1 @@ +S�g�C�u���u���������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/925a91e7c25a43d9da8b63eba51ed66a52d833aa b/src/sys/libwebm/webm_parser/fuzzing/corpus/925a91e7c25a43d9da8b63eba51ed66a52d833aa new file mode 100644 index 0000000000000000000000000000000000000000..8eac37e5ef74069e5e8510831b96fd5b166c33ae GIT binary patch literal 42 wcmWGxaF7UYNS`70rX^$@L-yo#6LTBX`;r*`TRF4@7&bB{IkYe`0U1op08%avcmMzZ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/92de5c217802ec24886240188dca293325eb17c9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/92de5c217802ec24886240188dca293325eb17c9 new file mode 100644 index 0000000..8237f0b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/92de5c217802ec24886240188dca293325eb17c9 @@ -0,0 +1 @@ +S�g�T�k���Sn�! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/939da66e1fc8bb9854865066ee47b6ac4b933aa9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/939da66e1fc8bb9854865066ee47b6ac4b933aa9 new file mode 100644 index 0000000000000000000000000000000000000000..f5179b1469473fda4c255ff5293545fefccaf5b0 GIT binary patch literal 107 zcmb0LZb<(l;JmzGyX(#^+cq^UXmw!CD9K69ajt94Nz6+(0Mdy?sfi$3iuL~D1`GgH jWa#{-F3%{Z)j2(}6(OH!DCK&8K~G;-0|NuY0tW{G281q@ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/93a91331e7c3c060f461ae1f22e2bbf4747ffe33 b/src/sys/libwebm/webm_parser/fuzzing/corpus/93a91331e7c3c060f461ae1f22e2bbf4747ffe33 new file mode 100644 index 0000000000000000000000000000000000000000..1b2868432336c55b158218032f22420e556f7ebd GIT binary patch literal 64 zcmb0LZb;uP6mmFyTXFH`^b;GbTvsPkLwKg)iwEpjONp56pO+PWyrM Q?9$ran3jH`1t^vd0HqTgssI20 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/94f6dfc499cbf2e84ffe1d69cb751ada9f2f2e3a b/src/sys/libwebm/webm_parser/fuzzing/corpus/94f6dfc499cbf2e84ffe1d69cb751ada9f2f2e3a new file mode 100644 index 0000000..30a5c63 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/94f6dfc499cbf2e84ffe1d69cb751ada9f2f2e3a @@ -0,0 +1 @@ +S�g�C�u����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9539fef8ffb9f7c542061f1af1f3f98e9a714cc3 b/src/sys/libwebm/webm_parser/fuzzing/corpus/9539fef8ffb9f7c542061f1af1f3f98e9a714cc3 new file mode 100644 index 0000000000000000000000000000000000000000..0ea96501d095ffe58d28cd53c8dc7e925d5453ab GIT binary patch literal 1132 zcmb0LZb)A&@4T&a-hw#`TN@dGU{MQ*DqYwx%Yor{3q$FmhCT-d381`PE8=g@oDNv@0G`95B2Pja=pK}!>P%E zr93q$mzrLqL3j{y>+cpCMuS9fIxx~()Z6+>7rbaX(;$SI3}|gXf#_KT^gjLsMO*;Z z;!ToR6F+`yC4xce7(DbZn8oMOD9s>;lSFW1`btodvE;eKYevS^ F4gl^Cr49f9 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/953c9a616ea56067225c88fccc6423496f2501a6 b/src/sys/libwebm/webm_parser/fuzzing/corpus/953c9a616ea56067225c88fccc6423496f2501a6 new file mode 100644 index 0000000000000000000000000000000000000000..249824c23f9a4957c59810fe13936e1c0415b5cd GIT binary patch literal 39 scmb0#y}!7_smXz*JT)m-BDf)as=V{I(h1KU7#27%EN*RN00JNj04dcCp#T5? literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/95a60268c555a77c1010d75bb44142af47635486 b/src/sys/libwebm/webm_parser/fuzzing/corpus/95a60268c555a77c1010d75bb44142af47635486 new file mode 100644 index 0000000..a95f40a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/95a60268c555a77c1010d75bb44142af47635486 @@ -0,0 +1 @@ +������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������w��������������������������������������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/95e410025b965cf6ab2e8e2d3559efbe71c1a972 b/src/sys/libwebm/webm_parser/fuzzing/corpus/95e410025b965cf6ab2e8e2d3559efbe71c1a972 new file mode 100644 index 0000000000000000000000000000000000000000..8eddf69a2e5f1ec12fae1699db3bdca27c20988f GIT binary patch literal 44 icmb1gb^6rsropMT;Z2hRgA)jUM&?H`IJHA$8JPgLv=XiW literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9671f253d1eb7cd504a5617058ce4c01a80c897e b/src/sys/libwebm/webm_parser/fuzzing/corpus/9671f253d1eb7cd504a5617058ce4c01a80c897e new file mode 100644 index 0000000000000000000000000000000000000000..f0b837c7238932d2580ce21ecaf91ca5832e646d GIT binary patch literal 15 WcmaFS@TTDng8&1=n?{B?4C?_q=LU%Y literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9698d3424f1581a6bbb66c764f14c95a74b87675 b/src/sys/libwebm/webm_parser/fuzzing/corpus/9698d3424f1581a6bbb66c764f14c95a74b87675 new file mode 100644 index 0000000000000000000000000000000000000000..3aedc3202faeaf2bd038236efb773b42e8e06efd GIT binary patch literal 64 zcmb0LZb;uP6mmFyTXFH`^b;Fg7dIxlR835BX=!9|X>Uw+X>DXoKQR-?Oi4e{4dkV! MpJ)N{(jZhi0H^OAHUIzs literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/96f7f38de1f8601311733984cf51cec35500dabe b/src/sys/libwebm/webm_parser/fuzzing/corpus/96f7f38de1f8601311733984cf51cec35500dabe new file mode 100644 index 0000000..1230f4c --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/96f7f38de1f8601311733984cf51cec35500dabe @@ -0,0 +1 @@ +U���M \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/970ab6333aa5ccf8c2dc14bb56814f7bb4303b94 b/src/sys/libwebm/webm_parser/fuzzing/corpus/970ab6333aa5ccf8c2dc14bb56814f7bb4303b94 new file mode 100644 index 0000000000000000000000000000000000000000..cf0c884ea028132a858fe50e2b94edea51e918e6 GIT binary patch literal 53 zcmb0LZb;uC@4T&a^@5cPTbmd-7#J3{G&3+TlrC&u=D>guVq_{^)cC*8f%%040{|4F B6G#96 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/98978113d2116dc4bdbb10265fa32bd95230bdb6 b/src/sys/libwebm/webm_parser/fuzzing/corpus/98978113d2116dc4bdbb10265fa32bd95230bdb6 new file mode 100644 index 0000000..0da5825 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/98978113d2116dc4bdbb10265fa32bd95230bdb6 @@ -0,0 +1 @@ +S�g�C�u���u��������S�g�C�u���u������!S�g�C�u���u��������S�g�C�u���u������! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/989e2872d2a34de543f23c5061db68212d8258f7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/989e2872d2a34de543f23c5061db68212d8258f7 new file mode 100644 index 0000000000000000000000000000000000000000..3430234146c1fc024a47a73e204e5826e3506e54 GIT binary patch literal 21 ccmdnl{6FQvf5jC*>ivJk#{Ucq|Nlw@0G2Tf)Bpeg literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/98ca9a00ad571c4454fce709d5405e5aca2a363c b/src/sys/libwebm/webm_parser/fuzzing/corpus/98ca9a00ad571c4454fce709d5405e5aca2a363c new file mode 100644 index 0000000..938e0bc --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/98ca9a00ad571c4454fce709d5405e5aca2a363c @@ -0,0 +1 @@ +Eߣ�B�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9965361765a4151902ec04fb21d9247b3a5ed10d b/src/sys/libwebm/webm_parser/fuzzing/corpus/9965361765a4151902ec04fb21d9247b3a5ed10d new file mode 100644 index 0000000..6ec73d4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/9965361765a4151902ec04fb21d9247b3a5ed10d @@ -0,0 +1 @@ +S�g�T�k�����#��@�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/99d6fe94a50faa50db9d7eb38d74bc3cc8417dc1 b/src/sys/libwebm/webm_parser/fuzzing/corpus/99d6fe94a50faa50db9d7eb38d74bc3cc8417dc1 new file mode 100644 index 0000000000000000000000000000000000000000..0dcb93ea81d8547efa4fa962e4c52740d419ad28 GIT binary patch literal 39 lcmb0LZb)Aw>bWv)uGaO94KAGu3=A%bAOg;+UTMp~0007F3ibd1 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9a6869cec3dc84f2051bfaf0ee0d3552aa221f89 b/src/sys/libwebm/webm_parser/fuzzing/corpus/9a6869cec3dc84f2051bfaf0ee0d3552aa221f89 new file mode 100644 index 0000000000000000000000000000000000000000..32ad695ce24e33c9ce8a47e7d5520a686679671a GIT binary patch literal 218 zcmb1gy}P)>smXz*T*~$S;tnqmD>W%sBDf*l;h3QB?2=yJ-2w~@?7^#nBx55E5kcRT zX&qYEzkt**$vbZ=ZF>%4G9s8j*^OW!QO}id1_3=xVj=6YyVn7=v0Vr21@UJi_)Idv byR*9wf#f%XAMgWay3k3iG literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9cca361865a4fbff75abdbb79c1e91706780576c b/src/sys/libwebm/webm_parser/fuzzing/corpus/9cca361865a4fbff75abdbb79c1e91706780576c new file mode 100644 index 0000000..6735729 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/9cca361865a4fbff75abdbb79c1e91706780576c @@ -0,0 +1 @@ +S�g�T�k������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9d8e99f07604d6cb05ef613d41cbfb93b2aff787 b/src/sys/libwebm/webm_parser/fuzzing/corpus/9d8e99f07604d6cb05ef613d41cbfb93b2aff787 new file mode 100644 index 0000000..96aa349 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/9d8e99f07604d6cb05ef613d41cbfb93b2aff787 @@ -0,0 +1 @@ +S�g�T�k�������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9ecd61eaf2681a882473247a603b9f30c2663d49 b/src/sys/libwebm/webm_parser/fuzzing/corpus/9ecd61eaf2681a882473247a603b9f30c2663d49 new file mode 100644 index 0000000..256c70d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/9ecd61eaf2681a882473247a603b9f30c2663d49 @@ -0,0 +1 @@ +S�g�C�u�������́�́ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9f0a3b7c0814b4f80c0745161c8769f63098981b b/src/sys/libwebm/webm_parser/fuzzing/corpus/9f0a3b7c0814b4f80c0745161c8769f63098981b new file mode 100644 index 0000000000000000000000000000000000000000..fe2403bb5bd5e979f6ecf9d5cc8500927a1f3498 GIT binary patch literal 19 Zcmb0LZb((2A3K|)qJP?PG31rYTv5jIQIYm literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/9fae60819c28d4fcc88a6a1b93dcf69b4e458203 b/src/sys/libwebm/webm_parser/fuzzing/corpus/9fae60819c28d4fcc88a6a1b93dcf69b4e458203 new file mode 100644 index 0000000000000000000000000000000000000000..9194d9d28c18324534d0f6c3e97c273b4c41f0c3 GIT binary patch literal 6 NcmaFU!obMH3;+l$0e1iZ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a02431cf7c501a5b368c91e41283419d8fa9fb03 b/src/sys/libwebm/webm_parser/fuzzing/corpus/a02431cf7c501a5b368c91e41283419d8fa9fb03 new file mode 100644 index 0000000000000000000000000000000000000000..17706ff6b3fca632b077b72117a5df5883610154 GIT binary patch literal 2 JcmYdc0002W0A&CG literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a0ac6c3c83817637bbbcb11a5106c57aa6654afb b/src/sys/libwebm/webm_parser/fuzzing/corpus/a0ac6c3c83817637bbbcb11a5106c57aa6654afb new file mode 100644 index 0000000000000000000000000000000000000000..a5d2ab48564fd72270ff8c82a4da85aa7aa85e88 GIT binary patch literal 12 Tcmb1gy}!8Ksj0;ylYs#MAgu&q literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a15fdfa620d19a92d9eaa9f3f13010e53f902796 b/src/sys/libwebm/webm_parser/fuzzing/corpus/a15fdfa620d19a92d9eaa9f3f13010e53f902796 new file mode 100644 index 0000000..d5b108f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/a15fdfa620d19a92d9eaa9f3f13010e53f902796 @@ -0,0 +1 @@ +S�g�C�p�E���@�@B�@�XC�@sā�@sā�@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a18e76ae792a054c2f6d0d01e0e78d58678b35e3 b/src/sys/libwebm/webm_parser/fuzzing/corpus/a18e76ae792a054c2f6d0d01e0e78d58678b35e3 new file mode 100644 index 0000000..135e70d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/a18e76ae792a054c2f6d0d01e0e78d58678b35e3 @@ -0,0 +1 @@ +S�g�T�k�����! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a19d04f18f574e561d793ac0dfcffe2b38183eb1 b/src/sys/libwebm/webm_parser/fuzzing/corpus/a19d04f18f574e561d793ac0dfcffe2b38183eb1 new file mode 100644 index 0000000..cb84077 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/a19d04f18f574e561d793ac0dfcffe2b38183eb1 @@ -0,0 +1 @@ +"��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a26fb85be3d2bb8a2360bb4d9533a1651bd12d99 b/src/sys/libwebm/webm_parser/fuzzing/corpus/a26fb85be3d2bb8a2360bb4d9533a1651bd12d99 new file mode 100644 index 0000000000000000000000000000000000000000..6fb743bb3862fb5a09391f4e0f7eeeca3a86c2fa GIT binary patch literal 50 ucmb1gy}z)-smXz*Ts0|IBDf)as=V{I(h1KU7*;zlEN*R-a+P930So}RO$}!N literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a2e860fae30005a9e75b61f54f3d019c44090fcc b/src/sys/libwebm/webm_parser/fuzzing/corpus/a2e860fae30005a9e75b61f54f3d019c44090fcc new file mode 100644 index 0000000..124e7d6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/a2e860fae30005a9e75b61f54f3d019c44090fcc @@ -0,0 +1 @@ +D���VT� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a3071bfcb7b2fd3c4286ea42e1f7940754b55697 b/src/sys/libwebm/webm_parser/fuzzing/corpus/a3071bfcb7b2fd3c4286ea42e1f7940754b55697 new file mode 100644 index 0000000000000000000000000000000000000000..f16be68912be0d06827175bdafb1e0bb292420a9 GIT binary patch literal 56 vcmb0LZb�;�8�5�2�/�,�)�&�#� ������� ����~��~��~��~��~�~�~��~�~�~�~�~޶~۶~ض~ն~Ҷ~϶~̶~ɶ~ƶ~ö~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~��~~�~{�~x�~u�~r�~o�~l�~i�~f�~c�~`�~]�~Z�~W�~T�~Q�~N�~K�~H�~E�~B�~?�~<�~9�~6�~3�~0�~-�~*�~'�~$�~!�~�~�~�~�~�~�~ �~ �~�~�~�}��}��}��}��}�}�}�}�}�}�}߶}ܶ}ٶ}ֶ}Ӷ}ж}Ͷ}ʶ}Ƕ}Ķ}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}��}�}|�}y�}v�}s�}p�}m�}j�}g�}d�}a�}^�}[�}X�}U�}R�}O�}L�}I�}F�}C�}@�}=�}:�}7�}4�}1�}.�}+�}(�}%�}"�}�}�}�}�}�}�} �} +�}�}�}�|��|��|��|��|�|�|�|�|�|�|�|ݶ|ڶ|׶|Զ|Ѷ|ζ|˶|ȶ|Ŷ|¶|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|��|}�|z�|w�|t�|q�|n�|k�|h�|e�|b�|_�|\�|Y�|V�|S�|P�|M�|J�|G�|D�|A�|>�|;�|8�|5�|2�|/�|,�|)�|&�|#�| �|�|�|�|�|�|�| �|�|�|�{��{��{��{��{�{�{��{�{�{�{�{޶{۶{ض{ն{Ҷ{϶{̶{ɶ{ƶ{ö{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{��{~�{{�{x�{u�{r�{o�{l�{i�{f�{c�{`�{]�{Z�{W�{T�{Q�{N�{K�{H�{E�{B�{?�{<�{9�{6�{3�{0�{-�{*�{'�{$�{!�{�{�{�{�{�{�{ �{ �{�{�{�z��z��z��z��z�z�z�z�z�z�z߶zܶzٶzֶzӶzжzͶzʶzǶzĶz��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z��z�z|�zy�zv�zs�zp�zm�zj�zg�zd�za�z^�z[�zX�zU�zR�zO�zL�zI�zF�zC�z@�z=�z:�z7�z4�z1�z.�z+�z(�z%�z"�z�z�z�z�z�z�z �z +�z�z�z�y��y��y��y��y�y�y�y�y�y�y�yݶyڶy׶yԶyѶyζy˶yȶyŶy¶y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y��y}�yz�yw�yt�yq�yn�yk�yh�ye�yb�y_�y\�yY�yV�yS�yP�yM�yJ�yG�yD�yA�y>�y;�y8�y5�y2�y/�y,�y)�y&�y#�y �y�y�y�y�y�y�y �y�y�y�x��x��x��x��x�x�x��x�x�x�x�x޶x۶xضxնxҶx϶x̶xɶxƶxöx��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x��x~�x{�xx�xu�xr�xo�xl�xi�xf�xc�x`�x]�xZ�xW�xT�xQ�xN�xK�xH�xE�xB�x?�x<�x9�x6�x3�x0�x-�x*�x'�x$�x!�x�x�x�x�x�x�x �x �x�x�x�w��w��w��w��w�w�w�w�w�w�w߶wܶwٶwֶwӶwжwͶwʶwǶwĶw��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w��w�w|�wy�wv�ws�wp�wm�wj�wg�wd�wa�w^�w[�wX�wU�wR�wO�wL�wI�wF�wC�w@�w=�w:�w7�w4�w1�w.�w+�w(�w%�w"�w�w�w�w�w�w�w �w +�w�w�w�v��v��v��v��v�v�v�v�v�v�v�vݶvڶv׶vԶvѶvζv˶vȶvŶv¶v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v��v}�vz�vw�vt�vq�vn�vk�vh�ve�vb�v_�v\�vY�vV�vS�vP�vM�vJ�vG�vD�vA�v>�v;�v8�v5�v2�v/�v,�v)�v&�v#�v �v�v�v�v�v�v�v �v�v�v�u��u��u��u��u�u�u��u�u�u�u�u޶u۶uضuնuҶu϶u̶uɶuƶuöu��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u��u~�u{�ux�uu�ur�uo�ul�ui�uf�uc�u`�u]�uZ�uW�uT�uQ�uN�uK�uH�uE�uB�u?�u<�u9�u6�u3�u0�u-�u*�u'�u$�u!�u�u�u�u�u�u�u �u �u�u�u�t��t��t��t��t�t�t�t�t�t�t߶tܶtٶtֶtӶtжtͶtʶtǶtĶt��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t��t�t|�ty�tv�ts�tp�tm�tj�tg�td�ta�t^�t[�tX�tU�tR�tO�tL�tI�tF�tC�t@�t=�t:�t7�t4�t1�t.�t+�t(�t%�t"�t�t�t�t�t�t�t �t +�t�t�t�s��s��s��s��s�s�s�s�s�s�s�sݶsڶs׶sԶsѶsζs˶sȶsŶs¶s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s��s}�sz�sw�st�sq�sn�sk�sh�se�sb�s_�s\�sY�sV�sS�sP�sM�sJ�sG�sD�sA�s>�s;�s8�s5�s2�s/�s,�s)�s&�s#�s �s�s�s�s�s�s�s �s�s�s�r��r��r��r��r�r�r��r�r�r�r�r޶r۶rضrնrҶr϶r̶rɶrƶrör��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r��r~�r{�rx�ru�rr�ro�rl�ri�rf�rc�r`�r]�rZ�rW�rT�rQ�rN�rK�rH�rE�rB�r?�r<�r9�r6�r3�r0�r-�r*�r'�r$�r!�r�r�r�r�r�r�r �r �r�r�r�q��q��q��q��q�q�q�q�q�q�q߶qܶqٶqֶqӶqжqͶqʶqǶqĶq��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q��q�q|�qy�qv�qs�qp�qm�qj�qg�qd�qa�q^�q[�qX�qU�qR�qO�qL�qI�qF�qC�q@�q=�q:�q7�q4�q1�q.�q+�q(�q%�q"�q�q�q�q�q�q�q �q +�q�q�q�p��p��p��p��p�p�p�p�p�p�p�pݶpڶp׶pԶpѶpζp˶pȶpŶp¶p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p��p}�pz�pw�pt�pq�pn�pk�ph�pe�pb�p_�p\�pY�pV�pS�pP�pM�pJ�pG�pD�pA�p>�p;�p8�p5�p2�p/�p,�p)�p&�p#�p �p�p�p�p�p�p�p �p�p�p�o��o��o��o��o�o�o��o�o�o�o�o޶o۶oضoնoҶo϶o̶oɶoƶoöo��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o��o~�o{�ox�ou�or�oo�ol�oi�of�oc�o`�o]�oZ�oW�oT�oQ�oN�oK�oH�oE�oB�o?�o<�o9�o6�o3�o0�o-�o*�o'�o$�o!�o�o�o�o�o�o�o �o �o�o�o�n��n��n��n��n�n�n�n�n�n�n߶nܶnٶnֶnӶnжnͶnʶnǶnĶn��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n��n�n|�ny�nv�ns�np�nm�nj�ng�nd�na�n^�n[�nX�nU�nR�nO�nL�nI�nF�nC�n@�n=�n:�n7�n4�n1�n.�n+�n(�n%�n"�n�n�n�n�n�n�n �n +�n�n�n�m��m��m��m��m�m�m�m�m�m�m�mݶmڶm׶mԶmѶmζm˶mȶmŶm¶m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m��m}�mz�mw�mt�mq�mn�mk�mh�me�mb�m_�m\�mY�mV�mS�mP�mM�mJ�mG�mD�mA�m>�m;�m8�m5�m2�m/�m,�m)�m&�m#�m �m�m�m�m�m�m�m �m�m�m�l��l��l��l��l�l�l��l�l�l�l�l޶l۶lضlնlҶl϶l̶lɶlƶlöl��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l��l~�l{�lx�lu�lr�lo�ll�li�lf�lc�l`�l]�lZ�lW�lT�lQ�lN�lK�lH�lE�lB�l?�l<�l9�l6�l3�l0�l-�l*�l'�l$�l!�l�l�l�l�l�l�l �l �l�l�l�k��k��k��k��k�k�k�k�k�k�k߶kܶkٶkֶkӶkжkͶkʶkǶkĶk��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k��k�k|�ky�kv�ks�kp�km�kj�kg�kd�ka�k^�k[�kX�kU�kR�kO�kL�kI�kF�kC�k@�k=�k:�k7�k4�k1�k.�k+�k(�k%�k"�k�k�k�k�k�k�k �k +�k�k�k�j��j��j��j��j�j�j�j�j�j�j�jݶjڶj׶jԶjѶjζj˶jȶjŶj¶j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j��j}�jz�jw�jt�jq�jn�jk�jh�je�jb�j_�j\�jY�jV�jS�jP�jM�jJ�jG�jD�jA�j>�j;�j8�j5�j2�j/�j,�j)�j&�j#�j �j�j�j�j�j�j�j �j�j�j�i��i��i��i��i�i�i��i�i�i�i�i޶i۶iضiնiҶi϶i̶iɶiƶiöi��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i��i~�i{�ix�iu�ir�io�il�ii�if�ic�i`�i]�iZ�iW�iT�iQ�iN�iK�iH�iE�iB�i?�i<�i9�i6�i3�i0�i-�i*�i'�i$�i!�i�i�i�i�i�i�i �i �i�i�i�h��h��h��h��h�h�h�h�h�h�h߶hܶhٶhֶhӶhжhͶhʶhǶhĶh��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h��h�h|�hy�hv�hs�hp�hm�hj�hg�hd�ha�h^�h[�hX�hU�hR�hO�hL�hI�hF�hC�h@�h=�h:�h7�h4�h1�h.�h+�h(�h%�h"�h�h�h�h�h�h�h �h +�h�h�h�g��g��g��g��g�g�g�g�g�g�g�gݶgڶg׶gԶgѶgζg˶gȶgŶg¶g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g��g}�gz�gw�gt�gq�gn�gk�gh�ge�gb�g_�g\�gY�gV�gS�gP�gM�gJ�gG�gD�gA�g>�g;�g8�g5�g2�g/�g,�g)�g&�g#�g �g�g�g�g�g�g�g �g�g�g�f��f��f��f��f�f�f��f�f�f�f�f޶f۶fضfնfҶf϶f̶fɶfƶföf��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f��f~�f{�fx�fu�fr�fo�fl�fi�ff�fc�f`�f]�fZ�fW�fT�fQ�fN�fK�fH�fE�fB�f?�f<�f9�f6�f3�f0�f-�f*�f'�f$�f!�f�f�f�f�f�f�f �f �f�f�f�e��e��e��e��e�e�e�e�e�e�e߶eܶeٶeֶeӶeжeͶeʶeǶeĶe��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e��e�e|�ey�ev�es�ep�em�ej�eg�ed�ea�e^�e[�eX�eU�eR�eO�eL�eI�eF�eC�e@�e=�e:�e7�e4�e1�e.�e+�e(�e%�e"�e�e�e�e�e�e�e �e +�e�e�e�d��d��d��d��d�d�d�d�d�d�d�dݶdڶd׶dԶdѶdζd˶dȶdŶd¶d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d��d}�dz�dw�dt�dq�dn�dk�dh�de�db�d_�d\�dY�dV�dS�dP�dM�dJ�dG�dD�dA�d>�d;�d8�d5�d2�d/�d,�d)�d&�d#�d �d�d�d�d�d�d�d �d�d�d�c��c��c��c��c�c�c��c�c�c�c�c޶c۶cضcնcҶc϶c̶cɶcƶcöc��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c��c~�c{�cx�cu�cr�co�cl�ci�cf�cc�c`�c]�cZ�cW�cT�cQ�cN�cK�cH�cE�cB�c?�c<�c9�c6�c3�c0�c-�c*�c'�c$�c!�c�c�c�c�c�c�c �c �c�c�c�b��b��b��b��b�b�b�b�b�b�b߶bܶbٶbֶbӶbжbͶbʶbǶbĶb��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b��b�b|�by�bv�bs�bp�bm�bj�bg�bd�ba�b^�b[�bX�bU�bR�bO�bL�bI�bF�bC�b@�b=�b:�b7�b4�b1�b.�b+�b(�b%�b"�b�b�b�b�b�b�b �b +�b�b�b�a��a��a��a��a�a�a�a�a�a�a�aݶaڶa׶aԶaѶaζa˶aȶaŶa¶a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a��a}�az�aw�at�aq�an�ak�ah�ae�ab�a_�a\�aY�aV�aS�aP�aM�aJ�aG�aD�aA�a>�a;�a8�a5�a2�a/�a,�a)�a&�a#�a �a�a�a�a�a�a�a �a�a�a�`��`��`��`��`�`�`��`�`�`�`�`޶`۶`ض`ն`Ҷ`϶`̶`ɶ`ƶ`ö`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`��`~�`{�`x�`u�`r�`o�`l�`i�`f�`c�``�`]�`Z�`W�`T�`Q�`N�`K�`H�`E�`B�`?�`<�`9�`6�`3�`0�`-�`*�`'�`$�`!�`�`�`�`�`�`�` �` �`�`�`�_��_��_��_��_�_�_�_�_�_�_߶_ܶ_ٶ_ֶ_Ӷ_ж_Ͷ_ʶ_Ƕ_Ķ_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_��_�_|�_y�_v�_s�_p�_m�_j�_g�_d�_a�_^�_[�_X�_U�_R�_O�_L�_I�_F�_C�_@�_=�_:�_7�_4�_1�_.�_+�_(�_%�_"�_�_�_�_�_�_�_ �_ +�_�_�_�^��^��^��^��^�^�^�^�^�^�^�^ݶ^ڶ^׶^Զ^Ѷ^ζ^˶^ȶ^Ŷ^¶^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^��^}�^z�^w�^t�^q�^n�^k�^h�^e�^b�^_�^\�^Y�^V�^S�^P�^M�^J�^G�^D�^A�^>�^;�^8�^5�^2�^/�^,�^)�^&�^#�^ �^�^�^�^�^�^�^ �^�^�^�]��]��]��]��]�]�]��]�]�]�]�]޶]۶]ض]ն]Ҷ]϶]̶]ɶ]ƶ]ö]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]��]~�]{�]x�]u�]r�]o�]l�]i�]f�]c�]`�]]�]Z�]W�]T�]Q�]N�]K�]H�]E�]B�]?�]<�]9�]6�]3�]0�]-�]*�]'�]$�]!�]�]�]�]�]�]�] �] �]�]�]�\��\��\��\��\�\�\�\�\�\�\߶\ܶ\ٶ\ֶ\Ӷ\ж\Ͷ\ʶ\Ƕ\Ķ\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\��\�\|�\y�\v�\s�\p�\m�\j�\g�\d�\a�\^�\[�\X�\U�\R�\O�\L�\I�\F�\C�\@�\=�\:�\7�\4�\1�\.�\+�\(�\%�\"�\�\�\�\�\�\�\ �\ +�\�\�\�[��[��[��[��[�[�[�[�[�[�[�[ݶ[ڶ[׶[Զ[Ѷ[ζ[˶[ȶ[Ŷ[¶[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[��[}�[z�[w�[t�[q�[n�[k�[h�[e�[b�[_�[\�[Y�[V�[S�[P�[M�[J�[G�[D�[A�[>�[;�[8�[5�[2�[/�[,�[)�[&�[#�[ �[�[�[�[�[�[�[ �[�[�[�Z��Z��Z��Z��Z�Z�Z��Z�Z�Z�Z�Z޶Z۶ZضZնZҶZ϶Z̶ZɶZƶZöZ��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z��Z~�Z{�Zx�Zu�Zr�Zo�Zl�Zi�Zf�Zc�Z`�Z]�ZZ�ZW�ZT�ZQ�ZN�ZK�ZH�ZE�ZB�Z?�Z<�Z9�Z6�Z3�Z0�Z-�Z*�Z'�Z$�Z!�Z�Z�Z�Z�Z�Z�Z �Z �Z�Z�Z�Y��Y��Y��Y��Y�Y�Y�Y�Y�Y�Y߶YܶYٶYֶYӶYжYͶYʶYǶYĶY��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y��Y�Y|�Yy�Yv�Ys�Yp�Ym�Yj�Yg�Yd�Ya�Y^�Y[�YX�YU�YR�YO�YL�YI�YF�YC�Y@�Y=�Y:�Y7�Y4�Y1�Y.�Y+�Y(�Y%�Y"�Y�Y�Y�Y�Y�Y�Y �Y +�Y�Y�Y�X��X��X��X��X�X�X�X�X�X�X�XݶXڶX׶XԶXѶXζX˶XȶXŶX¶X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X��X}�Xz�Xw�Xt�Xq�Xn�Xk�Xh�Xe�Xb�X_�X\�XY�XV�XS�XP�XM�XJ�XG�XD�XA�X>�X;�X8�X5�X2�X/�X,�X)�X&�X#�X �X�X�X�X�X�X�X �X�X�X�W��W��W��W��W�W�W��W�W�W�W�W޶W۶WضWնWҶW϶W̶WɶWƶWöW��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W��W~�W{�Wx�Wu�Wr�Wo�Wl�Wi�Wf�Wc�W`�W]�WZ�WW�WT�WQ�WN�WK�WH�WE�WB�W?�W<�W9�W6�W3�W0�W-�W*�W'�W$�W!�W�W�W�W�W�W�W �W �W�W�W�V��V��V��V��V�V�V�V�V�V�V߶VܶVٶVֶVӶVжVͶVʶVǶVĶV��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V��V�V|�Vy�Vv�Vs�Vp�Vm�Vj�Vg�Vd�Va�V^�V[�VX�VU�VR�VO�VL�VI�VF�VC�V@�V=�V:�V7�V4�V1�V.�V+�V(�V%�V"�V�V�V�V�V�V�V �V +�V�V�V�U��U��U��U��U�U�U�U�U�U�U�UݶUڶU׶UԶUѶUζU˶UȶUŶU¶U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U��U}�Uz�Uw�Ut�Uq�Un�Uk�Uh�Ue�Ub�U_�U\�UY�UV�US�UP�UM�UJ�UG�UD�UA�U>�U;�U8�U5�U2�U/�U,�U)�U&�U#�U �U�U�U�U�U�U�U �U�U�U�T��T��T��T��T�T�T��T�T�T�T�T޶T۶TضTնTҶT϶T̶TɶTƶTöT��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T��T~�T{�Tx�Tu�Tr�To�Tl�Ti�Tf�Tc�T`�T]�TZ�TW�TT�TQ�TN�TK�TH�TE�TB�T?�T<�T9�T6�T3�T0�T-�T*�T'�T$�T!�T�T�T�T�T�T�T �T �T�T�T�S��S��S��S��S�S�S�S�S�S�S߶SܶSٶSֶSӶSжSͶSʶSǶSĶS��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S��S�S|�Sy�Sv�Ss�Sp�Sm�Sj�Sg�Sd�Sa�S^�S[�SX�SU�SR�SO�SL�SI�SF�SC�S@�S=�S:�S7�S4�S1�S.�S+�S(�S%�S"�S�S�S�S�S�S�S �S +�S�S�S�R��R��R��R��R�R�R�R�R�R�R�RݶRڶR׶RԶRѶRζR˶RȶRŶR¶R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R��R}�Rz�Rw�Rt�Rq�Rn�Rk�Rh�Re�Rb�R_�R\�RY�RV�RS�RP�RM�RJ�RG�RD�RA�R>�R;�R8�R5�R2�R/�R,�R)�R&�R#�R �R�R�R�R�R�R�R �R�R�R�Q��Q��Q��Q��Q�Q�Q��Q�Q�Q�Q�Q޶Q۶QضQնQҶQ϶Q̶QɶQƶQöQ��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q��Q~�Q{�Qx�Qu�Qr�Qo�Ql�Qi�Qf�Qc�Q`�Q]�QZ�QW�QT�QQ�QN�QK�QH�QE�QB�Q?�Q<�Q9�Q6�Q3�Q0�Q-�Q*�Q'�Q$�Q!�Q�Q�Q�Q�Q�Q�Q �Q �Q�Q�Q�P��P��P��P��P�P�P�P�P�P�P߶PܶPٶPֶPӶPжPͶPʶPǶPĶP��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P��P�P|�Py�Pv�Ps�Pp�Pm�Pj�Pg�Pd�Pa�P^�P[�PX�PU�PR�PO�PL�PI�PF�PC�P@�P=�P:�P7�P4�P1�P.�P+�P(�P%�P"�P�P�P�P�P�P�P �P +�P�P�P�O��O��O��O��O�O�O�O�O�O�O�OݶOڶO׶OԶOѶOζO˶OȶOŶO¶O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O��O}�Oz�Ow�Ot�Oq�On�Ok�Oh�Oe�Ob�O_�O\�OY�OV�OS�OP�OM�OJ�OG�OD�OA�O>�O;�O8�O5�O2�O/�O,�O)�O&�O#�O �O�O�O�O�O�O�O �O�O�O�N��N��N��N��N�N�N��N�N�N�N�N޶N۶NضNնNҶN϶N̶NɶNƶNöN��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N��N~�N{�Nx�Nu�Nr�No�Nl�Ni�Nf�Nc�N`�N]�NZ�NW�NT�NQ�NN�NK�NH�NE�NB�N?�N<�N9�N6�N3�N0�N-�N*�N'�N$�N!�N�N�N�N�N�N�N �N �N�N�N�M��M��M��M��M�M�M�M�M�M�M߶MܶMٶMֶMӶMжMͶMʶMǶMĶM��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M��M�M|�My�Mv�Ms�Mp�Mm�Mj�Mg�Md�Ma�M^�M[�MX�MU�MR�MO�ML�MI�MF�MC�M@�M=�M:�M7�M4�M1�M.�M+�M(�M%�M"�M�M�M�M�M�M�M �M +�M�M�M�L��L��L��L��L�L�L�L�L�L�L�LݶLڶL׶LԶLѶLζL˶LȶLŶL¶L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L��L}�Lz�Lw�Lt�Lq�Ln�Lk�Lh�Le�Lb�L_�L\�LY�LV�LS�LP�LM�LJ�LG�LD�LA�L>�L;�L8�L5�L2�L/�L,�L)�L&�L#�L �L�L�L�L�L�L�L �L�L�L�K��K��K��K��K�K�K��K�K�K�K�K޶K۶KضKնKҶK϶K̶KɶKƶKöK��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K��K~�K{�Kx�Ku�Kr�Ko�Kl�Ki�Kf�Kc�K`�K]�KZ�KW�KT�KQ�KN�KK�KH�KE�KB�K?�K<�K9�K6�K3�K0�K-�K*�K'�K$�K!�K�K�K�K�K�K�K �K �K�K�K�J��J��J��J��J�J�J�J�J�J�J߶JܶJٶJֶJӶJжJͶJʶJǶJĶJ��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J��J�J|�Jy�Jv�Js�Jp�Jm�Jj�Jg�Jd�Ja�J^�J[�JX�JU�JR�JO�JL�JI�JF�JC�J@�J=�J:�J7�J4�J1�J.�J+�J(�J%�J"�J�J�J�J�J�J�J �J +�J�J�J�I��I��I��I��I�I�I�I�I�I�I�IݶIڶI׶IԶIѶIζI˶IȶIŶI¶I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I��I}�Iz�Iw�It�Iq�In�Ik�Ih�Ie�Ib�I_�I\�IY�IV�IS�IP�IM�IJ�IG�ID�IA�I>�I;�I8�I5�I2�I/�I,�I)�I&�I#�I �I�I�I�I�I�I�I �I�I�I�H��H��H��H��H�H�H��H�H�H�H�H޶H۶HضHնHҶH϶H̶HɶHƶHöH��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H��H~�H{�Hx�Hu�Hr�Ho�Hl�Hi�Hf�Hc�H`�H]�HZ�HW�HT�HQ�HN�HK�HH�HE�HB�H?�H<�H9�H6�H3�H0�H-�H*�H'�H$�H!�H�H�H�H�H�H�H �H �H�H�H�G��G��G��G��G�G�G�G�G�G�G߶GܶGٶGֶGӶGжGͶGʶGǶGĶG��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G��G�G|�Gy�Gv�Gs�Gp�Gm�Gj�Gg�Gd�Ga�G^�G[�GX�GU�GR�GO�GL�GI�GF�GC�G@�G=�G:�G7�G4�G1�G.�G+�G(�G%�G"�G�G�G�G�G�G�G �G +�G�G�G�F��F��F��F��F�F�F�F�F�F�F�FݶFڶF׶FԶFѶFζF˶FȶFŶF¶F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F��F}�Fz�Fw�Ft�Fq�Fn�Fk�Fh�Fe�Fb�F_�F\�FY�FV�FS�FP�FM�FJ�FG�FD�FA�F>�F;�F8�F5�F2�F/�F,�F)�F&�F#�F �F�F�F�F�F�F�F �F�F�F�E��E��E��E��E�E�E��E�E�E�E�E޶E۶EضEնEҶE϶E̶EɶEƶEöE��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E��E~�E{�Ex�Eu�Er�Eo�El�Ei�Ef�Ec�E`�E]�EZ�EW�ET�EQ�EN�EK�EH�EE�EB�E?�E<�E9�E6�E3�E0�E-�E*�E'�E$�E!�E�E�E�E�E�E�E �E �E�E�E�D��D��D��D��D�D�D�D�D�D�D߶DܶDٶDֶDӶDжDͶDʶDǶDĶD��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D��D�D|�Dy�Dv�Ds�Dp�Dm�Dj�Dg�Dd�Da�D^�D[�DX�DU�DR�DO�DL�DI�DF�DC�D@�D=�D:�D7�D4�D1�D.�D+�D(�D%�D"�D�D�D�D�D�D�D �D +�D�D�D�C��C��C��C��C�C�C�C�C�C�C�CݶCڶC׶CԶCѶCζC˶CȶCŶC¶C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C��C}�Cz�Cw�Ct�Cq�Cn�Ck�Ch�Ce�Cb�C_�C\�CY�CV�CS�CP�CM�CJ�CG�CD�CA�C>�C;�C8�C5�C2�C/�C,�C)�C&�C#�C �C�C�C�C�C�C�C �C�C�C�B��B��B��B��B�B�B��B�B�B�B�B޶B۶BضBնBҶB϶B̶BɶBƶBöB��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B��B~�B{�Bx�Bu�Br�Bo�Bl�Bi�Bf�Bc�B`�B]�BZ�BW�BT�BQ�BN�BK�BH�BE�BB�B?�B<�B9�B6�B3�B0�B-�B*�B'�B$�B!�B�B�B�B�B�B�B �B �B�B�B�A��A��A��A��A�A�A�A�A�A�A߶AܶAٶAֶAӶAжAͶAʶAǶAĶA��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A��A�A|�Ay�Av�As�Ap�Am�Aj�Ag�Ad�Aa�A^�A[�AX�AU�AR�AO�AL�AI�AF�AC�A@�A=�A:�A7�A4�A1�A.�A+�A(�A%�A"�A�A�A�A�A�A�A �A +�A�A�A�@��@��@��@��@�@�@�@�@�@�@�@ݶ@ڶ@׶@Զ@Ѷ@ζ@˶@ȶ@Ŷ@¶@��@��@��@��@��@��@��@��@��@��@��@��@��@��@��@��@��@��@��@��@��@������������������������޶ܶڶضֶԶҶжζ̶ʶȶƶͶ����������������������������������������������������������������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a8468104c65a6002fd3a9d4ac39f3ee34c21ce4a b/src/sys/libwebm/webm_parser/fuzzing/corpus/a8468104c65a6002fd3a9d4ac39f3ee34c21ce4a new file mode 100644 index 0000000..9b15205 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/a8468104c65a6002fd3a9d4ac39f3ee34c21ce4a @@ -0,0 +1 @@ +S�g�T�g�ss�c��hʁ� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a899424027f1d69a05384355858311a6fa3940a3 b/src/sys/libwebm/webm_parser/fuzzing/corpus/a899424027f1d69a05384355858311a6fa3940a3 new file mode 100644 index 0000000..3ef41ca --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/a899424027f1d69a05384355858311a6fa3940a3 @@ -0,0 +1 @@ +S�g�T�k�����T�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/a8a5de5a86a16952aacdf602120f27807294c3ec b/src/sys/libwebm/webm_parser/fuzzing/corpus/a8a5de5a86a16952aacdf602120f27807294c3ec new file mode 100644 index 0000000..865b44e --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/a8a5de5a86a16952aacdf602120f27807294c3ec @@ -0,0 +1 @@ +S�g�T�g�ss�c��hʃ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/aa65229e62d7cb8048d2f5911226b177e8e53cab b/src/sys/libwebm/webm_parser/fuzzing/corpus/aa65229e62d7cb8048d2f5911226b177e8e53cab new file mode 100644 index 0000000..80476c0 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/aa65229e62d7cb8048d2f5911226b177e8e53cab @@ -0,0 +1 @@ +S�g�T�k���ׁ� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/aaa96713f8ccb0bbd5c8e91715d4b86e7b338676 b/src/sys/libwebm/webm_parser/fuzzing/corpus/aaa96713f8ccb0bbd5c8e91715d4b86e7b338676 new file mode 100644 index 0000000000000000000000000000000000000000..1fa146d48d189d5b2614660e01131c0fd5ef8709 GIT binary patch literal 36 qcmZp>zt~l(VV;xI_Xej=4h*GE)(vkQ7@V4bxV^!twc$+@BNG53^$wT- literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/aae6354e5ba12ee3ad89fabfd72f5368a639d30f b/src/sys/libwebm/webm_parser/fuzzing/corpus/aae6354e5ba12ee3ad89fabfd72f5368a639d30f new file mode 100644 index 0000000000000000000000000000000000000000..fb16013b54bdad20ba17c32f1b56b30c5650364f GIT binary patch literal 43 wcmb1gy}!7_smXz*JT)m-BDf)as=V{I(h1KU7*;zlEN*QCa#bkO2TG!WwP> literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/adad2ca7ab313add6e955f704719e03d5229e4d0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/adad2ca7ab313add6e955f704719e03d5229e4d0 new file mode 100644 index 0000000..2105af1 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/adad2ca7ab313add6e955f704719e03d5229e4d0 @@ -0,0 +1 @@ +� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/adb1f8cd3b68c076d81311071aee2a1c3785c7cb b/src/sys/libwebm/webm_parser/fuzzing/corpus/adb1f8cd3b68c076d81311071aee2a1c3785c7cb new file mode 100644 index 0000000..4710f7f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/adb1f8cd3b68c076d81311071aee2a1c3785c7cb @@ -0,0 +1 @@ +S�g�T�k����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ade30c327d9f51daf37cb3e39fdb15125b84a257 b/src/sys/libwebm/webm_parser/fuzzing/corpus/ade30c327d9f51daf37cb3e39fdb15125b84a257 new file mode 100644 index 0000000..4bc05f4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/ade30c327d9f51daf37cb3e39fdb15125b84a257 @@ -0,0 +1 @@ +S�g�T�k�����S�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ae783661f52d36f9d6b87c8394ee6f2d61dae640 b/src/sys/libwebm/webm_parser/fuzzing/corpus/ae783661f52d36f9d6b87c8394ee6f2d61dae640 new file mode 100644 index 0000000..d5fe0e2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/ae783661f52d36f9d6b87c8394ee6f2d61dae640 @@ -0,0 +1 @@ +S�g�M�t�M��S��Matroska \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ae8da06c3c69076c06108219e19c8b36dba05a5c b/src/sys/libwebm/webm_parser/fuzzing/corpus/ae8da06c3c69076c06108219e19c8b36dba05a5c new file mode 100644 index 0000000..78a347a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/ae8da06c3c69076c06108219e19c8b36dba05a5c @@ -0,0 +1 @@ +Eߣ8S�g;� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/aec8a29238dba3c37f45f2e2e4e64b0e7fa60a74 b/src/sys/libwebm/webm_parser/fuzzing/corpus/aec8a29238dba3c37f45f2e2e4e64b0e7fa60a74 new file mode 100644 index 0000000..359bfe6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/aec8a29238dba3c37f45f2e2e4e64b0e7fa60a74 @@ -0,0 +1 @@ +S�g�I�f�D��?��w���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/affba8e4061bf260b1bdf8a815675cc3b4ebefa5 b/src/sys/libwebm/webm_parser/fuzzing/corpus/affba8e4061bf260b1bdf8a815675cc3b4ebefa5 new file mode 100644 index 0000000000000000000000000000000000000000..94b2f2d3efe51f4f1ecea9333640b97f42a85f1a GIT binary patch literal 63 mcmey|@Wz2*b&~^wQ+tEcXJk$*l>Zu1^^)04dDO) literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b0ab4f92df810edf4371baad1d4bbd95d360c607 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b0ab4f92df810edf4371baad1d4bbd95d360c607 new file mode 100644 index 0000000..02f58e2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b0ab4f92df810edf4371baad1d4bbd95d360c607 @@ -0,0 +1 @@ +S�g�C�u����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b14e5f5f6d29b6b71e7fec03eaf7d8237c0c6b2e b/src/sys/libwebm/webm_parser/fuzzing/corpus/b14e5f5f6d29b6b71e7fec03eaf7d8237c0c6b2e new file mode 100644 index 0000000000000000000000000000000000000000..32796f0599c2b336bc9abb5292f06732adf58edd GIT binary patch literal 178 zcmb1gm2$nmxWlQ*fu%e(DOV!6A>HAa;OW^VSA2I1FfgzOuK|*bjDo(iOL}19BiKa{l)E00{?-gNB{+ambOA9 oL_Jq8dG5f-xY~h{X>qI6KG*xoX$?$bA?u{FyVn7AvPE4705do_b%7 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b1efd9e687d79e3f5a75eba02bd80bedb72350ba b/src/sys/libwebm/webm_parser/fuzzing/corpus/b1efd9e687d79e3f5a75eba02bd80bedb72350ba new file mode 100644 index 0000000000000000000000000000000000000000..348fa2cfb3e9f71a21700a5479c8cd8c3c2d95b1 GIT binary patch literal 59 zcmZ?0zqrGx$$_OjH7QpjxFLO|yz{owCC?og8CN?nGA(XtWdMT3txX_mftCZyY@o~n HFvSD_dHNDb literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b25b0fbf46cef1d888fe900445c9ab95330f44cd b/src/sys/libwebm/webm_parser/fuzzing/corpus/b25b0fbf46cef1d888fe900445c9ab95330f44cd new file mode 100644 index 0000000..b59c594 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b25b0fbf46cef1d888fe900445c9ab95330f44cd @@ -0,0 +1 @@ +� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b2786e0b9d6e7b39165eb4e87e3110362e9e6660 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b2786e0b9d6e7b39165eb4e87e3110362e9e6660 new file mode 100644 index 0000000..6004cde --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b2786e0b9d6e7b39165eb4e87e3110362e9e6660 @@ -0,0 +1 @@ +Eߣ�B�@webmS�g�C�u��@�@ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b332536a77d6efcd379cfc2f9828291516cc1ff4 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b332536a77d6efcd379cfc2f9828291516cc1ff4 new file mode 100644 index 0000000..2082647 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b332536a77d6efcd379cfc2f9828291516cc1ff4 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G�'� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b33962eca397f59591dbb9668e622cf99f2d7cda b/src/sys/libwebm/webm_parser/fuzzing/corpus/b33962eca397f59591dbb9668e622cf99f2d7cda new file mode 100644 index 0000000000000000000000000000000000000000..9f6ee1d38de50d4f27ee9a58f44e7a36e81f3001 GIT binary patch literal 91 zcmb0LZb-i-7P2n;;=1$K6&M(bj{=EiAl?bY9Y7qq3P{WWV&%up4Z(RphSJtK4Q)U= bc@dCMZR=bWv)tJd|60t^g{j4qumzI~q$xg`FFg6fq(aptuAeBTBTBPp>c+!4a4 F0svFg80i22 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b3e01674a1e4dd78e748782fcfc3add5523f51d8 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b3e01674a1e4dd78e748782fcfc3add5523f51d8 new file mode 100644 index 0000000..3416407 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b3e01674a1e4dd78e748782fcfc3add5523f51d8 @@ -0,0 +1 @@ +� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b53e7ef9aad70fcd80986696ebc586c03495b8ed b/src/sys/libwebm/webm_parser/fuzzing/corpus/b53e7ef9aad70fcd80986696ebc586c03495b8ed new file mode 100644 index 0000000..ee865d8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b53e7ef9aad70fcd80986696ebc586c03495b8ed @@ -0,0 +1 @@ +G�Eߣ�B�@webm�S�g�*M'�t�I�f�C�u�TSkk����C�p�T�€�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b540412c01f960f95edd2a1bc03f1b4447f2b4f2 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b540412c01f960f95edd2a1bc03f1b4447f2b4f2 new file mode 100644 index 0000000000000000000000000000000000000000..b77bc28047a8b07d8c779d1ee9d8fed9babefe91 GIT binary patch literal 5 McmZ21b>Ec%00zSW;s5{u literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b62c2c591db32b26e997aa4ece577742db84428a b/src/sys/libwebm/webm_parser/fuzzing/corpus/b62c2c591db32b26e997aa4ece577742db84428a new file mode 100644 index 0000000..64a70ac --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b62c2c591db32b26e997aa4ece577742db84428a @@ -0,0 +1 @@ +S�g�C�u������́�́ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b62d99583f30c15c3c2dbed2f69c5e45075d7640 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b62d99583f30c15c3c2dbed2f69c5e45075d7640 new file mode 100644 index 0000000..edf7ec3 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b62d99583f30c15c3c2dbed2f69c5e45075d7640 @@ -0,0 +1 @@ +{��g�C�u��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b62f98976c11d79674b019ea78a7ce4d6d78b479 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b62f98976c11d79674b019ea78a7ce4d6d78b479 new file mode 100644 index 0000000000000000000000000000000000000000..6a4f18607c79a88e0389dc87354e03c5a70114fe GIT binary patch literal 2 JcmWe&0000Y01*HH literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b6787dabeb5cd64ac85f1ec5a7cbeecfd48b2c5f b/src/sys/libwebm/webm_parser/fuzzing/corpus/b6787dabeb5cd64ac85f1ec5a7cbeecfd48b2c5f new file mode 100644 index 0000000..d043095 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b6787dabeb5cd64ac85f1ec5a7cbeecfd48b2c5f @@ -0,0 +1 @@ +S�g�C�p�E����|��@hello����������@B�@�@C�@ sĀ��������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b82ebcf4d09ba28d835cb9667da603e46e3438eb b/src/sys/libwebm/webm_parser/fuzzing/corpus/b82ebcf4d09ba28d835cb9667da603e46e3438eb new file mode 100644 index 0000000..cea92d6 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b82ebcf4d09ba28d835cb9667da603e46e3438eb @@ -0,0 +1 @@ +S�g�C�p�E������C~�! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b85c6bc2473aa12e22f91db3546dfa9d85d8b3d1 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b85c6bc2473aa12e22f91db3546dfa9d85d8b3d1 new file mode 100644 index 0000000000000000000000000000000000000000..5f82c67367f79531e35244973b239742c5abce54 GIT binary patch literal 27 icmb0LZb+Xd@4T&a;)4E#y^RbEE$j>ojEqc7%*+6Yzz2K) literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b86e98660980680890bcbf02cacdf568d530fa64 b/src/sys/libwebm/webm_parser/fuzzing/corpus/b86e98660980680890bcbf02cacdf568d530fa64 new file mode 100644 index 0000000000000000000000000000000000000000..207162b0fcfadbdaefa3a1c1a65546d49a0a642d GIT binary patch literal 48 xcmb1gy}!7_smXz5N@`NBL~uj;N_ppPrAwYWFfz<`U}Rk2z_7r91;PSROaQbh56%Dp literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/b8d9beea35762009941189674c2cfcd14f81254a b/src/sys/libwebm/webm_parser/fuzzing/corpus/b8d9beea35762009941189674c2cfcd14f81254a new file mode 100644 index 0000000..25ec34a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/b8d9beea35762009941189674c2cfcd14f81254a @@ -0,0 +1 @@ +S�g�T�k����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ba517141fc9a468142a8d03d4ee395b4d4f30edc b/src/sys/libwebm/webm_parser/fuzzing/corpus/ba517141fc9a468142a8d03d4ee395b4d4f30edc new file mode 100644 index 0000000..aaea60d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/ba517141fc9a468142a8d03d4ee395b4d4f30edc @@ -0,0 +1 @@ +S�c�Dg�ss�cS�g�S���g�k���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/bb0a596017cfc2185505d28065ab3cd238d0e2ea b/src/sys/libwebm/webm_parser/fuzzing/corpus/bb0a596017cfc2185505d28065ab3cd238d0e2ea new file mode 100644 index 0000000..1379811 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/bb0a596017cfc2185505d28065ab3cd238d0e2ea @@ -0,0 +1 @@ +S�g�C�p�E�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/bb6232815b373e441e2acfcca015f75c680eafac b/src/sys/libwebm/webm_parser/fuzzing/corpus/bb6232815b373e441e2acfcca015f75c680eafac new file mode 100644 index 0000000000000000000000000000000000000000..04a597c1fd890f6592515eba17bf3bfeb880c412 GIT binary patch literal 39 pcmb0LZb)Aw>bWv)uGaO94KAGu3=A%bK%#mjknn8)65)+LOAiSE literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/bdb1cc868d6ced390f5d35c5f43da9f464fac464 b/src/sys/libwebm/webm_parser/fuzzing/corpus/bdb1cc868d6ced390f5d35c5f43da9f464fac464 new file mode 100644 index 0000000..44bb8cd --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/bdb1cc868d6ced390f5d35c5f43da9f464fac464 @@ -0,0 +1 @@ +S�g�T�g�ss�gȩȄ#��dgȄ]��egȄD��dgȄ]��egȄD��gȀD��dgȀg \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/bf67bb08e0abde692748031c297bc1c7910542f4 b/src/sys/libwebm/webm_parser/fuzzing/corpus/bf67bb08e0abde692748031c297bc1c7910542f4 new file mode 100644 index 0000000000000000000000000000000000000000..8705e840a040fe30cfa298e381147ed9243e7dbf GIT binary patch literal 34 ocmb0LZb+Xi6mmFyMse}f(?501AT-z5oCK literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/bfc07c62ef2770d53d9188b260f531a8128a5c5e b/src/sys/libwebm/webm_parser/fuzzing/corpus/bfc07c62ef2770d53d9188b260f531a8128a5c5e new file mode 100644 index 0000000000000000000000000000000000000000..341f94d40edac96a722c4e54285f104fcde590b4 GIT binary patch literal 53 zcmb1gl~~;2{-_~1-KohTWK(KVu0(J{`bv4{ZA*?gFfy)oU}Rd`+Qa|^3mgPW7ye)N I|D6K^03MALdjJ3c literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/bfed121df31ff73b770ed7f27fc7f4da2fa73e0c b/src/sys/libwebm/webm_parser/fuzzing/corpus/bfed121df31ff73b770ed7f27fc7f4da2fa73e0c new file mode 100644 index 0000000000000000000000000000000000000000..7b2c56135ecc05d31bbbf416cad52f293bdaf670 GIT binary patch literal 24 gcmeZmIMWc~)TXua9mBhK@7mum2rw{6zkBxv0F-_VCjbBd literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c01816206d93691165e6e3a1924cf9fbc9cf39bd b/src/sys/libwebm/webm_parser/fuzzing/corpus/c01816206d93691165e6e3a1924cf9fbc9cf39bd new file mode 100644 index 0000000..b99d57a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c01816206d93691165e6e3a1924cf9fbc9cf39bd @@ -0,0 +1 @@ +S��gT�k���m��b@�P5��G�G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c02be525edae59ad9d0d9dcbd790629dc9aaee9b b/src/sys/libwebm/webm_parser/fuzzing/corpus/c02be525edae59ad9d0d9dcbd790629dc9aaee9b new file mode 100644 index 0000000000000000000000000000000000000000..67629fee4e0804c5e06a022a58fbc0969ef07fd5 GIT binary patch literal 130 zcmWGxaF7UYNS`70rX^&ZL~we@x`u0F+3U_IW0|30QCeQ!? literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c094ce0c13ee9a4ca37817d9f7dddc11b2d60177 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c094ce0c13ee9a4ca37817d9f7dddc11b2d60177 new file mode 100644 index 0000000..9b44fb0 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c094ce0c13ee9a4ca37817d9f7dddc11b2d60177 @@ -0,0 +1 @@ +S�g�C�u��������:� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c0aab5486ad2e80bcc12fca9fb6653984aa68274 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c0aab5486ad2e80bcc12fca9fb6653984aa68274 new file mode 100644 index 0000000..d643dc1 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c0aab5486ad2e80bcc12fca9fb6653984aa68274 @@ -0,0 +1 @@ +Eߣ� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c13ca850db259c032cf24cdf6f2833c9d74529d0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c13ca850db259c032cf24cdf6f2833c9d74529d0 new file mode 100644 index 0000000..46ddda2 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c13ca850db259c032cf24cdf6f2833c9d74529d0 @@ -0,0 +1 @@ +Eߣ�B�@webmS�g�C�u����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c1a8da6cdc8988e6a69961413803acbd1ee935e0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c1a8da6cdc8988e6a69961413803acbd1ee935e0 new file mode 100644 index 0000000..80a14f7 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c1a8da6cdc8988e6a69961413803acbd1ee935e0 @@ -0,0 +1 @@ +S�g�C�p�E����sāVT�A�@�@�@�@B�@�@C�@sā�@sā�@s� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c25abc82a0470129f2d098ac65fabf34c4e11188 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c25abc82a0470129f2d098ac65fabf34c4e11188 new file mode 100644 index 0000000000000000000000000000000000000000..774e5f1d44e65ed4fb68d7981dcde0c4428830b5 GIT binary patch literal 61 qcmb1gy?>y=>3f6ICkFa6e)AJ7@#K%c{QCZW%lG5A#f!s%d~EO?ZVF4f>F4k%j4W-EhaSegc9M1X z+hMkYO_CXI_splTQMODpon&8fs>QxL%$I<citz$ltW(4LSA39Sngrv2S z#4-5&!0#v4T>w+P@>}s#fy%!}L@&w&j9F6GNQ@XVE$Z4odMN|%iAsz*PmD^7|Ew4U zRM4_#cJn;=z?p22BveQS^XlkfA)DSerA1Q-IiVs7ufl|sGapua@nl3D#=Gf$fl-vp9MLL$q^-|Y(3r4Z z$(+5Aq{t`C3Sl%06Q1cK#-2E*;-2oW#E!}UIarLST+E7+$SOIy~(1e*2utCP9dA2$acF4CWKtDGB zR9G0fJjl3b4M|18CddxEu3GWrs2t#CMCAjrhJ{Gw9NCr;aCKVjjN3Ak!5K>h({!wO zEUfLLk9q-@m!sS$#ua+u&l4h!gnlT!Wag zO{m}>4x92k(UdhR(SJUK4;bzoF>oq$bn*p$Pf7S8^D=b8D$(}mbtQ`VC z_CisR=$`(I1KA|BHH?FkQURDf_b@m7&SI55FzIuZU2S$m$PQ-pCov0e!V7BVPhwoE zKu-$Qe*&q3dCfGI;*{C**JAplv7S{4=pgewOmBEv(Fad`t|E>8h;eN_D*Z`J z^7RqD+aJp{)pctZA=y)6IH46aKx*F;_mVo`v9PYxi$k_D?Q_`D14Y=oW)vex76y@{ zlybr~Ex59ou(!s&%U+NV60>qXgb&m$P2=e3q?h>pz)xaazS=;tNrHiR@iNBrqG|tt zy0?6-jXBe#iU8FjUo{C@t1qN1&>vE1ZH!Hnr(2jT@~*Xzmg4R4UkO@i&we`8Fp!f0 zZ2dzj(8dC{OZ9?9P*FhfSXkQ=E`J`bcO43sT~lf(#uo-z!fzcpq1g<8PA4;Bn4VIH5X>Ii7 zvDJTbr0fj%hzr`sNC1ykLN0^0gmrGua!cdyH^GJ0 zgEBGhd$86d**1oW*8}vt4oo>Pvo25)ONE5pu~HqMZUV*=EWKJyGci^5CEb z2_yaU1lbd05kST?8_u06_~K<*MfxCJ@OBQdn|s!bbED_sE+_q3BWQBJ`a9UBxk{k3_MG{6vOnR4J7YO@Eb#G>@$Owk z&_l}$1!kYC&&HWRu|()&(;UWav%&V z2XwA%iB{AA$*nkELet}z7KmLK$X~G1%FAQLmc$!EPLbwaRfqm$>6c<2igpDJuzZ@* z(_GZTi46hfWB^MR)O0NwuyBGd#@2_b=p9(2Y@W=5Jt^v)D2Z_|?f)a93RHS0Dr#&I za!N&zeBwWy%pw$5FCK^r(ImO+sTvrkHY~z%CS89$`Pr+6f?A5xUj;a!k@v4EF-gLZ z%t5V7Y*vNYPun41nD96I+d|-}ta=9DG{V}St0L-h+Xq(!A|>UNeIkj{#JhGRW&qai znjzsUDtp10w4>N;ofBSHo_RI~JQVMBtUMYS89KCD+k3-YlZ%Zj}k2HUhz Re+x{^h^GWRu(2WF{SWi<_Z$EK literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c2d63b1d75cf53ee3b955bb143036ca93ef3a256 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c2d63b1d75cf53ee3b955bb143036ca93ef3a256 new file mode 100644 index 0000000000000000000000000000000000000000..3fbf8e455f7c8f5dfbcbbaf011c590c30d07d951 GIT binary patch literal 105 zcmWeCo*O));jl!AmPBwvdbdpQ?(DYREt}KT(i@7WCLd_YIMv9Y=z4!~hf|XSOL=Ni zZZAmPVnJW^*(D9>Ct6$=Z*LIwT$$D&@4T(FA!J>4Lu29zkSPrU&dUoLghE*x|Z!>$VBSM;aN!S{)dj8XQ=Fl=C(R G?*9PR_$~GT literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c3b2749ab6c4d303bfd5da9ea9c8807e9f92d259 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c3b2749ab6c4d303bfd5da9ea9c8807e9f92d259 new file mode 100644 index 0000000000000000000000000000000000000000..e94d73726c06e1c08e1c5d1fe063748f511becd5 GIT binary patch literal 25 gcmb0LZb+XZ@4T(Fe{pXk0|PT-3nK#q6B9Et0Bh0)M*si- literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c4dd3c8cdd8d7c95603dd67f1cd873d5f9148b29 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c4dd3c8cdd8d7c95603dd67f1cd873d5f9148b29 new file mode 100644 index 0000000..c5fa784 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c4dd3c8cdd8d7c95603dd67f1cd873d5f9148b29 @@ -0,0 +1 @@ +< \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c52fa8d16e520980e470d76e3fb4f6a612f0f3cf b/src/sys/libwebm/webm_parser/fuzzing/corpus/c52fa8d16e520980e470d76e3fb4f6a612f0f3cf new file mode 100644 index 0000000000000000000000000000000000000000..d614d45172342f15795b9c098c67b2caff5526e4 GIT binary patch literal 28 jcmZ?W+5A7{!D3gb`~MXeuK=>&|5t4M-^9T1|F1Lv?w1fB literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c56fb214efcd707e6fa68b803d9e7686fc2f4336 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c56fb214efcd707e6fa68b803d9e7686fc2f4336 new file mode 100644 index 0000000..e03fe14 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c56fb214efcd707e6fa68b803d9e7686fc2f4336 @@ -0,0 +1 @@ +S�g�C�p�E����sāVT�A�@�@�@�@B�@�@C�@sā�@sā�@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c5902afe54998ebc5d8d59043227d379a8c2eee0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c5902afe54998ebc5d8d59043227d379a8c2eee0 new file mode 100644 index 0000000000000000000000000000000000000000..d71d57311e3d3751c094da6c16012c0ea39ce6d2 GIT binary patch literal 16 XcmWI9?9^7!uJw-L-MfD2cke0yL$L_C literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c6a16abeea323833079e97b1830610aa6c6eba91 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c6a16abeea323833079e97b1830610aa6c6eba91 new file mode 100644 index 0000000..b48967d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c6a16abeea323833079e97b1830610aa6c6eba91 @@ -0,0 +1 @@ +�gk���TEߣ�B�@���x��@��webmS�g�C�u����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c6fcfd2a1f91a7f6a8c124f2637e60645be01006 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c6fcfd2a1f91a7f6a8c124f2637e60645be01006 new file mode 100644 index 0000000000000000000000000000000000000000..5aaebfbfad5e9923a59246a7ba0f117d60f8cc3c GIT binary patch literal 25 gcmb0LZb+XZ@4T(Fe{pXk149cl0|O%?6B9Et0Bq6*M*si- literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c75b02a90370df1f54de2f63a4da8db22f2cf719 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c75b02a90370df1f54de2f63a4da8db22f2cf719 new file mode 100644 index 0000000..0cb101b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c75b02a90370df1f54de2f63a4da8db22f2cf719 @@ -0,0 +1 @@ +�E�E��B; \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c77cb763d73db279aebfb42d2b5dca3d705d3df7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c77cb763d73db279aebfb42d2b5dca3d705d3df7 new file mode 100644 index 0000000000000000000000000000000000000000..cae00316302d693b0b9e0b931f3c1962017f332e GIT binary patch literal 91 zcmb0LZb-i-7P2n;;=1$K6&M(bj{=EiAl?bY9Y7qq3P{WWV&%up4Z(RphSJtK4Q)U= Zc@dCMZR=U0RS6-8UX+R literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c864ac8bce0353ecc7d5cb0ce5a1e77a5239201e b/src/sys/libwebm/webm_parser/fuzzing/corpus/c864ac8bce0353ecc7d5cb0ce5a1e77a5239201e new file mode 100644 index 0000000..d745027 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c864ac8bce0353ecc7d5cb0ce5a1e77a5239201e @@ -0,0 +1 @@ +��M \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c877c08a79a7408aed779d4a430c5db1bce26314 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c877c08a79a7408aed779d4a430c5db1bce26314 new file mode 100644 index 0000000..de29891 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c877c08a79a7408aed779d4a430c5db1bce26314 @@ -0,0 +1 @@ +S�g�I�f�D��@ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c8aff6e2e2dfb18be385483b871ac86ff6eac63f b/src/sys/libwebm/webm_parser/fuzzing/corpus/c8aff6e2e2dfb18be385483b871ac86ff6eac63f new file mode 100644 index 0000000000000000000000000000000000000000..d553636e9bdc1adf7fa7d002b5131c1568b3299c GIT binary patch literal 200 zcmWG>YSUWzj^W+AckR;e-buOMU;N*x$$_OjH7QpjxFOx)n4s_MieBH{0t^i7!E1md zBO_3x1Vw~N)N^H8ht`#iAZeGXki+Sdi;D$#85oiefV5?t0*N!pJ8vs(dk$ub1@F%8 z1{uk=8N_E4aJE`r(CfMr$YFQg0~Qj3n!>=q3pGUpE?xmL9w?E10;IvE6(j)wgF literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c8c1c1f970bc809a75ad076bdb06275b6f72d078 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c8c1c1f970bc809a75ad076bdb06275b6f72d078 new file mode 100644 index 0000000..f2f8214 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c8c1c1f970bc809a75ad076bdb06275b6f72d078 @@ -0,0 +1 @@ +Eߣ�B�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c995d52934ac188971f02d5dbdb3cdd70cb03267 b/src/sys/libwebm/webm_parser/fuzzing/corpus/c995d52934ac188971f02d5dbdb3cdd70cb03267 new file mode 100644 index 0000000..fe179c9 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c995d52934ac188971f02d5dbdb3cdd70cb03267 @@ -0,0 +1 @@ +T���J��������"����>sŜ� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/c9e7fc3e0e1015a1c15992447f678a495c3ea5dc b/src/sys/libwebm/webm_parser/fuzzing/corpus/c9e7fc3e0e1015a1c15992447f678a495c3ea5dc new file mode 100644 index 0000000..b784d77 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/c9e7fc3e0e1015a1c15992447f678a495c3ea5dc @@ -0,0 +1 @@ +S�g�C�p�E���@sā�@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ca5b619ce1bbe23d519f5764d53458d2b85eb9fa b/src/sys/libwebm/webm_parser/fuzzing/corpus/ca5b619ce1bbe23d519f5764d53458d2b85eb9fa new file mode 100644 index 0000000000000000000000000000000000000000..a7b7c191c7fd26e721d3c481961dc633ef4ec4da GIT binary patch literal 121 zcmb1=dgr>h!>P%Er93q$S0cC}-Qk#^lhxAagYUlyWC2 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cb0556c65c7381192c94324a3b1b8afb7e33fecc b/src/sys/libwebm/webm_parser/fuzzing/corpus/cb0556c65c7381192c94324a3b1b8afb7e33fecc new file mode 100644 index 0000000000000000000000000000000000000000..2a7063ef0146a6a5804b15cd30a1b3c10b9af5df GIT binary patch literal 54 zcmb0LZb;uC@4T&a^@5cPTN!|0QA;zBEM3^V$bn(D!v@CR4vZkoRI2!5QRDwU2j&+J F3;-@Y6m9?j literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cb1a093e6810c7f6c002a2a54ea390cf769c9949 b/src/sys/libwebm/webm_parser/fuzzing/corpus/cb1a093e6810c7f6c002a2a54ea390cf769c9949 new file mode 100644 index 0000000000000000000000000000000000000000..6f2ab374cd29e4b9c92bd12e83cc6050e42eca01 GIT binary patch literal 52 zcmb1gl?ZM~U)B9fZ{x5Z4 F1OV?-6GQ+2 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cc1487af64aeefd7080e7678a04870dc85a7928a b/src/sys/libwebm/webm_parser/fuzzing/corpus/cc1487af64aeefd7080e7678a04870dc85a7928a new file mode 100644 index 0000000000000000000000000000000000000000..815b9079dbd6453e1a4b8152c03f4398ff600e49 GIT binary patch literal 25 gcmb0LZb+XZ@4T(Fe{pX!1A`Sa0|O%?6B9Et0BQ&Y{{R30 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cc71d2c9f5eae12acee133bd9e50d84881a1bd88 b/src/sys/libwebm/webm_parser/fuzzing/corpus/cc71d2c9f5eae12acee133bd9e50d84881a1bd88 new file mode 100644 index 0000000000000000000000000000000000000000..2f87371ebbd0e56c014bb2350503f9e4ba6dd627 GIT binary patch literal 5 Mcmdlbb>Ec%00%Y!`2YX_ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ccb8f962426683663972534c15354f70c3b34a10 b/src/sys/libwebm/webm_parser/fuzzing/corpus/ccb8f962426683663972534c15354f70c3b34a10 new file mode 100644 index 0000000..3b41d17 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/ccb8f962426683663972534c15354f70c3b34a10 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cd0771c4754dfcd9c89b9b8a02df96fed974850d b/src/sys/libwebm/webm_parser/fuzzing/corpus/cd0771c4754dfcd9c89b9b8a02df96fed974850d new file mode 100644 index 0000000..519a312 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/cd0771c4754dfcd9c89b9b8a02df96fed974850d @@ -0,0 +1 @@ +�!Eߣ�B�@webm!S�g*M�'�t�I�f�C�u�TSkk����C�p�T�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cd8899c66cbd92ee57f94e000744b32662258ba3 b/src/sys/libwebm/webm_parser/fuzzing/corpus/cd8899c66cbd92ee57f94e000744b32662258ba3 new file mode 100644 index 0000000000000000000000000000000000000000..42db6e81709065c9e3930fe1220be1492d759171 GIT binary patch literal 20 bcmb0LZbDWx;^f9wMwj#xGl9&M^b_4cDmDE? z3rO-vYh!z3T0W4|-k2_dYRUxH#f=bCT7agsHzoryBgm9?h$-z5Q-JzGhGFUlx&piY I7F-4Z07<4=!2kdN literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cfb09018afa0eb1a829e556d9f8bceff40cb36bc b/src/sys/libwebm/webm_parser/fuzzing/corpus/cfb09018afa0eb1a829e556d9f8bceff40cb36bc new file mode 100644 index 0000000..31fc352 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/cfb09018afa0eb1a829e556d9f8bceff40cb36bc @@ -0,0 +1 @@ +S�g�I�f�Da�4Vx���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/cfbe3d66d7eb3199440e8e911a93044cc3165c6c b/src/sys/libwebm/webm_parser/fuzzing/corpus/cfbe3d66d7eb3199440e8e911a93044cc3165c6c new file mode 100644 index 0000000000000000000000000000000000000000..ba138c42534da6ab228e210074377d8453d47d64 GIT binary patch literal 227 zcmb1gm2$nmxWlQ*fu%e(DOV!6A>H9vIf&{P3OStKRb1SjetLGv72n+g4D2UbTv~(I z2rw`(G79?6F6jjcGO!1)NnrqqF^Nhwy8cHoE4fd|CB3t_xGfoEV!KQ*i2A=$-g#T8 z=gPDWt?L^FL57J!Ibc&jl5NkymdM{<-0mdsA851$P!OoK6(S+(d0=-#`ibm@rqxTH mJ1{b?c2Hzw+TF0YRcfE>edV+UCb5upQrX?>fQGO|T?YW808iTh literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d0a91f7984904976de592cb68e8832853fbec9bc b/src/sys/libwebm/webm_parser/fuzzing/corpus/d0a91f7984904976de592cb68e8832853fbec9bc new file mode 100644 index 0000000000000000000000000000000000000000..d61a53a0aa62dd1dbde0784c1a4bf218aa1c3567 GIT binary patch literal 20 bcmb0LZbp*k5s-QY7G?&xK3ohI IAYcUn0FJE+j{pDw literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d2709a1c9d96e72cb844eedca8bfe8440cdb0ef8 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d2709a1c9d96e72cb844eedca8bfe8440cdb0ef8 new file mode 100644 index 0000000..c41d905 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d2709a1c9d96e72cb844eedca8bfe8440cdb0ef8 @@ -0,0 +1 @@ +S�g�I�f�Da��ܺ�vT2 \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d2e385f61ad4b5d45a10a5a6cb85d72e84dea54b b/src/sys/libwebm/webm_parser/fuzzing/corpus/d2e385f61ad4b5d45a10a5a6cb85d72e84dea54b new file mode 100644 index 0000000..433cbfd --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d2e385f61ad4b5d45a10a5a6cb85d72e84dea54b @@ -0,0 +1 @@ +@p� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d2facb213561b30a5bcd012e4e01d0d5b0b26957 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d2facb213561b30a5bcd012e4e01d0d5b0b26957 new file mode 100644 index 0000000..26ca861 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d2facb213561b30a5bcd012e4e01d0d5b0b26957 @@ -0,0 +1 @@ +S�g�T�k�����T�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d300e5e46a825e5892fae1ba3c466c836f9e1da2 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d300e5e46a825e5892fae1ba3c466c836f9e1da2 new file mode 100644 index 0000000000000000000000000000000000000000..7b6f1d84b7ad23bf5571722a44cccdb532a33d72 GIT binary patch literal 63 zcmb0LZb;uP6mmFyTXFH`^b;Fg7dIxlR5d2Kv^FvTak5KmCu91FnJ(>(EeN6Z;v?xN IT7Y8d0D7Mr{Qv*} literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d302c69c881e230e6433283007d318ba437025c3 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d302c69c881e230e6433283007d318ba437025c3 new file mode 100644 index 0000000..055ab79 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d302c69c881e230e6433283007d318ba437025c3 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P3�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d30c1b65bc141d1a15d4ed622ba182c96dacdf92 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d30c1b65bc141d1a15d4ed622ba182c96dacdf92 new file mode 100644 index 0000000000000000000000000000000000000000..aeb5e2ec68749015d56020ae50a50e2d443f81dd GIT binary patch literal 22 dcmb0LZb+Xb6mmGdx45_~`9OQ}sTL0g1^{W92^9bU literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d3adf09fe6fb1534157c1dc68eb61365b46b1c35 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d3adf09fe6fb1534157c1dc68eb61365b46b1c35 new file mode 100644 index 0000000..ad8336b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d3adf09fe6fb1534157c1dc68eb61365b46b1c35 @@ -0,0 +1 @@ +Eߣ��p�Ӓ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d3c74d3a64dba86f98a31bb726587ec97a7e4531 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d3c74d3a64dba86f98a31bb726587ec97a7e4531 new file mode 100644 index 0000000..c2ce861 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d3c74d3a64dba86f98a31bb726587ec97a7e4531 @@ -0,0 +1 @@ +������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit��������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit��������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit��������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������D������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit�������;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������IIII�����������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������timeout_exitcode����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������timeout_exit�������;������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d3c9846ab319f12fc646c23a532c780daa9e993f b/src/sys/libwebm/webm_parser/fuzzing/corpus/d3c9846ab319f12fc646c23a532c780daa9e993f new file mode 100644 index 0000000..6986002 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d3c9846ab319f12fc646c23a532c780daa9e993f @@ -0,0 +1 @@ +S�g�T�k���m��b@�P1�P2�P3�P5� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d3f03301b52cf4a830c7dd200ed8ccbc09e6ec94 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d3f03301b52cf4a830c7dd200ed8ccbc09e6ec94 new file mode 100644 index 0000000000000000000000000000000000000000..3910637501cd5884b2e5e75ca12f0efa6d728c70 GIT binary patch literal 18 Zcmb1gJ-@i!N#H*NQ?Nv9gQw`~1^_>j2BiQ1 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d4800745440dace38766db3520ffe7baa0bd78f2 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d4800745440dace38766db3520ffe7baa0bd78f2 new file mode 100644 index 0000000000000000000000000000000000000000..78d6b02b53cd448daf5cbf9d0cf9a12fc1471670 GIT binary patch literal 4 LcmdnI>plYj2D}1I literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d4d6271bba704ba08c2678eb8b1bc4e457144f50 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d4d6271bba704ba08c2678eb8b1bc4e457144f50 new file mode 100644 index 0000000000000000000000000000000000000000..5715e682c795a47f2f488480a82a332164beb323 GIT binary patch literal 20 acmZ>+<9wZbl!1X^bv*+M149OoXaE2|r3Cl@ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d54020f766061e80f445690c2b5694ed8af21e9d b/src/sys/libwebm/webm_parser/fuzzing/corpus/d54020f766061e80f445690c2b5694ed8af21e9d new file mode 100644 index 0000000..d0e8288 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d54020f766061e80f445690c2b5694ed8af21e9d @@ -0,0 +1 @@ +G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d588515f125ebe968fe6a81cb6df7cfc41969e68 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d588515f125ebe968fe6a81cb6df7cfc41969e68 new file mode 100644 index 0000000..4b30c90 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d588515f125ebe968fe6a81cb6df7cfc41969e68 @@ -0,0 +1 @@ +Eߣ�Eߣ2 \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d5ee5e4dc8fad9f1da43102d8322beb005a047c0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d5ee5e4dc8fad9f1da43102d8322beb005a047c0 new file mode 100644 index 0000000..d51648b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d5ee5e4dc8fad9f1da43102d8322beb005a047c0 @@ -0,0 +1 @@ +E߾�B�@webmS�g�C�u�����@ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d62459bb217d3050bcd9e29a6327cf81f5ed68b9 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d62459bb217d3050bcd9e29a6327cf81f5ed68b9 new file mode 100644 index 0000000..c4ec3c4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d62459bb217d3050bcd9e29a6327cf81f5ed68b9 @@ -0,0 +1 @@ +������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������w�������������������������������������������������������������������������������������������������������������������������������������������������������������������;����������������������������������������������������m����������݀������������������������������������������������������������������������������������������������嶀������Eߣ��������m����������݀���������������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d6acbf1cb46845618ed0d5a322c8bd4879d16422 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d6acbf1cb46845618ed0d5a322c8bd4879d16422 new file mode 100644 index 0000000..479a877 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d6acbf1cb46845618ed0d5a322c8bd4879d16422 @@ -0,0 +1 @@ +S�g�T�g�ss�gȩȄ#��dgȄ]��egȄD*�dgȄ]��egȄD��gȀD��dgȁg \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d6fc8cdbb0f1517159531098e900e2dcc91edba0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d6fc8cdbb0f1517159531098e900e2dcc91edba0 new file mode 100644 index 0000000..d7384b7 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d6fc8cdbb0f1517159531098e900e2dcc91edba0 @@ -0,0 +1 @@ +S�g�S�k��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d7a9bbd9875a60edf9c528b298ea72a2fad7d3d7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d7a9bbd9875a60edf9c528b298ea72a2fad7d3d7 new file mode 100644 index 0000000000000000000000000000000000000000..e2c81b6263c26dbd886ff3d34f6da1320200f7d5 GIT binary patch literal 59 qcmb0LZb;uC@4T&a^@5cPTbmewU{OmmjDtn2bkUOkeGbeo92fxZ#u-`w literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d82e70046a544e95e81f6271dd2695f2599f0574 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d82e70046a544e95e81f6271dd2695f2599f0574 new file mode 100644 index 0000000..a2fe29e --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d82e70046a544e95e81f6271dd2695f2599f0574 @@ -0,0 +1 @@ +S�g�T�g�ss�c��gȀ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d84bc8dca7c8fcd227254c06f5b88eaaf7cd5fde b/src/sys/libwebm/webm_parser/fuzzing/corpus/d84bc8dca7c8fcd227254c06f5b88eaaf7cd5fde new file mode 100644 index 0000000..f5d0f36 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d84bc8dca7c8fcd227254c06f5b88eaaf7cd5fde @@ -0,0 +1 @@ +� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d8bcb7dd21205e7126e700323b1d58817e9d9a6d b/src/sys/libwebm/webm_parser/fuzzing/corpus/d8bcb7dd21205e7126e700323b1d58817e9d9a6d new file mode 100644 index 0000000000000000000000000000000000000000..b32e7048f1954efc84213f63893709ec9b630467 GIT binary patch literal 39 pcmb0LZb)A&@4T&a-hw#`TN@dGU{MQ*DqYyn=fLpWfvFTk0{|wq4i5kT literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d8e2628b4092b9bbab4f02041647f950503eeb48 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d8e2628b4092b9bbab4f02041647f950503eeb48 new file mode 100644 index 0000000000000000000000000000000000000000..6aa71bd89d56f1ea903f3c0a41d6907b6d3dbf15 GIT binary patch literal 33 pcmb0LZb+Xa;JmzGy6es<+a?tsX$T8xnCQST$$_E4fnl2i0|4#K4FmuH literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d8ee4c2b79863a237c432efe7d43d99c8d0afb9b b/src/sys/libwebm/webm_parser/fuzzing/corpus/d8ee4c2b79863a237c432efe7d43d99c8d0afb9b new file mode 100644 index 0000000000000000000000000000000000000000..db8723cceaa75949e972dc0e9df272a916dcd3fa GIT binary patch literal 53 vcmb0LZb;uC@4T&a^@5cPTNgGjb6}Y5z{vO;f|1!wrHdN>_c<`XX!s8RHlGzS literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d8ee9724bf16ff336387723dcf27319c3be72e01 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d8ee9724bf16ff336387723dcf27319c3be72e01 new file mode 100644 index 0000000..ce72a85 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d8ee9724bf16ff336387723dcf27319c3be72e01 @@ -0,0 +1 @@ +S�g�T�k�����T�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d9379969bc956ad623e4bab8bbe47270a880a62d b/src/sys/libwebm/webm_parser/fuzzing/corpus/d9379969bc956ad623e4bab8bbe47270a880a62d new file mode 100644 index 0000000..40bdf1a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d9379969bc956ad623e4bab8bbe47270a880a62d @@ -0,0 +1 @@ +S�g�C�u���u�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/d9ccb79b0e070dcc2f5ed8e15d99bc5ef86ecff7 b/src/sys/libwebm/webm_parser/fuzzing/corpus/d9ccb79b0e070dcc2f5ed8e15d99bc5ef86ecff7 new file mode 100644 index 0000000..4c2c858 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/d9ccb79b0e070dcc2f5ed8e15d99bc5ef86ecff7 @@ -0,0 +1 @@ +Eߣ�B�@webmS�g�C�u��@�@������@ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/db83586ca6266e03067e9a9772ea728ab770ad9a b/src/sys/libwebm/webm_parser/fuzzing/corpus/db83586ca6266e03067e9a9772ea728ab770ad9a new file mode 100644 index 0000000000000000000000000000000000000000..0b49ef89517f704123b3c1577885e871cc69d4dd GIT binary patch literal 25 gcmb0LZb+XZ@4T(Fe{pXk14GMq1_nk(CMITP0Ci>uI{*Lx literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/dcc63c06ed2790d1380bdb9281fe8677f439c76d b/src/sys/libwebm/webm_parser/fuzzing/corpus/dcc63c06ed2790d1380bdb9281fe8677f439c76d new file mode 100644 index 0000000000000000000000000000000000000000..c5769be7800f5e5cc5fb1d77053056f5d9b23e0c GIT binary patch literal 53 xcmb0LZb;uC@4T&a^@5cPTbmewU{OmmkStx;yvzZ?p60+X+kuhs9T5Lk000s=5|jV{ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/dd509e9a4660ec34b8f9dc23441c6df4ff97c34d b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd509e9a4660ec34b8f9dc23441c6df4ff97c34d new file mode 100644 index 0000000..2a77375 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd509e9a4660ec34b8f9dc23441c6df4ff97c34d @@ -0,0 +1 @@ +S�g�C�p�E��E��E��E�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/dd72f8ff3a067dc7871438b6023e1ed0a4c5787b b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd72f8ff3a067dc7871438b6023e1ed0a4c5787b new file mode 100644 index 0000000..dec5b01 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd72f8ff3a067dc7871438b6023e1ed0a4c5787b @@ -0,0 +1 @@ +S�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/dd75880c5ad488885260f4031a763c86a8084406 b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd75880c5ad488885260f4031a763c86a8084406 new file mode 100644 index 0000000000000000000000000000000000000000..ad235541cb0db474960b55f717cd274512861346 GIT binary patch literal 111 zcmb0LZb;uF;JmzGyX(#^+cq_9XmyZiV9iL)$;o%FX_WxVE|zy@+*Ueo!JLJyjSN7r zs0BooE^L_Xz>t%emu}!(*P2-LJJr#^*@2;SQA15DP_)neQMv;|x*^aEkQyVfn$$!? E0L11ifB*mh literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/dd962d74d04aa4aed270fd8e6b0ae9c4ac35fd19 b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd962d74d04aa4aed270fd8e6b0ae9c4ac35fd19 new file mode 100644 index 0000000..dcb3af4 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd962d74d04aa4aed270fd8e6b0ae9c4ac35fd19 @@ -0,0 +1 @@ +������������6�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������JIII|������������������������������������������������������������������;���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������;�������������������������������������������������������������������������������������������������������������������������������������w��������������������������������������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/dd9aa9a49dd790b2ce99c5af1933232d46a7f80d b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd9aa9a49dd790b2ce99c5af1933232d46a7f80d new file mode 100644 index 0000000..28fd4f5 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/dd9aa9a49dd790b2ce99c5af1933232d46a7f80d @@ -0,0 +1 @@ +S�g�I�f�D��@�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ddad7630818a1caa8054d2d7280a1d01bdb33ca3 b/src/sys/libwebm/webm_parser/fuzzing/corpus/ddad7630818a1caa8054d2d7280a1d01bdb33ca3 new file mode 100644 index 0000000000000000000000000000000000000000..5fdbe5b3e5897b00919553724d12d92bcda59647 GIT binary patch literal 18 acmWH!yV1yc>#Z!|HWSnYbIML#|czZ)*;)xcQs>UP$ D>#h}u literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/de0ff884898c83fb880498f1b8328f78701e6534 b/src/sys/libwebm/webm_parser/fuzzing/corpus/de0ff884898c83fb880498f1b8328f78701e6534 new file mode 100644 index 0000000..b9f4c9d --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/de0ff884898c83fb880498f1b8328f78701e6534 @@ -0,0 +1 @@ +��݀禀��݀禀�u�u \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/de9e0ed8ae29220e5b65e5b97eb3b254ccbe7e0c b/src/sys/libwebm/webm_parser/fuzzing/corpus/de9e0ed8ae29220e5b65e5b97eb3b254ccbe7e0c new file mode 100644 index 0000000000000000000000000000000000000000..d48be42d1366c674dc4c5fd94cf9e9ed723d452a GIT binary patch literal 45106 zcmeHQJB}np5akG%xL8OW0T-Wqwv z%!;hZnGUsfx@Wrc_u|EiPu0wR_T9%HZl8Yr`_H!zf8Sp2kKgXE=x4v)zx#LpF?#dk z_U7#c!y5)KbN@%f{#^bobMp-H_+@2}ZRYDK=Q_L8=gWb3DLNCM=$lWzrN;{AFF*eD zeHUVYJGWM{&;XEhqdbezzao1s|M*dHgUgH#=70=2sdanpoX9?`$IRH=o~cPN4pzT| z&5-XDD)|&F(qJ2l)(GeQ$HD;GPUm?OzXmvQ13YzX!8+)f8T(mL(OpI003D=&(q|Tc zNzW%eC++cCCcUwknQ%T(qCt4(mbUL8SPAdQF)N%hxs#EVXVYKb-K^QL6i6;hF#w>1 zHWcp4ia^WO{A!G#3EN!a=E?#;s6nWzFQoOFGm?wl2uB&`8b z8ZFqU`0D5{Ehjb@nsax+Ssfsm_kOrVtLV|CB~Zh;=-*k<5DEp9AO2d=apcp?m=(td zOI~iqyx|lFtAkh5tWrv^fS}zkt$vS4zSl$!OD$pMpj1SfaShLr=xLz5NXo4^+VbH5Fw@Kf6IWAoM;@( z**I9b0u2S6kW$DIQgNJm-wdvb!I901q80ahwB-#|(n{IvBL}O4Q>dUlv-Parr4a(dP*tf%0U^6w>JwC|OYy zM$aWSwA~2Eo9$&EGNd(UuEnfjecM0;IfA-*dRlViJRW`3WZ7aVb8bI6uqn+St3I}qc1;G+lH+W_mVLVa>!G~wUfX*{fT?Yc5ryg@!2$P+1Szt z(%2y-rn}>~roo=r9NdRehi*s#h{UozN7-G_J)PQ+tq)O7IT!IXs$$s`IuY$l}M7p7yV4;T<9}lQ$QJ>u%JSZ5&FzC3#j7_ zdfuyC`IF9!j3x?eucj4*#%OJm?kN}6jVfl`jc|^q%nf!P@f3F>v0g-5i*b+xeAPQ> zP-lU)$p3Lc+XAa3*w#q5k!Lori~9jR+VUiF2f&aiY|9Qg3b zXO`z-rM0{xL<)JCp80IYV&9LsR)ogIy7`0rGi46+PMI*Y`|$3n9xqo;%RjG}jNa_f zjHnvB(e8}JJ2pktxPwDUB~lKQv;1(tk*kvREz+qNRXiE9xx?^v+|S)yj$6^%(WNW)9Yf}vaA-wE~gDr_q} z*Jl>sLeFrh88Iu4pEmwxgbP~+&UOXz}brz%pvVWY5TO(SPt(6F$@H#6s}PZ@!lh%iOj5Y3duOe46~jGv4s;{?@k7E z*@*&M3O5R)MS_AviAJg~sBg|CHgqxxpu6n`NJdyN5nE%q#6w_#s~XxJ#^J^Xg}=;cb3D^StF?WAoQIxIdQK9>0pUQQ-W!XV3Fq8XbZZ_YN(p&`XXci+@4(6@ z{T$X=o`;puIAB}1MC)iAM&wY5;hLYTD@pjJ0kl#2gycdc!=<_O?4#Efgx_NU^M!jJUMP_)kNOcK iO_OMmC{}>%DfeFrH&isX5msN#xOUObLFOxe8S;O4yVZ~9R&aY literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e01962d7dc1b94e5c4424ec7adae16a7c03b9773 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e01962d7dc1b94e5c4424ec7adae16a7c03b9773 new file mode 100644 index 0000000..8d7f32a --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e01962d7dc1b94e5c4424ec7adae16a7c03b9773 @@ -0,0 +1 @@ +��X \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e058723f2964bf1405ae043ddb99efb17d821e15 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e058723f2964bf1405ae043ddb99efb17d821e15 new file mode 100644 index 0000000..a294613 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e058723f2964bf1405ae043ddb99efb17d821e15 @@ -0,0 +1 @@ +S�g�C�p�E������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e09e306ef596dcd0e44bd3ef3c5f7019c7343f84 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e09e306ef596dcd0e44bd3ef3c5f7019c7343f84 new file mode 100644 index 0000000..1abbf62 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e09e306ef596dcd0e44bd3ef3c5f7019c7343f84 @@ -0,0 +1 @@ +S�g�T�k����x��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e154eb76d096c1e545dcad591a58a02c37cd71ff b/src/sys/libwebm/webm_parser/fuzzing/corpus/e154eb76d096c1e545dcad591a58a02c37cd71ff new file mode 100644 index 0000000..f575e8b --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e154eb76d096c1e545dcad591a58a02c37cd71ff @@ -0,0 +1 @@ +!Eߣ�B�@webm�S�g�*M'�t�I�f�C�u�TSkk����C�p�T�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e198d2e4f2f3528c2ff46d769a9281ebb3cfb44a b/src/sys/libwebm/webm_parser/fuzzing/corpus/e198d2e4f2f3528c2ff46d769a9281ebb3cfb44a new file mode 100644 index 0000000..75c0df8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e198d2e4f2f3528c2ff46d769a9281ebb3cfb44a @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G�!S�g�T�k���m��b@�P5�G�!S�g�T�k���m��S�g�T�k���m�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e2068af1e903f4a81cd6fa5f4022e62070c259ec b/src/sys/libwebm/webm_parser/fuzzing/corpus/e2068af1e903f4a81cd6fa5f4022e62070c259ec new file mode 100644 index 0000000000000000000000000000000000000000..8ceb55924f014418eb8bd28cc64f4b9ed0bd1fe4 GIT binary patch literal 39 vcmb1gy}!7_smXz*JT)m-BDf)as=V{I(h1KU7*;zlEN*RNc=MlWfdc~oH%||# literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e2890330b5655cb277a581b8dd2eeba0d9061ba5 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e2890330b5655cb277a581b8dd2eeba0d9061ba5 new file mode 100644 index 0000000..ffdb9c0 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e2890330b5655cb277a581b8dd2eeba0d9061ba5 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e2e0767d055a7042c24a7acd5d5b6b7c093ad065 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e2e0767d055a7042c24a7acd5d5b6b7c093ad065 new file mode 100644 index 0000000..145b54c --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e2e0767d055a7042c24a7acd5d5b6b7c093ad065 @@ -0,0 +1 @@ +S�g�T�k������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e394a8e21e2c43c42135daa034ad5aabb06acffb b/src/sys/libwebm/webm_parser/fuzzing/corpus/e394a8e21e2c43c42135daa034ad5aabb06acffb new file mode 100644 index 0000000000000000000000000000000000000000..3bfae2e67aa80ab8d4e2c601ba0fa78cbb791722 GIT binary patch literal 145 zcmb1gy}!7_smXz*JT)m-BDf*l;h3QB?2=yJ-2w~@?7?e*BqJk+2$QJi%Crux>l?w+ x$Q&kl=b5E#&q3l+K%wE&uH4H0A#3t88g-MtQ|fbBY1H&6hX4*+w+DPsTt literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e3b200e97ec226a197e91f12103aaa53d5c37b0e b/src/sys/libwebm/webm_parser/fuzzing/corpus/e3b200e97ec226a197e91f12103aaa53d5c37b0e new file mode 100644 index 0000000..a2f27b7 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e3b200e97ec226a197e91f12103aaa53d5c37b0e @@ -0,0 +1 @@ +S�g�C�p�E����sāV�@��@s��@sā�@sā�@sā�@sā�@sā \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e45b077cda64c380ae1b0910bc81d010c27e1c93 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e45b077cda64c380ae1b0910bc81d010c27e1c93 new file mode 100644 index 0000000..e05b783 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e45b077cda64c380ae1b0910bc81d010c27e1c93 @@ -0,0 +1 @@ +Sx�g%T:k���m��b@�1� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e45e71ca01ebe01b01b0ca99b8f20a756c36b967 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e45e71ca01ebe01b01b0ca99b8f20a756c36b967 new file mode 100644 index 0000000..3d1f9b0 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e45e71ca01ebe01b01b0ca99b8f20a756c36b967 @@ -0,0 +1 @@ +$��T�g� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e4ff4bd938c3737a02862fc0656a1859d384d066 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e4ff4bd938c3737a02862fc0656a1859d384d066 new file mode 100644 index 0000000..635b823 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e4ff4bd938c3737a02862fc0656a1859d384d066 @@ -0,0 +1 @@ +S�g�C�p�E������� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e5a1acb7e6f71bc1a2fedaa6173764dfd04c844c b/src/sys/libwebm/webm_parser/fuzzing/corpus/e5a1acb7e6f71bc1a2fedaa6173764dfd04c844c new file mode 100644 index 0000000..ca4a19c --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e5a1acb7e6f71bc1a2fedaa6173764dfd04c844c @@ -0,0 +1 @@ +S�g�T�k���m��b@�P5�G�G�S�gg�T�k���m��b@�P5�G�;G� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e6081eeff4ddb76e88e87ef9e4b5f199f5f11c28 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e6081eeff4ddb76e88e87ef9e4b5f199f5f11c28 new file mode 100644 index 0000000000000000000000000000000000000000..7b80d1b94193a114f9c97e55056007080c2f1123 GIT binary patch literal 63 zcmb0LZb;uP6mmFyTXFH`^b;Fg7dIxlR5d2Kv^Fxhw6-=Ucd9d{pP1>Q+1LURYD{)% PZ7)8Oexk*ty)hjCZ_pcr literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e73c42dd266c4d9671da0c7af09e98c02fc052fd b/src/sys/libwebm/webm_parser/fuzzing/corpus/e73c42dd266c4d9671da0c7af09e98c02fc052fd new file mode 100644 index 0000000000000000000000000000000000000000..18e6ae2a8a3ee230a64894152cc04768d999e2b2 GIT binary patch literal 86 zcmb0L{+K>N)N^H8x0LJs#T`yf4lL!VE{Prg?(CXT7GfZflq(V3knV6y@a*i8Ufy09KF(qyPW_ literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e7dd34a80646a8c38ae1ec3a27c1358bab13b360 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e7dd34a80646a8c38ae1ec3a27c1358bab13b360 new file mode 100644 index 0000000..8a7f10e --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e7dd34a80646a8c38ae1ec3a27c1358bab13b360 @@ -0,0 +1 @@ +S�g�T�k������ \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e80b344f943ff0ad9219277c4578d3b4100b71dc b/src/sys/libwebm/webm_parser/fuzzing/corpus/e80b344f943ff0ad9219277c4578d3b4100b71dc new file mode 100644 index 0000000..0f27b93 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e80b344f943ff0ad9219277c4578d3b4100b71dc @@ -0,0 +1 @@ +Eߣ���b \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e86e26200290d9d428c5e98e191ec874eb918fb6 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e86e26200290d9d428c5e98e191ec874eb918fb6 new file mode 100644 index 0000000..dedb463 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/e86e26200290d9d428c5e98e191ec874eb918fb6 @@ -0,0 +1 @@ +S�g�T�k���m��b@�P2�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e873a3b8f5c3b716e6446df34279b837cf8d2c30 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e873a3b8f5c3b716e6446df34279b837cf8d2c30 new file mode 100644 index 0000000000000000000000000000000000000000..40a9456476463b9d98ec50d9daddfb054617bd64 GIT binary patch literal 53 zcmb1gl?ZM~U)B9fZ{x9ut GU<3dI{S(Xp literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/e8fb71319db98d8e8cd131a4eb82879bfbec14d0 b/src/sys/libwebm/webm_parser/fuzzing/corpus/e8fb71319db98d8e8cd131a4eb82879bfbec14d0 new file mode 100644 index 0000000000000000000000000000000000000000..2bf9e0dee6c869d026ee3a4a84a7ecd98bcd3b39 GIT binary patch literal 123 zcmb0LZb<(o7P2n;l?w+ z$Q&kl=WV5J&%xpdCX-mmy6o~4^iY@5OI0?x||dR=z{+3fXu Yz#>8+htnq)7X#V6$p=8<8K*$v0C_Poe*gdg literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ef11f14feee00e3c198015e6bc76688e970e2d8c b/src/sys/libwebm/webm_parser/fuzzing/corpus/ef11f14feee00e3c198015e6bc76688e970e2d8c new file mode 100644 index 0000000..414c1b3 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/ef11f14feee00e3c198015e6bc76688e970e2d8c @@ -0,0 +1 @@ +S�g��� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/efa12e91e0d63c2353c120ca1ded7b36afbf57eb b/src/sys/libwebm/webm_parser/fuzzing/corpus/efa12e91e0d63c2353c120ca1ded7b36afbf57eb new file mode 100644 index 0000000000000000000000000000000000000000..1673fc014bb32ef779b186b9182b48db984f9c09 GIT binary patch literal 59 zcmb1gy}!7_smXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfuJ}ZDas~#jQ<9)B*>V*({7q E0By+;;{X5v literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/efa14cba9bbaf749067b7bb8515a5d8a289fa389 b/src/sys/libwebm/webm_parser/fuzzing/corpus/efa14cba9bbaf749067b7bb8515a5d8a289fa389 new file mode 100644 index 0000000..7c34b99 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/efa14cba9bbaf749067b7bb8515a5d8a289fa389 @@ -0,0 +1 @@ +S�g�I�f�WA�! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/eff9bf13cd33ea50a8eacc5f2839cc4b5d67b2de b/src/sys/libwebm/webm_parser/fuzzing/corpus/eff9bf13cd33ea50a8eacc5f2839cc4b5d67b2de new file mode 100644 index 0000000..5f0ecb9 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/eff9bf13cd33ea50a8eacc5f2839cc4b5d67b2de @@ -0,0 +1 @@ +Sg��I��@D���� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/f0143756917f0b2e374bd03e731cd64168180054 b/src/sys/libwebm/webm_parser/fuzzing/corpus/f0143756917f0b2e374bd03e731cd64168180054 new file mode 100644 index 0000000..6773d0f --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/f0143756917f0b2e374bd03e731cd64168180054 @@ -0,0 +1 @@ +S�g�C�u����� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/f0b9dcd4e1845f774bb0f42653b11040baee0765 b/src/sys/libwebm/webm_parser/fuzzing/corpus/f0b9dcd4e1845f774bb0f42653b11040baee0765 new file mode 100644 index 0000000000000000000000000000000000000000..71caf1466ad9ea6986f3a40cd9de87ec5e54f3ec GIT binary patch literal 118 zcmb1gy}!7_smXz*JT)m-BDf*l;h3QB?2=yJ-2w~@?7?e*BqJk+2$QJi%Crux>l?w+ h$Q&kl=WV5J&%xpdCX-mmy6ol?w+ z$Q&kl=WVHN&%xqAW+{ZpBo?wRyL%l_lsmXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfy%eZDIg|1r7qU9T;CObYKsj IC*`^Z01W*Ss{jB1 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/f69d2954da077043c6ae085e2771a702689314d5 b/src/sys/libwebm/webm_parser/fuzzing/corpus/f69d2954da077043c6ae085e2771a702689314d5 new file mode 100644 index 0000000000000000000000000000000000000000..8474e60c2fe71ec9abe325e54942299169c6eeee GIT binary patch literal 82 zcmb0LZb;uC@4T&a^@5cPTP37i&o6Fw()iE76fDu&!~g_~TAG1m=|Tyh!k1zp>$0D$ dd-UMJECB`vMyB8$5b6MkYVZ_Y-N3v-008}39Af|g literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/f74e2203adb9c94ba80f7cc3214e3b3040e5675d b/src/sys/libwebm/webm_parser/fuzzing/corpus/f74e2203adb9c94ba80f7cc3214e3b3040e5675d new file mode 100644 index 0000000000000000000000000000000000000000..0caab79590748c65879cdaff3693feb4c784c10c GIT binary patch literal 90 zcmb1gy}!7_smXz*JT)y>BDf)arM&aD(k0Iw7#UYPFfuJ}ZDas~#jQ;sYJmgGY@h^$ IBA}WH0AVd0Jpcdz literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/f7906e7dc01323b9d3d6e298e8dc2386c8d152f6 b/src/sys/libwebm/webm_parser/fuzzing/corpus/f7906e7dc01323b9d3d6e298e8dc2386c8d152f6 new file mode 100644 index 0000000..d70e0ac --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/f7906e7dc01323b9d3d6e298e8dc2386c8d152f6 @@ -0,0 +1 @@ +���g��C�u�� \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/f825cac511f3dc38a5ecf3aab3691b4c49ca8f0e b/src/sys/libwebm/webm_parser/fuzzing/corpus/f825cac511f3dc38a5ecf3aab3691b4c49ca8f0e new file mode 100644 index 0000000000000000000000000000000000000000..8ea43ca7857536a4c131eafd2d4872c9ebaf7981 GIT binary patch literal 59 zcmb1gy}!7_smXz*JT)m-BDf)arM&aD(k0Iw7#UYPFfuJ}ZDas~#jQ;sYJmgGZ=eK( GVgdkj#1i%Z literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/f84c3f9e305172f2ae15dff0b4d955324b3a398e b/src/sys/libwebm/webm_parser/fuzzing/corpus/f84c3f9e305172f2ae15dff0b4d955324b3a398e new file mode 100644 index 0000000000000000000000000000000000000000..c1987a9265e781d5c8bf1ac117208c9c9c356761 GIT binary patch literal 19 acmb0LZbeZ`PW$%+`*W2SePv5*eZtjkU?)6Le zKltpX`|aQU*Wl!}d%p)?`j3X=;Ex}D042UI4||ONDUy;G^#w7_XQ@0bKbco{Fao zRQ}l!hTvSkR*oo7sYAZHej*YUu8B%YAd{jJNryv5*)BhH?iEH}SiVp`;P#h+nsn8Z z8Zc<~zVQp8-o+EnHoFRWn}PsXE4SZ4=)l0x9fJcxo~MXHOL?FYOk(Gwl8xKO@fxQO zSDAq|96X=`XajJ}$95`6`!Z3?fV9p4}L+M&8N9hf~6bw%<3i`^#V7!E-jS;V@mK9{Jbhl|rI?Z&IK~-c? zU#dmp7QR{;l9rNQz;pv~+xqO>AAO8lYH8SQDR=GAT^w@|MKR$d6uZ{kLyHasi;oiD zohhWIE?MH7*4*>91z4w47k!5Egp`4aY;v-f~ZHetRVQz8Fo4_(V2ye4M(!g z5<`o?z_d|RaU0qp9V4lI`wX91gRi0cNJiz_5i2eQ1CPbgzP}AC6(`Edsw2?3koDI-57_>$#%tet2W7(|UCoOlLZn$8@sl7d2JN z+@`clX#trg^Mfg^HaS4Scwr?@DbJKv>jO;DRJw;CCQ~u$K#L#ES%7 zduSg(7syuufa`%SaYwju87%r8O!<0NC$t(BTxE4aYYgU&Mn8IGQ0arXj4iBAkP?&C z2@dVV(3Pn>s}m%#1*qrGcbJz6>?|t^{NphcW_e-2dgM*a$`jPgnf^lF6Py5F2>m6` zKV?FLmBhpcZX>MLh_9w!J7*w!e9|7DbhwBEcEue6?MEF35)_3#SsRWfQfje^oKDW< z1#assUFpnHi_Olq?-#BrC}7(BG@9u%zjoSIzxix8^qV}wG#X-BXwuYz?&45E?&~TC z?^!{}Tjv4Ibh#wgz{&fj?q|US(DB?gIDl(ylC@}XpP}e%Sbapo6~20^P3&)@TSR8q zjN>0!158<%o-JJ9J3s)zh+)bHSulW2@;#cVGkAhkjpY12ED@ExKYHY?76opD?uT~o z(wckV_Qv(?u>c=19O5S>{g$vrX{5O&oplhcxo6G22I(=tPFjI2AXAi%oik> zQvtmMgA_?RBu%deS0_evV4^b%8JiLf94kXoea$^Sy8Ae{249m)&Wgym9Eii}jNg$87-@W1DiDDJ?WzdXCrE6h--r;*|#X^#PsrT8L%%ktp!9 zFSdvjmDcKPMqpr^U0Ke&{{xMCoUn3|M(X3d90mT4?sHjPuCIi%q5;4|O`->IC%QK;jAA zOpIl90$OFEOlKWg9@EJRUq363jGRepE6OyCWU4G@mZ)@1O$Dq#o=)cmmHPzA*jD6o zkIFD1@Uh2$D^61@ZqGkhh)kek#}k)56OVKd#&3tvhL?(?Ik`gu*Yj6-3k9Tm<16y; z6r5z241uAp1>VGXevXHcgWyG6XUKgjb;^ zv)(Q6se9u~Amfm9g#qhX4GoEVbBdJheqZ zyPQWqmafUH@&)E_Z+wj>!Njaw0d$FP>*rPSE*|IHkASqwfI~Y`EiMahC4gUPJ#1jj zD-MLE2~M}CmM~m1Yi$@*s1Um>fETvEBMl59VAw13kXZ)@a2gE_?}ItHDL@0^NO`Le z1;N#q+R3##p+%-ZpMZoS3|eCjgNcln9D@r+Wk>~?`Glh>gUI?IGJ%ez2s)9Zy@u@J z_}9Ci{=GfCdiBTl{+b7Six54-yH?Ma%{>F{p?;gY0J&xVu*!}KHm}0+68UK7>j-l%hjsLa3{z&o7 yMIhqOGkh{h(Lgw=3x)6ezY&ZBOY4*rU;JfDlq^6 literal 0 HcmV?d00001 diff --git a/src/sys/libwebm/webm_parser/fuzzing/corpus/ffff6a92363e0e55a9688d9bc025cd8dea3b50d4 b/src/sys/libwebm/webm_parser/fuzzing/corpus/ffff6a92363e0e55a9688d9bc025cd8dea3b50d4 new file mode 100644 index 0000000..975d9b3 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/corpus/ffff6a92363e0e55a9688d9bc025cd8dea3b50d4 @@ -0,0 +1 @@ +S�g�T�g�ss�gȄD��! \ No newline at end of file diff --git a/src/sys/libwebm/webm_parser/fuzzing/webm.dict b/src/sys/libwebm/webm_parser/fuzzing/webm.dict new file mode 100644 index 0000000..7660ce8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/webm.dict @@ -0,0 +1,152 @@ +# Element IDs. +IdEbml = "\x1A\x45\xDF\xA3" +IdEbmlVersion = "\x42\x86" +IdEbmlReadVersion = "\x42\xF7" +IdEbmlMaxIdLength = "\x42\xF2" +IdEbmlMaxSizeLength = "\x42\xF3" +IdDocType = "\x42\x82" +IdDocTypeVersion = "\x42\x87" +IdDocTypeReadVersion = "\x42\x85" +IdVoid = "\xEC" +IdSegment = "\x18\x53\x80\x67" +IdSeekHead = "\x11\x4D\x9B\x74" +IdSeek = "\x4D\xBB" +IdSeekId = "\x53\xAB" +IdSeekPosition = "\x53\xAC" +IdInfo = "\x15\x49\xA9\x66" +IdTimecodeScale = "\x2A\xD7\xB1" +IdDuration = "\x44\x89" +IdDateUtc = "\x44\x61" +IdTitle = "\x7B\xA9" +IdMuxingApp = "\x4D\x80" +IdWritingApp = "\x57\x41" +IdCluster = "\x1F\x43\xB6\x75" +IdTimecode = "\xE7" +IdPrevSize = "\xAB" +IdSimpleBlock = "\xA3" +IdBlockGroup = "\xA0" +IdBlock = "\xA1" +IdBlockVirtual = "\xA2" +IdBlockAdditions = "\x75\xA1" +IdBlockMore = "\xA6" +IdBlockAddId = "\xEE" +IdBlockAdditional = "\xA5" +IdBlockDuration = "\x9B" +IdReferenceBlock = "\xFB" +IdDiscardPadding = "\x75\xA2" +IdSlices = "\x8E" +IdTimeSlice = "\xE8" +IdLaceNumber = "\xCC" +IdTracks = "\x16\x54\xAE\x6B" +IdTrackEntry = "\xAE" +IdTrackNumber = "\xD7" +IdTrackUid = "\x73\xC5" +IdTrackType = "\x83" +IdFlagEnabled = "\xB9" +IdFlagDefault = "\x88" +IdFlagForced = "\x55\xAA" +IdFlagLacing = "\x9C" +IdDefaultDuration = "\x23\xE3\x83" +IdName = "\x53\x6E" +IdLanguage = "\x22\xB5\x9C" +IdCodecId = "\x86" +IdCodecPrivate = "\x63\xA2" +IdCodecName = "\x25\x86\x88" +IdCodecDelay = "\x56\xAA" +IdSeekPreRoll = "\x56\xBB" +IdVideo = "\xE0" +IdFlagInterlaced = "\x9A" +IdStereoMode = "\x53\xB8" +IdAlphaMode = "\x53\xC0" +IdPixelWidth = "\xB0" +IdPixelHeight = "\xBA" +IdPixelCropBottom = "\x54\xAA" +IdPixelCropTop = "\x54\xBB" +IdPixelCropLeft = "\x54\xCC" +IdPixelCropRight = "\x54\xDD" +IdDisplayWidth = "\x54\xB0" +IdDisplayHeight = "\x54\xBA" +IdDisplayUnit = "\x54\xB2" +IdAspectRatioType = "\x54\xB3" +IdFrameRate = "\x23\x83\xE3" +IdColour = "\x55\xB0" +IdMatrixCoefficients = "\x55\xB1" +IdBitsPerChannel = "\x55\xB2" +IdChromaSubsamplingHorz = "\x55\xB3" +IdChromaSubsamplingVert = "\x55\xB4" +IdCbSubsamplingHorz = "\x55\xB5" +IdCbSubsamplingVert = "\x55\xB6" +IdChromaSitingHorz = "\x55\xB7" +IdChromaSitingVert = "\x55\xB8" +IdRange = "\x55\xB9" +IdTransferCharacteristics = "\x55\xBA" +IdPrimaries = "\x55\xBB" +IdMaxCll = "\x55\xBC" +IdMaxFall = "\x55\xBD" +IdMasteringMetadata = "\x55\xD0" +IdPrimaryRChromaticityX = "\x55\xD1" +IdPrimaryRChromaticityY = "\x55\xD2" +IdPrimaryGChromaticityX = "\x55\xD3" +IdPrimaryGChromaticityY = "\x55\xD4" +IdPrimaryBChromaticityX = "\x55\xD5" +IdPrimaryBChromaticityY = "\x55\xD6" +IdWhitePointChromaticityX = "\x55\xD7" +IdWhitePointChromaticityY = "\x55\xD8" +IdLuminanceMax = "\x55\xD9" +IdLuminanceMin = "\x55\xDA" +IdProjection = "\x76\x70" +IdProjectionType = "\x76\x71" +IdProjectionPrivate = "\x76\x72" +IdProjectionPoseYaw = "\x76\x73" +IdProjectionPosePitch = "\x76\x74" +IdProjectionPoseRoll = "\x76\x75" +IdAudio = "\xE1" +IdSamplingFrequency = "\xB5" +IdOutputSamplingFrequency = "\x78\xB5" +IdChannels = "\x9F" +IdBitDepth = "\x62\x64" +IdContentEncodings = "\x6D\x80" +IdContentEncoding = "\x62\x40" +IdContentEncodingOrder = "\x50\x31" +IdContentEncodingScope = "\x50\x32" +IdContentEncodingType = "\x50\x33" +IdContentEncryption = "\x50\x35" +IdContentEncAlgo = "\x47\xE1" +IdContentEncKeyId = "\x47\xE2" +IdContentEncAesSettings = "\x47\xE7" +IdAesSettingsCipherMode = "\x47\xE8" +IdCues = "\x1C\x53\xBB\x6B" +IdCuePoint = "\xBB" +IdCueTime = "\xB3" +IdCueTrackPositions = "\xB7" +IdCueTrack = "\xF7" +IdCueClusterPosition = "\xF1" +IdCueRelativePosition = "\xF0" +IdCueDuration = "\xB2" +IdCueBlockNumber = "\x53\x78" +IdChapters = "\x10\x43\xA7\x70" +IdEditionEntry = "\x45\xB9" +IdChapterAtom = "\xB6" +IdChapterUid = "\x73\xC4" +IdChapterStringUid = "\x56\x54" +IdChapterTimeStart = "\x91" +IdChapterTimeEnd = "\x92" +IdChapterDisplay = "\x80" +IdChapString = "\x85" +IdChapLanguage = "\x43\x7C" +IdChapCountry = "\x43\x7E" +IdTags = "\x12\x54\xC3\x67" +IdTag = "\x73\x73" +IdTargets = "\x63\xC0" +IdTargetTypeValue = "\x68\xCA" +IdTargetType = "\x63\xCA" +IdTagTrackUid = "\x63\xC5" +IdSimpleTag = "\x67\xC8" +IdTagName = "\x45\xA3" +IdTagLanguage = "\x44\x7A" +IdTagDefault = "\x44\x84" +IdTagString = "\x44\x87" +IdTagBinary = "\x44\x85" + +# Interesting sizes. +SizeUnknown = "\xFF" diff --git a/src/sys/libwebm/webm_parser/fuzzing/webm_fuzzer.cc b/src/sys/libwebm/webm_parser/fuzzing/webm_fuzzer.cc new file mode 100644 index 0000000..bfc4f62 --- /dev/null +++ b/src/sys/libwebm/webm_parser/fuzzing/webm_fuzzer.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#include +#include +#include +#include +#include +#include +#include + +#include "webm/buffer_reader.h" +#include "webm/callback.h" +#include "webm/file_reader.h" +#include "webm/reader.h" +#include "webm/status.h" +#include "webm/webm_parser.h" + +using webm::BufferReader; +using webm::Callback; +using webm::FileReader; +using webm::Reader; +using webm::Status; +using webm::WebmParser; + +static int Run(Reader* reader) { + Callback callback; + WebmParser parser; + +#if WEBM_FUZZER_SEEK_FIRST + parser.DidSeek(); +#endif + + Status status(-1); + try { + status = parser.Feed(&callback, reader); + } catch (std::bad_alloc&) { + // Failed allocations are okay. MSan doesn't throw std::bad_alloc, but + // someday it might. + } + + // BufferReader/FileReader should never return either of the following codes, + // which means the parser never should too: + assert(status.code != Status::kWouldBlock); + assert(status.code != Status::kOkPartial); + + // Only the following ranges have status codes defined: + assert((-1031 <= status.code && status.code <= -1025) || + (-3 <= status.code && status.code <= 0)); + + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, + std::size_t size) { + BufferReader reader(std::vector(data, data + size)); + return Run(&reader); +} + +#if __AFL_COMPILER +int main(int argc, char* argv[]) { + FILE* file = (argc == 2) ? std::fopen(argv[1], "rb") + : std::freopen(nullptr, "rb", stdin); + if (!file) { + std::cerr << "File cannot be opened\n"; + return EXIT_FAILURE; + } + + FileReader reader(file); + return Run(&reader); +} +#endif diff --git a/src/sys/libwebm/webm_parser/include/webm/buffer_reader.h b/src/sys/libwebm/webm_parser/include/webm/buffer_reader.h new file mode 100644 index 0000000..d479b5c --- /dev/null +++ b/src/sys/libwebm/webm_parser/include/webm/buffer_reader.h @@ -0,0 +1,138 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef INCLUDE_WEBM_BUFFER_READER_H_ +#define INCLUDE_WEBM_BUFFER_READER_H_ + +#include +#include +#include +#include + +#include "./reader.h" +#include "./status.h" + +/** + \file + A `Reader` implementation that reads from a `std::vector`. + */ + +namespace webm { + +/** + \addtogroup PUBLIC_API + @{ + */ + +/** + A simple reader that reads data from a buffer of bytes. + */ +class BufferReader : public Reader { + public: + /** + Constructs a new, empty reader. + */ + BufferReader() = default; + + /** + Constructs a new reader by copying the provided reader into the new reader. + + \param other The source reader to copy. + */ + BufferReader(const BufferReader& other) = default; + + /** + Copies the provided reader into this reader. + + \param other The source reader to copy. May be equal to `*this`, in which + case this is a no-op. + \return `*this`. + */ + BufferReader& operator=(const BufferReader& other) = default; + + /** + Constructs a new reader by moving the provided reader into the new reader. + + \param other The source reader to move. After moving, it will be reset to an + empty stream. + */ + BufferReader(BufferReader&&); + + /** + Moves the provided reader into this reader. + + \param other The source reader to move. After moving, it will be reset to an + empty stream. May be equal to `*this`, in which case this is a no-op. + \return `*this`. + */ + BufferReader& operator=(BufferReader&&); + + /** + Creates a new `BufferReader` populated with the provided bytes. + + \param bytes Bytes that are assigned to the internal buffer and used as the + source which is read from. + */ + BufferReader(std::initializer_list bytes); + + /** + Creates a new `BufferReader` populated with the provided data. + + \param vector A vector of bytes that is copied to the internal buffer and + used as the source which is read from. + */ + explicit BufferReader(const std::vector& vector); + + /** + Creates a new `BufferReader` populated with the provided data. + + \param vector A vector of bytes that is moved to the internal buffer and used + as the source which is read from. + */ + explicit BufferReader(std::vector&& vector); + + /** + Resets the reader to read from the given list of bytes, starting at the + beginning. + + This makes `reader = {1, 2, 3};` effectively equivalent to `reader = + BufferReader({1, 2, 3});`. + + \param bytes Bytes that are assigned to the internal buffer and used as the + source which is read from. + \return `*this`. + */ + BufferReader& operator=(std::initializer_list bytes); + + Status Read(std::size_t num_to_read, std::uint8_t* buffer, + std::uint64_t* num_actually_read) override; + + Status Skip(std::uint64_t num_to_skip, + std::uint64_t* num_actually_skipped) override; + + std::uint64_t Position() const override; + + /** + Gets the total size of the buffer. + */ + std::size_t size() const { return data_.size(); } + + private: + // Stores the byte buffer from which data is read. + std::vector data_; + + // The position of the reader in the byte buffer. + std::size_t pos_ = 0; +}; + +/** + @} + */ + +} // namespace webm + +#endif // INCLUDE_WEBM_BUFFER_READER_H_ diff --git a/src/sys/libwebm/webm_parser/include/webm/callback.h b/src/sys/libwebm/webm_parser/include/webm/callback.h new file mode 100644 index 0000000..f70f1f8 --- /dev/null +++ b/src/sys/libwebm/webm_parser/include/webm/callback.h @@ -0,0 +1,363 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef INCLUDE_WEBM_CALLBACK_H_ +#define INCLUDE_WEBM_CALLBACK_H_ + +#include + +#include "./dom_types.h" +#include "./reader.h" +#include "./status.h" + +/** + \file + The main callback type that receives parsing events. + */ + +namespace webm { + +/** + \addtogroup PUBLIC_API + @{ + */ + +/** + The action to be performed when parsing an element. + */ +enum class Action { + /** + Read and parse the element. + */ + kRead, + + /** + Skip the element. Skipped elements are not parsed or stored, and the callback + is not given any further notifications regarding the element. + */ + kSkip, +}; + +/** + A callback that receives parsing events. + + Every method that returns a `Status` should return `Status::kOkCompleted` when + the method has completed and parsing should continue. Returning any other value + will cause parsing to stop. Parsing may be resumed if the returned status was + not a parsing error (see `Status::is_parsing_error()`). When parsing is + resumed, the same `Callback` method will be called again. + + Methods that take a `Reader` expect the implementation to consume (either via + `Reader::Read()` or `Reader::Skip()`) the specified number of bytes before + returning `Status::kOkCompleted`. Default implementations will call + `Reader::Skip()` to skip the specified number of bytes and the resulting + `Status` will be returned (unless it's `Status::kOkPartial`, in which case + `Reader::Skip()` will be called again to skip more data). + + Throwing an exception from the member functions is permitted, though if the + exception will be caught and parsing resumed, then the reader should not + advance its position (for methods that take a `Reader`) before the exception is + thrown. When parsing is resumed, the same `Callback` method will be called + again. + + Users should derive from this class and override member methods as needed. + */ +class Callback { + public: + virtual ~Callback() = default; + + /** + Called when the parser starts a new element. This is called after the + elements ID and size has been parsed, but before any of its body has been + read (or validated). + + Defaults to `Action::kRead` and returning `Status::kOkCompleted`. + + \param metadata Metadata about the element that has just been encountered. + \param[out] action The action that should be taken when handling this + element. Will not be null. + */ + virtual Status OnElementBegin(const ElementMetadata& metadata, + Action* action); + + /** + Called when the parser encounters an unknown element. + + Defaults to calling (and returning the result of) `Reader::Skip()`. + + \param metadata Metadata about the element. + \param reader The reader that should be used to consume data. Will not be + null. + \param[in,out] bytes_remaining The number of remaining bytes that need to be + consumed for the element. Will not be null. + \return `Status::kOkCompleted` when the element has been fully consumed and + `bytes_remaining` is now zero. + */ + virtual Status OnUnknownElement(const ElementMetadata& metadata, + Reader* reader, + std::uint64_t* bytes_remaining); + + /** + Called when the parser encounters an `Id::kEbml` element and it has been + fully parsed. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param ebml The parsed element. + */ + virtual Status OnEbml(const ElementMetadata& metadata, const Ebml& ebml); + + /** + Called when the parser encounters an Id::kVoid element. + + Defaults to calling (and returning the result of) Reader::Skip. + + \param metadata Metadata about the element. + \param reader The reader that should be used to consume data. Will not be + null. + \param[in,out] bytes_remaining The number of remaining bytes that need to be + consumed for the element. Will not be null. + \return `Status::kOkCompleted` when the element has been fully consumed and + `bytes_remaining` is now zero. + */ + virtual Status OnVoid(const ElementMetadata& metadata, Reader* reader, + std::uint64_t* bytes_remaining); + + /** + Called when the parser starts an `Id::kSegment` element. + + Defaults to `Action::kRead` and returning `Status::kOkCompleted`. + + \param metadata Metadata about the element that has just been encountered. + \param[out] action The action that should be taken when handling this + element. Will not be null. + */ + virtual Status OnSegmentBegin(const ElementMetadata& metadata, + Action* action); + + /** + Called when the parser encounters an `Id::kSeek` element and it has been + fully parsed. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param seek The parsed element. + */ + virtual Status OnSeek(const ElementMetadata& metadata, const Seek& seek); + + /** + Called when the parser encounters an `Id::kInfo` element and it has been + fully parsed. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param info The parsed element. + */ + virtual Status OnInfo(const ElementMetadata& metadata, const Info& info); + + /** + Called when the parser starts an `Id::kCluster` element. + + Because Cluster elements should start with a Timecode (and optionally + PrevSize) child, this method is not invoked until a child BlockGroup or + SimpleBlock element is encountered (or the Cluster ends if no such child + exists). + + Defaults to `Action::kRead` and returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param cluster The element, as it has currently been parsed. + \param[out] action The action that should be taken when handling this + element. Will not be null. + */ + virtual Status OnClusterBegin(const ElementMetadata& metadata, + const Cluster& cluster, Action* action); + + /** + Called when the parser starts an `Id::kSimpleBlock` element. + + Defaults to `Action::kRead` and returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param simple_block The parsed SimpleBlock header. + \param[out] action The action that should be taken when handling this + element. Will not be null. + */ + virtual Status OnSimpleBlockBegin(const ElementMetadata& metadata, + const SimpleBlock& simple_block, + Action* action); + + /** + Called when the parser finishes an `Id::kSimpleBlock` element. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param simple_block The parsed SimpleBlock header. + */ + virtual Status OnSimpleBlockEnd(const ElementMetadata& metadata, + const SimpleBlock& simple_block); + + /** + Called when the parser starts an `Id::kBlockGroup` element. + + Defaults to `Action::kRead` and returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param[out] action The action that should be taken when handling this + element. Will not be null. + */ + virtual Status OnBlockGroupBegin(const ElementMetadata& metadata, + Action* action); + + /** + Called when the parser starts an `Id::kBlock` element. + + Defaults to `Action::kRead` and returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param block The parsed Block header. + \param[out] action The action that should be taken when handling this + element. Will not be null. + */ + virtual Status OnBlockBegin(const ElementMetadata& metadata, + const Block& block, Action* action); + + /** + Called when the parser finishes an `Id::Block` element. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param block The parsed Block header. + */ + virtual Status OnBlockEnd(const ElementMetadata& metadata, + const Block& block); + + /** + Called when the parser finishes an `Id::kBlockGroup` element. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param block_group The parsed element. + */ + virtual Status OnBlockGroupEnd(const ElementMetadata& metadata, + const BlockGroup& block_group); + + /** + Called when the parser encounters a frame within a `Id::kBlock` or + `Id::kSimpleBlock` element. + + Defaults to calling (and returning the result of) `Reader::Skip`. + + \param metadata Metadata about the frame. + \param reader The reader that should be used to consume data. Will not be + null. + \param[in,out] bytes_remaining The number of remaining bytes that need to be + consumed for the frame. Will not be null. + \return `Status::kOkCompleted` when the frame has been fully consumed and + `bytes_remaining` is now zero. + */ + virtual Status OnFrame(const FrameMetadata& metadata, Reader* reader, + std::uint64_t* bytes_remaining); + + /** + Called when the parser finishes an `Id::kCluster` element. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param cluster The parsed element. + */ + virtual Status OnClusterEnd(const ElementMetadata& metadata, + const Cluster& cluster); + + /** + Called when the parser starts an `Id::kTrackEntry` element. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param track_entry The parsed element. + */ + virtual Status OnTrackEntry(const ElementMetadata& metadata, + const TrackEntry& track_entry); + + /** + Called when the parser encounters an `Id::kCuePoint` element and it has been + fully parsed. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param cue_point The parsed element. + */ + virtual Status OnCuePoint(const ElementMetadata& metadata, + const CuePoint& cue_point); + + /** + Called when the parser encounters an `Id::kEditionEntry` element and it has + been fully parsed. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param edition_entry The parsed element. + */ + virtual Status OnEditionEntry(const ElementMetadata& metadata, + const EditionEntry& edition_entry); + + /** + Called when the parser encounters an `Id::kTag` element and it has been fully + parsed. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + \param tag The parsed element. + */ + virtual Status OnTag(const ElementMetadata& metadata, const Tag& tag); + + /** + Called when the parser finishes an `Id::kSegment` element. + + Defaults to returning `Status::kOkCompleted`. + + \param metadata Metadata about the element. + */ + virtual Status OnSegmentEnd(const ElementMetadata& metadata); + + protected: + /** + Calls (and returns the result of) `Reader::Skip()`, skipping (up to) the + requested number of bytes. + + Unlike `Reader::Skip()`, this method may be called with `*bytes_remaining == + 0`, which will result in `Status::kOkCompleted`. `Reader::Skip()` will be + called multiple times if it returns `Status::kOkPartial` until it returns a + different status (indicating the requested number of bytes has been fully + skipped or some error occurred). + + \param reader The reader that should be used to skip data. Must not be null. + \param[in,out] bytes_remaining The number of remaining bytes that need to be + skipped. Must not be null. May be zero. + \return The result of `Reader::Skip()`. + */ + static Status Skip(Reader* reader, std::uint64_t* bytes_remaining); +}; + +/** + @} + */ + +} // namespace webm + +#endif // INCLUDE_WEBM_CALLBACK_H_ diff --git a/src/sys/libwebm/webm_parser/include/webm/dom_types.h b/src/sys/libwebm/webm_parser/include/webm/dom_types.h new file mode 100644 index 0000000..7ae4a0c --- /dev/null +++ b/src/sys/libwebm/webm_parser/include/webm/dom_types.h @@ -0,0 +1,1781 @@ +// Copyright (c) 2016 The WebM project authors. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +#ifndef INCLUDE_WEBM_DOM_TYPES_H_ +#define INCLUDE_WEBM_DOM_TYPES_H_ + +#include +#include +#include + +#include "./element.h" +#include "./id.h" + +/** + \file + Data structures representing parsed DOM objects. + + For more information on each type and member, see the WebM specification for + the element that each type/member represents. + */ + +namespace webm { + +/** + \addtogroup PUBLIC_API + @{ + */ + +/** + Metadata for a single frame. + */ +struct FrameMetadata { + /** + Metadata for the EBML element (\WebMID{Block} or \WebMID{SimpleBlock}) that + contains this frame. + */ + ElementMetadata parent_element; + + /** + Absolute byte position (from the beginning of the byte stream/file) of the + frame start. + */ + std::uint64_t position; + + /** + Size (in bytes) of the frame. + */ + std::uint64_t size; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const FrameMetadata& other) const { + return parent_element == other.parent_element && + position == other.position && size == other.size; + } +}; + +/** + A parsed \WebMID{BlockMore} element. + */ +struct BlockMore { + /** + A parsed \WebMID{BlockAddID} element. + */ + Element id{1}; + + /** + A parsed \WebMID{BlockAdditional} element. + */ + Element> data; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const BlockMore& other) const { + return id == other.id && data == other.data; + } +}; + +/** + A parsed \WebMID{BlockAdditions} element. + */ +struct BlockAdditions { + /** + Parsed \WebMID{BlockMore} elements. + */ + std::vector> block_mores; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const BlockAdditions& other) const { + return block_mores == other.block_mores; + } +}; + +/** + A parsed \WebMID{TimeSlice} element (deprecated). + */ +struct TimeSlice { + /** + A parsed \WebMID{LaceNumber} element (deprecated). + */ + Element lace_number; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const TimeSlice& other) const { + return lace_number == other.lace_number; + } +}; + +/** + A parsed \WebMID{Slices} element (deprecated). + */ +struct Slices { + /** + Parsed \WebMID{TimeSlice} elements (deprecated). + */ + std::vector> slices; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Slices& other) const { return slices == other.slices; } +}; + +/** + A parsed \WebMID{BlockVirtual} element. + */ +struct VirtualBlock { + /** + The virtual block's track number. + */ + std::uint64_t track_number; + + /** + The timecode of the virtual block. + */ + std::int16_t timecode; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const VirtualBlock& other) const { + return track_number == other.track_number && timecode == other.timecode; + } +}; + +/** + The frame lacing used in a block. + */ +enum class Lacing : std::uint8_t { + /** + No lacing is used. + */ + kNone = 0x00, + + /** + Xiph-style lacing is used. + */ + kXiph = 0x02, + + /** + Fixed-lacing is used, where each frame has the same, fixed size. + */ + kFixed = 0x04, + + /** + EBML-style lacing is used. + */ + kEbml = 0x06, +}; + +/** + A parsed \WebMID{Block} element. + */ +struct Block { + /** + The block's track number. + */ + std::uint64_t track_number; + + /** + The number of frames in the block. + */ + int num_frames; + + /** + The timecode of the block (relative to the containing \WebMID{Cluster}'s + timecode). + */ + std::int16_t timecode; + + /** + The lacing used to store frames in the block. + */ + Lacing lacing; + + /** + True if the frames are visible, false if they are invisible. + */ + bool is_visible; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Block& other) const { + return track_number == other.track_number && + num_frames == other.num_frames && timecode == other.timecode && + lacing == other.lacing && is_visible == other.is_visible; + } +}; + +/** + A parsed \WebMID{SimpleBlock} element. + */ +struct SimpleBlock : public Block { + /** + True if the frames are all key frames. + */ + bool is_key_frame; + + /** + True if frames can be discarded during playback if needed. + */ + bool is_discardable; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const SimpleBlock& other) const { + return Block::operator==(other) && is_key_frame == other.is_key_frame && + is_discardable == other.is_discardable; + } +}; + +/** + A parsed \WebMID{BlockGroup} element. + */ +struct BlockGroup { + /** + A parsed \WebMID{Block} element. + */ + Element block; + + /** + A parsed \WebMID{BlockVirtual} element. + */ + Element virtual_block; + + /** + A parsed \WebMID{BlockAdditions} element. + */ + Element additions; + + /** + A parsed \WebMID{BlockDuration} element. + */ + Element duration; + + /** + Parsed \WebMID{ReferenceBlock} elements. + */ + std::vector> references; + + /** + A parsed \WebMID{DiscardPadding} element. + */ + Element discard_padding; + + /** + A parsed \WebMID{Slices} element (deprecated). + */ + Element slices; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const BlockGroup& other) const { + return block == other.block && virtual_block == other.virtual_block && + additions == other.additions && duration == other.duration && + references == other.references && + discard_padding == other.discard_padding && slices == other.slices; + } +}; + +/** + A parsed \WebMID{Cluster} element. + */ +struct Cluster { + /** + A parsed \WebMID{Timecode} element. + */ + Element timecode; + + /** + A parsed \WebMID{PrevSize} element. + */ + Element previous_size; + + /** + Parsed \WebMID{SimpleBlock} elements. + */ + std::vector> simple_blocks; + + /** + Parsed \WebMID{BlockGroup} elements. + */ + std::vector> block_groups; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Cluster& other) const { + return timecode == other.timecode && previous_size == other.previous_size && + simple_blocks == other.simple_blocks && + block_groups == other.block_groups; + } +}; + +/** + A parsed \WebMID{EBML} element. + */ +struct Ebml { + /** + A parsed \WebMID{EBMLVersion} element. + */ + Element ebml_version{1}; + + /** + A parsed \WebMID{EBMLReadVersion} element. + */ + Element ebml_read_version{1}; + + /** + A parsed \WebMID{EBMLMaxIDLength} element. + */ + Element ebml_max_id_length{4}; + + /** + A parsed \WebMID{EBMLMaxSizeLength} element. + */ + Element ebml_max_size_length{8}; + + /** + A parsed \WebMID{DocType} element. + */ + Element doc_type{"matroska"}; + + /** + A parsed \WebMID{DocTypeVersion} element. + */ + Element doc_type_version{1}; + + /** + A parsed \WebMID{DocTypeReadVersion} element. + */ + Element doc_type_read_version{1}; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Ebml& other) const { + return ebml_version == other.ebml_version && + ebml_read_version == other.ebml_read_version && + ebml_max_id_length == other.ebml_max_id_length && + ebml_max_size_length == other.ebml_max_size_length && + doc_type == other.doc_type && + doc_type_version == other.doc_type_version && + doc_type_read_version == other.doc_type_read_version; + } +}; + +/** + A parsed \WebMID{Info} element. + */ +struct Info { + /** + A parsed \WebMID{TimecodeScale} element. + */ + Element timecode_scale{1000000}; + + /** + A parsed \WebMID{Duration} element. + */ + Element duration; + + /** + A parsed \WebMID{DateUTC} element. + */ + Element date_utc; + + /** + A parsed \WebMID{Title} element. + */ + Element title; + + /** + A parsed \WebMID{MuxingApp} element. + */ + Element muxing_app; + + /** + A parsed \WebMID{WritingApp} element. + */ + Element writing_app; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Info& other) const { + return timecode_scale == other.timecode_scale && + duration == other.duration && date_utc == other.date_utc && + title == other.title && muxing_app == other.muxing_app && + writing_app == other.writing_app; + } +}; + +/** + A parsed \WebMID{Seek} element. + */ +struct Seek { + /** + A parsed \WebMID{SeekID} element. + */ + Element id; + + /** + A parsed \WebMID{SeekPosition} element. + */ + Element position; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Seek& other) const { + return id == other.id && position == other.position; + } +}; + +/** + A parsed \WebMID{Audio} element. + */ +struct Audio { + /** + A parsed \WebMID{SamplingFrequency} element. + */ + Element sampling_frequency{8000}; + + /** + A parsed \WebMID{OutputSamplingFrequency} element. + */ + Element output_frequency{8000}; + + /** + A parsed \WebMID{Channels} element. + */ + Element channels{1}; + + /** + A parsed \WebMID{BitDepth} element. + */ + Element bit_depth; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Audio& other) const { + return sampling_frequency == other.sampling_frequency && + output_frequency == other.output_frequency && + channels == other.channels && bit_depth == other.bit_depth; + } +}; + +/** + A parsed \WebMID{MasteringMetadata} element. + */ +struct MasteringMetadata { + /** + A parsed \WebMID{PrimaryRChromaticityX} element. + */ + Element primary_r_chromaticity_x; + + /** + A parsed \WebMID{PrimaryRChromaticityY} element. + */ + Element primary_r_chromaticity_y; + + /** + A parsed \WebMID{PrimaryGChromaticityX} element. + */ + Element primary_g_chromaticity_x; + + /** + A parsed \WebMID{PrimaryGChromaticityY} element. + */ + Element primary_g_chromaticity_y; + + /** + A parsed \WebMID{PrimaryBChromaticityX} element. + */ + Element primary_b_chromaticity_x; + + /** + A parsed \WebMID{PrimaryBChromaticityY} element. + */ + Element primary_b_chromaticity_y; + + /** + A parsed \WebMID{WhitePointChromaticityX} element. + */ + Element white_point_chromaticity_x; + + /** + A parsed \WebMID{WhitePointChromaticityY} element. + */ + Element white_point_chromaticity_y; + + /** + A parsed \WebMID{LuminanceMax} element. + */ + Element luminance_max; + + /** + A parsed \WebMID{LuminanceMin} element. + */ + Element luminance_min; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const MasteringMetadata& other) const { + return primary_r_chromaticity_x == other.primary_r_chromaticity_x && + primary_r_chromaticity_y == other.primary_r_chromaticity_y && + primary_g_chromaticity_x == other.primary_g_chromaticity_x && + primary_g_chromaticity_y == other.primary_g_chromaticity_y && + primary_b_chromaticity_x == other.primary_b_chromaticity_x && + primary_b_chromaticity_y == other.primary_b_chromaticity_y && + white_point_chromaticity_x == other.white_point_chromaticity_x && + white_point_chromaticity_y == other.white_point_chromaticity_y && + luminance_max == other.luminance_max && + luminance_min == other.luminance_min; + } +}; + +/** + A parsed \WebMID{MatrixCoefficients} element. + + Matroska/WebM adopted these values from Table 4 of ISO/IEC 23001-8:2013/DCOR1. + See that document for further details. + */ +enum class MatrixCoefficients : std::uint64_t { + /** + The identity matrix. + + Typically used for GBR (often referred to as RGB); however, may also be used + for YZX (often referred to as XYZ). + */ + kRgb = 0, + + /** + Rec. ITU-R BT.709-5. + */ + kBt709 = 1, + + /** + Image characteristics are unknown or are determined by the application. + */ + kUnspecified = 2, + + /** + United States Federal Communications Commission Title 47 Code of Federal + Regulations (2003) 73.682 (a) (20). + */ + kFcc = 4, + + /** + Rec. ITU-R BT.470‑6 System B, G (historical). + */ + kBt470Bg = 5, + + /** + Society of Motion Picture and Television Engineers 170M (2004). + */ + kSmpte170M = 6, + + /** + Society of Motion Picture and Television Engineers 240M (1999). + */ + kSmpte240M = 7, + + /** + YCgCo. + */ + kYCgCo = 8, + + /** + Rec. ITU-R BT.2020 (non-constant luminance). + */ + kBt2020NonconstantLuminance = 9, + + /** + Rec. ITU-R BT.2020 (constant luminance). + */ + kBt2020ConstantLuminance = 10, +}; + +/** + A parsed \WebMID{Range} element. + */ +enum class Range : std::uint64_t { + /** + Unspecified. + */ + kUnspecified = 0, + + /** + Broadcast range. + */ + kBroadcast = 1, + + /** + Full range (no clipping). + */ + kFull = 2, + + /** + Defined by MatrixCoefficients/TransferCharacteristics. + */ + kDerived = 3, +}; + +/** + A parsed \WebMID{TransferCharacteristics} element. + + Matroska/WebM adopted these values from Table 3 of ISO/IEC 23001-8:2013/DCOR1. + See that document for further details. + */ +enum class TransferCharacteristics : std::uint64_t { + /** + Rec. ITU-R BT.709-6. + */ + kBt709 = 1, + + /** + Image characteristics are unknown or are determined by the application. + */ + kUnspecified = 2, + + /** + Rec. ITU‑R BT.470‑6 System M (historical) with assumed display gamma 2.2. + */ + kGamma22curve = 4, + + /** + Rec. ITU‑R BT.470-6 System B, G (historical) with assumed display gamma 2.8. + */ + kGamma28curve = 5, + + /** + Society of Motion Picture and Television Engineers 170M (2004). + */ + kSmpte170M = 6, + + /** + Society of Motion Picture and Television Engineers 240M (1999). + */ + kSmpte240M = 7, + + /** + Linear transfer characteristics. + */ + kLinear = 8, + + /** + Logarithmic transfer characteristic (100:1 range). + */ + kLog = 9, + + /** + Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range). + */ + kLogSqrt = 10, + + /** + IEC 61966-2-4. + */ + kIec6196624 = 11, + + /** + Rec. ITU‑R BT.1361-0 extended colour gamut system (historical). + */ + kBt1361ExtendedColourGamut = 12, + + /** + IEC 61966-2-1 sRGB or sYCC. + */ + kIec6196621 = 13, + + /** + Rec. ITU-R BT.2020-2 (10-bit system). + */ + k10BitBt2020 = 14, + + /** + Rec. ITU-R BT.2020-2 (12-bit system). + */ + k12BitBt2020 = 15, + + /** + Society of Motion Picture and Television Engineers ST 2084. + */ + kSmpteSt2084 = 16, + + /** + Society of Motion Picture and Television Engineers ST 428-1. + */ + kSmpteSt4281 = 17, + + /** + Association of Radio Industries and Businesses (ARIB) STD-B67. + */ + kAribStdB67Hlg = 18, +}; + +/** + A parsed \WebMID{Primaries} element. + + Matroska/WebM adopted these values from Table 2 of ISO/IEC 23001-8:2013/DCOR1. + See that document for further details. + */ +enum class Primaries : std::uint64_t { + /** + Rec. ITU‑R BT.709-6. + */ + kBt709 = 1, + + /** + Image characteristics are unknown or are determined by the application. + */ + kUnspecified = 2, + + /** + Rec. ITU‑R BT.470‑6 System M (historical). + */ + kBt470M = 4, + + /** + Rec. ITU‑R BT.470‑6 System B, G (historical). + */ + kBt470Bg = 5, + + /** + Society of Motion Picture and Television Engineers 170M (2004). + */ + kSmpte170M = 6, + + /** + Society of Motion Picture and Television Engineers 240M (1999). + */ + kSmpte240M = 7, + + /** + Generic film. + */ + kFilm = 8, + + /** + Rec. ITU-R BT.2020-2. + */ + kBt2020 = 9, + + /** + Society of Motion Picture and Television Engineers ST 428-1. + */ + kSmpteSt4281 = 10, + + /** + Society of Motion Picture and Television Engineers RP 431-2 (a.k.a. DCI-P3). + */ + kSmpteRp431 = 11, + + /** + Society of Motion Picture and Television Engineers EG 432-1 + (a.k.a. DCI-P3 D65). + */ + kSmpteEg432 = 12, + + /** + JEDEC P22 phosphors/EBU Tech. 3213-E (1975). + */ + kJedecP22Phosphors = 22, +}; + +/** + A parsed \WebMID{Colour} element. + */ +struct Colour { + /** + A parsed \WebMID{MatrixCoefficients} element. + */ + Element matrix_coefficients{ + MatrixCoefficients::kUnspecified}; + + /** + A parsed \WebMID{BitsPerChannel} element. + */ + Element bits_per_channel{0}; + + /** + A parsed \WebMID{ChromaSubsamplingHorz} element. + */ + Element chroma_subsampling_x; + + /** + A parsed \WebMID{ChromaSubsamplingVert} element. + */ + Element chroma_subsampling_y; + + /** + A parsed \WebMID{CbSubsamplingHorz} element. + */ + Element cb_subsampling_x; + + /** + A parsed \WebMID{CbSubsamplingVert} element. + */ + Element cb_subsampling_y; + + /** + A parsed \WebMID{ChromaSitingHorz} element. + */ + Element chroma_siting_x{0}; + + /** + A parsed \WebMID{ChromaSitingVert} element. + */ + Element chroma_siting_y{0}; + + /** + A parsed \WebMID{Range} element. + */ + Element range{Range::kUnspecified}; + + /** + A parsed \WebMID{TransferCharacteristics} element. + */ + Element transfer_characteristics{ + TransferCharacteristics::kUnspecified}; + + /** + A parsed \WebMID{Primaries} element. + */ + Element primaries{Primaries::kUnspecified}; + + /** + A parsed \WebMID{MaxCLL} element. + */ + Element max_cll; + + /** + A parsed \WebMID{MaxFALL} element. + */ + Element max_fall; + + /** + A parsed \WebMID{MasteringMetadata} element. + */ + Element mastering_metadata; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Colour& other) const { + return matrix_coefficients == other.matrix_coefficients && + bits_per_channel == other.bits_per_channel && + chroma_subsampling_x == other.chroma_subsampling_x && + chroma_subsampling_y == other.chroma_subsampling_y && + cb_subsampling_x == other.cb_subsampling_x && + cb_subsampling_y == other.cb_subsampling_y && + chroma_siting_x == other.chroma_siting_x && + chroma_siting_y == other.chroma_siting_y && range == other.range && + transfer_characteristics == other.transfer_characteristics && + primaries == other.primaries && max_cll == other.max_cll && + max_fall == other.max_fall && + mastering_metadata == other.mastering_metadata; + } +}; + +/** + A parsed \WebMID{ProjectionType} element. + */ +enum class ProjectionType : std::uint64_t { + /** + Rectangular. + */ + kRectangular = 0, + + /** + Equirectangular. + */ + kEquirectangular = 1, + + /** + Cube map. + */ + kCubeMap = 2, + + /** + Mesh. + */ + kMesh = 3, +}; + +/** + A parsed \WebMID{Projection} element. + */ +struct Projection { + /** + A parsed \WebMID{ProjectionType} element. + */ + Element type; + + /** + A parsed \WebMID{ProjectionPrivate} element. + */ + Element> projection_private; + + /** + A parsed \WebMID{ProjectionPoseYaw} element. + */ + Element pose_yaw; + + /** + A parsed \WebMID{ProjectionPosePitch} element. + */ + Element pose_pitch; + + /** + A parsed \WebMID{ProjectionPoseRoll} element. + */ + Element pose_roll; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Projection& other) const { + return type == other.type && + projection_private == other.projection_private && + pose_yaw == other.pose_yaw && pose_pitch == other.pose_pitch && + pose_roll == other.pose_roll; + } +}; + +/** + A parsed \WebMID{FlagInterlaced} element. + */ +enum class FlagInterlaced : std::uint64_t { + /** + Unspecified. + */ + kUnspecified = 0, + + /** + Interlaced. + */ + kInterlaced = 1, + + /** + Progressive. + */ + kProgressive = 2, +}; + +/** + A parsed \WebMID{StereoMode} element. + */ +enum class StereoMode : std::uint64_t { + /** + Mono. + */ + kMono = 0, + + /** + Side-by-side, left eye is first. + */ + kSideBySideLeftFirst = 1, + + /** + Top-bottom, right eye is first. + */ + kTopBottomRightFirst = 2, + + /** + Top-bottom, left eye is first. + */ + kTopBottomLeftFirst = 3, + + /** + Checkboard, right eye is first. + */ + kCheckboardRightFirst = 4, + + /** + Checkboard, left eye is first. + */ + kCheckboardLeftFirst = 5, + + /** + Row interleaved, right eye is first. + */ + kRowInterleavedRightFirst = 6, + + /** + Row interleaved, left eye is first. + */ + kRowInterleavedLeftFirst = 7, + + /** + Column interleaved, right eye is first. + */ + kColumnInterleavedRightFirst = 8, + + /** + Column interleaved, left eye is first. + */ + kColumnInterleavedLeftFirst = 9, + + /** + Anaglyph (cyan/read). + */ + kAnaglyphCyanRed = 10, + + /** + Side-by-side, right eye is first. + */ + kSideBySideRightFirst = 11, + + /** + Anaglyph (green/magenta). + */ + kAnaglyphGreenMagenta = 12, + + /** + Both eyes are laced in one block, left eye is first. + */ + kBlockLacedLeftFirst = 13, + + /** + Both eyes are laced in one block, right eye is first. + */ + kBlockLacedRightFirst = 14, + + /** + Stereo, but the layout for the left and right eyes is application dependent + and must be determined from other data (like the ProjectionPrivate element). + */ + kStereoCustom = 15, +}; + +/** + A parsed \WebMID{DisplayUnit} element. + + Note that WebM only supports pixel display units. Centimeters, inches, and + display aspect ratio aren't supported. + */ +enum class DisplayUnit : std::uint64_t { + // The only value legal value in WebM is 0 (pixels). + /** + Pixels. + + This is the only option supported by WebM. + */ + kPixels = 0, + + /** + Centimeters. + */ + kCentimeters = 1, + + /** + Inches. + */ + kInches = 2, + + /** + Display aspect ratio. + */ + kDisplayAspectRatio = 3, +}; + +/** + A parsed \WebMID{AspectRatioType} element. + */ +enum class AspectRatioType : std::uint64_t { + /** + Free resizing. + */ + kFreeResizing = 0, + + /** + Keep aspect ratio. + */ + kKeep = 1, + + /** + Fixed aspect ratio. + */ + kFixed = 2, +}; + +/** + A parsed \WebMID{Video} element. + */ +struct Video { + /** + A parsed \WebMID{FlagInterlaced} element. + */ + Element interlaced{FlagInterlaced::kUnspecified}; + + /** + A parsed \WebMID{StereoMode} element. + */ + Element stereo_mode{StereoMode::kMono}; + + /** + A parsed \WebMID{AlphaMode} element. + */ + Element alpha_mode{0}; + + /** + A parsed \WebMID{PixelWidth} element. + */ + Element pixel_width; + + /** + A parsed \WebMID{PixelHeight} element. + */ + Element pixel_height; + + /** + A parsed \WebMID{PixelCropBottom} element. + */ + Element pixel_crop_bottom{0}; + + /** + A parsed \WebMID{PixelCropTop} element. + */ + Element pixel_crop_top{0}; + + /** + A parsed \WebMID{PixelCropLeft} element. + */ + Element pixel_crop_left{0}; + + /** + A parsed \WebMID{PixelCropRight} element. + */ + Element pixel_crop_right{0}; + + /** + A parsed \WebMID{DisplayWidth} element. + */ + Element display_width; + + /** + A parsed \WebMID{DisplayHeight} element. + */ + Element display_height; + + /** + A parsed \WebMID{DisplayUnit} element. + */ + Element display_unit{DisplayUnit::kPixels}; + + /** + A parsed \WebMID{AspectRatioType} element. + */ + Element aspect_ratio_type{AspectRatioType::kFreeResizing}; + + /** + A parsed \WebMID{FrameRate} element (deprecated). + */ + Element frame_rate; + + /** + A parsed \WebMID{Colour} element. + */ + Element colour; + + /** + A parsed \WebMID{Projection} element. + */ + Element projection; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const Video& other) const { + return interlaced == other.interlaced && stereo_mode == other.stereo_mode && + alpha_mode == other.alpha_mode && pixel_width == other.pixel_width && + pixel_height == other.pixel_height && + pixel_crop_bottom == other.pixel_crop_bottom && + pixel_crop_top == other.pixel_crop_top && + pixel_crop_left == other.pixel_crop_left && + pixel_crop_right == other.pixel_crop_right && + display_width == other.display_width && + display_height == other.display_height && + display_unit == other.display_unit && + aspect_ratio_type == other.aspect_ratio_type && + frame_rate == other.frame_rate && colour == other.colour && + projection == other.projection; + } +}; + +/** + A parsed \WebMID{AESSettingsCipherMode} element. + */ +enum class AesSettingsCipherMode : std::uint64_t { + /** + Counter (CTR). + */ + kCtr = 1, +}; + +/** + A parsed \WebMID{ContentEncAESSettings} element. + */ +struct ContentEncAesSettings { + /** + A parsed \WebMID{AESSettingsCipherMode} element. + */ + Element aes_settings_cipher_mode{ + AesSettingsCipherMode::kCtr}; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const ContentEncAesSettings& other) const { + return aes_settings_cipher_mode == other.aes_settings_cipher_mode; + } +}; + +/** + A parsed \WebMID{ContentEncAlgo} element. + */ +enum class ContentEncAlgo : std::uint64_t { + /** + The contents have been signed but not encrypted. + */ + kOnlySigned = 0, + + /** + DES encryption. + */ + kDes = 1, + + /** + 3DES encryption. + */ + k3Des = 2, + + /** + Twofish encryption. + */ + kTwofish = 3, + + /** + Blowfish encryption. + */ + kBlowfish = 4, + + /** + AES encryption. + */ + kAes = 5, +}; + +/** + A parsed \WebMID{ContentEncryption} element. + */ +struct ContentEncryption { + /** + A parsed \WebMID{ContentEncAlgo} element. + */ + Element algorithm{ContentEncAlgo::kOnlySigned}; + + /** + A parsed \WebMID{ContentEncKeyID} element. + */ + Element> key_id; + + /** + A parsed \WebMID{ContentEncAESSettings} element. + */ + Element aes_settings; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const ContentEncryption& other) const { + return algorithm == other.algorithm && key_id == other.key_id && + aes_settings == other.aes_settings; + } +}; + +/** + A parsed \WebMID{ContentEncodingType} element. + */ +enum class ContentEncodingType : std::uint64_t { + /** + Compression. + */ + kCompression = 0, + + /** + Encryption. + */ + kEncryption = 1, +}; + +/** + A parsed \WebMID{ContentEncoding} element. + */ +struct ContentEncoding { + /** + A parsed \WebMID{ContentEncodingOrder} element. + */ + Element order{0}; + + /** + A parsed \WebMID{ContentEncodingScope} element. + */ + Element scope{1}; + + /** + A parsed \WebMID{ContentEncodingType} element. + */ + Element type{ContentEncodingType::kCompression}; + + /** + A parsed \WebMID{ContentEncryption} element. + */ + Element encryption; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const ContentEncoding& other) const { + return order == other.order && scope == other.scope && type == other.type && + encryption == other.encryption; + } +}; + +/** + A parsed \WebMID{ContentEncodings} element. + */ +struct ContentEncodings { + /** + Parsed \WebMID{ContentEncoding} elements. + */ + std::vector> encodings; + + /** + Returns true if every member within the two objects are equal. + */ + bool operator==(const ContentEncodings& other) const { + return encodings == other.encodings; + } +}; + +/** + A parsed \WebMID{TrackType} element. + */ +enum class TrackType : std::uint64_t { + /** + Video. + */ + kVideo = 0x01, + + /** + Audio. + */ + kAudio = 0x02, + + /** + Complex. + */ + kComplex = 0x03, + + /** + Logo. + */ + kLogo = 0x10, + + /** + Subtitle. + */ + kSubtitle = 0x11, + + /** + Buttons. + */ + kButtons = 0x12, + + /** + Control. + */ + kControl = 0x20, +}; + +/** + A parsed \WebMID{TrackEntry} element. + */ +struct TrackEntry { + /** + A parsed \WebMID{TrackNumber} element. + */ + Element track_number; + + /** + A parsed \WebMID{TrackUID} element. + */ + Element track_uid; + + /** + A parsed \WebMID{TrackType} element. + */ + Element track_type; + + /** + A parsed \WebMID{FlagEnabled} element. + */ + Element is_enabled{true}; + + /** + A parsed \WebMID{FlagDefault} element. + */ + Element is_default{true}; + + /** + A parsed \WebMID{FlagForced} element. + */ + Element is_forced{false}; + + /** + A parsed \WebMID{FlagLacing} element. + */ + Element uses_lacing{true}; + + /** + A parsed \WebMID{DefaultDuration} element. + */ + Element default_duration; + + /** + A parsed \WebMID{Name} element. + */ + Element name; + + /** + A parsed \WebMID{Language} element. + */ + Element language{"eng"}; + + /** + A parsed \WebMID{CodecID} element. + */ + Element codec_id; + + /** + A parsed \WebMID{CodecPrivate} element. + */ + Element> codec_private; + + /** + A parsed \WebMID{CodecName} element. + */ + Element codec_name; + + /** + A parsed \WebMID{CodecDelay} element. + */ + Element codec_delay{0}; + + /** + A parsed \WebMID{SeekPreRoll} element. + */ + Element seek_pre_roll{0}; + + /** + A parsed \WebMID{Video} element. + */ + Element