react-native-alpha-video 0.0.0-stage → 1.0.1

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.
Files changed (283) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +908 -2
  3. package/THIRD_PARTY_NOTICES.md +30 -0
  4. package/android/av1/build.gradle +67 -0
  5. package/android/av1/consumer-rules.pro +4 -0
  6. package/android/av1/src/main/cpp/Av1Codec_jni.cpp +8 -0
  7. package/android/av1/src/main/cpp/CMakeLists.txt +34 -0
  8. package/android/av1/src/main/java/dev/mediacache/alphavideo/av1/Av1Codec.java +21 -0
  9. package/android/build.gradle +90 -0
  10. package/android/consumer-rules.pro +2 -0
  11. package/android/gradle.properties +1 -0
  12. package/android/publish.gradle +82 -0
  13. package/android/settings.gradle +5 -0
  14. package/android/src/main/AndroidManifest.xml +1 -0
  15. package/android/src/main/cpp/CMakeLists.txt +59 -0
  16. package/android/src/main/java/dev/mediacache/alphavideo/AlphaVideoCodecs.java +73 -0
  17. package/android/src/main/java/dev/mediacache/alphavideo/AlphaVideoView.java +1982 -0
  18. package/android/src/main/java/dev/mediacache/alphavideo/BufferedDualStreamPlayer.java +978 -0
  19. package/android/src/main/java/dev/mediacache/alphavideo/Fetcher.java +37 -0
  20. package/android/src/main/java/dev/mediacache/alphavideo/HttpFetcher.java +156 -0
  21. package/android/src/main/java/dev/mediacache/alphavideo/MediaCodecColor.java +47 -0
  22. package/android/src/main/java/dev/mediacache/alphavideo/MediaCodecDecoders.java +135 -0
  23. package/android/src/main/java/dev/mediacache/alphavideo/RangeSourceLink.java +54 -0
  24. package/android/src/main/java/dev/mediacache/alphavideo/SourceReader.java +174 -0
  25. package/android/src/main/java/dev/mediacache/alphavideo/SurfaceTextureVideoDecoder.java +802 -0
  26. package/android/src/main/java/dev/mediacache/alphavideo/WebMAlphaPlayerNative.java +95 -0
  27. package/android/src/main/java/dev/mediacache/alphavideo/WebMFrame.java +54 -0
  28. package/android/src/main/java/dev/mediacache/alphavideo/WebMSource.java +160 -0
  29. package/android/src/rangesource/java/dev/mediacache/alphavideo/AppDataSource.java +50 -0
  30. package/android/vpx/build.gradle +67 -0
  31. package/android/vpx/consumer-rules.pro +4 -0
  32. package/android/vpx/src/main/cpp/CMakeLists.txt +34 -0
  33. package/android/vpx/src/main/cpp/VpxCodec_jni.cpp +8 -0
  34. package/android/vpx/src/main/java/dev/mediacache/alphavideo/vpx/VpxCodec.java +21 -0
  35. package/codecs/av1/Dav1dDecoderPlugin.cpp +157 -0
  36. package/codecs/av1/Dav1dDecoderPlugin.h +17 -0
  37. package/codecs/vpx/VpxDecoderPlugin.cpp +103 -0
  38. package/codecs/vpx/VpxDecoderPlugin.h +17 -0
  39. package/cpp/AlphaDemuxer.cpp +984 -0
  40. package/cpp/AlphaDemuxer.h +123 -0
  41. package/cpp/AlphaVideoDecoderPlugin.h +84 -0
  42. package/cpp/Av1SequenceHeader.cpp +175 -0
  43. package/cpp/Av1SequenceHeader.h +25 -0
  44. package/cpp/ByteSource.cpp +116 -0
  45. package/cpp/ByteSource.h +59 -0
  46. package/cpp/RangeSourceClient.h +40 -0
  47. package/cpp/VideoDecoder.cpp +157 -0
  48. package/cpp/VideoDecoder.h +83 -0
  49. package/cpp/WebMAlphaPlayer.cpp +1666 -0
  50. package/cpp/WebMAlphaPlayer.h +389 -0
  51. package/cpp/WebMAlphaPlayer_jni.cpp +1380 -0
  52. package/cpp/YuvToRgb.cpp +39 -0
  53. package/cpp/YuvToRgb.h +40 -0
  54. package/ios/Sources/AlphaVideo/AlphaVideoCodecs.mm +63 -0
  55. package/ios/Sources/AlphaVideo/AlphaVideoInternal.h +70 -0
  56. package/ios/Sources/AlphaVideo/AlphaVideoPlayer.mm +994 -0
  57. package/ios/Sources/AlphaVideo/AlphaVideoSource.mm +476 -0
  58. package/ios/Sources/AlphaVideo/AlphaVideoView.mm +374 -0
  59. package/ios/Sources/AlphaVideo/include/AlphaVideo.h +303 -0
  60. package/ios/Sources/AlphaVideoAV1/AlphaVideoAV1Codec.mm +16 -0
  61. package/ios/Sources/AlphaVideoAV1/include/AlphaVideoAV1.h +18 -0
  62. package/ios/Sources/AlphaVideoVPX/AlphaVideoVPXCodec.mm +16 -0
  63. package/ios/Sources/AlphaVideoVPX/include/AlphaVideoVPX.h +17 -0
  64. package/lib/commonjs/AlphaVideoView.js +187 -0
  65. package/lib/commonjs/AlphaVideoView.js.map +1 -0
  66. package/lib/commonjs/AlphaVideoViewNativeComponent.js +47 -0
  67. package/lib/commonjs/AlphaVideoViewNativeComponent.js.map +1 -0
  68. package/lib/commonjs/AlphaVideoViewNativeComponent.web.js +11 -0
  69. package/lib/commonjs/AlphaVideoViewNativeComponent.web.js.map +1 -0
  70. package/lib/commonjs/NativeAlphaVideoModule.js +10 -0
  71. package/lib/commonjs/NativeAlphaVideoModule.js.map +1 -0
  72. package/lib/commonjs/NativeAlphaVideoModule.web.js +9 -0
  73. package/lib/commonjs/NativeAlphaVideoModule.web.js.map +1 -0
  74. package/lib/commonjs/WebPlayer.js +12 -0
  75. package/lib/commonjs/WebPlayer.js.map +1 -0
  76. package/lib/commonjs/WebPlayer.web.js +115 -0
  77. package/lib/commonjs/WebPlayer.web.js.map +1 -0
  78. package/lib/commonjs/index.js +124 -0
  79. package/lib/commonjs/index.js.map +1 -0
  80. package/lib/module/AlphaVideoView.js +187 -0
  81. package/lib/module/AlphaVideoView.js.map +1 -0
  82. package/lib/module/AlphaVideoViewNativeComponent.js +47 -0
  83. package/lib/module/AlphaVideoViewNativeComponent.js.map +1 -0
  84. package/lib/module/AlphaVideoViewNativeComponent.web.js +11 -0
  85. package/lib/module/AlphaVideoViewNativeComponent.web.js.map +1 -0
  86. package/lib/module/NativeAlphaVideoModule.js +10 -0
  87. package/lib/module/NativeAlphaVideoModule.js.map +1 -0
  88. package/lib/module/NativeAlphaVideoModule.web.js +9 -0
  89. package/lib/module/NativeAlphaVideoModule.web.js.map +1 -0
  90. package/lib/module/WebPlayer.js +12 -0
  91. package/lib/module/WebPlayer.js.map +1 -0
  92. package/lib/module/WebPlayer.web.js +115 -0
  93. package/lib/module/WebPlayer.web.js.map +1 -0
  94. package/lib/module/index.js +124 -0
  95. package/lib/module/index.js.map +1 -0
  96. package/lib/typescript/react-native/src/AlphaVideoView.d.ts +189 -0
  97. package/lib/typescript/react-native/src/AlphaVideoView.d.ts.map +1 -0
  98. package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.d.ts +109 -0
  99. package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.d.ts.map +1 -0
  100. package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.web.d.ts +5 -0
  101. package/lib/typescript/react-native/src/AlphaVideoViewNativeComponent.web.d.ts.map +1 -0
  102. package/lib/typescript/react-native/src/NativeAlphaVideoModule.d.ts +21 -0
  103. package/lib/typescript/react-native/src/NativeAlphaVideoModule.d.ts.map +1 -0
  104. package/lib/typescript/react-native/src/NativeAlphaVideoModule.web.d.ts +3 -0
  105. package/lib/typescript/react-native/src/NativeAlphaVideoModule.web.d.ts.map +1 -0
  106. package/lib/typescript/react-native/src/WebPlayer.d.ts +3 -0
  107. package/lib/typescript/react-native/src/WebPlayer.d.ts.map +1 -0
  108. package/lib/typescript/react-native/src/WebPlayer.web.d.ts +9 -0
  109. package/lib/typescript/react-native/src/WebPlayer.web.d.ts.map +1 -0
  110. package/lib/typescript/react-native/src/index.d.ts +77 -0
  111. package/lib/typescript/react-native/src/index.d.ts.map +1 -0
  112. package/licenses/dav1d-COPYING.txt +23 -0
  113. package/licenses/libvpx-LICENSE.txt +31 -0
  114. package/licenses/libvpx-PATENTS.txt +23 -0
  115. package/licenses/libwebm-LICENSE.txt +30 -0
  116. package/licenses/libwebm-PATENTS.txt +23 -0
  117. package/package.json +152 -4
  118. package/prebuilt/android/arm64-v8a/lib/libdav1d.a +0 -0
  119. package/prebuilt/android/arm64-v8a/lib/libvpx.a +0 -0
  120. package/prebuilt/android/armeabi-v7a/lib/libdav1d.a +0 -0
  121. package/prebuilt/android/armeabi-v7a/lib/libvpx.a +0 -0
  122. package/prebuilt/android/x86_64/lib/libdav1d.a +0 -0
  123. package/prebuilt/android/x86_64/lib/libvpx.a +0 -0
  124. package/prebuilt/include/dav1d/common.h +94 -0
  125. package/prebuilt/include/dav1d/data.h +117 -0
  126. package/prebuilt/include/dav1d/dav1d.h +329 -0
  127. package/prebuilt/include/dav1d/headers.h +440 -0
  128. package/prebuilt/include/dav1d/picture.h +157 -0
  129. package/prebuilt/include/dav1d/version.h +50 -0
  130. package/prebuilt/include/vpx/vp8.h +136 -0
  131. package/prebuilt/include/vpx/vp8dx.h +228 -0
  132. package/prebuilt/include/vpx/vpx_codec.h +475 -0
  133. package/prebuilt/include/vpx/vpx_decoder.h +365 -0
  134. package/prebuilt/include/vpx/vpx_frame_buffer.h +83 -0
  135. package/prebuilt/include/vpx/vpx_image.h +209 -0
  136. package/prebuilt/include/vpx/vpx_integer.h +40 -0
  137. package/prebuilt/ios/lib/libdav1d.a +0 -0
  138. package/prebuilt/ios/lib/libvpx.a +0 -0
  139. package/prebuilt/ios-simulator/include/dav1d/common.h +94 -0
  140. package/prebuilt/ios-simulator/include/dav1d/data.h +117 -0
  141. package/prebuilt/ios-simulator/include/dav1d/dav1d.h +329 -0
  142. package/prebuilt/ios-simulator/include/dav1d/headers.h +440 -0
  143. package/prebuilt/ios-simulator/include/dav1d/picture.h +157 -0
  144. package/prebuilt/ios-simulator/include/dav1d/version.h +50 -0
  145. package/prebuilt/ios-simulator/include/vpx/vp8.h +136 -0
  146. package/prebuilt/ios-simulator/include/vpx/vp8dx.h +228 -0
  147. package/prebuilt/ios-simulator/include/vpx/vpx_codec.h +475 -0
  148. package/prebuilt/ios-simulator/include/vpx/vpx_decoder.h +365 -0
  149. package/prebuilt/ios-simulator/include/vpx/vpx_frame_buffer.h +83 -0
  150. package/prebuilt/ios-simulator/include/vpx/vpx_image.h +209 -0
  151. package/prebuilt/ios-simulator/include/vpx/vpx_integer.h +40 -0
  152. package/prebuilt/ios-simulator/lib/libdav1d.a +0 -0
  153. package/prebuilt/ios-simulator/lib/libvpx.a +0 -0
  154. package/react-native/android/CMakeLists.txt +14 -0
  155. package/react-native/android/build.gradle +113 -0
  156. package/react-native/android/src/main/AndroidManifest.xml +1 -0
  157. package/react-native/android/src/main/java/dev/mediacache/alphavideo/reactnative/AlphaVideoModule.java +102 -0
  158. package/react-native/android/src/main/java/dev/mediacache/alphavideo/reactnative/AlphaVideoPackage.java +50 -0
  159. package/react-native/android/src/main/java/dev/mediacache/alphavideo/reactnative/AlphaVideoViewManager.java +317 -0
  160. package/react-native/android/src/newarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoModuleSpec.java +10 -0
  161. package/react-native/android/src/newarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoViewManagerSpec.java +23 -0
  162. package/react-native/android/src/norangesource/java/dev/mediacache/alphavideo/AppDataSource.java +15 -0
  163. package/react-native/android/src/oldarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoModuleSpec.java +30 -0
  164. package/react-native/android/src/oldarch/java/dev/mediacache/alphavideo/reactnative/AlphaVideoViewManagerSpec.java +61 -0
  165. package/react-native/ios/RNAlphaVideoViewComponentView.mm +173 -0
  166. package/react-native/ios/RNAlphaVideoViewManager.mm +147 -0
  167. package/react-native/src/AlphaVideoView.tsx +329 -0
  168. package/react-native/src/AlphaVideoViewNativeComponent.ts +132 -0
  169. package/react-native/src/AlphaVideoViewNativeComponent.web.ts +5 -0
  170. package/react-native/src/NativeAlphaVideoModule.ts +22 -0
  171. package/react-native/src/NativeAlphaVideoModule.web.ts +2 -0
  172. package/react-native/src/WebPlayer.tsx +7 -0
  173. package/react-native/src/WebPlayer.web.tsx +87 -0
  174. package/react-native/src/index.tsx +144 -0
  175. package/react-native-alpha-video.podspec +99 -0
  176. package/react-native.config.js +12 -0
  177. package/scripts/build_codecs_android.sh +246 -0
  178. package/scripts/build_codecs_ios.sh +31 -0
  179. package/scripts/build_codecs_ios_device.sh +210 -0
  180. package/scripts/build_codecs_ios_simulator.sh +256 -0
  181. package/scripts/build_wasm.sh +230 -0
  182. package/scripts/build_xcframework.sh +49 -0
  183. package/scripts/fetch-prebuilt.sh +48 -0
  184. package/scripts/package_release.sh +107 -0
  185. package/scripts/publish-android.sh +85 -0
  186. package/scripts/vendor_range_source.sh +47 -0
  187. package/third_party/libwebm/AUTHORS.TXT +5 -0
  188. package/third_party/libwebm/LICENSE.TXT +30 -0
  189. package/third_party/libwebm/PATENTS.TXT +23 -0
  190. package/third_party/libwebm/README.md +7 -0
  191. package/third_party/libwebm/webm_parser/include/webm/buffer_reader.h +138 -0
  192. package/third_party/libwebm/webm_parser/include/webm/callback.h +363 -0
  193. package/third_party/libwebm/webm_parser/include/webm/dom_types.h +1781 -0
  194. package/third_party/libwebm/webm_parser/include/webm/element.h +208 -0
  195. package/third_party/libwebm/webm_parser/include/webm/file_reader.h +103 -0
  196. package/third_party/libwebm/webm_parser/include/webm/id.h +1085 -0
  197. package/third_party/libwebm/webm_parser/include/webm/istream_reader.h +99 -0
  198. package/third_party/libwebm/webm_parser/include/webm/reader.h +94 -0
  199. package/third_party/libwebm/webm_parser/include/webm/status.h +166 -0
  200. package/third_party/libwebm/webm_parser/include/webm/webm_parser.h +133 -0
  201. package/third_party/libwebm/webm_parser/src/ancestory.cc +334 -0
  202. package/third_party/libwebm/webm_parser/src/ancestory.h +83 -0
  203. package/third_party/libwebm/webm_parser/src/audio_parser.h +84 -0
  204. package/third_party/libwebm/webm_parser/src/bit_utils.cc +26 -0
  205. package/third_party/libwebm/webm_parser/src/bit_utils.h +24 -0
  206. package/third_party/libwebm/webm_parser/src/block_additions_parser.h +30 -0
  207. package/third_party/libwebm/webm_parser/src/block_group_parser.h +71 -0
  208. package/third_party/libwebm/webm_parser/src/block_header_parser.cc +76 -0
  209. package/third_party/libwebm/webm_parser/src/block_header_parser.h +65 -0
  210. package/third_party/libwebm/webm_parser/src/block_more_parser.h +32 -0
  211. package/third_party/libwebm/webm_parser/src/block_parser.cc +285 -0
  212. package/third_party/libwebm/webm_parser/src/block_parser.h +126 -0
  213. package/third_party/libwebm/webm_parser/src/bool_parser.h +95 -0
  214. package/third_party/libwebm/webm_parser/src/buffer_reader.cc +110 -0
  215. package/third_party/libwebm/webm_parser/src/byte_parser.h +144 -0
  216. package/third_party/libwebm/webm_parser/src/callback.cc +155 -0
  217. package/third_party/libwebm/webm_parser/src/chapter_atom_parser.h +42 -0
  218. package/third_party/libwebm/webm_parser/src/chapter_display_parser.h +34 -0
  219. package/third_party/libwebm/webm_parser/src/chapters_parser.h +28 -0
  220. package/third_party/libwebm/webm_parser/src/cluster_parser.h +48 -0
  221. package/third_party/libwebm/webm_parser/src/colour_parser.h +55 -0
  222. package/third_party/libwebm/webm_parser/src/content_enc_aes_settings_parser.h +32 -0
  223. package/third_party/libwebm/webm_parser/src/content_encoding_parser.h +38 -0
  224. package/third_party/libwebm/webm_parser/src/content_encodings_parser.h +30 -0
  225. package/third_party/libwebm/webm_parser/src/content_encryption_parser.h +37 -0
  226. package/third_party/libwebm/webm_parser/src/cue_point_parser.h +38 -0
  227. package/third_party/libwebm/webm_parser/src/cue_track_positions_parser.h +39 -0
  228. package/third_party/libwebm/webm_parser/src/cues_parser.h +27 -0
  229. package/third_party/libwebm/webm_parser/src/date_parser.cc +72 -0
  230. package/third_party/libwebm/webm_parser/src/date_parser.h +64 -0
  231. package/third_party/libwebm/webm_parser/src/ebml_parser.h +48 -0
  232. package/third_party/libwebm/webm_parser/src/edition_entry_parser.h +35 -0
  233. package/third_party/libwebm/webm_parser/src/element_parser.h +102 -0
  234. package/third_party/libwebm/webm_parser/src/file_reader.cc +142 -0
  235. package/third_party/libwebm/webm_parser/src/float_parser.cc +77 -0
  236. package/third_party/libwebm/webm_parser/src/float_parser.h +65 -0
  237. package/third_party/libwebm/webm_parser/src/id_element_parser.cc +49 -0
  238. package/third_party/libwebm/webm_parser/src/id_element_parser.h +56 -0
  239. package/third_party/libwebm/webm_parser/src/id_parser.cc +75 -0
  240. package/third_party/libwebm/webm_parser/src/id_parser.h +45 -0
  241. package/third_party/libwebm/webm_parser/src/info_parser.h +44 -0
  242. package/third_party/libwebm/webm_parser/src/int_parser.h +121 -0
  243. package/third_party/libwebm/webm_parser/src/istream_reader.cc +133 -0
  244. package/third_party/libwebm/webm_parser/src/master_parser.cc +298 -0
  245. package/third_party/libwebm/webm_parser/src/master_parser.h +230 -0
  246. package/third_party/libwebm/webm_parser/src/master_value_parser.h +533 -0
  247. package/third_party/libwebm/webm_parser/src/mastering_metadata_parser.h +57 -0
  248. package/third_party/libwebm/webm_parser/src/parser.h +34 -0
  249. package/third_party/libwebm/webm_parser/src/parser_utils.cc +34 -0
  250. package/third_party/libwebm/webm_parser/src/parser_utils.h +64 -0
  251. package/third_party/libwebm/webm_parser/src/projection_parser.h +40 -0
  252. package/third_party/libwebm/webm_parser/src/recursive_parser.h +93 -0
  253. package/third_party/libwebm/webm_parser/src/seek_head_parser.h +27 -0
  254. package/third_party/libwebm/webm_parser/src/seek_parser.h +37 -0
  255. package/third_party/libwebm/webm_parser/src/segment_parser.cc +86 -0
  256. package/third_party/libwebm/webm_parser/src/segment_parser.h +53 -0
  257. package/third_party/libwebm/webm_parser/src/simple_tag_parser.h +37 -0
  258. package/third_party/libwebm/webm_parser/src/size_parser.cc +56 -0
  259. package/third_party/libwebm/webm_parser/src/size_parser.h +43 -0
  260. package/third_party/libwebm/webm_parser/src/skip_callback.h +63 -0
  261. package/third_party/libwebm/webm_parser/src/skip_parser.cc +59 -0
  262. package/third_party/libwebm/webm_parser/src/skip_parser.h +35 -0
  263. package/third_party/libwebm/webm_parser/src/slices_parser.h +30 -0
  264. package/third_party/libwebm/webm_parser/src/tag_parser.h +37 -0
  265. package/third_party/libwebm/webm_parser/src/tags_parser.h +27 -0
  266. package/third_party/libwebm/webm_parser/src/targets_parser.h +35 -0
  267. package/third_party/libwebm/webm_parser/src/time_slice_parser.h +30 -0
  268. package/third_party/libwebm/webm_parser/src/track_entry_parser.h +65 -0
  269. package/third_party/libwebm/webm_parser/src/tracks_parser.h +27 -0
  270. package/third_party/libwebm/webm_parser/src/unknown_parser.cc +49 -0
  271. package/third_party/libwebm/webm_parser/src/unknown_parser.h +38 -0
  272. package/third_party/libwebm/webm_parser/src/var_int_parser.cc +71 -0
  273. package/third_party/libwebm/webm_parser/src/var_int_parser.h +56 -0
  274. package/third_party/libwebm/webm_parser/src/video_parser.h +122 -0
  275. package/third_party/libwebm/webm_parser/src/virtual_block_parser.cc +72 -0
  276. package/third_party/libwebm/webm_parser/src/virtual_block_parser.h +69 -0
  277. package/third_party/libwebm/webm_parser/src/void_parser.cc +49 -0
  278. package/third_party/libwebm/webm_parser/src/void_parser.h +41 -0
  279. package/third_party/libwebm/webm_parser/src/webm_parser.cc +282 -0
  280. package/third_party/range-source/LICENSE +21 -0
  281. package/third_party/range-source/README.md +8 -0
  282. package/third_party/range-source/include/range_source.h +395 -0
  283. package/third_party/range-source/include/range_source_download.h +309 -0
