8000 fix Videocapturer and VideoRenderer for new webrtc framework. · CodeStrings/flutter-webrtc@4e23168 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4e23168

Browse files
committed
fix Videocapturer and VideoRenderer for new webrtc framework.
1 parent 6eacefe commit 4e23168

5 files changed

+106
-12
lines changed

ios/Classes/FlutterRTCMediaStream.m

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ - (void)getUserVideo:(NSDictionary *)constraints
259259
if (videoDevice) {
260260
RTCVideoSource *videoSource = [self.peerConnectionFactory videoSource];
261261
// FIXME: Video capturer shouldn't be local to be able to stop
262-
RTCCameraVideoCapturer *capt = [[RTCCameraVideoCapturer alloc] initWithDelegate:videoSource];
262+
self.videoCapturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:videoSource];
263263
AVCaptureDeviceFormat *selectedFormat = nil;
264264
int currentDiff = INT_MAX;
265265
// TODO: use values from constraints map
@@ -272,15 +272,15 @@ - (void)getUserVideo:(NSDictionary *)constraints
272272
if (diff < currentDiff) {
273273
selectedFormat = format;
274274
currentDiff = diff;
275-
} else if (diff == currentDiff && pixelFormat == [capt preferredOutputPixelFormat]) {
275+
} else if (diff == currentDiff && pixelFormat == [self.videoCapturer preferredOutputPixelFormat]) {
276276
selectedFormat = format;
277277
}
278278
}
279279
if (selectedFormat == nil) {
280280
NSLog(@"Capture format is nil. Fallback");
281281
selectedFormat = [RTCCameraVideoCapturer supportedFormatsForDevice:videoDevice].firstObject;
282282
}
283-
[capt startCaptureWithDevice:videoDevice format:selectedFormat fps:30 completionHandler:^(NSError *error) {
283+
[self.videoCapturer startCaptureWithDevice:videoDevice format:selectedFormat fps:30 completionHandler:^(NSError *error) {
284284
if (error) {
285285
NSLog(@"Start capture error: %@", [error localizedDescription]);
286286
}

ios/Classes/FlutterRTCVideoRenderer.m

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
#import <AVFoundation/AVFoundation.h>
44
#import <CoreGraphics/CGImage.h>
55
#import <WebRTC/WebRTC.h>
6+
#import <WebRTC/RTCYUVPlanarBuffer.h>
7+
68
#import <objc/runtime.h>
9+
#include "libyuv.h"
710

811
#import "FlutterWebRTCPlugin.h"
912

@@ -71,15 +74,99 @@ - (void)setVideoTrack:(RTCVideoTrack *)videoTrack {
7174
}
7275
}
7376

77+
78+
-(id<RTCI420Buffer>) correctRotation:(const id<RTCI420Buffer>) src
79+
withRotation:(RTCVideoRotation) rotation
80+
{
81+
82+
int rotated_width = src.width;
83+
int rotated_height = src.height;
84+
85+
if (rotation == RTCVideoRotation_90 ||
86+
rotation == RTCVideoRotation_270) {
87+
int temp = rotated_width;
88+
rotated_width = rotated_height;
89+
rotated_height = temp;
90+
}
91+
92+
id<RTCI420Buffer> buffer = [[RTCI420Buffer alloc] initWithWidth:rotated_width height:rotated_height];
93+
94+
I420Rotate(src.dataY, src.strideY,
95+
src.dataU, src.strideU,
96+
src.dataV, src.strideV,
97+
(uint8_t*)buffer.dataY, buffer.strideY,
98+
(uint8_t*)buffer.dataU,buffer.strideU,
99+
(uint8_t*)buffer.dataV, buffer.strideV,
100+
src.width, src.height,
101+
(RotationModeEnum)rotation);
102+
103+
return buffer;
104+
}
105+
106+
-(void)copyI420ToCVPixelBuffer:(CVPixelBufferRef)outputPixelBuffer withFrame:(RTCVideoFrame *) frame
107+
{
108+
id<RTCI420Buffer> i420Buffer = [self correctRotation:[frame.buffer toI420] withRotation:frame.rotation];
109+
CVPixelBufferLockBaseAddress(outputPixelBuffer, 0);
110+
111+
const OSType pixelFormat = CVPixelBufferGetPixelFormatType(outputPixelBuffer);
112+
if (pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
113+
pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
114+
// NV12
115+
uint8_t* dstY = CVPixelBufferGetBaseAddressOfPlane(outputPixelBuffer, 0);
116+
const size_t dstYStride = CVPixelBufferGetBytesPerRowOfPlane(outputPixelBuffer, 0);
117+
uint8_t* dstUV = CVPixelBufferGetBaseAddressOfPlane(outputPixelBuffer, 1);
118+
const size_t dstUVStride = CVPixelBufferGetBytesPerRowOfPlane(outputPixelBuffer, 1);
119+
120+
I420ToNV12(i420Buffer.dataY,
121+
i420Buffer.strideY,
122+
i420Buffer.dataU,
123+
i420Buffer.strideU,
124+
i420Buffer.dataV,
125+
i420Buffer.strideV,
126+
dstY,
127+
(int)dstYStride,
128+
dstUV,
129+
(int)dstUVStride,
130+
i420Buffer.width,
131+
i420Buffer.height);
132+
} else {
133+
uint8_t* dst = CVPixelBufferGetBaseAddress(outputPixelBuffer);
134+
const size_t bytesPerRow = CVPixelBufferGetBytesPerRow(outputPixelBuffer);
135+
136+
if (pixelFormat == kCVPixelFormatType_32BGRA) {
137+
// Corresponds to libyuv::FOURCC_ARGB
138+
I420ToARGB(i420Buffer.dataY,
139+
i420Buffer.strideY,
140+
i420Buffer.dataU,
141+
i420Buffer.strideU,
< 9E88 code>142+
i420Buffer.dataV,
143+
i420Buffer.strideV,
144+
dst,
145+
(int)bytesPerRow,
146+
i420Buffer.width,
147+
i420Buffer.height);
148+
} else if (pixelFormat == kCVPixelFormatType_32ARGB) {
149+
// Corresponds to libyuv::FOURCC_BGRA
150+
I420ToBGRA(i420Buffer.dataY,
151+
i420Buffer.strideY,
152+
i420Buffer.dataU,
153+
i420Buffer.strideU,
154+
i420Buffer.dataV,
155+
i420Buffer.strideV,
156+
dst,
157+
(int)bytesPerRow,
158+
i420Buffer.width,
159+
i420Buffer.height);
160+
}
161+
}
162+
163+
CVPixelBufferUnlockBaseAddress(outputPixelBuffer, 0);
164+
}
165+
74166
#pragma mark - RTCVideoRenderer methods
75167
- (void)renderFrame:(RTCVideoFrame *)frame {
76-
77-
//TODO: got a frame => scale to _renderSize => convert to BGRA32 pixelBufferRef
78-
RTCI420Buffer *buffer = [[frame buffer] toI420];
79-
buffer.dataY;
80-
buffer.dataU;
81-
buffer.dataV;
82-
//TODO: copy it somehow, I dunno what to do with this data
168+
169+
[self copyI420ToCVPixelBuffer:_pixelBufferRef withFrame:frame];
83170

84171
__weak FlutterRTCVideoRenderer *weakSelf = self;
85172

ios/Classes/FlutterWebRTCPlugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#import <WebRTC/RTCDataChannel.h>
77
#import <WebRTC/RTCDataChannelConfiguration.h>
88
#import <WebRTC/RTCMediaStreamTrack.h>
9+
#import <WebRTC/RTCCameraVideoCapturer.h>
910

1011
@class FlutterRTCVideoRenderer;
1112

@@ -18,6 +19,7 @@
1819
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, FlutterRTCVideoRenderer *> *renders;
1920
@property (nonatomic, retain) UIViewController *viewController;/*for broadcast or ReplayKit */
2021
@property (nonatomic, strong) NSObject<FlutterBinaryMessenger>* messenger;
22+
@property (nonatomic, strong) RTCCameraVideoCapturer *videoCapturer;
2123

2224
- (RTCMediaStream*)streamForId:(NSString*)streamId;
2325

ios/Classes/FlutterWebRTCPlugin.m

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,11 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult) result
257257
for (RTCVideoTrack *track in stream.videoTracks) {
258258
[self.localTracks removeObjectForKey:track.trackId];
259259
RTCVideoTrack *videoTrack = (RTCVideoTrack *)track;
260-
//TODO(rostopira)
260+
RTCVideoSource *source = videoTrack.source;
261+
if(source){
262+
[self.videoCapturer stopCapture];
263+
self.videoCapturer = nil;
264+
}
261265
}
262266
for (RTCAudioTrack *track in stream.audioTracks) {
263267
[self.localTracks removeObjectForKey:track.trackId];

ios/flutter_webrtc.podspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ A new flutter plugin project.
1515
s.source_files = 'Classes/**/*'
1616
s.public_header_files = 'Classes/**/*.h'
1717
s.dependency 'Flutter'
18-
s.dependency 'GoogleWebRTC', '1.1.25544'
18+
s.dependency 'libyuv-iOS'
19+
s.dependency 'GoogleWebRTC'
1920
s.ios.deployment_target = '9.0'
2021
end
2122

0 commit comments

Comments
 (0)
0