@@ -25,13 +25,14 @@ @interface CameraTextureDelegate : NSObject <AVCaptureVideoDataOutputSampleBuffe
25
25
{
26
26
@public AVCaptureVideoOrientation videoOrientation;
27
27
28
- std::shared_ptr<Babylon::Plugins::Camera::Impl::ImplData> implData ;
28
+ CVMetalTextureCacheRef textureCache ;
29
29
bool orientationUpdated;
30
30
}
31
31
32
- - (id )init : (std::shared_ptr<Babylon::Plugins::Camera::Impl::ImplData>) implData ;
32
+ - (id )init : (CVMetalTextureCacheRef) textureCache ;
33
33
- (id <MTLTexture >)getCameraTextureY ;
34
34
- (id <MTLTexture >)getCameraTextureCbCr ;
35
+ - (void )reset ;
35
36
36
37
@end
37
38
@@ -140,7 +141,9 @@ fragment float4 fragmentShader(RasterizerData in [[stage_in]],
140
141
[currentCommandBuffer waitUntilCompleted ];
141
142
}
142
143
143
- [avCaptureSession stopRunning ];
144
+ dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
145
+ [avCaptureSession stopRunning ];
146
+ });
144
147
145
148
if (textureCache)
146
149
{
@@ -152,7 +155,7 @@ fragment float4 fragmentShader(RasterizerData in [[stage_in]],
152
155
CameraTextureDelegate* cameraTextureDelegate{};
153
156
AVCaptureSession* avCaptureSession{};
154
157
CVMetalTextureCacheRef textureCache{};
155
- id <MTLTexture > textureRGBA{};
158
+ id <MTLTexture > textureRGBA{};
156
159
id <MTLRenderPipelineState > cameraPipelineState{};
157
160
id <MTLDevice > metalDevice{};
158
161
id <MTLCommandQueue > commandQueue{};
@@ -191,7 +194,7 @@ fragment float4 fragmentShader(RasterizerData in [[stage_in]],
191
194
192
195
dispatch_async (dispatch_get_main_queue (), ^{
193
196
CVMetalTextureCacheCreate (nullptr , nullptr , m_implData->metalDevice , nullptr , &m_implData->textureCache );
194
- m_implData->cameraTextureDelegate = [[CameraTextureDelegate alloc ]init:m_implData];
197
+ m_implData->cameraTextureDelegate = [[CameraTextureDelegate alloc ]init:m_implData->textureCache ];
195
198
m_implData->avCaptureSession = [[AVCaptureSession alloc ] init ];
196
199
m_implData->textureRGBA = nil ;
197
200
@@ -347,7 +350,9 @@ fragment float4 fragmentShader(RasterizerData in [[stage_in]],
347
350
// Actually start the camera session.
348
351
[m_implData->avCaptureSession addOutput: dataOutput];
349
352
[m_implData->avCaptureSession commitConfiguration ];
350
- [m_implData->avCaptureSession startRunning ];
353
+ dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
354
+ [m_implData->avCaptureSession startRunning ];
355
+ });
351
356
352
357
// Create a pipeline state for converting the camera output to RGBA.
353
358
id <MTLLibrary > lib = CompileShader (m_implData->metalDevice , shaderSource);
@@ -463,7 +468,9 @@ fragment float4 fragmentShader(RasterizerData in [[stage_in]],
463
468
464
469
void Camera::Impl::Close ()
465
470
{
466
- m_implData.reset (new ImplData);
471
+ [m_implData->cameraTextureDelegate reset ];
472
+ m_implData.reset ();
473
+ m_implData = std::make_unique<ImplData>();
467
474
}
468
475
}
469
476
@@ -472,10 +479,10 @@ @implementation CameraTextureDelegate {
472
479
CVMetalTextureRef cameraTextureCbCr;
473
480
}
474
481
475
- - (id )init : (std::shared_ptr<Babylon::Plugins::Camera::Impl::ImplData>) implData
482
+ - (id )init : (CVMetalTextureCacheRef) textureCache
476
483
{
477
484
self = [super init ];
478
- self->implData = implData ;
485
+ self->textureCache = textureCache ;
479
486
#if (TARGET_OS_IPHONE)
480
487
[[NSNotificationCenter defaultCenter ]addObserver:self selector: @selector (OrientationDidChange: ) name: UIDeviceOrientationDidChangeNotification object: nil ];
481
488
[self updateOrientation ];
@@ -513,6 +520,12 @@ - (id)init:(std::shared_ptr<Babylon::Plugins::Camera::Impl::ImplData>)implData
513
520
return nil ;
514
521
}
515
522
523
+ - (void ) reset {
524
+ @synchronized (self) {
525
+ self->textureCache = nil ;
526
+ }
527
+ }
528
+
516
529
#if (TARGET_OS_IPHONE)
517
530
/* *
518
531
Updates target video orientation.
@@ -603,11 +616,16 @@ - (CVMetalTextureRef)getCameraTexture:(CVPixelBufferRef)pixelBuffer plane:(int)p
603
616
auto pixelFormat = planeIndex ? MTLPixelFormatRG8Unorm : MTLPixelFormatR8Unorm ;
604
617
CVMetalTextureRef textureRef;
605
618
606
- // Create a texture from the corresponding plane.
607
- auto status = CVMetalTextureCacheCreateTextureFromImage (kCFAllocatorDefault , implData->textureCache , pixelBuffer, nil , pixelFormat, planeWidth, planeHeight, planeIndex, &textureRef);
608
- if (status != kCVReturnSuccess ) {
609
- CVBufferRelease (textureRef);
610
- textureRef = nil ;
619
+ @synchronized (self) {
620
+ if (self->textureCache == nil ) {
621
+ return {};
622
+ }
623
+
624
+ auto status = CVMetalTextureCacheCreateTextureFromImage (kCFAllocatorDefault , textureCache, pixelBuffer, nil , pixelFormat, planeWidth, planeHeight, planeIndex, &textureRef);
625
+ if (status != kCVReturnSuccess ) {
626
+ CVBufferRelease (textureRef);
627
+ textureRef = nil ;
628
+ }
611
629
}
612
630
613
631
return textureRef;
0 commit comments