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

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

Issue 1016773002: MJPEG acceleration for video capture using VAAPI (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: support multiple jpeg decoder Created 5 years, 8 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/renderer_host/gpu_jpeg_decoder.h"
10 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" 11 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
11 #include "content/browser/renderer_host/media/video_capture_controller.h" 12 #include "content/browser/renderer_host/media/video_capture_controller.h"
12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
13 #include "media/base/bind_to_current_loop.h" 14 #include "media/base/bind_to_current_loop.h"
14 #include "media/base/video_capture_types.h" 15 #include "media/base/video_capture_types.h"
15 #include "media/base/video_frame.h" 16 #include "media/base/video_frame.h"
16 #include "third_party/libyuv/include/libyuv.h" 17 #include "third_party/libyuv/include/libyuv.h"
17 18
18 using media::VideoCaptureFormat; 19 using media::VideoCaptureFormat;
19 using media::VideoFrame; 20 using media::VideoFrame;
20 21
21 namespace content { 22 namespace content {
22 23
23 // Class combining a Client::Buffer interface implementation and a pool buffer 24 // Class combining a Client::Buffer interface implementation and a pool buffer
24 // implementation to guarantee proper cleanup on destruction on our side. 25 // implementation to guarantee proper cleanup on destruction on our side.
25 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer { 26 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
26 public: 27 public:
27 AutoReleaseBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool, 28 AutoReleaseBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool,
28 int buffer_id, 29 int buffer_id,
29 void* data, 30 void* data,
30 size_t size) 31 size_t size,
31 : pool_(pool), 32 base::SharedMemoryHandle handle)
32 id_(buffer_id), 33 : pool_(pool), id_(buffer_id), data_(data), size_(size), handle_(handle) {
33 data_(data),
34 size_(size) {
35 DCHECK(pool_.get()); 34 DCHECK(pool_.get());
36 } 35 }
37 int id() const override { return id_; } 36 int id() const override { return id_; }
38 void* data() const override { return data_; } 37 void* data() const override { return data_; }
39 size_t size() const override { return size_; } 38 size_t size() const override { return size_; }
39 base::SharedMemoryHandle handle() const override { return handle_; }
40 40
41 private: 41 private:
42 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); } 42 ~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); }
43 43
44 const scoped_refptr<VideoCaptureBufferPool> pool_; 44 const scoped_refptr<VideoCaptureBufferPool> pool_;
45 const int id_; 45 const int id_;
46 void* const data_; 46 void* const data_;
47 const size_t size_; 47 const size_t size_;
48 const base::SharedMemoryHandle handle_;
48 }; 49 };
49 50
50 VideoCaptureDeviceClient::VideoCaptureDeviceClient( 51 VideoCaptureDeviceClient::VideoCaptureDeviceClient(
51 const base::WeakPtr<VideoCaptureController>& controller, 52 const base::WeakPtr<VideoCaptureController>& controller,
52 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool) 53 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool)
53 : controller_(controller), 54 : controller_(controller),
54 buffer_pool_(buffer_pool), 55 buffer_pool_(buffer_pool),
55 last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {} 56 last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
58 }
56 59
57 VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {} 60 VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {
61 }
58 62
59 void VideoCaptureDeviceClient::OnIncomingCapturedData( 63 void VideoCaptureDeviceClient::OnIncomingCapturedData(
60 const uint8* data, 64 const uint8* data,
61 int length, 65 int length,
62 const VideoCaptureFormat& frame_format, 66 const VideoCaptureFormat& frame_format,
63 int rotation, 67 int rotation,
64 const base::TimeTicks& timestamp) { 68 const base::TimeTicks& timestamp) {
65 TRACE_EVENT0("video", "VideoCaptureDeviceClient::OnIncomingCapturedData"); 69 TRACE_EVENT0("video", "VideoCaptureDeviceClient::OnIncomingCapturedData");
66 70
67 if (last_captured_pixel_format_ != frame_format.pixel_format) { 71 if (last_captured_pixel_format_ != frame_format.pixel_format) {
68 OnLog("Pixel format: " + media::VideoCaptureFormat::PixelFormatToString( 72 OnLog("Pixel format: " + media::VideoCaptureFormat::PixelFormatToString(
69 frame_format.pixel_format)); 73 frame_format.pixel_format));
70 last_captured_pixel_format_ = frame_format.pixel_format; 74 last_captured_pixel_format_ = frame_format.pixel_format;
75
76 if (frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG &&
77 !external_jpeg_decoder_ &&
78 GpuJpegDecoder::Supported()) {
79 external_jpeg_decoder_.reset(new GpuJpegDecoder(this));
80 if (!external_jpeg_decoder_->Initialize()) {
wuchengli 2015/04/24 05:54:23 We'll try this for every frame if this fails. Can
kcwu 2015/04/30 19:25:39 Done.
81 // Reset external_jpeg_decoder_ to fallback to software decode.
82 external_jpeg_decoder_.reset();
83 }
84 }
71 } 85 }
72 86
73 if (!frame_format.IsValid()) 87 if (!frame_format.IsValid())
74 return; 88 return;
75 89
90 if (frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG &&
91 external_jpeg_decoder_ && rotation == 0 &&
92 !external_jpeg_decoder_->IsFailed()) {
wuchengli 2015/04/24 05:54:23 Let's have a failure callback from GpuJpegDecoder
kcwu 2015/04/30 19:25:39 Since |external_jpeg_decoder_| is created in the c
93 external_jpeg_decoder_->DecodeCapturedData(data, length, frame_format,
wuchengli 2015/04/24 05:54:23 DecodeCapturedData can return a value to indicate
kcwu 2015/04/30 19:25:39 Done.
94 rotation, timestamp);
95 return;
96 }
97
76 // |chopped_{width,height} and |new_unrotated_{width,height}| are the lowest 98 // |chopped_{width,height} and |new_unrotated_{width,height}| are the lowest
77 // bit decomposition of {width, height}, grabbing the odd and even parts. 99 // bit decomposition of {width, height}, grabbing the odd and even parts.
78 const int chopped_width = frame_format.frame_size.width() & 1; 100 const int chopped_width = frame_format.frame_size.width() & 1;
79 const int chopped_height = frame_format.frame_size.height() & 1; 101 const int chopped_height = frame_format.frame_size.height() & 1;
80 const int new_unrotated_width = frame_format.frame_size.width() & ~1; 102 const int new_unrotated_width = frame_format.frame_size.width() & ~1;
81 const int new_unrotated_height = frame_format.frame_size.height() & ~1; 103 const int new_unrotated_height = frame_format.frame_size.height() & ~1;
82 104
83 int destination_width = new_unrotated_width; 105 int destination_width = new_unrotated_width;
84 int destination_height = new_unrotated_height; 106 int destination_height = new_unrotated_height;
85 if (rotation == 90 || rotation == 270) { 107 if (rotation == 90 || rotation == 270) {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 DCHECK_GT(dimensions.width(), 0); 331 DCHECK_GT(dimensions.width(), 0);
310 DCHECK_GT(dimensions.height(), 0); 332 DCHECK_GT(dimensions.height(), 0);
311 333
312 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId; 334 int buffer_id_to_drop = VideoCaptureBufferPool::kInvalidId;
313 const int buffer_id = 335 const int buffer_id =
314 buffer_pool_->ReserveForProducer(format, dimensions, &buffer_id_to_drop); 336 buffer_pool_->ReserveForProducer(format, dimensions, &buffer_id_to_drop);
315 if (buffer_id == VideoCaptureBufferPool::kInvalidId) 337 if (buffer_id == VideoCaptureBufferPool::kInvalidId)
316 return NULL; 338 return NULL;
317 void* data; 339 void* data;
318 size_t size; 340 size_t size;
319 buffer_pool_->GetBufferInfo(buffer_id, &data, &size); 341 base::SharedMemoryHandle handle;
342 buffer_pool_->GetBufferInfo(buffer_id, &data, &size, &handle);
320 343
321 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer( 344 scoped_refptr<media::VideoCaptureDevice::Client::Buffer> output_buffer(
322 new AutoReleaseBuffer(buffer_pool_, buffer_id, data, size)); 345 new AutoReleaseBuffer(buffer_pool_, buffer_id, data, size, handle));
323 346
324 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) { 347 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) {
325 BrowserThread::PostTask(BrowserThread::IO, 348 BrowserThread::PostTask(BrowserThread::IO,
326 FROM_HERE, 349 FROM_HERE,
327 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread, 350 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread,
328 controller_, buffer_id_to_drop)); 351 controller_, buffer_id_to_drop));
329 } 352 }
330 353
331 return output_buffer; 354 return output_buffer;
332 } 355 }
(...skipping 29 matching lines...) Expand all
362 } 385 }
363 386
364 void VideoCaptureDeviceClient::OnLog( 387 void VideoCaptureDeviceClient::OnLog(
365 const std::string& message) { 388 const std::string& message) {
366 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 389 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
367 base::Bind(&VideoCaptureController::DoLogOnIOThread, 390 base::Bind(&VideoCaptureController::DoLogOnIOThread,
368 controller_, message)); 391 controller_, message));
369 } 392 }
370 393
371 } // namespace content 394 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698