Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(772)

Side by Side Diff: webrtc/sdk/objc/Framework/Classes/RTCFileVideoCapturer.m

Issue 2887673002: Add RTCFileVideoCapturer class. (Closed)
Patch Set: Move all operations in dispatch block Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/sdk/objc/Framework/Classes/RTCFileVideoCapturer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /**
2 * Copyright 2017 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #import "RTCFileVideoCapturer.h"
12
13 #import "WebRTC/RTCLogging.h"
14
15 @implementation RTCFileVideoCapturer {
16 AVAssetReader *_reader;
17 CMTime _lastPresentationTime;
18 dispatch_queue_t _frameQueue;
19 dispatch_semaphore_t _frameSemaphore;
20 BOOL _capturerStopped;
sakal 2017/05/24 08:34:09 I think this should be a property declared as atom
daniela-webrtc 2017/06/01 13:08:57 Not necessarily. The worst thing that can happen i
21 }
22
23 - (void)startCapturingFromFileNamed:(NSString *)nameOfFile {
24 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
25 if (_reader && _reader.status == AVAssetReaderStatusReading) {
26 RTCLog("Capturer exists and reads anoth6er file. Start capture request fai led.");
magjed_webrtc 2017/05/29 13:14:25 nit: anoth6er
daniela-webrtc 2017/06/01 13:08:57 Done.
27 return;
28 }
29 NSString *pathForFile = [self pathForFileName:nameOfFile];
30 if (!pathForFile) {
31 RTCLog("File %@ not found in bundle", nameOfFile);
32 return;
33 }
34
35 _lastPresentationTime = CMTimeMake(0, 0);
36 _frameSemaphore = dispatch_semaphore_create(0);
37
38 NSURL *URLForFile = [NSURL fileURLWithPath:pathForFile];
39 AVURLAsset *asset = [AVURLAsset URLAssetWithURL:URLForFile options:nil];
40
41 NSArray *allTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
42 NSError *error = nil;
43 _reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
44 if (error) {
45 RTCLog("File reader failed with error: %@", error);
46 return;
47 }
48
49 NSDictionary *options = @{
50 (NSString *)
51 kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanar VideoRange)
magjed_webrtc 2017/05/29 13:14:25 Is it possible to use FullRange?
daniela-webrtc 2017/06/01 13:08:57 Yes. I've changed it
52 };
53 AVAssetReaderTrackOutput *outTrack =
54 [[AVAssetReaderTrackOutput alloc] initWithTrack:allTracks.firstObject
55 outputSettings:options];
56 [_reader addOutput:outTrack];
57
58 [_reader startReading];
59 RTCLog(@"File capturer started reading");
60 while (_reader.status == AVAssetReaderStatusReading && !_capturerStopped) {
61 CMSampleBufferRef sampleBuffer = [outTrack copyNextSampleBuffer];
62 if (sampleBuffer) {
63 if (CMSampleBufferGetNumSamples(sampleBuffer) != 1 ||
64 !CMSampleBufferIsValid(sampleBuffer) || !CMSampleBufferDataIsReady(s ampleBuffer)) {
65 continue;
66 }
67
68 CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer );
69 if (pixelBuffer == nil) {
70 continue;
71 }
72
73 CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleB uffer);
74 Float64 presentationDifference =
75 CMTimeGetSeconds(CMTimeSubtract(presentationTime, _lastPresentationT ime));
76 int64_t presentationDifferenceRound = lroundf(presentationDifference * N SEC_PER_SEC);
77 _lastPresentationTime = presentationTime;
78
79 // dispatch with delay, we want to achieve a real time play.
magjed_webrtc 2017/05/29 13:14:25 nit: Begin sentence with capital letter.
80 dispatch_after(
81 dispatch_time(DISPATCH_TIME_NOW, presentationDifferenceRound), [self frameQueue], ^{
82 int64_t timeStampNs = CACurrentMediaTime() * NSEC_PER_SEC;
83 RTCVideoFrame *videoFrame = [[RTCVideoFrame alloc] initWithPixelBu ffer:pixelBuffer
84 rota tion:0
85 timeSta mpNs:timeStampNs];
86 CFRelease(sampleBuffer);
87
88 [self.delegate capturer:self didCaptureVideoFrame:videoFrame];
89 dispatch_semaphore_signal(_frameSemaphore);
magjed_webrtc 2017/05/29 13:14:25 I would like to only use one frame queue and avoid
daniela-webrtc 2017/06/01 13:08:57 I've removed the semaphore and the blocking and no
magjed_webrtc 2017/06/01 13:44:37 Sure, we can have a separate frameQueue to publish
90 });
91
92 dispatch_semaphore_wait(_frameSemaphore, DISPATCH_TIME_FOREVER);
93 }
94 }
95 [_reader cancelReading];
96 _reader = nil;
97 });
98 }
99
100 - (void)stopCapture {
101 _capturerStopped = YES;
102 RTCLog(@"File capturer stopped.");
103 }
104
105 #pragma mark - Private
106
107 - (nullable NSString *)pathForFileName:(NSString *)fileName {
108 NSArray *nameComponents = [fileName componentsSeparatedByString:@"."];
109 if (nameComponents.count != 2) {
110 return nil;
111 }
112
113 NSString *path =
114 [[NSBundle mainBundle] pathForResource:nameComponents[0] ofType:nameCompon ents[1]];
115 return path;
116 }
117
118 - (dispatch_queue_t)frameQueue {
119 if (!_frameQueue) {
120 _frameQueue = dispatch_queue_create("org.webrtc.filecapturer.video", DISPATC H_QUEUE_SERIAL);
121 dispatch_set_target_queue(_frameQueue,
122 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_ BACKGROUND, 0));
123 }
124 return _frameQueue;
125 }
126
127 - (void)dealloc {
128 [self stopCapture];
129 }
130
131 @end
OLDNEW
« no previous file with comments | « webrtc/sdk/objc/Framework/Classes/RTCFileVideoCapturer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698