@@ -33,50 +33,50 @@ - (void)setSize:(CGSize)size
3333
3434- (void )renderFrame : (nullable RTCVideoFrame *)frame
3535{
36- if (_gotFrame) return ;
36+ if (_gotFrame || frame == nil ) return ;
3737 _gotFrame = true ;
3838
39- dispatch_async (dispatch_get_main_queue (), ^{
40- [self ->_track removeRenderer: self ];
41- });
42-
43- id <RTCVideoFrameBuffer> buffer = [frame buffer ];
44- id <RTCI420Buffer> i420Buffer = [buffer toI420 ];
45-
46- CVPixelBufferRef pixelBuffer = nil ;
47- CVPixelBufferCreate (kCFAllocatorDefault , i420Buffer.width , i420Buffer.height , kCVPixelFormatType_32ARGB , nil , &pixelBuffer);
48- CVPixelBufferLockBaseAddress (pixelBuffer, 0 );
49-
50- uint8_t * dst = CVPixelBufferGetBaseAddress (pixelBuffer);
51- const size_t bytesPerRow = CVPixelBufferGetBytesPerRow (pixelBuffer);
39+ id <RTCVideoFrameBuffer> buffer = frame.buffer ;
40+ CVPixelBufferRef pixelBufferRef = ((RTCCVPixelBuffer *) buffer).pixelBuffer ;
5241
53- I420ToBGRA (i420Buffer.dataY ,
54- i420Buffer.strideY ,
55- i420Buffer.dataU ,
56- i420Buffer.strideU ,
57- i420Buffer.dataV ,
58- i420Buffer.strideV ,
59- dst,
60- (int )bytesPerRow,
61- i420Buffer.width ,
62- i420Buffer.height );
42+ CIImage *ciImage = [CIImage imageWithCVPixelBuffer: pixelBufferRef];
43+ CIContext *context = [CIContext contextWithOptions: nil ];
44+ CGImageRef cgImage = [context createCGImage: ciImage
45+ fromRect: CGRectMake (0 , 0 , frame.width, frame.height)];
6346
64- CIContext *context = [[CIContext alloc ] init ];
65- CIImage *coreImage = [[CIImage alloc ] initWithCVPixelBuffer: pixelBuffer];
66-
67- CIImage *rotatedImage;
47+ UIImageOrientation orientation;
6848 switch (frame.rotation ) {
69- case RTCVideoRotation_0: rotatedImage = coreImage; break ;
70- case RTCVideoRotation_90: rotatedImage = [coreImage imageByApplyingOrientation: kCGImagePropertyOrientationRight ]; break ;
71- case RTCVideoRotation_180: rotatedImage = [coreImage imageByApplyingOrientation: kCGImagePropertyOrientationDown ]; break ;
72- case RTCVideoRotation_270: rotatedImage = [coreImage imageByApplyingOrientation: kCGImagePropertyOrientationLeft ]; break ;
49+ case RTCVideoRotation_90:
50+ orientation = UIImageOrientationRight;
51+ break ;
52+ case RTCVideoRotation_180:
53+ orientation = UIImageOrientationDown;
54+ break ;
55+ case RTCVideoRotation_270:
56+ orientation = UIImageOrientationLeft;
57+ default :
58+ orientation = UIImageOrientationUp;
59+ break ;
7360 }
7461
75- NSData * data = [context JPEGRepresentationOfImage: rotatedImage colorSpace: rotatedImage.colorSpace options: @{}];
76-
77- [data writeToFile: _path atomically: NO ];
62+ UIImage *uiImage = [UIImage imageWithCGImage: cgImage scale: 1 orientation: orientation];
63+ CGImageRelease (cgImage);
64+ NSData *jpgData = UIImageJPEGRepresentation (uiImage, 0 .9f );
65+
66+ if ([jpgData writeToFile: _path atomically: NO ]) {
67+ NSLog (@" File writed successfully to %@ " , _path);
68+ _result (nil );
69+ } else {
70+ NSLog (@" Failed to write to file" );
71+ _result ([FlutterError errorWithCode: @" CaptureFrameFailed"
72+ message: @" Failed to write JPEG data to file"
73+ details: nil ]);
74+ }
7875
79- _result (nil );
76+ dispatch_async (dispatch_get_main_queue (), ^{
77+ [self ->_track removeRenderer: self ];
78+ self->_track = nil ;
79+ });
8080}
8181
8282@end
0 commit comments