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

Side by Side Diff: webrtc/api/androidvideocapturer.cc

Issue 1973873003: Delete AndroidVideoCapturer::FrameFactory. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix width/height typo. Tests. Formatting. Created 4 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
OLDNEW
1 /* 1 /*
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/api/androidvideocapturer.h" 11 #include "webrtc/api/androidvideocapturer.h"
12 12
13 #include <memory> 13 #include <memory>
14 14
15 #include "webrtc/api/java/jni/native_handle_impl.h" 15 #include "webrtc/api/java/jni/native_handle_impl.h"
16 #include "webrtc/base/common.h" 16 #include "webrtc/base/common.h"
17 #include "webrtc/base/timeutils.h" 17 #include "webrtc/base/timeutils.h"
18 #include "webrtc/media/engine/webrtcvideoframe.h" 18 #include "webrtc/media/engine/webrtcvideoframe.h"
19 19
20 namespace webrtc { 20 namespace webrtc {
21 21
22 // A hack for avoiding deep frame copies in
23 // cricket::VideoCapturer.SignalFrameCaptured() using a custom FrameFactory.
24 // A frame is injected using UpdateCapturedFrame(), and converted into a
25 // cricket::VideoFrame with CreateAliasedFrame(). UpdateCapturedFrame() should
26 // be called before CreateAliasedFrame() for every frame.
27 // TODO(magjed): Add an interface cricket::VideoCapturer::OnFrameCaptured()
28 // for ref counted I420 frames instead of this hack.
29 class AndroidVideoCapturer::FrameFactory : public cricket::VideoFrameFactory {
30 public:
31 explicit FrameFactory(
32 const rtc::scoped_refptr<AndroidVideoCapturerDelegate>& delegate)
33 : delegate_(delegate) {
34 // Create a CapturedFrame that only contains header information, not the
35 // actual pixel data.
36 captured_frame_.pixel_height = 1;
37 captured_frame_.pixel_width = 1;
38 captured_frame_.data = nullptr;
39 captured_frame_.data_size = cricket::CapturedFrame::kUnknownDataSize;
40 captured_frame_.fourcc = static_cast<uint32_t>(cricket::FOURCC_ANY);
41 }
42
43 void UpdateCapturedFrame(
44 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
45 int rotation,
46 int64_t time_stamp_in_ns) {
47 RTC_DCHECK(rotation == 0 || rotation == 90 || rotation == 180 ||
48 rotation == 270);
49 buffer_ = buffer;
50 captured_frame_.width = buffer->width();
51 captured_frame_.height = buffer->height();
52 captured_frame_.time_stamp = time_stamp_in_ns;
53 captured_frame_.rotation = static_cast<webrtc::VideoRotation>(rotation);
54 }
55
56 void ClearCapturedFrame() {
57 buffer_ = nullptr;
58 captured_frame_.width = 0;
59 captured_frame_.height = 0;
60 captured_frame_.time_stamp = 0;
61 }
62
63 const cricket::CapturedFrame* GetCapturedFrame() const {
64 return &captured_frame_;
65 }
66
67 cricket::VideoFrame* CreateAliasedFrame(
68 const cricket::CapturedFrame* captured_frame,
69 int dst_width,
70 int dst_height) const override {
71 // Check that captured_frame is actually our frame.
72 RTC_CHECK(captured_frame == &captured_frame_);
73 RTC_CHECK(buffer_->native_handle() == nullptr);
74
75 std::unique_ptr<cricket::VideoFrame> frame(new cricket::WebRtcVideoFrame(
76 ShallowCenterCrop(buffer_, dst_width, dst_height),
77 captured_frame->time_stamp, captured_frame->rotation));
78 // Caller takes ownership.
79 // TODO(magjed): Change CreateAliasedFrame() to return a std::unique_ptr.
80 return apply_rotation_ ? frame->GetCopyWithRotationApplied()->Copy()
81 : frame.release();
82 }
83
84 cricket::VideoFrame* CreateAliasedFrame(
85 const cricket::CapturedFrame* input_frame,
86 int cropped_input_width,
87 int cropped_input_height,
88 int output_width,
89 int output_height) const override {
90 if (buffer_->native_handle() != nullptr) {
91 rtc::scoped_refptr<webrtc::VideoFrameBuffer> scaled_buffer(
92 static_cast<webrtc_jni::AndroidTextureBuffer*>(buffer_.get())
93 ->CropScaleAndRotate(cropped_input_width, cropped_input_height,
94 output_width, output_height,
95 apply_rotation_ ? input_frame->rotation
96 : webrtc::kVideoRotation_0));
97 return new cricket::WebRtcVideoFrame(
98 scaled_buffer, input_frame->time_stamp,
99 apply_rotation_ ? webrtc::kVideoRotation_0 : input_frame->rotation);
100 }
101 return VideoFrameFactory::CreateAliasedFrame(input_frame,
102 cropped_input_width,
103 cropped_input_height,
104 output_width,
105 output_height);
106 }
107
108 private:
109 rtc::scoped_refptr<webrtc::VideoFrameBuffer> buffer_;
110 cricket::CapturedFrame captured_frame_;
111 rtc::scoped_refptr<AndroidVideoCapturerDelegate> delegate_;
112 };
113
114 AndroidVideoCapturer::AndroidVideoCapturer( 22 AndroidVideoCapturer::AndroidVideoCapturer(
115 const rtc::scoped_refptr<AndroidVideoCapturerDelegate>& delegate) 23 const rtc::scoped_refptr<AndroidVideoCapturerDelegate>& delegate)
116 : running_(false), 24 : running_(false),
117 delegate_(delegate), 25 delegate_(delegate),
118 frame_factory_(NULL),
119 current_state_(cricket::CS_STOPPED) { 26 current_state_(cricket::CS_STOPPED) {
120 thread_checker_.DetachFromThread(); 27 thread_checker_.DetachFromThread();
121 SetSupportedFormats(delegate_->GetSupportedFormats()); 28 SetSupportedFormats(delegate_->GetSupportedFormats());
122 } 29 }
123 30
124 AndroidVideoCapturer::~AndroidVideoCapturer() { 31 AndroidVideoCapturer::~AndroidVideoCapturer() {
125 RTC_CHECK(!running_); 32 RTC_CHECK(!running_);
126 } 33 }
127 34
128 cricket::CaptureState AndroidVideoCapturer::Start( 35 cricket::CaptureState AndroidVideoCapturer::Start(
129 const cricket::VideoFormat& capture_format) { 36 const cricket::VideoFormat& capture_format) {
130 RTC_CHECK(thread_checker_.CalledOnValidThread()); 37 RTC_CHECK(thread_checker_.CalledOnValidThread());
131 RTC_CHECK(!running_); 38 RTC_CHECK(!running_);
132 const int fps = cricket::VideoFormat::IntervalToFps(capture_format.interval); 39 const int fps = cricket::VideoFormat::IntervalToFps(capture_format.interval);
133 LOG(LS_INFO) << " AndroidVideoCapturer::Start " << capture_format.width << "x" 40 LOG(LS_INFO) << " AndroidVideoCapturer::Start " << capture_format.width << "x"
134 << capture_format.height << "@" << fps; 41 << capture_format.height << "@" << fps;
135 42
136 frame_factory_ = new AndroidVideoCapturer::FrameFactory(delegate_.get());
137 set_frame_factory(frame_factory_);
138
139 running_ = true; 43 running_ = true;
140 delegate_->Start(capture_format.width, capture_format.height, fps, this); 44 delegate_->Start(capture_format.width, capture_format.height, fps, this);
141 SetCaptureFormat(&capture_format); 45 SetCaptureFormat(&capture_format);
142 current_state_ = cricket::CS_STARTING; 46 current_state_ = cricket::CS_STARTING;
143 return current_state_; 47 return current_state_;
144 } 48 }
145 49
146 void AndroidVideoCapturer::Stop() { 50 void AndroidVideoCapturer::Stop() {
147 LOG(LS_INFO) << " AndroidVideoCapturer::Stop "; 51 LOG(LS_INFO) << " AndroidVideoCapturer::Stop ";
148 RTC_CHECK(thread_checker_.CalledOnValidThread()); 52 RTC_CHECK(thread_checker_.CalledOnValidThread());
(...skipping 20 matching lines...) Expand all
169 void AndroidVideoCapturer::OnCapturerStarted(bool success) { 73 void AndroidVideoCapturer::OnCapturerStarted(bool success) {
170 RTC_CHECK(thread_checker_.CalledOnValidThread()); 74 RTC_CHECK(thread_checker_.CalledOnValidThread());
171 cricket::CaptureState new_state = 75 cricket::CaptureState new_state =
172 success ? cricket::CS_RUNNING : cricket::CS_FAILED; 76 success ? cricket::CS_RUNNING : cricket::CS_FAILED;
173 if (new_state == current_state_) 77 if (new_state == current_state_)
174 return; 78 return;
175 current_state_ = new_state; 79 current_state_ = new_state;
176 SetCaptureState(new_state); 80 SetCaptureState(new_state);
177 } 81 }
178 82
179 void AndroidVideoCapturer::OnIncomingFrame( 83 void AndroidVideoCapturer::OnIncomingFrame(
magjed_webrtc 2016/05/17 12:12:39 Add two methods OnIncomingTexture and OnIncomingNV
nisse-webrtc 2016/05/18 11:16:33 Done. (But named OnNV21Frame and OnTextureFrame).
magjed_webrtc 2016/05/18 11:41:59 If you can choose, I prefer to keep the conversion
nisse-webrtc 2016/05/18 12:17:52 I'll give it a try.
180 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer, 84 const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
181 int rotation, 85 int rotation_int,
182 int64_t time_stamp) { 86 int64_t time_stamp) {
183 RTC_CHECK(thread_checker_.CalledOnValidThread()); 87 RTC_CHECK(thread_checker_.CalledOnValidThread());
184 frame_factory_->UpdateCapturedFrame(buffer, rotation, time_stamp); 88 RTC_DCHECK(rotation_int == 0 || rotation_int == 90 || rotation_int == 180 ||
185 SignalFrameCaptured(this, frame_factory_->GetCapturedFrame()); 89 rotation_int == 270);
186 frame_factory_->ClearCapturedFrame(); 90 webrtc::VideoRotation rotation =
91 static_cast<webrtc::VideoRotation>(rotation_int);
92 int adapted_width;
93 int adapted_height;
94 int crop_width;
95 int crop_height;
96 int crop_x;
97 int crop_y;
98
99 if (!AdaptFrame(buffer->width(), buffer->height(),
100 &adapted_width, &adapted_height,
101 &crop_width, &crop_height,
102 &crop_x, &crop_y)) {
103 return;
104 }
105
106 rtc::scoped_refptr<webrtc::VideoFrameBuffer> adapted;
107 if (buffer->native_handle() != nullptr) {
108 // Texture frame.
109 OnFrame(
110 cricket::WebRtcVideoFrame(
111 static_cast<webrtc_jni::AndroidTextureBuffer*>(buffer.get())
112 ->CropScaleAndRotate(
113 crop_width, crop_height, crop_width, crop_height,
114 adapted_width, adapted_height,
115 apply_rotation() ? rotation : webrtc::kVideoRotation_0),
116 time_stamp, apply_rotation() ? webrtc::kVideoRotation_0 : rotation),
117 buffer->width(), buffer->height());
118 } else {
119 // Memory frame.
120 rtc::scoped_refptr<webrtc::VideoFrameBuffer> adapted;
121 if (adapted_width == buffer->width() &&
122 adapted_height == buffer->height() &&
123 crop_width == buffer->width() &&
124 crop_width == buffer->height()) {
125 adapted = buffer;
126 } else {
127 adapted = I420Buffer::CropAndScale(buffer, crop_x, crop_y,
magjed_webrtc 2016/05/17 12:19:12 Use a frame pool instead of allocating new memory
nisse-webrtc 2016/05/18 11:16:33 Haven't done this yet. Would the pool be an additi
magjed_webrtc 2016/05/18 11:41:59 I think it's best if the output I420Buffer is an a
nisse-webrtc 2016/05/18 12:17:52 I really dislike destination arguments accessed vi
nisse-webrtc 2016/05/18 13:54:58 I now use buffer_pool_ for the unscaled frame, sim
128 crop_width, crop_height,
129 adapted_width, adapted_height);
130 }
131 // TODO(nisse): Introduce a rotate method working with I420Buffer?
132 cricket::WebRtcVideoFrame frame(adapted, time_stamp, rotation);
133 OnFrame(apply_rotation() ? *frame.GetCopyWithRotationApplied() : frame,
134 buffer->width(), buffer->height());
135 }
187 } 136 }
188 137
189 void AndroidVideoCapturer::OnOutputFormatRequest( 138 void AndroidVideoCapturer::OnOutputFormatRequest(
190 int width, int height, int fps) { 139 int width, int height, int fps) {
191 RTC_CHECK(thread_checker_.CalledOnValidThread()); 140 RTC_CHECK(thread_checker_.CalledOnValidThread());
192 cricket::VideoFormat format(width, height, 141 cricket::VideoFormat format(width, height,
193 cricket::VideoFormat::FpsToInterval(fps), 0); 142 cricket::VideoFormat::FpsToInterval(fps), 0);
194 video_adapter()->OnOutputFormatRequest(format); 143 video_adapter()->OnOutputFormatRequest(format);
195 } 144 }
196 145
197 bool AndroidVideoCapturer::GetBestCaptureFormat( 146 bool AndroidVideoCapturer::GetBestCaptureFormat(
198 const cricket::VideoFormat& desired, 147 const cricket::VideoFormat& desired,
199 cricket::VideoFormat* best_format) { 148 cricket::VideoFormat* best_format) {
200 // Delegate this choice to VideoCapturer.startCapture(). 149 // Delegate this choice to VideoCapturer.startCapture().
201 *best_format = desired; 150 *best_format = desired;
202 return true; 151 return true;
203 } 152 }
204 153
205 } // namespace webrtc 154 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698