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

Side by Side Diff: content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc

Issue 2263183002: Revert of Delete the class WebRtcVideoCapturerAdapter::MediaVideoFrameFactory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" 5 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/aligned_memory.h" 8 #include "base/memory/aligned_memory.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h" 10 #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h"
11 #include "media/base/timestamp_constants.h" 11 #include "media/base/timestamp_constants.h"
12 #include "media/base/video_frame.h"
13 #include "media/base/video_frame_pool.h"
12 #include "media/base/video_util.h" 14 #include "media/base/video_util.h"
13 #include "third_party/libyuv/include/libyuv/convert_from.h" 15 #include "third_party/libyuv/include/libyuv/convert_from.h"
14 #include "third_party/libyuv/include/libyuv/scale.h" 16 #include "third_party/libyuv/include/libyuv/scale.h"
15 #include "third_party/webrtc/common_video/include/video_frame_buffer.h" 17 #include "third_party/webrtc/common_video/include/video_frame_buffer.h"
16 #include "third_party/webrtc/common_video/rotation.h" 18 #include "third_party/webrtc/common_video/rotation.h"
19 #include "third_party/webrtc/media/base/videoframefactory.h"
17 #include "third_party/webrtc/media/engine/webrtcvideoframe.h" 20 #include "third_party/webrtc/media/engine/webrtcvideoframe.h"
18 21
19 namespace content { 22 namespace content {
20 namespace { 23 namespace {
21 24
22 // Empty method used for keeping a reference to the original media::VideoFrame. 25 // Empty method used for keeping a reference to the original media::VideoFrame.
23 // The reference to |frame| is kept in the closure that calls this method. 26 // The reference to |frame| is kept in the closure that calls this method.
24 void ReleaseOriginalFrame(const scoped_refptr<media::VideoFrame>& frame) { 27 void ReleaseOriginalFrame(const scoped_refptr<media::VideoFrame>& frame) {
25 } 28 }
26 29
27 } // anonymous namespace 30 } // anonymous namespace
28 31
32 // A cricket::VideoFrameFactory for media::VideoFrame. The purpose of this
33 // class is to avoid a premature frame copy. A media::VideoFrame is injected
34 // with SetFrame, and converted into a cricket::VideoFrame with
35 // CreateAliasedFrame. SetFrame should be called before CreateAliasedFrame
36 // for every frame.
37 class WebRtcVideoCapturerAdapter::MediaVideoFrameFactory
38 : public cricket::VideoFrameFactory {
39 public:
40 void SetFrame(const scoped_refptr<media::VideoFrame>& frame) {
41 DCHECK(frame.get());
42 // Create a CapturedFrame that only contains header information, not the
43 // actual pixel data.
44 captured_frame_.width = frame->natural_size().width();
45 captured_frame_.height = frame->natural_size().height();
46 captured_frame_.time_stamp = frame->timestamp().InMicroseconds() *
47 base::Time::kNanosecondsPerMicrosecond;
48 captured_frame_.pixel_height = 1;
49 captured_frame_.pixel_width = 1;
50 captured_frame_.rotation = webrtc::kVideoRotation_0;
51 captured_frame_.data = NULL;
52 captured_frame_.data_size = cricket::CapturedFrame::kUnknownDataSize;
53 captured_frame_.fourcc = static_cast<uint32_t>(cricket::FOURCC_ANY);
54
55 frame_ = frame;
56 }
57
58 void ReleaseFrame() { frame_ = NULL; }
59
60 const cricket::CapturedFrame* GetCapturedFrame() const {
61 return &captured_frame_;
62 }
63
64 cricket::VideoFrame* CreateAliasedFrame(
65 const cricket::CapturedFrame* input_frame,
66 int cropped_input_width,
67 int cropped_input_height,
68 int output_width,
69 int output_height) const override {
70 // Check that captured_frame is actually our frame.
71 DCHECK(input_frame == &captured_frame_);
72 DCHECK(frame_.get());
73
74 const int64_t timestamp_ns = frame_->timestamp().InMicroseconds() *
75 base::Time::kNanosecondsPerMicrosecond;
76
77 // Return |frame_| directly if it is texture backed, because there is no
78 // cropping support for texture yet. See http://crbug/503653.
79 // Return |frame_| directly if it is GpuMemoryBuffer backed, as we want to
80 // keep the frame on native buffers.
81 if (frame_->HasTextures() ||
82 frame_->storage_type() ==
83 media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS) {
84 return new cricket::WebRtcVideoFrame(
85 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame_),
86 timestamp_ns, webrtc::kVideoRotation_0);
87 }
88
89 // Create a centered cropped visible rect that preservers aspect ratio for
90 // cropped natural size.
91 gfx::Rect visible_rect = frame_->visible_rect();
92 visible_rect.ClampToCenteredSize(gfx::Size(
93 visible_rect.width() * cropped_input_width / input_frame->width,
94 visible_rect.height() * cropped_input_height / input_frame->height));
95
96 const gfx::Size output_size(output_width, output_height);
97 scoped_refptr<media::VideoFrame> video_frame =
98 media::VideoFrame::WrapVideoFrame(frame_, frame_->format(),
99 visible_rect, output_size);
100 if (!video_frame)
101 return nullptr;
102 video_frame->AddDestructionObserver(
103 base::Bind(&ReleaseOriginalFrame, frame_));
104
105 // If no scaling is needed, return a wrapped version of |frame_| directly.
106 if (video_frame->natural_size() == video_frame->visible_rect().size()) {
107 return new cricket::WebRtcVideoFrame(
108 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(video_frame),
109 timestamp_ns, webrtc::kVideoRotation_0);
110 }
111
112 // We need to scale the frame before we hand it over to cricket.
113 scoped_refptr<media::VideoFrame> scaled_frame =
114 scaled_frame_pool_.CreateFrame(media::PIXEL_FORMAT_I420, output_size,
115 gfx::Rect(output_size), output_size,
116 frame_->timestamp());
117 libyuv::I420Scale(video_frame->visible_data(media::VideoFrame::kYPlane),
118 video_frame->stride(media::VideoFrame::kYPlane),
119 video_frame->visible_data(media::VideoFrame::kUPlane),
120 video_frame->stride(media::VideoFrame::kUPlane),
121 video_frame->visible_data(media::VideoFrame::kVPlane),
122 video_frame->stride(media::VideoFrame::kVPlane),
123 video_frame->visible_rect().width(),
124 video_frame->visible_rect().height(),
125 scaled_frame->data(media::VideoFrame::kYPlane),
126 scaled_frame->stride(media::VideoFrame::kYPlane),
127 scaled_frame->data(media::VideoFrame::kUPlane),
128 scaled_frame->stride(media::VideoFrame::kUPlane),
129 scaled_frame->data(media::VideoFrame::kVPlane),
130 scaled_frame->stride(media::VideoFrame::kVPlane),
131 output_width, output_height, libyuv::kFilterBilinear);
132 return new cricket::WebRtcVideoFrame(
133 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(scaled_frame),
134 timestamp_ns, webrtc::kVideoRotation_0);
135 }
136
137 cricket::VideoFrame* CreateAliasedFrame(
138 const cricket::CapturedFrame* input_frame,
139 int output_width,
140 int output_height) const override {
141 return CreateAliasedFrame(input_frame, input_frame->width,
142 input_frame->height, output_width, output_height);
143 }
144
145 private:
146 scoped_refptr<media::VideoFrame> frame_;
147 cricket::CapturedFrame captured_frame_;
148 // This is used only if scaling is needed.
149 mutable media::VideoFramePool scaled_frame_pool_;
150 };
151
29 WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast) 152 WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast)
30 : is_screencast_(is_screencast), 153 : is_screencast_(is_screencast),
31 running_(false) { 154 running_(false) {
32 thread_checker_.DetachFromThread(); 155 thread_checker_.DetachFromThread();
156 // The base class takes ownership of the frame factory.
157 set_frame_factory(new MediaVideoFrameFactory);
33 } 158 }
34 159
35 WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() { 160 WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() {
36 DVLOG(3) << " WebRtcVideoCapturerAdapter::dtor"; 161 DVLOG(3) << " WebRtcVideoCapturerAdapter::dtor";
37 } 162 }
38 163
39 cricket::CaptureState WebRtcVideoCapturerAdapter::Start( 164 cricket::CaptureState WebRtcVideoCapturerAdapter::Start(
40 const cricket::VideoFormat& capture_format) { 165 const cricket::VideoFormat& capture_format) {
41 DCHECK(thread_checker_.CalledOnValidThread()); 166 DCHECK(thread_checker_.CalledOnValidThread());
42 DCHECK(!running_); 167 DCHECK(!running_);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 // just use what is provided. 211 // just use what is provided.
87 // Use the desired format as the best format. 212 // Use the desired format as the best format.
88 best_format->width = desired.width; 213 best_format->width = desired.width;
89 best_format->height = desired.height; 214 best_format->height = desired.height;
90 best_format->fourcc = cricket::FOURCC_I420; 215 best_format->fourcc = cricket::FOURCC_I420;
91 best_format->interval = desired.interval; 216 best_format->interval = desired.interval;
92 return true; 217 return true;
93 } 218 }
94 219
95 void WebRtcVideoCapturerAdapter::OnFrameCaptured( 220 void WebRtcVideoCapturerAdapter::OnFrameCaptured(
96 const scoped_refptr<media::VideoFrame>& input_frame) { 221 const scoped_refptr<media::VideoFrame>& video_frame) {
97 DCHECK(thread_checker_.CalledOnValidThread()); 222 DCHECK(thread_checker_.CalledOnValidThread());
98 TRACE_EVENT0("video", "WebRtcVideoCapturerAdapter::OnFrameCaptured"); 223 TRACE_EVENT0("video", "WebRtcVideoCapturerAdapter::OnFrameCaptured");
99 if (!(input_frame->IsMappable() && 224 if (!(video_frame->IsMappable() &&
100 (input_frame->format() == media::PIXEL_FORMAT_I420 || 225 (video_frame->format() == media::PIXEL_FORMAT_I420 ||
101 input_frame->format() == media::PIXEL_FORMAT_YV12 || 226 video_frame->format() == media::PIXEL_FORMAT_YV12 ||
102 input_frame->format() == media::PIXEL_FORMAT_YV12A))) { 227 video_frame->format() == media::PIXEL_FORMAT_YV12A))) {
103 // Since connecting sources and sinks do not check the format, we need to 228 // Since connecting sources and sinks do not check the format, we need to
104 // just ignore formats that we can not handle. 229 // just ignore formats that we can not handle.
105 NOTREACHED(); 230 NOTREACHED();
106 return; 231 return;
107 } 232 }
108 scoped_refptr<media::VideoFrame> frame = input_frame; 233 scoped_refptr<media::VideoFrame> frame = video_frame;
109 // Drop alpha channel since we do not support it yet. 234 // Drop alpha channel since we do not support it yet.
110 if (frame->format() == media::PIXEL_FORMAT_YV12A) 235 if (frame->format() == media::PIXEL_FORMAT_YV12A)
111 frame = media::WrapAsI420VideoFrame(input_frame); 236 frame = media::WrapAsI420VideoFrame(video_frame);
112 237
113 const int orig_width = frame->natural_size().width(); 238 // Inject the frame via the VideoFrameFactory of base class.
114 const int orig_height = frame->natural_size().height(); 239 MediaVideoFrameFactory* media_video_frame_factory =
115 int adapted_width; 240 reinterpret_cast<MediaVideoFrameFactory*>(frame_factory());
116 int adapted_height; 241 media_video_frame_factory->SetFrame(frame);
117 // The VideoAdapter is only used for cpu-adaptation downscaling, no
118 // aspect changes. So we ignore these crop-related outputs.
119 int crop_width;
120 int crop_height;
121 int crop_x;
122 int crop_y;
123 int64_t translated_camera_time_us;
124 242
125 if (!AdaptFrame(orig_width, orig_height, 243 // This signals to libJingle that a new VideoFrame is available.
126 frame->timestamp().InMicroseconds(), 244 SignalFrameCaptured(this, media_video_frame_factory->GetCapturedFrame());
127 rtc::TimeMicros(),
128 &adapted_width, &adapted_height,
129 &crop_width, &crop_height, &crop_x, &crop_y,
130 &translated_camera_time_us)) {
131 return;
132 }
133 245
134 // Return |frame| directly if it is texture backed, because there is no 246 media_video_frame_factory->ReleaseFrame(); // Release the frame ASAP.
135 // cropping support for texture yet. See http://crbug/503653.
136 // Return |frame| directly if it is GpuMemoryBuffer backed, as we want to
137 // keep the frame on native buffers.
138 if (frame->HasTextures() ||
139 frame->storage_type() ==
140 media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS) {
141 OnFrame(cricket::WebRtcVideoFrame(
142 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(frame),
143 translated_camera_time_us, webrtc::kVideoRotation_0),
144 orig_width, orig_height);
145 return;
146 }
147
148 // Create a centered cropped visible rect that preservers aspect ratio for
149 // cropped natural size.
150 gfx::Rect visible_rect = frame->visible_rect();
151 visible_rect.ClampToCenteredSize(gfx::Size(
152 visible_rect.width() * adapted_width / orig_width,
153 visible_rect.height() * adapted_height / orig_height));
154
155 const gfx::Size adapted_size(adapted_width, adapted_height);
156 scoped_refptr<media::VideoFrame> video_frame =
157 media::VideoFrame::WrapVideoFrame(frame, frame->format(),
158 visible_rect, adapted_size);
159 if (!video_frame)
160 return;
161
162 video_frame->AddDestructionObserver(base::Bind(&ReleaseOriginalFrame, frame));
163
164 // If no scaling is needed, return a wrapped version of |frame| directly.
165 if (video_frame->natural_size() == video_frame->visible_rect().size()) {
166 OnFrame(cricket::WebRtcVideoFrame(
167 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(video_frame),
168 translated_camera_time_us, webrtc::kVideoRotation_0),
169 orig_width, orig_height);
170 return;
171 }
172
173 // We need to scale the frame before we hand it over to webrtc.
174 scoped_refptr<media::VideoFrame> scaled_frame =
175 scaled_frame_pool_.CreateFrame(media::PIXEL_FORMAT_I420, adapted_size,
176 gfx::Rect(adapted_size), adapted_size,
177 frame->timestamp());
178 libyuv::I420Scale(video_frame->visible_data(media::VideoFrame::kYPlane),
179 video_frame->stride(media::VideoFrame::kYPlane),
180 video_frame->visible_data(media::VideoFrame::kUPlane),
181 video_frame->stride(media::VideoFrame::kUPlane),
182 video_frame->visible_data(media::VideoFrame::kVPlane),
183 video_frame->stride(media::VideoFrame::kVPlane),
184 video_frame->visible_rect().width(),
185 video_frame->visible_rect().height(),
186 scaled_frame->data(media::VideoFrame::kYPlane),
187 scaled_frame->stride(media::VideoFrame::kYPlane),
188 scaled_frame->data(media::VideoFrame::kUPlane),
189 scaled_frame->stride(media::VideoFrame::kUPlane),
190 scaled_frame->data(media::VideoFrame::kVPlane),
191 scaled_frame->stride(media::VideoFrame::kVPlane),
192 adapted_width, adapted_height, libyuv::kFilterBilinear);
193
194 OnFrame(cricket::WebRtcVideoFrame(
195 new rtc::RefCountedObject<WebRtcVideoFrameAdapter>(scaled_frame),
196 translated_camera_time_us, webrtc::kVideoRotation_0),
197 orig_width, orig_height);
198 } 247 }
199 248
200 } // namespace content 249 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698