@@ -0,0 +1,95 @@
1
+ package dev.mediacache.alphavideo;
2
+
3
+ import java.nio.ByteBuffer;
4
+
5
+ /**
6
+ * JNI bridge to C++ WebMAlphaPlayer core
7
+ * Provides high-performance VP9+Alpha WebM playback
8
+ */
9
+ public class WebMAlphaPlayerNative {
10
+
11
+ static {
12
+ System.loadLibrary("alphavideo");
13
+ AlphaVideoCodecs.discover();
14
+ }
15
+
16
+ /**
17
+ * Listener for player events
18
+ */
19
+ public interface PlayerListener {
20
+ void onLoad(int totalFrames, int width, int height);
21
+ void onFrame(int frameIndex, ByteBuffer yPlane, ByteBuffer uPlane, ByteBuffer vPlane, ByteBuffer aPlane, int width, int height);
22
+ void onPlay();
23
+ void onPause();
24
+ void onStop();
25
+ void onLoop();
26
+ void onEnd();
27
+ /** @param code {@link AlphaVideoView#ERROR_NO_DECODER}, or null */
28
+ void onError(String error, String code);
29
+ void onPreloadComplete(int totalFrames, double timeMs);
30
+ }
31
+
32
+ // Player lifecycle
33
+ public static native long nativeCreate(
34
+ int decodeThreads,
35
+ int cacheSize,
36
+ boolean preloadAllFrames,
37
+ boolean loopPlayback,
38
+ double playbackSpeed,
39
+ String mode, // Playback mode: "preload", "stream", or "streamAndPreload"
40
+ int streamPrefetchAhead // Frames decoded ahead of the shown one (default: 8)
41
+ );
42
+
43
+ public static native void nativeDestroy(long playerId);
44
+
45
+ // Callbacks
46
+ public static native void nativeSetListener(long playerId, PlayerListener listener);
47
+
48
+ // Loading
49
+ public static native boolean nativeLoadFromFile(long playerId, String path);
50
+ /** Bytes [offset, offset + length) of fd; length -1 means to end of file. fd is duplicated. */
51
+ public static native boolean nativeLoadFromFd(long playerId, int fd, long offset, long length);
52
+ /** A {@link SourceReader} reference; the player takes a reference of its own. */
53
+ static native boolean nativeLoadFromReader(long playerId, long reader);
54
+ public static native boolean nativeLoadFromBytes(long playerId, byte[] data);
55
+ public static native void nativeUnload(long playerId);
56
+
57
+ // Playback control
58
+ public static native void nativePlay(long playerId);
59
+ public static native void nativePause(long playerId);
60
+ public static native void nativeStop(long playerId);
61
+ public static native void nativeSeekToFrame(long playerId, int frameIndex);
62
+
63
+ /**
64
+ * Changes playback rate without moving the playhead. Safe mid-playback.
65
+ */
66
+ public static native void nativeSetPlaybackSpeed(long playerId, double speed);
67
+ public static native void nativeSetVerbose(long playerId, boolean verbose);
68
+ public static native void nativeSeekToTime(long playerId, double seconds);
69
+
70
+ // State queries
71
+ public static native boolean nativeIsLoaded(long playerId);
72
+ public static native boolean nativeIsPlaying(long playerId);
73
+ public static native int nativeGetCurrentFrame(long playerId);
74
+ public static native int nativeGetTotalFrames(long playerId);
75
+ public static native int nativeGetWidth(long playerId);
76
+ public static native int nativeGetHeight(long playerId);
77
+ public static native double nativeGetDuration(long playerId);
78
+ public static native double nativeGetFrameRate(long playerId);
79
+ /** The loaded clip's YUV to RGB for the shader: a column-major mat4, or null if no player. */
80
+ public static native float[] nativeGetYuvToRgb(long playerId);
81
+ /** The decoder for the loaded clip, "libvpx" or "dav1d", or null if no player. */
82
+ public static native String nativeGetDecoderName(long playerId);
83
+ /** The same matrix for a stream's colour range and matrix (YuvToRgb.h), by the core's rules. */
84
+ public static native float[] nativeYuvToRgbFor(int colorRange, int colorSpace, int width, int height);
85
+
86
+ // Direct frame access
87
+ public static native WebMFrame nativeGetFrame(long playerId, int frameIndex);
88
+
89
+ // Statistics
90
+ public static native long[] nativeGetStats(long playerId);
91
+ public static native void nativeResetStats(long playerId);
92
+
93
+ /** The registered software decoders, e.g. "libvpx v1.14.0, dav1d 1.5.1"; empty with none. */
94
+ public static native String nativeGetLibraryVersions();
95
+ }
@@ -0,0 +1,54 @@
1
+ package dev.mediacache.alphavideo;
2
+
3
+ import java.nio.ByteBuffer;
4
+
5
+ /**
6
+ * Represents a decoded YUVA frame from the C++ player
7
+ * Uses direct ByteBuffers for zero-copy access to plane data
8
+ */
9
+ public class WebMFrame {
10
+
11
+ private final ByteBuffer yPlane;
12
+ private final ByteBuffer uPlane;
13
+ private final ByteBuffer vPlane;
14
+ private final ByteBuffer aPlane;
15
+ private final int width;
16
+ private final int height;
17
+ private final int frameIndex;
18
+ private final double timestamp;
19
+
20
+ public WebMFrame(
21
+ ByteBuffer yPlane,
22
+ ByteBuffer uPlane,
23
+ ByteBuffer vPlane,
24
+ ByteBuffer aPlane,
25
+ int width,
26
+ int height,
27
+ int frameIndex,
28
+ double timestamp
29
+ ) {
30
+ this.yPlane = yPlane;
31
+ this.uPlane = uPlane;
32
+ this.vPlane = vPlane;
33
+ this.aPlane = aPlane;
34
+ this.width = width;
35
+ this.height = height;
36
+ this.frameIndex = frameIndex;
37
+ this.timestamp = timestamp;
38
+ }
39
+
40
+ public ByteBuffer getYPlane() { return yPlane; }
41
+ public ByteBuffer getUPlane() { return uPlane; }
42
+ public ByteBuffer getVPlane() { return vPlane; }
43
+ public ByteBuffer getAPlane() { return aPlane; }
44
+
45
+ public int getWidth() { return width; }
46
+ public int getHeight() { return height; }
47
+ public int getFrameIndex() { return frameIndex; }
48
+ public double getTimestamp() { return timestamp; }
49
+
50
+ // Convenience getters for plane sizes
51
+ public int getYSize() { return width * height; }
52
+ public int getUVSize() { return ((width + 1) / 2) * ((height + 1) / 2); }
53
+ public int getASize() { return width * height; }
54
+ }
@@ -0,0 +1,160 @@
1
+ package dev.mediacache.alphavideo;
2
+
3
+ import android.content.Context;
4
+ import android.content.res.AssetFileDescriptor;
5
+ import android.content.res.Resources;
6
+ import android.net.Uri;
7
+ import android.os.ParcelFileDescriptor;
8
+
9
+ import java.io.File;
10
+ import java.io.FileNotFoundException;
11
+ import java.io.IOException;
12
+ import java.util.regex.Pattern;
13
+
14
+ /**
15
+ * A local video the player can read in place: a file, an APK asset, a raw resource, or a
16
+ * content:// URI.
17
+ *
18
+ * Every local kind opens as an {@link AssetFileDescriptor} (descriptor + byte range), which
19
+ * native code reads directly, so nothing is copied out first. A URL or an app's data source is read
20
+ * through a {@link SourceReader} instead, by range as it plays.
21
+ */
22
+ final class WebMSource {
23
+
24
+ private enum Kind { FILE, ASSET, RAW, CONTENT, READER }
25
+
26
+ private static final String ASSET_SCHEME = "asset://";
27
+ // What Image.resolveAssetSource(require(...)) gives in a release build: a res/raw name
28
+ private static final Pattern RAW_RESOURCE_NAME = Pattern.compile("[A-Za-z_][A-Za-z0-9_]*");
29
+
30
+ private final Kind kind;
31
+ private final String location;
32
+ // READER only
33
+ private final SourceReader reader;
34
+
35
+ private WebMSource(Kind kind, String location) {
36
+ this(kind, location, null);
37
+ }
38
+
39
+ private WebMSource(Kind kind, String location, SourceReader reader) {
40
+ this.kind = kind;
41
+ this.location = location;
42
+ this.reader = reader;
43
+ }
44
+
45
+ static WebMSource file(String path) {
46
+ return new WebMSource(Kind.FILE, path);
47
+ }
48
+
49
+ /** {@code uri} read through {@code reader}. */
50
+ static WebMSource reader(String uri, SourceReader reader) {
51
+ return new WebMSource(Kind.READER, uri, reader);
52
+ }
53
+
54
+ /** Null unless this is read through a reader, not {@link #open}. */
55
+ SourceReader reader() {
56
+ return reader;
57
+ }
58
+
59
+ /**
60
+ * Parses {@code file:///abs/path}, {@code /abs/path}, {@code asset://relative/path},
61
+ * {@code content://...}, or a bare res/raw resource name.
62
+ *
63
+ * @throws IllegalArgumentException for anything else
64
+ */
65
+ static WebMSource parse(String uri) {
66
+ if (uri.startsWith(ASSET_SCHEME)) {
67
+ String path = Uri.decode(uri.substring(ASSET_SCHEME.length()));
68
+ while (path.startsWith("/")) path = path.substring(1);
69
+ if (path.isEmpty()) throw new IllegalArgumentException("Empty asset path: " + uri);
70
+ return new WebMSource(Kind.ASSET, path);
71
+ }
72
+ if (uri.startsWith("content://")) {
73
+ return new WebMSource(Kind.CONTENT, uri);
74
+ }
75
+ if (uri.startsWith("file://")) {
76
+ String path = Uri.parse(uri).getPath();
77
+ if (path == null || path.isEmpty()) throw new IllegalArgumentException("Bad file URI: " + uri);
78
+ return file(path);
79
+ }
80
+ if (uri.startsWith("/")) {
81
+ return file(uri);
82
+ }
83
+ if (RAW_RESOURCE_NAME.matcher(uri).matches()) {
84
+ return new WebMSource(Kind.RAW, uri);
85
+ }
86
+ throw new IllegalArgumentException(
87
+ "Unsupported source '" + uri + "'. Use https://, file://, an absolute path, asset:// or content://");
88
+ }
89
+
90
+ /** The caller closes the descriptor; native code duplicates it if it needs to keep reading. */
91
+ AssetFileDescriptor open(Context context) throws IOException {
92
+ switch (kind) {
93
+ case ASSET:
94
+ return openAsset(context);
95
+ case RAW:
96
+ return openRawResource(context);
97
+ case READER:
98
+ throw new IllegalStateException(location + " is read through its SourceReader");
99
+ case CONTENT: {
100
+ AssetFileDescriptor afd = context.getContentResolver()
101
+ .openAssetFileDescriptor(Uri.parse(location), "r");
102
+ if (afd == null) throw new FileNotFoundException("Cannot open " + location);
103
+ return afd;
104
+ }
105
+ default: {
106
+ ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
107
+ new File(location), ParcelFileDescriptor.MODE_READ_ONLY);
108
+ return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH);
109
+ }
110
+ }
111
+ }
112
+
113
+ private AssetFileDescriptor openAsset(Context context) throws IOException {
114
+ try {
115
+ return context.getAssets().openFd(location);
116
+ } catch (FileNotFoundException e) {
117
+ if (!assetExists(context)) throw new FileNotFoundException("Asset not found: " + location);
118
+ // openFd only works on assets stored uncompressed in the APK.
119
+ throw new IOException("Asset " + location + " is compressed in the APK; add its extension to "
120
+ + "android.androidResources.noCompress in the app's build.gradle");
121
+ }
122
+ }
123
+
124
+ private AssetFileDescriptor openRawResource(Context context) throws IOException {
125
+ Resources resources = context.getResources();
126
+ int id = resources.getIdentifier(location, "raw", context.getPackageName());
127
+ if (id == 0) throw new FileNotFoundException("No res/raw resource named " + location);
128
+ try {
129
+ return resources.openRawResourceFd(id);
130
+ } catch (Resources.NotFoundException e) {
131
+ // openRawResourceFd only works on resources stored uncompressed in the APK.
132
+ throw new IOException("Resource res/raw/" + location + " is compressed in the APK; add its "
133
+ + "extension to android.androidResources.noCompress in the app's build.gradle");
134
+ }
135
+ }
136
+
137
+ private boolean assetExists(Context context) {
138
+ int slash = location.lastIndexOf('/');
139
+ String dir = slash < 0 ? "" : location.substring(0, slash);
140
+ String name = location.substring(slash + 1);
141
+ try {
142
+ String[] names = context.getAssets().list(dir);
143
+ if (names == null) return false;
144
+ for (String n : names) {
145
+ if (n.equals(name)) return true;
146
+ }
147
+ } catch (IOException ignored) {
148
+ }
149
+ return false;
150
+ }
151
+
152
+ @Override
153
+ public String toString() {
154
+ switch (kind) {
155
+ case ASSET: return ASSET_SCHEME + location;
156
+ case RAW: return "res/raw/" + location;
157
+ default: return location;
158
+ }
159
+ }
160
+ }
@@ -0,0 +1,50 @@
1
+ package dev.mediacache.alphavideo;
2
+
3
+ import android.net.Uri;
4
+
5
+ import java.io.IOException;
6
+ import java.util.Map;
7
+
8
+ import dev.mediacache.rangesource.RangeDataSource;
9
+ import dev.mediacache.rangesource.RangeDataSources;
10
+
11
+ /**
12
+ * An app's data source, registered with range-source's {@code RangeDataSources}, as a
13
+ * {@link Fetcher}. The only class that touches the add-on's types: load it only once
14
+ * {@link RangeSourceLink#available()}, as an app may leave the add-on out.
15
+ */
16
+ final class AppDataSource implements Fetcher {
17
+
18
+ private final RangeDataSource source;
19
+
20
+ private AppDataSource(RangeDataSource source) {
21
+ this.source = source;
22
+ }
23
+
24
+ /** A new source from the factory registered under {@code name}, or null if there's none. */
25
+ static Fetcher create(String name) {
26
+ RangeDataSource.Factory factory = RangeDataSources.get(name);
27
+ return factory != null ? new AppDataSource(factory.create()) : null;
28
+ }
29
+
30
+ @Override
31
+ public Info open(Uri uri, long position, Map<String, String> headers) throws IOException {
32
+ RangeDataSource.Info info = source.open(uri, position, headers);
33
+ return new Info(info.size, info.etag, info.lastModified);
34
+ }
35
+
36
+ @Override
37
+ public int read(byte[] buffer, int offset, int length) throws IOException {
38
+ return source.read(buffer, offset, length);
39
+ }
40
+
41
+ @Override
42
+ public void close() throws IOException {
43
+ source.close();
44
+ }
45
+
46
+ @Override
47
+ public void cancel() {
48
+ source.cancel();
49
+ }
50
+ }
@@ -0,0 +1,67 @@
1
+ // dev.mediacache:alpha-video-vpx: libvpx, VP8 and VP9 in software for alpha-video's C++ core. alpha-video
2
+ // finds it on the classpath (AlphaVideoCodecs), so adding the dependency is all an app does.
3
+
4
+ apply plugin: 'com.android.library'
5
+
6
+ def safeExtGet(name, fallback) {
7
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : fallback
8
+ }
9
+
10
+ group = 'dev.mediacache'
11
+ version = rootProject.version
12
+
13
+ android {
14
+ namespace 'dev.mediacache.alphavideo.vpx'
15
+ compileSdk safeExtGet('compileSdkVersion', 36)
16
+ ndkVersion safeExtGet('ndkVersion', '27.1.12297006')
17
+
18
+ defaultConfig {
19
+ minSdk safeExtGet('minSdkVersion', 24)
20
+ consumerProguardFiles 'consumer-rules.pro'
21
+
22
+ externalNativeBuild {
23
+ cmake {
24
+ cppFlags '-std=c++17 -O3'
25
+ abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
26
+ // Its own C++ runtime: the core talks to it through C, and a second
27
+ // libc++_shared.so beside the core's would clash in the app
28
+ arguments '-DANDROID_STL=c++_static'
29
+ }
30
+ }
31
+ }
32
+
33
+ externalNativeBuild {
34
+ cmake {
35
+ path 'src/main/cpp/CMakeLists.txt'
36
+ version '3.22.1'
37
+ }
38
+ }
39
+
40
+ compileOptions {
41
+ sourceCompatibility JavaVersion.VERSION_17
42
+ targetCompatibility JavaVersion.VERSION_17
43
+ }
44
+
45
+ publishing {
46
+ singleVariant('release') {
47
+ withSourcesJar()
48
+ withJavadocJar()
49
+ }
50
+ }
51
+ }
52
+
53
+ repositories {
54
+ google()
55
+ mavenCentral()
56
+ }
57
+
58
+ dependencies {
59
+ api rootProject
60
+ }
61
+
62
+ ext.publishArtifactId = 'alpha-video-vpx'
63
+ ext.publishDescription = 'libvpx for alpha-video: VP8 and VP9 transparent video in software, for files and devices MediaCodec can\'t take, preload, and many players at once.'
64
+ ext.publishLicenses = [
65
+ [name: 'BSD-3-Clause (bundled libvpx)', url: 'https://chromium.googlesource.com/webm/libvpx/+/refs/tags/v1.14.0/LICENSE'],
66
+ ]
67
+ apply from: rootProject.file('publish.gradle')
@@ -0,0 +1,4 @@
1
+ # alpha-video finds the module by name (AlphaVideoCodecs)
2
+ -keep class dev.mediacache.alphavideo.vpx.VpxCodec {
3
+ public static long pluginList();
4
+ }
@@ -0,0 +1,34 @@
1
+ # libalphavideo_vpx.so: libvpx and its decoder plugin. It doesn't link the core: VpxCodec hands the
2
+ # core the plugin list's address (AlphaVideoCodecs.java).
3
+ cmake_minimum_required(VERSION 3.22.1)
4
+ project(alphavideo_vpx)
5
+
6
+ set(CMAKE_CXX_STANDARD 17)
7
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
8
+
9
+ get_filename_component(MODULE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../../.." ABSOLUTE)
10
+ # libvpx, prebuilt per ABI (scripts/build_codecs_android.sh)
11
+ set(CODECS_ROOT "${MODULE_ROOT}/prebuilt/android/${ANDROID_ABI}")
12
+
13
+ add_library(alphavideo_vpx SHARED
14
+ ${MODULE_ROOT}/codecs/vpx/VpxDecoderPlugin.cpp
15
+ VpxCodec_jni.cpp
16
+ )
17
+ target_include_directories(alphavideo_vpx PRIVATE
18
+ ${MODULE_ROOT}/cpp
19
+ ${MODULE_ROOT}/codecs/vpx
20
+ ${MODULE_ROOT}/prebuilt/include
21
+ )
22
+
23
+ # Google Play requires 16 KB-aligned segments for Android 15+; NDK r27 and older link 4 KB by default.
24
+ target_link_options(alphavideo_vpx PRIVATE "-Wl,-z,max-page-size=16384")
25
+ # libvpx stays private to this library, so an app that ships its own copy (ffmpeg-kit's
26
+ # libavcodec.so links it) can't interpose on it, or it on the app's.
27
+ target_link_options(alphavideo_vpx PRIVATE "-Wl,--exclude-libs,ALL")
28
+
29
+ target_link_libraries(alphavideo_vpx ${CODECS_ROOT}/lib/libvpx.a m)
30
+
31
+ set_target_properties(alphavideo_vpx PROPERTIES
32
+ CXX_VISIBILITY_PRESET hidden
33
+ C_VISIBILITY_PRESET hidden
34
+ )
@@ -0,0 +1,8 @@
1
+ #include <jni.h>
2
+
3
+ #include "VpxDecoderPlugin.h"
4
+
5
+ extern "C" JNIEXPORT jlong JNICALL
6
+ Java_dev_mediacache_alphavideo_vpx_VpxCodec_nativePluginList(JNIEnv*, jclass) {
7
+ return reinterpret_cast<jlong>(&alpha_video_vpx_plugins);
8
+ }
@@ -0,0 +1,21 @@
1
+ package dev.mediacache.alphavideo.vpx;
2
+
3
+ /**
4
+ * The vpx codec module: libvpx's VP8 and VP9 decoders for alpha-video's C++ core. alpha-video finds this
5
+ * class on the classpath and registers it (dev.mediacache.alphavideo.AlphaVideoCodecs); apps don't
6
+ * call it.
7
+ */
8
+ public final class VpxCodec {
9
+ static {
10
+ System.loadLibrary("alphavideo_vpx");
11
+ }
12
+
13
+ private VpxCodec() {}
14
+
15
+ /** The address of the module's native AlphaVideoDecoderPluginList. */
16
+ public static long pluginList() {
17
+ return nativePluginList();
18
+ }
19
+
20
+ private static native long nativePluginList();
21
+ }
@@ -0,0 +1,157 @@
1
+ #include "Dav1dDecoderPlugin.h"
2
+
3
+ #include <dav1d/dav1d.h>
4
+
5
+ #include <algorithm>
6
+ #include <cerrno>
7
+ #include <cstdio>
8
+ #include <cstring>
9
+ #include <new>
10
+
11
+ #if defined(__aarch64__) && defined(__linux__)
12
+ #include <asm/hwcap.h>
13
+ #include <sys/auxv.h>
14
+
15
+ #include <mutex>
16
+
17
+ // Exported by libdav1d (src/cpu.h), but not in its public headers
18
+ extern "C" void dav1d_set_cpu_flags_mask(unsigned mask);
19
+ #endif
20
+
21
+ namespace {
22
+
23
+ // dav1d takes SVE2 from HWCAP2 alone. Android's emulator on Apple M4 reports SVE2 without SVE and
24
+ // traps SVE instructions, so 10-bit AV1 crashed there; real SVE2 CPUs always have SVE.
25
+ void maskUnusableCpuFlags() {
26
+ #if defined(__aarch64__) && defined(__linux__)
27
+ static std::once_flag once;
28
+ std::call_once(once, [] {
29
+ if ((getauxval(AT_HWCAP2) & HWCAP2_SVE2) && !(getauxval(AT_HWCAP) & HWCAP_SVE)) {
30
+ constexpr unsigned kDav1dArmSve = 1u << 3, kDav1dArmSve2 = 1u << 4; // src/arm/cpu.h
31
+ dav1d_set_cpu_flags_mask(~(kDav1dArmSve | kDav1dArmSve2));
32
+ }
33
+ });
34
+ #endif
35
+ }
36
+
37
+ // Driven as FFmpeg's libdav1d wrapper drives it. dav1d_get_picture with no new data since the
38
+ // last call drains frames held by frame threads, so it's only called right after sending data,
39
+ // or when draining.
40
+ struct Dav1dDecoder {
41
+ Dav1dContext* ctx = nullptr;
42
+ Dav1dData data = {};
43
+ Dav1dPicture picture = {};
44
+ bool draining = false;
45
+ };
46
+
47
+ int supportsStream(const AlphaVideoStreamInfo* stream) {
48
+ return stream->codec == ALPHA_VIDEO_CODEC_AV1;
49
+ }
50
+
51
+ void* openDecoder(const AlphaVideoStreamInfo*, int threads, char* error, size_t errorSize) {
52
+ maskUnusableCpuFlags();
53
+ auto* decoder = new (std::nothrow) Dav1dDecoder();
54
+ if (!decoder) {
55
+ std::snprintf(error, errorSize, "dav1d: out of memory");
56
+ return nullptr;
57
+ }
58
+ Dav1dSettings settings;
59
+ dav1d_default_settings(&settings);
60
+ settings.n_threads = std::max(threads, 0);
61
+ settings.max_frame_delay = 0; // dav1d's choice for the thread count
62
+ settings.all_layers = 0; // Only the highest spatial layer
63
+ if (dav1d_open(&decoder->ctx, &settings) < 0) {
64
+ std::snprintf(error, errorSize, "dav1d: failed to open");
65
+ delete decoder;
66
+ return nullptr;
67
+ }
68
+ return decoder;
69
+ }
70
+
71
+ int sendPacket(void* opaque, const uint8_t* data, int size, int64_t ptsUs) {
72
+ auto* decoder = static_cast<Dav1dDecoder*>(opaque);
73
+ decoder->draining = false;
74
+ dav1d_data_unref(&decoder->data);
75
+ if (size <= 0) return 1;
76
+ uint8_t* buffer = dav1d_data_create(&decoder->data, static_cast<size_t>(size));
77
+ if (!buffer) return 0;
78
+ std::memcpy(buffer, data, static_cast<size_t>(size));
79
+ decoder->data.m.timestamp = ptsUs;
80
+ return 1;
81
+ }
82
+
83
+ int receivePicture(void* opaque, AlphaVideoPicture* out) {
84
+ auto* decoder = static_cast<Dav1dDecoder*>(opaque);
85
+ dav1d_picture_unref(&decoder->picture);
86
+ // A drain can stop at a frame it drops (an invisible one) with more behind it
87
+ int drainRetries = 1;
88
+ for (;;) {
89
+ if (decoder->data.sz) {
90
+ const int res = dav1d_send_data(decoder->ctx, &decoder->data);
91
+ if (res < 0 && res != DAV1D_ERR(EAGAIN)) {
92
+ dav1d_data_unref(&decoder->data);
93
+ return 0;
94
+ }
95
+ } else if (!decoder->draining) {
96
+ return 0;
97
+ }
98
+ const int res = dav1d_get_picture(decoder->ctx, &decoder->picture);
99
+ if (res == 0) break;
100
+ if (res != DAV1D_ERR(EAGAIN)) return 0;
101
+ if (decoder->draining && drainRetries-- == 0) return 0;
102
+ }
103
+
104
+ const Dav1dPicture& p = decoder->picture;
105
+ const Dav1dSequenceHeader* seq = p.seq_hdr;
106
+ out->planes[0] = static_cast<const uint8_t*>(p.data[0]);
107
+ out->planes[1] = static_cast<const uint8_t*>(p.data[1]);
108
+ out->planes[2] = static_cast<const uint8_t*>(p.data[2]);
109
+ out->strides[0] = static_cast<int>(p.stride[0]);
110
+ out->strides[1] = out->strides[2] = static_cast<int>(p.stride[1]);
111
+ out->width = p.p.w;
112
+ out->height = p.p.h;
113
+ out->chromaShiftX = p.p.layout == DAV1D_PIXEL_LAYOUT_I420 || p.p.layout == DAV1D_PIXEL_LAYOUT_I422;
114
+ out->chromaShiftY = p.p.layout == DAV1D_PIXEL_LAYOUT_I420;
115
+ out->monochrome = p.p.layout == DAV1D_PIXEL_LAYOUT_I400;
116
+ if (out->monochrome) out->planes[1] = out->planes[2] = nullptr;
117
+ out->bitDepth = p.p.bpc;
118
+ out->colorRange = seq && seq->color_range ? 2 : 1;
119
+ // FFmpeg's test for GBR output
120
+ out->rgb = seq && p.p.layout == DAV1D_PIXEL_LAYOUT_I444 && seq->mtrx == DAV1D_MC_IDENTITY &&
121
+ seq->pri == DAV1D_COLOR_PRI_BT709 && seq->trc == DAV1D_TRC_SRGB;
122
+ out->ptsUs = p.m.timestamp;
123
+ return 1;
124
+ }
125
+
126
+ void drainDecoder(void* opaque) {
127
+ static_cast<Dav1dDecoder*>(opaque)->draining = true;
128
+ }
129
+
130
+ void flushDecoder(void* opaque) {
131
+ auto* decoder = static_cast<Dav1dDecoder*>(opaque);
132
+ dav1d_data_unref(&decoder->data);
133
+ dav1d_picture_unref(&decoder->picture);
134
+ dav1d_flush(decoder->ctx);
135
+ decoder->draining = false;
136
+ }
137
+
138
+ void closeDecoder(void* opaque) {
139
+ auto* decoder = static_cast<Dav1dDecoder*>(opaque);
140
+ dav1d_data_unref(&decoder->data);
141
+ dav1d_picture_unref(&decoder->picture);
142
+ if (decoder->ctx) dav1d_close(&decoder->ctx);
143
+ delete decoder;
144
+ }
145
+
146
+ } // namespace
147
+
148
+ const AlphaVideoDecoderPlugin* const* alpha_video_av1_plugins(int* count) {
149
+ static const AlphaVideoDecoderPlugin av1 = {
150
+ ALPHA_VIDEO_DECODER_ABI, sizeof(AlphaVideoDecoderPlugin), "dav1d", dav1d_version(),
151
+ ALPHA_VIDEO_CODEC_AV1, supportsStream, openDecoder, sendPacket, receivePicture, drainDecoder,
152
+ flushDecoder, closeDecoder,
153
+ };
154
+ static const AlphaVideoDecoderPlugin* const plugins[] = {&av1};
155
+ *count = 1;
156
+ return plugins;
157
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef ALPHA_VIDEO_DAV1D_DECODER_PLUGIN_H
2
+ #define ALPHA_VIDEO_DAV1D_DECODER_PLUGIN_H
3
+
4
+ #include "AlphaVideoDecoderPlugin.h"
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ /* The av1 codec module's plugins: dav1d (8-, 10- and 12-bit). An AlphaVideoDecoderPluginList. */
11
+ const AlphaVideoDecoderPlugin* const* alpha_video_av1_plugins(int* count);
12
+
13
+ #ifdef __cplusplus
14
+ }
15
+ #endif
16
+
17
+ #endif