react-native-alpha-video 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +903 -2
- package/THIRD_PARTY_NOTICES.md +30 -0
- package/android/av1/build.gradle +67 -0
- package/android/av1/consumer-rules.pro +4 -0
- package/android/av1/src/main/cpp/Av1Codec_jni.cpp +8 -0
- package/android/av1/src/main/cpp/CMakeLists.txt +34 -0
- package/android/av1/src/main/java/dev/mediacache/alphavideo/av1/Av1Codec.java +21 -0
- package/android/build.gradle +85 -0
- package/android/consumer-rules.pro +2 -0
- package/android/gradle.properties +1 -0
- package/android/publish.gradle +82 -0
- package/android/settings.gradle +5 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/cpp/CMakeLists.txt +59 -0
- package/android/src/main/java/dev/mediacache/alphavideo/AlphaVideoCodecs.java +73 -0
- package/android/src/main/java/dev/mediacache/alphavideo/AlphaVideoView.java +1966 -0
- package/android/src/main/java/dev/mediacache/alphavideo/BufferedDualStreamPlayer.java +978 -0
- package/android/src/main/java/dev/mediacache/alphavideo/Fetcher.java +37 -0
- package/android/src/main/java/dev/mediacache/alphavideo/HttpFetcher.java +156 -0
- package/android/src/main/java/dev/mediacache/alphavideo/MediaCodecColor.java +47 -0
- package/android/src/main/java/dev/mediacache/alphavideo/MediaCodecDecoders.java +135 -0
- package/android/src/main/java/dev/mediacache/alphavideo/RangeSourceLink.java +54 -0
- package/android/src/main/java/dev/mediacache/alphavideo/SourceReader.java +174 -0
- package/android/src/main/java/dev/mediacache/alphavideo/SurfaceTextureVideoDecoder.java +802 -0
- package/android/src/main/java/dev/mediacache/alphavideo/WebMAlphaPlayerNative.java +95 -0
- package/android/src/main/java/dev/mediacache/alphavideo/WebMFrame.java +54 -0
- package/android/src/main/java/dev/mediacache/alphavideo/WebMSource.java +160 -0
- package/android/src/rangesource/java/dev/mediacache/alphavideo/AppDataSource.java +50 -0
- package/android/vpx/build.gradle +67 -0
- package/android/vpx/consumer-rules.pro +4 -0
- package/android/vpx/src/main/cpp/CMakeLists.txt +34 -0
- package/android/vpx/src/main/cpp/VpxCodec_jni.cpp +8 -0
- package/android/vpx/src/main/java/dev/mediacache/alphavideo/vpx/VpxCodec.java +21 -0
- package/codecs/av1/Dav1dDecoderPlugin.cpp +157 -0
- package/codecs/av1/Dav1dDecoderPlugin.h +17 -0
- package/codecs/vpx/VpxDecoderPlugin.cpp +103 -0
- package/codecs/vpx/VpxDecoderPlugin.h +17 -0
- package/cpp/AlphaDemuxer.cpp +984 -0
- package/cpp/AlphaDemuxer.h +123 -0
- package/cpp/AlphaVideoDecoderPlugin.h +84 -0
- package/cpp/Av1SequenceHeader.cpp +175 -0
- package/cpp/Av1SequenceHeader.h +25 -0
- package/cpp/ByteSource.cpp +116 -0
- package/cpp/ByteSource.h +59 -0
- package/cpp/RangeSourceClient.h +40 -0
- package/cpp/VideoDecoder.cpp +157 -0
- package/cpp/VideoDecoder.h +83 -0
- package/cpp/WebMAlphaPlayer.cpp +1666 -0
- package/cpp/WebMAlphaPlayer.h +389 -0
- package/cpp/WebMAlphaPlayer_jni.cpp +1380 -0
- package/cpp/YuvToRgb.cpp +39 -0
- package/cpp/YuvToRgb.h +40 -0
- package/ios/Sources/AlphaVideo/AlphaVideoCodecs.mm +63 -0
- package/ios/Sources/AlphaVideo/AlphaVideoInternal.h +70 -0
- package/ios/Sources/AlphaVideo/AlphaVideoPlayer.mm +994 -0
- package/ios/Sources/AlphaVideo/AlphaVideoSource.mm +476 -0
- package/ios/Sources/AlphaVideo/AlphaVideoView.mm +374 -0
- package/ios/Sources/AlphaVideo/include/AlphaVideo.h +303 -0
- package/ios/Sources/AlphaVideoAV1/AlphaVideoAV1Codec.mm +16 -0
- package/ios/Sources/AlphaVideoAV1/include/AlphaVideoAV1.h +18 -0
- package/ios/Sources/AlphaVideoVPX/AlphaVideoVPXCodec.mm +16 -0
- package/ios/Sources/AlphaVideoVPX/include/AlphaVideoVPX.h +17 -0
- package/lib/commonjs/AlphaVideoView.js +187 -0
- package/lib/commonjs/AlphaVideoView.js.map +1 -0
- package/lib/commonjs/AlphaVideoViewNativeComponent.js +47 -0
- package/lib/commonjs/AlphaVideoViewNativeComponent.js.map +1 -0
- package/lib/commonjs/AlphaVideoViewNativeComponent.web.js +11 -0
- package/lib/commonjs/AlphaVideoViewNativeComponent.web.js.map +1 -0
- package/lib/commonjs/NativeAlphaVideoModule.js +10 -0
- package/lib/commonjs/NativeAlphaVideoModule.js.map +1 -0
- package/lib/commonjs/NativeAlphaVideoModule.web.js +9 -0
- package/lib/commonjs/NativeAlphaVideoModule.web.js.map +1 -0
- package/lib/commonjs/WebPlayer.js +12 -0
- package/lib/commonjs/WebPlayer.js.map +1 -0
- package/lib/commonjs/WebPlayer.web.js +92 -0
- package/lib/commonjs/WebPlayer.web.js.map +1 -0
- package/lib/commonjs/index.js +124 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/AlphaVideoView.js +187 -0
- package/lib/module/AlphaVideoView.js.map +1 -0
- package/lib/module/AlphaVideoViewNativeComponent.js +47 -0
- package/lib/module/AlphaVideoViewNativeComponent.js.map +1 -0
- package/lib/module/AlphaVideoViewNativeComponent.web.js +11 -0
- package/lib/module/AlphaVideoViewNativeComponent.web.js.map +1 -0
- package/lib/module/NativeAlphaVideoModule.js +10 -0
- package/lib/module/NativeAlphaVideoModule.js.map +1 -0
- package/lib/module/NativeAlphaVideoModule.web.js +9 -0
- package/lib/module/NativeAlphaVideoModule.web.js.map +1 -0
- package/lib/module/WebPlayer.js +12 -0
- package/lib/module/WebPlayer.js.map +1 -0
- package/lib/module/WebPlayer.web.js +92 -0
- package/lib/module/WebPlayer.web.js.map +1 -0
- package/lib/module/index.js +124 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/react-native/src/AlphaVideoView.d.ts +189 -0
- package/lib/typescript/react-native/src/AlphaVideoView.d.ts.map +1 -0
- package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.d.ts +109 -0
- package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.web.d.ts +5 -0
- package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.web.d.ts.map +1 -0
- package/lib/typescript/react-native/src/NativeAlphaVideoModule.d.ts +21 -0
- package/lib/typescript/react-native/src/NativeAlphaVideoModule.d.ts.map +1 -0
- package/lib/typescript/react-native/src/NativeAlphaVideoModule.web.d.ts +3 -0
- package/lib/typescript/react-native/src/NativeAlphaVideoModule.web.d.ts.map +1 -0
- package/lib/typescript/react-native/src/WebPlayer.d.ts +3 -0
- package/lib/typescript/react-native/src/WebPlayer.d.ts.map +1 -0
- package/lib/typescript/react-native/src/WebPlayer.web.d.ts +9 -0
- package/lib/typescript/react-native/src/WebPlayer.web.d.ts.map +1 -0
- package/lib/typescript/react-native/src/index.d.ts +77 -0
- package/lib/typescript/react-native/src/index.d.ts.map +1 -0
- package/licenses/dav1d-COPYING.txt +23 -0
- package/licenses/libvpx-LICENSE.txt +31 -0
- package/licenses/libvpx-PATENTS.txt +23 -0
- package/licenses/libwebm-LICENSE.txt +30 -0
- package/licenses/libwebm-PATENTS.txt +23 -0
- package/package.json +150 -4
- package/prebuilt/android/arm64-v8a/lib/libdav1d.a +0 -0
- package/prebuilt/android/arm64-v8a/lib/libvpx.a +0 -0
- package/prebuilt/android/armeabi-v7a/lib/libdav1d.a +0 -0
- package/prebuilt/android/armeabi-v7a/lib/libvpx.a +0 -0
- package/prebuilt/android/x86_64/lib/libdav1d.a +0 -0
- package/prebuilt/android/x86_64/lib/libvpx.a +0 -0
- package/prebuilt/include/dav1d/common.h +94 -0
- package/prebuilt/include/dav1d/data.h +117 -0
- package/prebuilt/include/dav1d/dav1d.h +329 -0
- package/prebuilt/include/dav1d/headers.h +440 -0
- package/prebuilt/include/dav1d/picture.h +157 -0
- package/prebuilt/include/dav1d/version.h +50 -0
- package/prebuilt/include/vpx/vp8.h +136 -0
- package/prebuilt/include/vpx/vp8dx.h +228 -0
- package/prebuilt/include/vpx/vpx_codec.h +475 -0
- package/prebuilt/include/vpx/vpx_decoder.h +365 -0
- package/prebuilt/include/vpx/vpx_frame_buffer.h +83 -0
- package/prebuilt/include/vpx/vpx_image.h +209 -0
- package/prebuilt/include/vpx/vpx_integer.h +40 -0
- package/prebuilt/ios/lib/libdav1d.a +0 -0
- package/prebuilt/ios/lib/libvpx.a +0 -0
- package/prebuilt/ios-simulator/include/dav1d/common.h +94 -0
- package/prebuilt/ios-simulator/include/dav1d/data.h +117 -0
- package/prebuilt/ios-simulator/include/dav1d/dav1d.h +329 -0
- package/prebuilt/ios-simulator/include/dav1d/headers.h +440 -0
- package/prebuilt/ios-simulator/include/dav1d/picture.h +157 -0
- package/prebuilt/ios-simulator/include/dav1d/version.h +50 -0
- package/prebuilt/ios-simulator/include/vpx/vp8.h +136 -0
- package/prebuilt/ios-simulator/include/vpx/vp8dx.h +228 -0
- package/prebuilt/ios-simulator/include/vpx/vpx_codec.h +475 -0
- package/prebuilt/ios-simulator/include/vpx/vpx_decoder.h +365 -0
- package/prebuilt/ios-simulator/include/vpx/vpx_frame_buffer.h +83 -0
- package/prebuilt/ios-simulator/include/vpx/vpx_image.h +209 -0
- package/prebuilt/ios-simulator/include/vpx/vpx_integer.h +40 -0
- package/prebuilt/ios-simulator/lib/libdav1d.a +0 -0
- package/prebuilt/ios-simulator/lib/libvpx.a +0 -0
- package/react-native/android/CMakeLists.txt +14 -0
- package/react-native/android/build.gradle +110 -0
- package/react-native/android/src/main/AndroidManifest.xml +1 -0
- package/react-native/android/src/main/java/dev/mediacache/alphavideo/reactnative/AlphaVideoModule.java +102 -0
- package/react-native/android/src/main/java/dev/mediacache/alphavideo/reactnative/AlphaVideoPackage.java +50 -0
- package/react-native/android/src/main/java/dev/mediacache/alphavideo/reactnative/AlphaVideoViewManager.java +317 -0
- package/react-native/android/src/newarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoModuleSpec.java +10 -0
- package/react-native/android/src/newarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoViewManagerSpec.java +23 -0
- package/react-native/android/src/norangesource/java/dev/mediacache/alphavideo/AppDataSource.java +15 -0
- package/react-native/android/src/oldarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoModuleSpec.java +30 -0
- package/react-native/android/src/oldarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoViewManagerSpec.java +61 -0
- package/react-native/ios/RNAlphaVideoViewComponentView.mm +173 -0
- package/react-native/ios/RNAlphaVideoViewManager.mm +147 -0
- package/react-native/src/AlphaVideoView.tsx +329 -0
- package/react-native/src/AlphaVideoViewNativeComponent.ts +132 -0
- package/react-native/src/AlphaVideoViewNativeComponent.web.ts +5 -0
- package/react-native/src/NativeAlphaVideoModule.ts +22 -0
- package/react-native/src/NativeAlphaVideoModule.web.ts +2 -0
- package/react-native/src/WebPlayer.tsx +7 -0
- package/react-native/src/WebPlayer.web.tsx +60 -0
- package/react-native/src/index.tsx +144 -0
- package/react-native-alpha-video.podspec +99 -0
- package/react-native.config.js +12 -0
- package/scripts/build_codecs_android.sh +246 -0
- package/scripts/build_codecs_ios.sh +31 -0
- package/scripts/build_codecs_ios_device.sh +210 -0
- package/scripts/build_codecs_ios_simulator.sh +256 -0
- package/scripts/build_wasm.sh +230 -0
- package/scripts/build_xcframework.sh +49 -0
- package/scripts/fetch-prebuilt.sh +48 -0
- package/scripts/package_release.sh +107 -0
- package/scripts/publish-android.sh +85 -0
- package/scripts/vendor_range_source.sh +47 -0
- package/third_party/libwebm/AUTHORS.TXT +5 -0
- package/third_party/libwebm/LICENSE.TXT +30 -0
- package/third_party/libwebm/PATENTS.TXT +23 -0
- package/third_party/libwebm/README.md +7 -0
- package/third_party/libwebm/webm_parser/include/webm/buffer_reader.h +138 -0
- package/third_party/libwebm/webm_parser/include/webm/callback.h +363 -0
- package/third_party/libwebm/webm_parser/include/webm/dom_types.h +1781 -0
- package/third_party/libwebm/webm_parser/include/webm/element.h +208 -0
- package/third_party/libwebm/webm_parser/include/webm/file_reader.h +103 -0
- package/third_party/libwebm/webm_parser/include/webm/id.h +1085 -0
- package/third_party/libwebm/webm_parser/include/webm/istream_reader.h +99 -0
- package/third_party/libwebm/webm_parser/include/webm/reader.h +94 -0
- package/third_party/libwebm/webm_parser/include/webm/status.h +166 -0
- package/third_party/libwebm/webm_parser/include/webm/webm_parser.h +133 -0
- package/third_party/libwebm/webm_parser/src/ancestory.cc +334 -0
- package/third_party/libwebm/webm_parser/src/ancestory.h +83 -0
- package/third_party/libwebm/webm_parser/src/audio_parser.h +84 -0
- package/third_party/libwebm/webm_parser/src/bit_utils.cc +26 -0
- package/third_party/libwebm/webm_parser/src/bit_utils.h +24 -0
- package/third_party/libwebm/webm_parser/src/block_additions_parser.h +30 -0
- package/third_party/libwebm/webm_parser/src/block_group_parser.h +71 -0
- package/third_party/libwebm/webm_parser/src/block_header_parser.cc +76 -0
- package/third_party/libwebm/webm_parser/src/block_header_parser.h +65 -0
- package/third_party/libwebm/webm_parser/src/block_more_parser.h +32 -0
- package/third_party/libwebm/webm_parser/src/block_parser.cc +285 -0
- package/third_party/libwebm/webm_parser/src/block_parser.h +126 -0
- package/third_party/libwebm/webm_parser/src/bool_parser.h +95 -0
- package/third_party/libwebm/webm_parser/src/buffer_reader.cc +110 -0
- package/third_party/libwebm/webm_parser/src/byte_parser.h +144 -0
- package/third_party/libwebm/webm_parser/src/callback.cc +155 -0
- package/third_party/libwebm/webm_parser/src/chapter_atom_parser.h +42 -0
- package/third_party/libwebm/webm_parser/src/chapter_display_parser.h +34 -0
- package/third_party/libwebm/webm_parser/src/chapters_parser.h +28 -0
- package/third_party/libwebm/webm_parser/src/cluster_parser.h +48 -0
- package/third_party/libwebm/webm_parser/src/colour_parser.h +55 -0
- package/third_party/libwebm/webm_parser/src/content_enc_aes_settings_parser.h +32 -0
- package/third_party/libwebm/webm_parser/src/content_encoding_parser.h +38 -0
- package/third_party/libwebm/webm_parser/src/content_encodings_parser.h +30 -0
- package/third_party/libwebm/webm_parser/src/content_encryption_parser.h +37 -0
- package/third_party/libwebm/webm_parser/src/cue_point_parser.h +38 -0
- package/third_party/libwebm/webm_parser/src/cue_track_positions_parser.h +39 -0
- package/third_party/libwebm/webm_parser/src/cues_parser.h +27 -0
- package/third_party/libwebm/webm_parser/src/date_parser.cc +72 -0
- package/third_party/libwebm/webm_parser/src/date_parser.h +64 -0
- package/third_party/libwebm/webm_parser/src/ebml_parser.h +48 -0
- package/third_party/libwebm/webm_parser/src/edition_entry_parser.h +35 -0
- package/third_party/libwebm/webm_parser/src/element_parser.h +102 -0
- package/third_party/libwebm/webm_parser/src/file_reader.cc +142 -0
- package/third_party/libwebm/webm_parser/src/float_parser.cc +77 -0
- package/third_party/libwebm/webm_parser/src/float_parser.h +65 -0
- package/third_party/libwebm/webm_parser/src/id_element_parser.cc +49 -0
- package/third_party/libwebm/webm_parser/src/id_element_parser.h +56 -0
- package/third_party/libwebm/webm_parser/src/id_parser.cc +75 -0
- package/third_party/libwebm/webm_parser/src/id_parser.h +45 -0
- package/third_party/libwebm/webm_parser/src/info_parser.h +44 -0
- package/third_party/libwebm/webm_parser/src/int_parser.h +121 -0
- package/third_party/libwebm/webm_parser/src/istream_reader.cc +133 -0
- package/third_party/libwebm/webm_parser/src/master_parser.cc +298 -0
- package/third_party/libwebm/webm_parser/src/master_parser.h +230 -0
- package/third_party/libwebm/webm_parser/src/master_value_parser.h +533 -0
- package/third_party/libwebm/webm_parser/src/mastering_metadata_parser.h +57 -0
- package/third_party/libwebm/webm_parser/src/parser.h +34 -0
- package/third_party/libwebm/webm_parser/src/parser_utils.cc +34 -0
- package/third_party/libwebm/webm_parser/src/parser_utils.h +64 -0
- package/third_party/libwebm/webm_parser/src/projection_parser.h +40 -0
- package/third_party/libwebm/webm_parser/src/recursive_parser.h +93 -0
- package/third_party/libwebm/webm_parser/src/seek_head_parser.h +27 -0
- package/third_party/libwebm/webm_parser/src/seek_parser.h +37 -0
- package/third_party/libwebm/webm_parser/src/segment_parser.cc +86 -0
- package/third_party/libwebm/webm_parser/src/segment_parser.h +53 -0
- package/third_party/libwebm/webm_parser/src/simple_tag_parser.h +37 -0
- package/third_party/libwebm/webm_parser/src/size_parser.cc +56 -0
- package/third_party/libwebm/webm_parser/src/size_parser.h +43 -0
- package/third_party/libwebm/webm_parser/src/skip_callback.h +63 -0
- package/third_party/libwebm/webm_parser/src/skip_parser.cc +59 -0
- package/third_party/libwebm/webm_parser/src/skip_parser.h +35 -0
- package/third_party/libwebm/webm_parser/src/slices_parser.h +30 -0
- package/third_party/libwebm/webm_parser/src/tag_parser.h +37 -0
- package/third_party/libwebm/webm_parser/src/tags_parser.h +27 -0
- package/third_party/libwebm/webm_parser/src/targets_parser.h +35 -0
- package/third_party/libwebm/webm_parser/src/time_slice_parser.h +30 -0
- package/third_party/libwebm/webm_parser/src/track_entry_parser.h +65 -0
- package/third_party/libwebm/webm_parser/src/tracks_parser.h +27 -0
- package/third_party/libwebm/webm_parser/src/unknown_parser.cc +49 -0
- package/third_party/libwebm/webm_parser/src/unknown_parser.h +38 -0
- package/third_party/libwebm/webm_parser/src/var_int_parser.cc +71 -0
- package/third_party/libwebm/webm_parser/src/var_int_parser.h +56 -0
- package/third_party/libwebm/webm_parser/src/video_parser.h +122 -0
- package/third_party/libwebm/webm_parser/src/virtual_block_parser.cc +72 -0
- package/third_party/libwebm/webm_parser/src/virtual_block_parser.h +69 -0
- package/third_party/libwebm/webm_parser/src/void_parser.cc +49 -0
- package/third_party/libwebm/webm_parser/src/void_parser.h +41 -0
- package/third_party/libwebm/webm_parser/src/webm_parser.cc +282 -0
- package/third_party/range-source/LICENSE +21 -0
- package/third_party/range-source/README.md +8 -0
- package/third_party/range-source/include/range_source.h +395 -0
- package/third_party/range-source/include/range_source_download.h +309 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstdint>
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <vector>
|
|
6
|
+
|
|
7
|
+
namespace webm {
|
|
8
|
+
|
|
9
|
+
class ByteSource;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Reads an alpha WebM's colour and alpha bitstreams as packets, without decoding them, for
|
|
13
|
+
* decoders that take one bitstream each: the core's libvpx and dav1d decoders, MediaCodec, and on
|
|
14
|
+
* the web WebCodecs and the software decoders in Workers.
|
|
15
|
+
*
|
|
16
|
+
* The colour stream is the first VP8, VP9 or AV1 track. The alpha stream is the second, or, for a
|
|
17
|
+
* single VP8 or VP9 track, the stream in each block's BlockAdditional (ID 1), which is how libvpx
|
|
18
|
+
* writes a standard `yuva420p` WebM.
|
|
19
|
+
*
|
|
20
|
+
* Built on libwebm's webm_parser. Android, iOS and the web (compiled to WebAssembly) all use it;
|
|
21
|
+
* tests/core/demuxer_compare checks it against FFmpeg's reading of each file.
|
|
22
|
+
*/
|
|
23
|
+
class AlphaDemuxer {
|
|
24
|
+
public:
|
|
25
|
+
enum Codec { VP8 = 0, VP9 = 1, AV1 = 2 };
|
|
26
|
+
|
|
27
|
+
/** Colour numbers are H.273's, as in YuvToRgb.h (and FFmpeg's AVColor* enums). */
|
|
28
|
+
struct StreamInfo {
|
|
29
|
+
Codec codec = VP9;
|
|
30
|
+
int profile = 0; // From the bitstream
|
|
31
|
+
int bitDepth = 8;
|
|
32
|
+
int colorRange = 0; // ColorRange
|
|
33
|
+
int colorSpace = 2; // ColorMatrix (2 = unspecified)
|
|
34
|
+
int colorPrimaries = 2;
|
|
35
|
+
int colorTrc = 2;
|
|
36
|
+
std::vector<uint8_t> codecPrivate; // Matroska CodecPrivate: av1C for AV1, empty for VP8 and VP9
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
struct Info {
|
|
40
|
+
int width = 0;
|
|
41
|
+
int height = 0;
|
|
42
|
+
int totalFrames = 0;
|
|
43
|
+
double frameRate = 30.0;
|
|
44
|
+
int64_t durationUs = 0;
|
|
45
|
+
int64_t startUs = 0; // The first colour packet's ptsUs
|
|
46
|
+
bool hasAlpha = false;
|
|
47
|
+
bool alphaInBlockAdditional = false;
|
|
48
|
+
StreamInfo color;
|
|
49
|
+
StreamInfo alpha; // Valid when hasAlpha
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
struct Packet {
|
|
53
|
+
int stream = 0; // 0 colour, 1 alpha
|
|
54
|
+
const uint8_t* data = nullptr; // Valid until the next read, seek or destruction
|
|
55
|
+
int size = 0;
|
|
56
|
+
int64_t ptsUs = 0;
|
|
57
|
+
int frameIndex = 0;
|
|
58
|
+
bool key = false;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
enum class Progress { kDone, kPending, kFailed };
|
|
62
|
+
|
|
63
|
+
/** Opens `source` as a WebM. Returns null if it can't be read or has no VP8, VP9 or AV1 track. */
|
|
64
|
+
static std::unique_ptr<AlphaDemuxer> open(std::unique_ptr<ByteSource> source);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A demuxer for a source that may answer ByteSource::kPending, not yet open: call tryOpen()
|
|
68
|
+
* until it no longer returns kPending. Null if `source` is.
|
|
69
|
+
*/
|
|
70
|
+
static std::unique_ptr<AlphaDemuxer> create(std::unique_ptr<ByteSource> source);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Reads the headers and the first packets. kPending: the source didn't have the bytes yet;
|
|
74
|
+
* call again once it has. kFailed: not a WebM with a VP8, VP9 or AV1 track, or unreadable.
|
|
75
|
+
* info() is valid once it returns kDone.
|
|
76
|
+
*/
|
|
77
|
+
Progress tryOpen();
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The colour and alpha bitstreams of `source`, as (codec, profile) pairs, colour first: two
|
|
81
|
+
* pairs for an alpha WebM, fewer otherwise.
|
|
82
|
+
*/
|
|
83
|
+
static std::vector<int> colorAlphaTracks(std::unique_ptr<ByteSource> source);
|
|
84
|
+
|
|
85
|
+
~AlphaDemuxer();
|
|
86
|
+
AlphaDemuxer(const AlphaDemuxer&) = delete;
|
|
87
|
+
AlphaDemuxer& operator=(const AlphaDemuxer&) = delete;
|
|
88
|
+
|
|
89
|
+
const Info& info() const;
|
|
90
|
+
|
|
91
|
+
/** The next colour or alpha packet; false at the end of the file or when reading fails. */
|
|
92
|
+
bool readPacket(Packet* out);
|
|
93
|
+
|
|
94
|
+
/** Whether the last readPacket() returned false because reading failed (an I/O error, a
|
|
95
|
+
* failed or aborted download), rather than at the end of the file. */
|
|
96
|
+
bool failed() const;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Whether the last readPacket() or seekToTimeUs() stopped because the source answered
|
|
100
|
+
* ByteSource::kPending. Call it again once the bytes are there: a read carries on where it
|
|
101
|
+
* stopped, and a seek starts over (seeking elsewhere instead is fine too).
|
|
102
|
+
*/
|
|
103
|
+
bool pending() const;
|
|
104
|
+
|
|
105
|
+
/** Back to the first packet, with frameIndex counting from 0 again. */
|
|
106
|
+
void seekToStart();
|
|
107
|
+
/** To the keyframe at or before `timeUs`, in the timebase of the packets' ptsUs. Keeps the
|
|
108
|
+
* frameIndex counters going. May read the Cues, or scan for keyframes, so may be pending(). */
|
|
109
|
+
void seekToTimeUs(int64_t timeUs);
|
|
110
|
+
|
|
111
|
+
private:
|
|
112
|
+
class Impl;
|
|
113
|
+
explicit AlphaDemuxer(std::unique_ptr<Impl> impl);
|
|
114
|
+
std::unique_ptr<Impl> impl_;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/** Whether a VP9 frame (or superframe) starts with a keyframe, from its uncompressed header. */
|
|
118
|
+
bool isVp9Keyframe(const uint8_t* data, int size);
|
|
119
|
+
|
|
120
|
+
/** Whether a VP8 frame is a keyframe, from its frame tag. */
|
|
121
|
+
bool isVp8Keyframe(const uint8_t* data, int size);
|
|
122
|
+
|
|
123
|
+
} // namespace webm
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The interface between the player's core and a software decoder: libvpx in the vpx codec module,
|
|
3
|
+
* dav1d in the av1 module, or a third party's. A module provides a list of plugins, one per codec,
|
|
4
|
+
* and the app (or the platform's discovery) registers them with the core.
|
|
5
|
+
*
|
|
6
|
+
* C, not C++: on Android each module is its own .so with its own static libc++, and on iOS a
|
|
7
|
+
* module may be built apart from the core. A plugin built for another ABI is refused.
|
|
8
|
+
*/
|
|
9
|
+
#ifndef ALPHA_VIDEO_DECODER_PLUGIN_H
|
|
10
|
+
#define ALPHA_VIDEO_DECODER_PLUGIN_H
|
|
11
|
+
|
|
12
|
+
#include <stddef.h>
|
|
13
|
+
#include <stdint.h>
|
|
14
|
+
|
|
15
|
+
#ifdef __cplusplus
|
|
16
|
+
extern "C" {
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
#define ALPHA_VIDEO_DECODER_ABI 1
|
|
20
|
+
|
|
21
|
+
/* AlphaDemuxer::Codec */
|
|
22
|
+
#define ALPHA_VIDEO_CODEC_VP8 0
|
|
23
|
+
#define ALPHA_VIDEO_CODEC_VP9 1
|
|
24
|
+
#define ALPHA_VIDEO_CODEC_AV1 2
|
|
25
|
+
|
|
26
|
+
/* A bitstream to decode, as the demuxer read it. Colour numbers are H.273's. */
|
|
27
|
+
typedef struct AlphaVideoStreamInfo {
|
|
28
|
+
int codec;
|
|
29
|
+
int profile;
|
|
30
|
+
int bitDepth;
|
|
31
|
+
int width;
|
|
32
|
+
int height;
|
|
33
|
+
const uint8_t* codecPrivate; /* Matroska CodecPrivate (av1C for AV1); may be null */
|
|
34
|
+
size_t codecPrivateSize;
|
|
35
|
+
} AlphaVideoStreamInfo;
|
|
36
|
+
|
|
37
|
+
/* A decoded frame, in the decoder's own buffers: valid until its next call. */
|
|
38
|
+
typedef struct AlphaVideoPicture {
|
|
39
|
+
const uint8_t* planes[3]; /* Y, U, V; G, B, R when rgb. U and V null when monochrome. */
|
|
40
|
+
int strides[3];
|
|
41
|
+
int width;
|
|
42
|
+
int height;
|
|
43
|
+
int chromaShiftX; /* 4:2:0 is 1, 1; 4:2:2 is 1, 0; 4:4:4 is 0, 0 */
|
|
44
|
+
int chromaShiftY;
|
|
45
|
+
int bitDepth; /* Deeper samples are 16 bits each */
|
|
46
|
+
int colorRange; /* 1 limited, 2 full */
|
|
47
|
+
int rgb;
|
|
48
|
+
int monochrome;
|
|
49
|
+
int64_t ptsUs;
|
|
50
|
+
} AlphaVideoPicture;
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
* One codec's decoder. Each decoder `open` returns is used from one thread at a time. send() a
|
|
54
|
+
* packet, then receive() until it returns 0. Frames come out in order, perhaps some packets late;
|
|
55
|
+
* drain() at the end of the stream lets receive() return the frames still held.
|
|
56
|
+
*/
|
|
57
|
+
typedef struct AlphaVideoDecoderPlugin {
|
|
58
|
+
uint32_t abi; /* ALPHA_VIDEO_DECODER_ABI */
|
|
59
|
+
uint32_t structSize; /* sizeof(AlphaVideoDecoderPlugin) */
|
|
60
|
+
const char* name; /* "libvpx" */
|
|
61
|
+
const char* version; /* "v1.14.0" */
|
|
62
|
+
int codec; /* ALPHA_VIDEO_CODEC_* */
|
|
63
|
+
/* 1 if it decodes this stream (libvpx here: 8-bit only) */
|
|
64
|
+
int (*supports)(const AlphaVideoStreamInfo* stream);
|
|
65
|
+
/* Null, with a message in `error`, if it can't open. threads: 0 for the decoder's choice. */
|
|
66
|
+
void* (*open)(const AlphaVideoStreamInfo* stream, int threads, char* error, size_t errorSize);
|
|
67
|
+
/* 0 if the packet can't be decoded */
|
|
68
|
+
int (*send)(void* decoder, const uint8_t* data, int size, int64_t ptsUs);
|
|
69
|
+
/* 1 with a frame in `out`, 0 when none is ready */
|
|
70
|
+
int (*receive)(void* decoder, AlphaVideoPicture* out);
|
|
71
|
+
void (*drain)(void* decoder);
|
|
72
|
+
/* Drops the frames held and in progress, for a seek */
|
|
73
|
+
void (*flush)(void* decoder);
|
|
74
|
+
void (*close)(void* decoder);
|
|
75
|
+
} AlphaVideoDecoderPlugin;
|
|
76
|
+
|
|
77
|
+
/* A codec module's entry point: its plugins, `*count` of them, valid for the process's life. */
|
|
78
|
+
typedef const AlphaVideoDecoderPlugin* const* (*AlphaVideoDecoderPluginList)(int* count);
|
|
79
|
+
|
|
80
|
+
#ifdef __cplusplus
|
|
81
|
+
}
|
|
82
|
+
#endif
|
|
83
|
+
|
|
84
|
+
#endif
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#include "Av1SequenceHeader.h"
|
|
2
|
+
|
|
3
|
+
namespace {
|
|
4
|
+
|
|
5
|
+
const int kObuSequenceHeader = 1;
|
|
6
|
+
|
|
7
|
+
// Reads bits most significant first; past the end it reads zeros and sets `overrun`.
|
|
8
|
+
struct Bits {
|
|
9
|
+
const uint8_t* data;
|
|
10
|
+
size_t size;
|
|
11
|
+
size_t pos = 0; // in bits
|
|
12
|
+
bool overrun = false;
|
|
13
|
+
|
|
14
|
+
uint32_t f(int n) {
|
|
15
|
+
uint32_t v = 0;
|
|
16
|
+
for (; n > 0; n--, pos++) {
|
|
17
|
+
int bit = 0;
|
|
18
|
+
if (pos < size * 8) {
|
|
19
|
+
bit = (data[pos >> 3] >> (7 - (pos & 7))) & 1;
|
|
20
|
+
} else {
|
|
21
|
+
overrun = true;
|
|
22
|
+
}
|
|
23
|
+
v = (v << 1) | static_cast<uint32_t>(bit);
|
|
24
|
+
}
|
|
25
|
+
return v;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
bool flag() { return f(1) != 0; }
|
|
29
|
+
|
|
30
|
+
// uvlc() (4.10.3)
|
|
31
|
+
void skipUvlc() {
|
|
32
|
+
int leadingZeros = 0;
|
|
33
|
+
while (!flag() && !overrun) leadingZeros++;
|
|
34
|
+
if (leadingZeros < 32) f(leadingZeros);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// leb128() (4.10.5); false if it runs past `end` or over 8 bytes
|
|
39
|
+
bool readLeb128(const uint8_t*& p, const uint8_t* end, uint64_t* value) {
|
|
40
|
+
*value = 0;
|
|
41
|
+
for (int i = 0; i < 8; i++) {
|
|
42
|
+
if (p >= end) return false;
|
|
43
|
+
const uint8_t byte = *p++;
|
|
44
|
+
*value |= static_cast<uint64_t>(byte & 0x7f) << (i * 7);
|
|
45
|
+
if (!(byte & 0x80)) return true;
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// color_config() (5.5.2)
|
|
51
|
+
void readColorConfig(Bits& b, Av1SequenceHeader* out) {
|
|
52
|
+
const bool highBitdepth = b.flag();
|
|
53
|
+
if (out->profile == 2 && highBitdepth) {
|
|
54
|
+
out->bitDepth = b.flag() ? 12 : 10;
|
|
55
|
+
} else {
|
|
56
|
+
out->bitDepth = highBitdepth ? 10 : 8;
|
|
57
|
+
}
|
|
58
|
+
out->monochrome = out->profile == 1 ? false : b.flag();
|
|
59
|
+
if (b.flag()) { // color_description_present_flag
|
|
60
|
+
out->colorPrimaries = static_cast<int>(b.f(8));
|
|
61
|
+
out->transferCharacteristics = static_cast<int>(b.f(8));
|
|
62
|
+
out->matrixCoefficients = static_cast<int>(b.f(8));
|
|
63
|
+
}
|
|
64
|
+
if (out->monochrome) {
|
|
65
|
+
out->fullRange = b.flag();
|
|
66
|
+
out->subsamplingX = out->subsamplingY = 1;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// sRGB: BT.709 primaries, the sRGB transfer, the identity matrix
|
|
70
|
+
if (out->colorPrimaries == 1 && out->transferCharacteristics == 13 && out->matrixCoefficients == 0) {
|
|
71
|
+
out->fullRange = true;
|
|
72
|
+
out->subsamplingX = out->subsamplingY = 0;
|
|
73
|
+
} else {
|
|
74
|
+
out->fullRange = b.flag();
|
|
75
|
+
if (out->profile == 0) {
|
|
76
|
+
out->subsamplingX = out->subsamplingY = 1;
|
|
77
|
+
} else if (out->profile == 1) {
|
|
78
|
+
out->subsamplingX = out->subsamplingY = 0;
|
|
79
|
+
} else if (out->bitDepth == 12) {
|
|
80
|
+
out->subsamplingX = static_cast<int>(b.f(1));
|
|
81
|
+
out->subsamplingY = out->subsamplingX ? static_cast<int>(b.f(1)) : 0;
|
|
82
|
+
} else {
|
|
83
|
+
out->subsamplingX = 1;
|
|
84
|
+
out->subsamplingY = 0;
|
|
85
|
+
}
|
|
86
|
+
if (out->subsamplingX && out->subsamplingY) b.f(2); // chroma_sample_position
|
|
87
|
+
}
|
|
88
|
+
b.f(1); // separate_uv_delta_q
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// sequence_header_obu() (5.5.1)
|
|
92
|
+
bool readSequenceHeader(Bits& b, Av1SequenceHeader* out) {
|
|
93
|
+
*out = Av1SequenceHeader();
|
|
94
|
+
out->profile = static_cast<int>(b.f(3));
|
|
95
|
+
if (out->profile > 2) return false;
|
|
96
|
+
const bool stillPicture = b.flag();
|
|
97
|
+
const bool reducedStillPictureHeader = b.flag();
|
|
98
|
+
if (reducedStillPictureHeader && !stillPicture) return false;
|
|
99
|
+
if (reducedStillPictureHeader) {
|
|
100
|
+
b.f(5); // seq_level_idx[0]
|
|
101
|
+
} else {
|
|
102
|
+
bool decoderModelInfoPresent = false;
|
|
103
|
+
int bufferDelayLength = 0;
|
|
104
|
+
if (b.flag()) { // timing_info_present_flag
|
|
105
|
+
b.f(32); // num_units_in_display_tick
|
|
106
|
+
b.f(32); // time_scale
|
|
107
|
+
if (b.flag()) b.skipUvlc(); // equal_picture_interval, num_ticks_per_picture_minus_1
|
|
108
|
+
decoderModelInfoPresent = b.flag();
|
|
109
|
+
if (decoderModelInfoPresent) {
|
|
110
|
+
bufferDelayLength = static_cast<int>(b.f(5)) + 1;
|
|
111
|
+
b.f(32); // num_units_in_decoding_tick
|
|
112
|
+
b.f(5); // buffer_removal_time_length_minus_1
|
|
113
|
+
b.f(5); // frame_presentation_time_length_minus_1
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const bool initialDisplayDelayPresent = b.flag();
|
|
117
|
+
const int operatingPoints = static_cast<int>(b.f(5)) + 1;
|
|
118
|
+
for (int i = 0; i < operatingPoints; i++) {
|
|
119
|
+
b.f(12); // operating_point_idc
|
|
120
|
+
if (b.f(5) > 7) b.f(1); // seq_level_idx, seq_tier
|
|
121
|
+
if (decoderModelInfoPresent && b.flag()) {
|
|
122
|
+
b.f(bufferDelayLength); // decoder_buffer_delay
|
|
123
|
+
b.f(bufferDelayLength); // encoder_buffer_delay
|
|
124
|
+
b.f(1); // low_delay_mode_flag
|
|
125
|
+
}
|
|
126
|
+
if (initialDisplayDelayPresent && b.flag()) b.f(4); // initial_display_delay_minus_1
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const int widthBits = static_cast<int>(b.f(4)) + 1;
|
|
130
|
+
const int heightBits = static_cast<int>(b.f(4)) + 1;
|
|
131
|
+
out->maxWidth = static_cast<int>(b.f(widthBits)) + 1;
|
|
132
|
+
out->maxHeight = static_cast<int>(b.f(heightBits)) + 1;
|
|
133
|
+
if (!reducedStillPictureHeader && b.flag()) b.f(7); // frame_id_numbers_present_flag, its lengths
|
|
134
|
+
b.f(3); // use_128x128_superblock, enable_filter_intra, enable_intra_edge_filter
|
|
135
|
+
if (!reducedStillPictureHeader) {
|
|
136
|
+
b.f(4); // enable_interintra_compound, enable_masked_compound, enable_warped_motion, enable_dual_filter
|
|
137
|
+
const bool enableOrderHint = b.flag();
|
|
138
|
+
if (enableOrderHint) b.f(2); // enable_jnt_comp, enable_ref_frame_mvs
|
|
139
|
+
int forceScreenContentTools = 2; // SELECT_SCREEN_CONTENT_TOOLS
|
|
140
|
+
if (!b.flag()) forceScreenContentTools = static_cast<int>(b.f(1));
|
|
141
|
+
if (forceScreenContentTools > 0 && !b.flag()) b.f(1); // seq_choose_integer_mv, seq_force_integer_mv
|
|
142
|
+
if (enableOrderHint) b.f(3); // order_hint_bits_minus_1
|
|
143
|
+
}
|
|
144
|
+
b.f(3); // enable_superres, enable_cdef, enable_restoration
|
|
145
|
+
readColorConfig(b, out);
|
|
146
|
+
b.f(1); // film_grain_params_present
|
|
147
|
+
return !b.overrun;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
} // namespace
|
|
151
|
+
|
|
152
|
+
bool parseAv1SequenceHeader(const uint8_t* data, size_t size, Av1SequenceHeader* out) {
|
|
153
|
+
if (!data || !out) return false;
|
|
154
|
+
const uint8_t* p = data;
|
|
155
|
+
const uint8_t* const end = data + size;
|
|
156
|
+
while (p < end) {
|
|
157
|
+
// obu_header() (5.3.2)
|
|
158
|
+
const uint8_t header = *p++;
|
|
159
|
+
if (header & 0x80) return false; // obu_forbidden_bit
|
|
160
|
+
const int type = (header >> 3) & 0xf;
|
|
161
|
+
const bool hasExtension = header & 0x04;
|
|
162
|
+
const bool hasSizeField = header & 0x02;
|
|
163
|
+
if (hasExtension && p++ >= end) return false;
|
|
164
|
+
uint64_t obuSize = static_cast<uint64_t>(end - p);
|
|
165
|
+
if (hasSizeField && (!readLeb128(p, end, &obuSize) || obuSize > static_cast<uint64_t>(end - p))) {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
if (type == kObuSequenceHeader) {
|
|
169
|
+
Bits bits{p, static_cast<size_t>(obuSize)};
|
|
170
|
+
return readSequenceHeader(bits, out);
|
|
171
|
+
}
|
|
172
|
+
p += obuSize;
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstddef>
|
|
4
|
+
#include <cstdint>
|
|
5
|
+
|
|
6
|
+
// What the core reads from an AV1 sequence header (AV1 spec 5.5), so that the demuxer and the
|
|
7
|
+
// MediaCodec path know a track's format without an AV1 decoder linked in. The fields and their
|
|
8
|
+
// defaults are dav1d_parse_sequence_header's.
|
|
9
|
+
struct Av1SequenceHeader {
|
|
10
|
+
int profile = 0;
|
|
11
|
+
int bitDepth = 8;
|
|
12
|
+
bool monochrome = false;
|
|
13
|
+
int subsamplingX = 1;
|
|
14
|
+
int subsamplingY = 1;
|
|
15
|
+
int colorPrimaries = 2; // 2: unspecified
|
|
16
|
+
int transferCharacteristics = 2;
|
|
17
|
+
int matrixCoefficients = 2;
|
|
18
|
+
bool fullRange = false;
|
|
19
|
+
int maxWidth = 0;
|
|
20
|
+
int maxHeight = 0;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Parses the first sequence header OBU in `data`, a run of OBUs (av1C's configOBUs, or a packet).
|
|
24
|
+
// False when there is none, or it is cut short or invalid.
|
|
25
|
+
bool parseAv1SequenceHeader(const uint8_t* data, size_t size, Av1SequenceHeader* out);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#include "ByteSource.h"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
#include <cerrno>
|
|
6
|
+
#include <cstring>
|
|
7
|
+
#include <fcntl.h>
|
|
8
|
+
#include <sys/stat.h>
|
|
9
|
+
#include <unistd.h>
|
|
10
|
+
#include <vector>
|
|
11
|
+
|
|
12
|
+
namespace webm {
|
|
13
|
+
|
|
14
|
+
namespace {
|
|
15
|
+
|
|
16
|
+
class FileRangeSource : public ByteSource {
|
|
17
|
+
public:
|
|
18
|
+
// Takes ownership of fd
|
|
19
|
+
FileRangeSource(int fd, int64_t offset, int64_t length) : fd_(fd), offset_(offset), length_(length) {}
|
|
20
|
+
|
|
21
|
+
~FileRangeSource() override { close(fd_); }
|
|
22
|
+
|
|
23
|
+
int64_t read(int64_t pos, uint8_t* out, int64_t size) override {
|
|
24
|
+
const int64_t remaining = length_ - pos;
|
|
25
|
+
if (remaining <= 0 || size <= 0) return 0;
|
|
26
|
+
|
|
27
|
+
const size_t toRead = static_cast<size_t>(std::min(size, remaining));
|
|
28
|
+
ssize_t n;
|
|
29
|
+
do {
|
|
30
|
+
n = pread(fd_, out, toRead, offset_ + pos);
|
|
31
|
+
} while (n < 0 && errno == EINTR);
|
|
32
|
+
return n < 0 ? -1 : n;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
int64_t size() const override { return length_; }
|
|
36
|
+
|
|
37
|
+
private:
|
|
38
|
+
const int fd_;
|
|
39
|
+
const int64_t offset_;
|
|
40
|
+
const int64_t length_;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
class ReaderSource : public ByteSource {
|
|
44
|
+
public:
|
|
45
|
+
ReaderSource(std::shared_ptr<SourceReader> reader, const AbortFlag* abort)
|
|
46
|
+
: reader_(std::move(reader)), abort_(abort) {}
|
|
47
|
+
|
|
48
|
+
int64_t read(int64_t pos, uint8_t* out, int64_t size) override { return reader_->read(pos, out, size, abort_); }
|
|
49
|
+
|
|
50
|
+
int64_t size() const override { return reader_->size(); }
|
|
51
|
+
|
|
52
|
+
private:
|
|
53
|
+
const std::shared_ptr<SourceReader> reader_;
|
|
54
|
+
const AbortFlag* const abort_;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
class MemorySource : public ByteSource {
|
|
58
|
+
public:
|
|
59
|
+
MemorySource(const uint8_t* data, size_t size) : bytes_(data, data + size) {}
|
|
60
|
+
|
|
61
|
+
int64_t read(int64_t pos, uint8_t* out, int64_t size) override {
|
|
62
|
+
const int64_t remaining = static_cast<int64_t>(bytes_.size()) - pos;
|
|
63
|
+
if (pos < 0 || remaining <= 0 || size <= 0) return 0;
|
|
64
|
+
const int64_t n = std::min(size, remaining);
|
|
65
|
+
std::memcpy(out, bytes_.data() + pos, static_cast<size_t>(n));
|
|
66
|
+
return n;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
int64_t size() const override { return static_cast<int64_t>(bytes_.size()); }
|
|
70
|
+
|
|
71
|
+
private:
|
|
72
|
+
const std::vector<uint8_t> bytes_;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
int openReadOnly(const std::string& path) {
|
|
76
|
+
int fd;
|
|
77
|
+
do {
|
|
78
|
+
fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
|
79
|
+
} while (fd < 0 && errno == EINTR);
|
|
80
|
+
return fd;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
} // namespace
|
|
84
|
+
|
|
85
|
+
std::unique_ptr<ByteSource> openFileRange(int fd, int64_t offset, int64_t length) {
|
|
86
|
+
if (fd < 0 || offset < 0) return nullptr;
|
|
87
|
+
|
|
88
|
+
if (length < 0) {
|
|
89
|
+
struct stat st;
|
|
90
|
+
if (fstat(fd, &st) != 0 || st.st_size < offset) return nullptr;
|
|
91
|
+
length = st.st_size - offset;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
int ownFd = dup(fd);
|
|
95
|
+
if (ownFd < 0) return nullptr;
|
|
96
|
+
return std::make_unique<FileRangeSource>(ownFd, offset, length);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
std::unique_ptr<ByteSource> openFile(const std::string& path) {
|
|
100
|
+
int fd = openReadOnly(path);
|
|
101
|
+
if (fd < 0) return nullptr;
|
|
102
|
+
std::unique_ptr<ByteSource> source = openFileRange(fd, 0, -1);
|
|
103
|
+
close(fd);
|
|
104
|
+
return source;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
std::unique_ptr<ByteSource> openReader(std::shared_ptr<SourceReader> reader, const AbortFlag* abort) {
|
|
108
|
+
if (!reader) return nullptr;
|
|
109
|
+
return std::make_unique<ReaderSource>(std::move(reader), abort);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
std::unique_ptr<ByteSource> openMemory(const uint8_t* data, size_t size) {
|
|
113
|
+
return std::make_unique<MemorySource>(data, size);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
} // namespace webm
|
package/cpp/ByteSource.h
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "RangeSourceClient.h"
|
|
4
|
+
|
|
5
|
+
#include <cstdint>
|
|
6
|
+
#include <memory>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
namespace webm {
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The bytes of a video, read at any position: a file, a range of one, a URL or an app's data
|
|
13
|
+
* source read through a SourceReader, or memory. The demuxer reads through one of these.
|
|
14
|
+
*/
|
|
15
|
+
class ByteSource {
|
|
16
|
+
public:
|
|
17
|
+
/** What read() returns when the bytes at `pos` aren't there yet and it won't wait for them. */
|
|
18
|
+
static constexpr int64_t kPending = -2;
|
|
19
|
+
|
|
20
|
+
virtual ~ByteSource() = default;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Reads up to `size` bytes at `pos` into `out` and returns how many it read: fewer near the
|
|
24
|
+
* end, 0 at or past the end, -1 on an error. A range reader returns once some bytes at `pos`
|
|
25
|
+
* have arrived. A source that can't wait (the web's, which fetches asynchronously) returns
|
|
26
|
+
* kPending instead; the demuxer then stops, and carries on when called again.
|
|
27
|
+
*/
|
|
28
|
+
virtual int64_t read(int64_t pos, uint8_t* out, int64_t size) = 0;
|
|
29
|
+
|
|
30
|
+
/** The total size, or -1 while it isn't known (a response without a Content-Length). */
|
|
31
|
+
virtual int64_t size() const = 0;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Bytes [offset, offset + length) of a file descriptor: a video stored inside an APK
|
|
36
|
+
* (AssetManager.openFd) or behind a content:// URI, read in place. The descriptor is duplicated,
|
|
37
|
+
* so the caller still owns and closes the one it passed. A negative length means "to end of file".
|
|
38
|
+
*
|
|
39
|
+
* Returns nullptr if the range can't be opened.
|
|
40
|
+
*/
|
|
41
|
+
std::unique_ptr<ByteSource> openFileRange(int fd, int64_t offset, int64_t length);
|
|
42
|
+
|
|
43
|
+
/** A whole file. Returns nullptr if it can't be opened. */
|
|
44
|
+
std::unique_ptr<ByteSource> openFile(const std::string& path);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* A URL or an app's data source, through a SourceReader: the range-source add-on's reader, or the
|
|
48
|
+
* basic input's download.
|
|
49
|
+
*
|
|
50
|
+
* Reads wait for bytes being fetched. They fail if the fetch fails, or once `abort` (may be null;
|
|
51
|
+
* must outlive the source) is raised, so a player can unload without waiting for the network.
|
|
52
|
+
* The reader may be shared, by a probe and then the player.
|
|
53
|
+
*/
|
|
54
|
+
std::unique_ptr<ByteSource> openReader(std::shared_ptr<SourceReader> reader, const AbortFlag* abort);
|
|
55
|
+
|
|
56
|
+
/** A copy of `size` bytes at `data`. */
|
|
57
|
+
std::unique_ptr<ByteSource> openMemory(const uint8_t* data, size_t size);
|
|
58
|
+
|
|
59
|
+
} // namespace webm
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
// URLs and data sources are read through the range-source add-on, by its C table, or without it
|
|
4
|
+
// through the basic input: a download into a temporary file. Both are a SourceReader.
|
|
5
|
+
#define RANGE_SOURCE_CLIENT_NAMESPACE webm_rs
|
|
6
|
+
#include "range_source.h"
|
|
7
|
+
#include "range_source_download.h"
|
|
8
|
+
|
|
9
|
+
#include <atomic>
|
|
10
|
+
#include <cstddef>
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <string>
|
|
13
|
+
|
|
14
|
+
namespace webm {
|
|
15
|
+
|
|
16
|
+
using SourceReader = webm_rs::Reader;
|
|
17
|
+
using SourceInfo = webm_rs::SourceInfo;
|
|
18
|
+
using Upstream = webm_rs::Upstream;
|
|
19
|
+
/** What a read waiting on the network checks to give up; the add-on's C table reads it too. */
|
|
20
|
+
using AbortFlag = std::atomic<int32_t>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* `plugin` if this player can use it: the same ABI, and every function it calls. Otherwise null,
|
|
24
|
+
* with `why` set.
|
|
25
|
+
*/
|
|
26
|
+
inline const RangeSourcePlugin* usablePlugin(const RangeSourcePlugin* plugin, std::string& why) {
|
|
27
|
+
if (!plugin) return nullptr;
|
|
28
|
+
if (plugin->abi != RANGE_SOURCE_ABI) {
|
|
29
|
+
why = "the range-source add-on has ABI " + std::to_string(plugin->abi) + ", and this player needs " +
|
|
30
|
+
std::to_string(RANGE_SOURCE_ABI);
|
|
31
|
+
return nullptr;
|
|
32
|
+
}
|
|
33
|
+
if (plugin->structSize < offsetof(RangeSourcePlugin, releaseReader) + sizeof(plugin->releaseReader)) {
|
|
34
|
+
why = "the range-source add-on is older than this player";
|
|
35
|
+
return nullptr;
|
|
36
|
+
}
|
|
37
|
+
return plugin;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
} // namespace webm
|