Skip to content

Commit 2470dde

Browse files
committed
fix(ios): video texture support
1 parent 0feae41 commit 2470dde

File tree

25 files changed

+483
-86
lines changed

25 files changed

+483
-86
lines changed

CanvasNative.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Pod::Spec.new do |s|
22

33
s.name = "CanvasNative"
44

5-
s.version = "0.9.10"
5+
s.version = "0.9.11"
66

77
s.summary = "A Canvas library"
88

packages/canvas-media/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nativescript/canvas-media",
3-
"version": "0.6.0",
3+
"version": "0.7.0",
44
"description": "Canvas media",
55
"main": "index",
66
"typings": "index.d.ts",

packages/canvas-media/video/index.ios.ts

+38-53
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { controlsProperty, VideoBase, playsinlineProperty, mutedProperty, srcProperty, currentTimeProperty } from './common';
22
import { Source } from '../common';
33
import { knownFolders, path } from '@nativescript/core';
4+
declare const Utils;
45
@NativeClass()
56
class NativeObject extends NSObject {
67
_owner: WeakRef<Video>;
@@ -26,7 +27,9 @@ class NativeObject extends NSObject {
2627
2728
*/
2829
} else if (owner._player.currentItem.status === AVPlayerItemStatus.ReadyToPlay) {
29-
console.log('ready');
30+
if (!owner._videoSize) {
31+
owner._videoSize = owner._asset.tracksWithMediaType(AVMediaTypeVideo)?.[0].naturalSize ?? undefined;
32+
}
3033
}
3134
}
3235
} else if (path === 'loadedTimeRanges') {
@@ -83,6 +86,7 @@ export class Video extends VideoBase {
8386
_fps: number;
8487
_ctx: any;
8588
_asset: AVURLAsset;
89+
_videoSize: any;
8690
get _player() {
8791
return this.#player;
8892
}
@@ -125,60 +129,39 @@ export class Video extends VideoBase {
125129
}
126130
if (this._assetOutput) {
127131
try {
128-
const currentTime = this.#player.currentTime();
129-
if (!this._assetOutput.hasNewPixelBufferForItemTime(currentTime)) {
130-
return;
131-
}
132-
const sampleBuffer = this._assetOutput.copyPixelBufferForItemTimeItemTimeForDisplay(currentTime, null);
133-
if (sampleBuffer !== 0) {
134-
/* const currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer);
135-
const differenceFromLastFrame = CMTimeSubtract(currentSampleTime, this['previousFrameTime']);
136-
const currentActualTime = CFAbsoluteTimeGetCurrent();
132+
// _ player: AVPlayer, _ output: AVPlayerItemVideoOutput,_ videoSize: CGSize
133+
Utils.drawFrame(this.#player, this._assetOutput, this._videoSize);
134+
/*
135+
const currentTime = this.#player.currentTime();
136+
if (!this._assetOutput.hasNewPixelBufferForItemTime(currentTime)) {
137+
return;
138+
}
139+
const pixel_buffer = this._assetOutput.copyPixelBufferForItemTimeItemTimeForDisplay(currentTime, null);
140+
if (pixel_buffer !== 0) {
141+
CVPixelBufferLockBaseAddress(pixel_buffer, 0);
142+
const bytesPerRow = CVPixelBufferGetBytesPerRow(pixel_buffer);
143+
const line_base = CVPixelBufferGetBaseAddress(pixel_buffer) as any;
137144
138-
const frameTimeDifference = CMTimeGetSeconds(differenceFromLastFrame);
139-
const actualTimeDifference = currentActualTime - this['previousActualFrameTime'];
140-
141-
142-
if (frameTimeDifference > actualTimeDifference) {
143-
usleep(1000000.0 * (frameTimeDifference - actualTimeDifference));
144-
}
145+
if (bytesPerRow / BYTES_PER_TEXEL === this._videoSize.width) {
146+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this._videoSize.width, this._videoSize.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, line_base);
147+
} else {
148+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this._videoSize.width, this._videoSize.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, null);
149+
for (let i = 0; i < this._videoSize.height; ++i) {
150+
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, i, this._videoSize.width, 1, GL_BGRA, GL_UNSIGNED_BYTE, line_base.add(i * bytesPerRow));
151+
}
152+
}
145153
146-
this['previousFrameTime'] = currentSampleTime;
147-
this['previousActualFrameTime'] = CFAbsoluteTimeGetCurrent();
148-
*/
149-
150-
//const pixel_buffer = CMSampleBufferGetImageBuffer(sampleBuffer);
151-
152-
//const startTime = CFAbsoluteTimeGetCurrent();
153-
154-
const GL_TEXTURE_2D = 3553;
155-
const GL_RGBA = 6408;
156-
const GL_BGRA_EXT = 32993;
157-
const GL_UNSIGNED_BYTE = 5121;
158-
159-
//const startTime = CFAbsoluteTimeGetCurrent();
160-
CVPixelBufferLockBaseAddress(sampleBuffer, 0);
161-
//const bpr = CVPixelBufferGetBytesPerRow(pixel_buffer);
162-
const width = CVPixelBufferGetBytesPerRow(sampleBuffer) / 4;
163-
const height = CVPixelBufferGetHeight(sampleBuffer);
164-
const line_base = CVPixelBufferGetBaseAddress(sampleBuffer);
165-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, line_base);
166-
167-
CVPixelBufferUnlockBaseAddress(sampleBuffer, 0);
168-
// CMSampleBufferInvalidate(sampleBuffer);
169-
170-
/*const currentFrameTime = CFAbsoluteTimeGetCurrent() - startTime;
171-
console.log('fps', currentFrameTime * 1000);
172-
*/
173-
//this._previousTS = currentTS;
174-
// may not need to release
175-
/*
176-
Unlike regular Core Foundation objects, toll-free bridged types are automatically memory managed by NativeScript,
177-
so there is no need to retain or release them using CFRetain and CFRelease.
178-
*/
179-
// https://docs.nativescript.org/core-concepts/ios-runtime/marshalling-overview#corefoundation-objects
180-
//CFRelease(sampleBuffer);
181-
}
154+
CVPixelBufferUnlockBaseAddress(pixel_buffer, 0);
155+
// may not need to release
156+
157+
// Unlike regular Core Foundation objects, toll-free bridged types are automatically memory managed by NativeScript,
158+
// so there is no need to retain or release them using CFRetain and CFRelease.
159+
160+
// https://docs.nativescript.org/core-concepts/ios-runtime/marshalling-overview#corefoundation-objects
161+
//CFRelease(sampleBuffer);
162+
}
163+
164+
*/
182165
} catch (e) {
183166
console.log('getCurrentFrame error:', e);
184167
}
@@ -305,6 +288,8 @@ export class Video extends VideoBase {
305288
this._asset = AVURLAsset.assetWithURL(url);
306289
const keys = ['tracks', 'duration'];
307290
this._asset.loadValuesAsynchronouslyForKeysCompletionHandler(keys, () => {
291+
this._videoSize = this._asset.tracksWithMediaType(AVMediaTypeVideo)?.[0].naturalSize ?? undefined;
292+
308293
const fps = this._asset.tracks.firstObject?.nominalFrameRate ?? 30;
309294

310295
const _interval = CMTimeMake(1, fps);

packages/canvas/platforms/ios/Podfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use_frameworks!
22
platform :ios, '11.0'
3-
pod 'CanvasNative' , '~> 0.9.10'
3+
pod 'CanvasNative' , '~> 0.9.11'
44
#pod 'CanvasNative', :path => "$(SRCROOT)/../../../../../"
55

66

packages/canvas/src-native/canvas-ios/CanvasNative/Dist/CanvasNative.xcframework/Info.plist

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,29 @@
66
<array>
77
<dict>
88
<key>LibraryIdentifier</key>
9-
<string>ios-x86_64-simulator</string>
9+
<string>ios-arm64</string>
1010
<key>LibraryPath</key>
1111
<string>CanvasNative.framework</string>
1212
<key>SupportedArchitectures</key>
1313
<array>
14-
<string>x86_64</string>
14+
<string>arm64</string>
1515
</array>
1616
<key>SupportedPlatform</key>
1717
<string>ios</string>
18-
<key>SupportedPlatformVariant</key>
19-
<string>simulator</string>
2018
</dict>
2119
<dict>
2220
<key>LibraryIdentifier</key>
23-
<string>ios-arm64</string>
21+
<string>ios-x86_64-simulator</string>
2422
<key>LibraryPath</key>
2523
<string>CanvasNative.framework</string>
2624
<key>SupportedArchitectures</key>
2725
<array>
28-
<string>arm64</string>
26+
<string>x86_64</string>
2927
</array>
3028
<key>SupportedPlatform</key>
3129
<string>ios</string>
30+
<key>SupportedPlatformVariant</key>
31+
<string>simulator</string>
3232
</dict>
3333
</array>
3434
<key>CFBundlePackageType</key>

packages/canvas/src-native/canvas-ios/CanvasNative/Dist/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/CanvasNative-Swift.h

+4
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,7 @@ SWIFT_CLASS_NAMED("TNSWebGL2RenderingContext")
12401240
- (int32_t)getFragDataLocation:(uint32_t)program :(NSString * _Nonnull)name SWIFT_WARN_UNUSED_RESULT;
12411241
- (id _Nonnull)getIndexedParameter:(uint32_t)target :(uint32_t)index SWIFT_WARN_UNUSED_RESULT;
12421242
- (id _Nonnull)getInternalformatParameter:(uint32_t)target :(uint32_t)internalformat :(uint32_t)pname SWIFT_WARN_UNUSED_RESULT;
1243+
- (id _Nullable)getParameter:(uint32_t)pname SWIFT_WARN_UNUSED_RESULT;
12431244
- (id _Nonnull)getQuery:(uint32_t)target :(uint32_t)pname SWIFT_WARN_UNUSED_RESULT;
12441245
- (id _Nonnull)getQueryParameter:(uint32_t)query :(uint32_t)pname SWIFT_WARN_UNUSED_RESULT;
12451246
- (id _Nonnull)getSamplerParameter:(uint32_t)sampler :(uint32_t)pname SWIFT_WARN_UNUSED_RESULT;
@@ -1836,11 +1837,14 @@ SWIFT_CLASS_NAMED("TNS_WEBGL_lose_context")
18361837
+ (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable");
18371838
@end
18381839

1840+
@class AVPlayer;
1841+
@class AVPlayerItemVideoOutput;
18391842

18401843
SWIFT_CLASS_NAMED("Utils")
18411844
@interface Utils : NSObject
18421845
+ (CVOpenGLESTextureCacheRef _Nullable)createTextureCache:(TNSWebGLRenderingContext * _Nonnull)context SWIFT_WARN_UNUSED_RESULT;
18431846
+ (CVOpenGLESTextureRef _Nullable)createImage:(CVOpenGLESTextureCacheRef _Nonnull)texturecache :(CVImageBufferRef _Nonnull)buffer :(CFDictionaryRef _Nullable)textureAttributes :(GLenum)target :(GLint)internalFormat :(GLsizei)width :(GLsizei)height :(GLenum)format :(GLenum)type :(NSInteger)planeIndex SWIFT_WARN_UNUSED_RESULT;
1847+
+ (void)drawFrame:(AVPlayer * _Nonnull)player :(AVPlayerItemVideoOutput * _Nonnull)output :(CGSize)videoSize;
18441848
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
18451849
@end
18461850

packages/canvas/src-native/canvas-ios/CanvasNative/Dist/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Headers/canvas_native.h

+122
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ typedef enum {
9292

9393
typedef struct Context Context;
9494

95+
typedef struct {
96+
uint8_t _unused[0];
97+
} ANativeWindow;
98+
99+
typedef struct {
100+
uint8_t _unused[0];
101+
} ASurfaceTexture;
102+
95103
typedef struct {
96104
long long value;
97105
PaintStyleValueType value_type;
@@ -137,6 +145,120 @@ typedef struct {
137145
uintptr_t data_len;
138146
} U32Array;
139147

148+
/**
149+
* Returns a reference to an ANativeWindow (i.e. the Producer) for this SurfaceTexture.
150+
* This is equivalent to Java's: Surface sur = new Surface(surfaceTexture);
151+
*
152+
* Available since API level 28.
153+
*
154+
* \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
155+
* @return A reference to an ANativeWindow. This reference MUST BE released when no longer needed
156+
* using ANativeWindow_release(). Failing to do so will result in leaked resources. nullptr is
157+
* returned if \p st is null or if it's not an instance of android.graphics.SurfaceTexture
158+
*/
159+
extern ANativeWindow *ASurfaceTexture_acquireANativeWindow(ASurfaceTexture *st);
160+
161+
/**
162+
* Attach the SurfaceTexture to the OpenGL ES context that is current on the calling thread. A
163+
* new OpenGL ES texture object is created and populated with the SurfaceTexture image frame
164+
* that was current at the time of the last call to {@link #detachFromGLContext}. This new
165+
* texture is bound to the GL_TEXTURE_EXTERNAL_OES texture target.
166+
*
167+
* This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
168+
* contexts. Note, however, that the image contents are only accessible from one OpenGL ES
169+
* context at a time.
170+
*
171+
* Available since API level 28.
172+
*
173+
* \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
174+
* \param texName The name of the OpenGL ES texture that will be created. This texture name
175+
* must be unusued in the OpenGL ES context that is current on the calling thread.
176+
* \return 0 on success, negative posix error code otherwise (see <errno.h>)
177+
*/
178+
extern int ASurfaceTexture_attachToGLContext(ASurfaceTexture *st, uint32_t texName);
179+
180+
/**
181+
* Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object.
182+
* This call must be made with the OpenGL ES context current on the calling thread. The OpenGL
183+
* ES texture object will be deleted as a result of this call. After calling this method all
184+
* calls to {@link #updateTexImage} will fail until a successful call to {@link #attachToGLContext}
185+
* is made.
186+
*
187+
* This can be used to access the SurfaceTexture image contents from multiple OpenGL ES
188+
* contexts. Note, however, that the image contents are only accessible from one OpenGL ES
189+
* context at a time.
190+
*
191+
* Available since API level 28.
192+
*
193+
* \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
194+
* \return 0 on success, negative posix error code otherwise (see <errno.h>)
195+
*/
196+
extern int ASurfaceTexture_detachFromGLContext(ASurfaceTexture *st);
197+
198+
/**
199+
* Retrieve the timestamp associated with the texture image set by the most recent call to
200+
* updateTexImage.
201+
*
202+
* This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp
203+
* should be unaffected by time-of-day adjustments, and for a camera should be strictly
204+
* monotonic but for a MediaPlayer may be reset when the position is set. The
205+
* specific meaning and zero point of the timestamp depends on the source providing images to
206+
* the SurfaceTexture. Unless otherwise specified by the image source, timestamps cannot
207+
* generally be compared across SurfaceTexture instances, or across multiple program
208+
* invocations. It is mostly useful for determining time offsets between subsequent frames.
209+
*
210+
* For EGL/Vulkan producers, this timestamp is the desired present time set with the
211+
* EGL_ANDROID_presentation_time or VK_GOOGLE_display_timing extensions
212+
*
213+
* Available since API level 28.
214+
*
215+
* \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
216+
*/
217+
extern int64_t ASurfaceTexture_getTimestamp(ASurfaceTexture *st);
218+
219+
/**
220+
* Retrieve the 4x4 texture coordinate transform matrix associated with the texture image set by
221+
* the most recent call to updateTexImage.
222+
*
223+
* This transform matrix maps 2D homogeneous texture coordinates of the form (s, t, 0, 1) with s
224+
* and t in the inclusive range [0, 1] to the texture coordinate that should be used to sample
225+
* that location from the texture. Sampling the texture outside of the range of this transform
226+
* is undefined.
227+
*
228+
* The matrix is stored in column-major order so that it may be passed directly to OpenGL ES via
229+
* the glLoadMatrixf or glUniformMatrix4fv functions.
230+
*
231+
* Available since API level 28.
232+
*
233+
* \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
234+
* \param mtx the array into which the 4x4 matrix will be stored. The array must have exactly
235+
* 16 elements.
236+
*/
237+
extern void ASurfaceTexture_getTransformMatrix(ASurfaceTexture *st, float *mtx);
238+
239+
/**
240+
* Release the reference to the native ASurfaceTexture acquired with
241+
* ASurfaceTexture_fromSurfaceTexture().
242+
* Failing to do so will result in leaked memory and graphic resources.
243+
*
244+
* Available since API level 28.
245+
*
246+
* \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
247+
*/
248+
extern void ASurfaceTexture_release(ASurfaceTexture *st);
249+
250+
/**
251+
* Update the texture image to the most recent frame from the image stream. This may only be
252+
* called while the OpenGL ES context that owns the texture is current on the calling thread.
253+
* It will implicitly bind its texture to the GL_TEXTURE_EXTERNAL_OES texture target.
254+
*
255+
* Available since API level 28.
256+
*
257+
* \param st A ASurfaceTexture reference acquired with ASurfaceTexture_fromSurfaceTexture()
258+
* \return 0 on success, negative posix error code otherwise (see <errno.h>)
259+
*/
260+
extern int ASurfaceTexture_updateTexImage(ASurfaceTexture *st);
261+
140262
void context_arc(long long context,
141263
float x,
142264
float y,

packages/canvas/src-native/canvas-ios/CanvasNative/Dist/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64-apple-ios.swiftinterface

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// swift-interface-format-version: 1.0
22
// swift-compiler-version: Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
33
// swift-module-flags: -target arm64-apple-ios10.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name CanvasNative
4+
import AVFoundation
45
@_exported import CanvasNative
56
import CoreVideo
67
import Foundation
@@ -391,6 +392,7 @@ extension RangeReplaceableCollection {
391392
@objc public func getFragDataLocation(_ program: Swift.UInt32, _ name: Swift.String) -> Swift.Int32
392393
@objc public func getIndexedParameter(_ target: Swift.UInt32, _ index: Swift.UInt32) -> Any
393394
@objc public func getInternalformatParameter(_ target: Swift.UInt32, _ internalformat: Swift.UInt32, _ pname: Swift.UInt32) -> Any
395+
@objc override public func getParameter(_ pname: Swift.UInt32) -> Any?
394396
@objc public func getQuery(_ target: Swift.UInt32, _ pname: Swift.UInt32) -> Any
395397
@objc public func getQueryParameter(_ query: Swift.UInt32, _ pname: Swift.UInt32) -> Any
396398
@objc public func getSamplerParameter(_ sampler: Swift.UInt32, _ pname: Swift.UInt32) -> Any
@@ -2454,6 +2456,7 @@ extension RangeReplaceableCollection {
24542456
@_inheritsConvenienceInitializers @objc(Utils) public class Utils : ObjectiveC.NSObject {
24552457
@objc public static func createTextureCache(_ context: CanvasNative.TNSWebGLRenderingContext) -> CoreVideo.CVOpenGLESTextureCache?
24562458
@objc public static func createImage(_ texturecache: CoreVideo.CVOpenGLESTextureCache, _ buffer: CoreVideo.CVImageBuffer, _ textureAttributes: CoreFoundation.CFDictionary?, _ target: OpenGLES.GLenum, _ internalFormat: OpenGLES.GLint, _ width: OpenGLES.GLsizei, _ height: OpenGLES.GLsizei, _ format: OpenGLES.GLenum, _ type: OpenGLES.GLenum, _ planeIndex: Swift.Int) -> CoreVideo.CVOpenGLESTexture?
2459+
@objc public static func drawFrame(_ player: AVFoundation.AVPlayer, _ output: AVFoundation.AVPlayerItemVideoOutput, _ videoSize: CoreGraphics.CGSize)
24572460
@objc deinit
24582461
@objc override dynamic public init()
24592462
}

packages/canvas/src-native/canvas-ios/CanvasNative/Dist/CanvasNative.xcframework/ios-arm64/CanvasNative.framework/Modules/CanvasNative.swiftmodule/arm64.swiftinterface

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// swift-interface-format-version: 1.0
22
// swift-compiler-version: Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
33
// swift-module-flags: -target arm64-apple-ios10.0 -enable-objc-interop -enable-library-evolution -swift-version 5 -enforce-exclusivity=checked -O -module-name CanvasNative
4+
import AVFoundation
45
@_exported import CanvasNative
56
import CoreVideo
67
import Foundation
@@ -391,6 +392,7 @@ extension RangeReplaceableCollection {
391392
@objc public func getFragDataLocation(_ program: Swift.UInt32, _ name: Swift.String) -> Swift.Int32
392393
@objc public func getIndexedParameter(_ target: Swift.UInt32, _ index: Swift.UInt32) -> Any
393394
@objc public func getInternalformatParameter(_ target: Swift.UInt32, _ internalformat: Swift.UInt32, _ pname: Swift.UInt32) -> Any
395+
@objc override public func getParameter(_ pname: Swift.UInt32) -> Any?
394396
@objc public func getQuery(_ target: Swift.UInt32, _ pname: Swift.UInt32) -> Any
395397
@objc public func getQueryParameter(_ query: Swift.UInt32, _ pname: Swift.UInt32) -> Any
396398
@objc public func getSamplerParameter(_ sampler: Swift.UInt32, _ pname: Swift.UInt32) -> Any
@@ -2454,6 +2456,7 @@ extension RangeReplaceableCollection {
24542456
@_inheritsConvenienceInitializers @objc(Utils) public class Utils : ObjectiveC.NSObject {
24552457
@objc public static func createTextureCache(_ context: CanvasNative.TNSWebGLRenderingContext) -> CoreVideo.CVOpenGLESTextureCache?
24562458
@objc public static func createImage(_ texturecache: CoreVideo.CVOpenGLESTextureCache, _ buffer: CoreVideo.CVImageBuffer, _ textureAttributes: CoreFoundation.CFDictionary?, _ target: OpenGLES.GLenum, _ internalFormat: OpenGLES.GLint, _ width: OpenGLES.GLsizei, _ height: OpenGLES.GLsizei, _ format: OpenGLES.GLenum, _ type: OpenGLES.GLenum, _ planeIndex: Swift.Int) -> CoreVideo.CVOpenGLESTexture?
2459+
@objc public static func drawFrame(_ player: AVFoundation.AVPlayer, _ output: AVFoundation.AVPlayerItemVideoOutput, _ videoSize: CoreGraphics.CGSize)
24572460
@objc deinit
24582461
@objc override dynamic public init()
24592462
}

0 commit comments

Comments
 (0)