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

Side by Side Diff: content/browser/renderer_host/media/video_capture_device_client.cc

Issue 1132683004: MJPEG acceleration for video capture, browser part (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mjpeg-2-gpu
Patch Set: add flag --enable-accelerated-mjpeg-decode Created 5 years, 6 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/browser/renderer_host/media/video_capture_device_client.h" 5 #include "content/browser/renderer_host/media/video_capture_device_client.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "content/browser/compositor/image_transport_factory.h" 10 #include "content/browser/compositor/image_transport_factory.h"
11 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" 11 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
12 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" 12 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
13 #include "content/browser/gpu/gpu_data_manager_impl.h" 13 #include "content/browser/gpu/gpu_data_manager_impl.h"
14 #include "content/browser/renderer_host/gpu_jpeg_decoder.h"
14 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" 15 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
15 #include "content/browser/renderer_host/media/video_capture_controller.h" 16 #include "content/browser/renderer_host/media/video_capture_controller.h"
16 #include "content/common/gpu/client/context_provider_command_buffer.h" 17 #include "content/common/gpu/client/context_provider_command_buffer.h"
17 #include "content/common/gpu/client/gl_helper.h" 18 #include "content/common/gpu/client/gl_helper.h"
18 #include "content/common/gpu/client/gpu_channel_host.h" 19 #include "content/common/gpu/client/gpu_channel_host.h"
19 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 20 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
20 #include "content/common/gpu/gpu_process_launch_causes.h" 21 #include "content/common/gpu/gpu_process_launch_causes.h"
21 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
22 #include "gpu/command_buffer/common/mailbox_holder.h" 23 #include "gpu/command_buffer/common/mailbox_holder.h"
23 #include "media/base/bind_to_current_loop.h" 24 #include "media/base/bind_to_current_loop.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 117 }
117 int id() const override { return id_; } 118 int id() const override { return id_; }
118 size_t size() const override { return buffer_handle_->size(); } 119 size_t size() const override { return buffer_handle_->size(); }
119 void* data() override { return buffer_handle_->data(); } 120 void* data() override { return buffer_handle_->data(); }
120 gfx::GpuMemoryBufferType GetType() override { 121 gfx::GpuMemoryBufferType GetType() override {
121 return buffer_handle_->GetType(); 122 return buffer_handle_->GetType();
122 } 123 }
123 ClientBuffer AsClientBuffer() override { 124 ClientBuffer AsClientBuffer() override {
124 return buffer_handle_->AsClientBuffer(); 125 return buffer_handle_->AsClientBuffer();
125 } 126 }
127 base::PlatformFile AsPlatformHandle() override {
128 return buffer_handle_->AsPlatformHandle();
129 }
126 130
127 private: 131 private:
128 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); } 132 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); }
129 133
130 const int id_; 134 const int id_;
131 const scoped_refptr<VideoCaptureBufferPool> pool_; 135 const scoped_refptr<VideoCaptureBufferPool> pool_;
132 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_; 136 const scoped_ptr<VideoCaptureBufferPool::BufferHandle> buffer_handle_;
133 }; 137 };
134 138
135 // Internal ref-counted class wrapping an incoming GpuMemoryBuffer into a 139 // Internal ref-counted class wrapping an incoming GpuMemoryBuffer into a
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 scoped_ptr<GLHelper> gl_helper_; 193 scoped_ptr<GLHelper> gl_helper_;
190 194
191 DISALLOW_COPY_AND_ASSIGN(TextureWrapHelper); 195 DISALLOW_COPY_AND_ASSIGN(TextureWrapHelper);
192 }; 196 };
193 197
194 VideoCaptureDeviceClient::VideoCaptureDeviceClient( 198 VideoCaptureDeviceClient::VideoCaptureDeviceClient(
195 const base::WeakPtr<VideoCaptureController>& controller, 199 const base::WeakPtr<VideoCaptureController>& controller,
196 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool, 200 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
197 const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner) 201 const scoped_refptr<base::SingleThreadTaskRunner>& capture_task_runner)
198 : controller_(controller), 202 : controller_(controller),
203 external_jpeg_decoder_initialized_(false),
199 buffer_pool_(buffer_pool), 204 buffer_pool_(buffer_pool),
200 capture_task_runner_(capture_task_runner), 205 capture_task_runner_(capture_task_runner),
201 last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) { 206 last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {
202 DCHECK_CURRENTLY_ON(BrowserThread::IO); 207 DCHECK_CURRENTLY_ON(BrowserThread::IO);
203 } 208 }
204 209
205 VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {} 210 VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {
211 DCHECK(capture_task_runner_->BelongsToCurrentThread());
212 external_jpeg_decoder_.reset();
213 }
206 214
207 void VideoCaptureDeviceClient::OnIncomingCapturedData( 215 void VideoCaptureDeviceClient::OnIncomingCapturedData(
208 const uint8* data, 216 const uint8* data,
209 int length, 217 int length,
210 const VideoCaptureFormat& frame_format, 218 const VideoCaptureFormat& frame_format,
211 int rotation, 219 int rotation,
212 const base::TimeTicks& timestamp) { 220 const base::TimeTicks& timestamp) {
213 TRACE_EVENT0("video", "VideoCaptureDeviceClient::OnIncomingCapturedData"); 221 TRACE_EVENT0("video", "VideoCaptureDeviceClient::OnIncomingCapturedData");
214 222
215 if (last_captured_pixel_format_ != frame_format.pixel_format) { 223 if (last_captured_pixel_format_ != frame_format.pixel_format) {
216 OnLog("Pixel format: " + media::VideoCaptureFormat::PixelFormatToString( 224 OnLog("Pixel format: " + media::VideoCaptureFormat::PixelFormatToString(
217 frame_format.pixel_format)); 225 frame_format.pixel_format));
218 last_captured_pixel_format_ = frame_format.pixel_format; 226 last_captured_pixel_format_ = frame_format.pixel_format;
227
228 if (frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG &&
229 !external_jpeg_decoder_initialized_) {
230 external_jpeg_decoder_initialized_ = true;
231 if (GpuJpegDecoder::Supported()) {
232 // base::Unretained is safe because |this| outlives
233 // |external_jpeg_decoder_|.
234 external_jpeg_decoder_.reset(new GpuJpegDecoder(
235 base::Bind(&VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame,
piman 2015/06/05 23:07:51 Maybe you can bind to DoIncomingCapturedVideoFrame
kcwu 2015/06/17 14:35:37 Done.
236 base::Unretained(this)),
237 // TODO(kcwu): fallback to software decode if error.
238 base::Bind(&VideoCaptureDeviceClient::OnError,
piman 2015/06/05 23:07:51 Same here, bind to DoErrorOnIOThread?
kcwu 2015/06/17 14:35:37 Not exactly. VideoCaptureDeviceClient::OnError = O
239 base::Unretained(this))));
240 if (!external_jpeg_decoder_->Initialize())
241 external_jpeg_decoder_.reset();
242 }
243 }
219 } 244 }
220 245
221 if (!frame_format.IsValid()) 246 if (!frame_format.IsValid())
222 return; 247 return;
223 248
224 // |chopped_{width,height} and |new_unrotated_{width,height}| are the lowest 249 // |chopped_{width,height} and |new_unrotated_{width,height}| are the lowest
225 // bit decomposition of {width, height}, grabbing the odd and even parts. 250 // bit decomposition of {width, height}, grabbing the odd and even parts.
226 const int chopped_width = frame_format.frame_size.width() & 1; 251 const int chopped_width = frame_format.frame_size.width() & 1;
227 const int chopped_height = frame_format.frame_size.height() & 1; 252 const int chopped_height = frame_format.frame_size.height() & 1;
228 const int new_unrotated_width = frame_format.frame_size.width() & ~1; 253 const int new_unrotated_width = frame_format.frame_size.width() & ~1;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 origin_colorspace = libyuv::FOURCC_MJPG; 347 origin_colorspace = libyuv::FOURCC_MJPG;
323 break; 348 break;
324 default: 349 default:
325 NOTREACHED(); 350 NOTREACHED();
326 } 351 }
327 352
328 // The input |length| can be greater than the required buffer size because of 353 // The input |length| can be greater than the required buffer size because of
329 // paddings and/or alignments, but it cannot be smaller. 354 // paddings and/or alignments, but it cannot be smaller.
330 DCHECK_GE(static_cast<size_t>(length), frame_format.ImageAllocationSize()); 355 DCHECK_GE(static_cast<size_t>(length), frame_format.ImageAllocationSize());
331 356
357 if (external_jpeg_decoder_ &&
358 frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG && rotation == 0 &&
359 !flip) {
360 external_jpeg_decoder_->DecodeCapturedData(data, length, frame_format,
361 timestamp, buffer.Pass());
362 return;
363 }
364
332 if (libyuv::ConvertToI420(data, 365 if (libyuv::ConvertToI420(data,
333 length, 366 length,
334 yplane, 367 yplane,
335 yplane_stride, 368 yplane_stride,
336 uplane, 369 uplane,
337 uv_plane_stride, 370 uv_plane_stride,
338 vplane, 371 vplane,
339 uv_plane_stride, 372 uv_plane_stride,
340 crop_x, 373 crop_x,
341 crop_y, 374 crop_y,
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 void VideoCaptureDeviceClient::TextureWrapHelper::OnError( 695 void VideoCaptureDeviceClient::TextureWrapHelper::OnError(
663 const std::string& message) { 696 const std::string& message) {
664 DCHECK(capture_task_runner_->BelongsToCurrentThread()); 697 DCHECK(capture_task_runner_->BelongsToCurrentThread());
665 DLOG(ERROR) << message; 698 DLOG(ERROR) << message;
666 BrowserThread::PostTask( 699 BrowserThread::PostTask(
667 BrowserThread::IO, FROM_HERE, 700 BrowserThread::IO, FROM_HERE,
668 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_)); 701 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
669 } 702 }
670 703
671 } // namespace content 704 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698