Skip to content

Commit

Permalink
[Mojo Video Capture] Simplify media::VideoCaptureDevice::Client:Buffe…
Browse files Browse the repository at this point in the history
…r to a struct

In interface media::VideoCaptureDevice::Client, change interface Buffer to a
move-only struct. The new struct separates the concerns of providing access
handles (for in-process as well as for inter-process transit) from access
permissions. This allows clients to explicitly obtain in-process memory-mapped
handles when they need it. Clients who only want to pass along the buffer or
move it across process boundaries do not need memory-mapped handles.

In interface media::VideoCaptureBufferPool, renamed
 GetBufferHandle() -> GetHandleForInProcessAccess()
 GetHandleForTransit() -> GetHandleForInterProcessTransit().

Removed outdated implementation in video_capture Mojo service. We leave the
implementation empty, until refactoring the interfaces has been completed.

This CL is part of the Mojo Video Capture work. For the bigger picture,
see [1] CL1.9.10

For a peek at the follow-up CLs, please see
https://codereview.chromium.org/2607203002/
https://codereview.chromium.org/2602983002/

BUG=584797
TEST=
  content_unittests --gtest_filter="*Video*",
  video_capture_unittests,
  Apprtc loopback on Debug,
  Desktop Capture Example extension on Release

[1] https://docs.google.com/a/chromium.org/document/d/1Qw7rw1AJy0QHXjha36jZNiEuxsxWslJ_X-zpOhijvI8/edit?usp=sharing

Review-Url: https://codereview.chromium.org/2573223002
Cr-Commit-Position: refs/heads/master@{#442066}
  • Loading branch information
chfremer authored and Commit bot committed Jan 6, 2017
1 parent a82983a commit e1aac99
Show file tree
Hide file tree
Showing 43 changed files with 534 additions and 826 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,39 +58,38 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
const std::string& reason));

// Trampoline methods to workaround GMOCK problems with std::unique_ptr<>.
std::unique_ptr<Buffer> ReserveOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
Buffer ReserveOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
EXPECT_EQ(media::PIXEL_STORAGE_CPU, storage);
DoReserveOutputBuffer();
return std::unique_ptr<Buffer>();
return Buffer();
}
void OnIncomingCapturedBuffer(std::unique_ptr<Buffer> buffer,
void OnIncomingCapturedBuffer(Buffer buffer,
const media::VideoCaptureFormat& frame_format,
base::TimeTicks reference_time,
base::TimeDelta timestamp) override {
DoOnIncomingCapturedBuffer();
}
void OnIncomingCapturedBufferExt(
std::unique_ptr<Buffer> buffer,
Buffer buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp,
gfx::Rect visible_rect,
const media::VideoFrameMetadata& additional_metadata) override {
DoOnIncomingCapturedVideoFrame();
}
std::unique_ptr<Buffer> ResurrectLastOutputBuffer(
const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
EXPECT_EQ(media::PIXEL_STORAGE_CPU, storage);
DoResurrectLastOutputBuffer();
return std::unique_ptr<Buffer>();
return Buffer();
}
double GetBufferPoolUtilization() const override { return 0.0; }
};
Expand Down
35 changes: 17 additions & 18 deletions content/browser/media/capture/desktop_capture_device_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,39 +77,38 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
const std::string& reason));

// Trampoline methods to workaround GMOCK problems with std::unique_ptr<>.
std::unique_ptr<Buffer> ReserveOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
Buffer ReserveOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
EXPECT_TRUE(format == media::PIXEL_FORMAT_I420 &&
storage == media::PIXEL_STORAGE_CPU);
DoReserveOutputBuffer();
return std::unique_ptr<Buffer>();
return Buffer();
}
void OnIncomingCapturedBuffer(std::unique_ptr<Buffer> buffer,
void OnIncomingCapturedBuffer(Buffer buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp) override {
DoOnIncomingCapturedBuffer();
}
void OnIncomingCapturedBufferExt(
std::unique_ptr<Buffer> buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp,
gfx::Rect visible_rect,
const media::VideoFrameMetadata& additional_metadata) override {
Buffer buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp,
gfx::Rect visible_rect,
const media::VideoFrameMetadata& additional_metadata) override {
DoOnIncomingCapturedVideoFrame();
}
std::unique_ptr<Buffer> ResurrectLastOutputBuffer(
const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
EXPECT_TRUE(format == media::PIXEL_FORMAT_I420 &&
storage == media::PIXEL_STORAGE_CPU);
DoResurrectLastOutputBuffer();
return std::unique_ptr<Buffer>();
return Buffer();
}
double GetBufferPoolUtilization() const override { return 0.0; }
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,39 +35,38 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
MOCK_CONST_METHOD0(GetBufferPoolUtilization, double(void));

// Trampoline methods to workaround GMOCK problems with std::unique_ptr<>.
std::unique_ptr<Buffer> ReserveOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
Buffer ReserveOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
EXPECT_EQ(media::PIXEL_STORAGE_CPU, storage);
DoReserveOutputBuffer();
return std::unique_ptr<Buffer>();
return Buffer();
}
void OnIncomingCapturedBuffer(std::unique_ptr<Buffer> buffer,
void OnIncomingCapturedBuffer(Buffer buffer,
const media::VideoCaptureFormat& frame_format,
base::TimeTicks reference_time,
base::TimeDelta timestamp) override {
DoOnIncomingCapturedBuffer();
}
void OnIncomingCapturedBufferExt(
std::unique_ptr<Buffer> buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp,
gfx::Rect visible_rect,
const media::VideoFrameMetadata& additional_metadata) override {
Buffer buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp,
gfx::Rect visible_rect,
const media::VideoFrameMetadata& additional_metadata) override {
DoOnIncomingCapturedVideoFrame();
}
std::unique_ptr<Buffer> ResurrectLastOutputBuffer(
const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
EXPECT_EQ(media::PIXEL_STORAGE_CPU, storage);
DoResurrectLastOutputBuffer();
return std::unique_ptr<Buffer>();
return Buffer();
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "media/base/yuv_convert.h"
#include "media/capture/video/video_capture_buffer_pool_impl.h"
#include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
#include "media/capture/video/video_capture_device_client.h"
#include "media/capture/video_capture_types.h"
#include "skia/ext/platform_canvas.h"
#include "testing/gmock/include/gmock/gmock.h"
Expand Down Expand Up @@ -243,35 +244,33 @@ class StubClient : public media::VideoCaptureDevice::Client {

MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));

std::unique_ptr<media::VideoCaptureDevice::Client::Buffer>
ReserveOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
media::VideoCaptureDevice::Client::Buffer ReserveOutputBuffer(
const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
CHECK_EQ(format, media::PIXEL_FORMAT_I420);
int buffer_id_to_drop =
media::VideoCaptureBufferPool::kInvalidId; // Ignored.
const int buffer_id = buffer_pool_->ReserveForProducer(
dimensions, format, storage, frame_feedback_id, &buffer_id_to_drop);
if (buffer_id == media::VideoCaptureBufferPool::kInvalidId)
return NULL;
return media::VideoCaptureDevice::Client::Buffer();

return std::unique_ptr<media::VideoCaptureDevice::Client::Buffer>(
new AutoReleaseBuffer(buffer_pool_,
buffer_pool_->GetBufferHandle(buffer_id),
buffer_id, frame_feedback_id));
return media::VideoCaptureDeviceClient::MakeBufferStruct(
buffer_pool_, buffer_id, frame_feedback_id);
}

// Trampoline method to workaround GMOCK problems with std::unique_ptr<>.
void OnIncomingCapturedBuffer(std::unique_ptr<Buffer> buffer,
void OnIncomingCapturedBuffer(Buffer buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp) override {
DoOnIncomingCapturedBuffer();
}

void OnIncomingCapturedBufferExt(
std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer,
media::VideoCaptureDevice::Client::Buffer buffer,
const media::VideoCaptureFormat& format,
base::TimeTicks reference_time,
base::TimeDelta timestamp,
Expand All @@ -285,11 +284,12 @@ class StubClient : public media::VideoCaptureDevice::Client {
// analysis is too slow, the backlog of frames will grow without bound and
// trouble erupts. http://crbug.com/174519
using media::VideoFrame;
auto buffer_access =
buffer.handle_provider()->GetHandleForInProcessAccess();
auto frame = VideoFrame::WrapExternalSharedMemory(
media::PIXEL_FORMAT_I420, format.frame_size, visible_rect,
format.frame_size, static_cast<uint8_t*>(buffer->data()),
buffer->mapped_size(), base::SharedMemory::NULLHandle(), 0u,
base::TimeDelta());
format.frame_size, buffer_access->data(), buffer_access->mapped_size(),
base::SharedMemory::NULLHandle(), 0u, base::TimeDelta());
const gfx::Point center = visible_rect.CenterPoint();
const int center_offset_y =
(frame->stride(VideoFrame::kYPlane) * center.y()) + center.x();
Expand All @@ -303,20 +303,18 @@ class StubClient : public media::VideoCaptureDevice::Client {
frame->visible_rect().size());
}

std::unique_ptr<media::VideoCaptureDevice::Client::Buffer>
ResurrectLastOutputBuffer(const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
media::VideoCaptureDevice::Client::Buffer ResurrectLastOutputBuffer(
const gfx::Size& dimensions,
media::VideoPixelFormat format,
media::VideoPixelStorage storage,
int frame_feedback_id) override {
CHECK_EQ(format, media::PIXEL_FORMAT_I420);
const int buffer_id =
buffer_pool_->ResurrectLastForProducer(dimensions, format, storage);
if (buffer_id == media::VideoCaptureBufferPool::kInvalidId)
return nullptr;
return std::unique_ptr<media::VideoCaptureDevice::Client::Buffer>(
new AutoReleaseBuffer(buffer_pool_,
buffer_pool_->GetBufferHandle(buffer_id),
buffer_id, frame_feedback_id));
return media::VideoCaptureDevice::Client::Buffer();
return media::VideoCaptureDeviceClient::MakeBufferStruct(
buffer_pool_, buffer_id, frame_feedback_id);
}

void OnError(const tracked_objects::Location& from_here,
Expand All @@ -327,49 +325,6 @@ class StubClient : public media::VideoCaptureDevice::Client {
double GetBufferPoolUtilization() const override { return 0.0; }

private:
class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer {
public:
AutoReleaseBuffer(
const scoped_refptr<media::VideoCaptureBufferPool>& pool,
std::unique_ptr<media::VideoCaptureBufferHandle> buffer_handle,
int buffer_id,
int frame_feedback_id)
: id_(buffer_id),
frame_feedback_id_(frame_feedback_id),
pool_(pool),
buffer_handle_(std::move(buffer_handle)) {
DCHECK(pool_);
}
int id() const override { return id_; }
int frame_feedback_id() const override { return frame_feedback_id_; }
gfx::Size dimensions() const override {
return buffer_handle_->dimensions();
}
size_t mapped_size() const override {
return buffer_handle_->mapped_size();
}
void* data(int plane) override { return buffer_handle_->data(plane); }
#if defined(OS_POSIX) && !defined(OS_MACOSX)
base::FileDescriptor AsPlatformFile() override {
return base::FileDescriptor();
}
#endif
bool IsBackedByVideoFrame() const override {
return buffer_handle_->IsBackedByVideoFrame();
}
scoped_refptr<media::VideoFrame> GetVideoFrame() override {
return buffer_handle_->GetVideoFrame();
}

private:
~AutoReleaseBuffer() override { pool_->RelinquishProducerReservation(id_); }

const int id_;
const int frame_feedback_id_;
const scoped_refptr<media::VideoCaptureBufferPool> pool_;
const std::unique_ptr<media::VideoCaptureBufferHandle> buffer_handle_;
};

scoped_refptr<media::VideoCaptureBufferPool> buffer_pool_;
base::Callback<void(SkColor, const gfx::Size&)> report_callback_;
base::Closure error_callback_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class VideoCaptureBufferPoolTest
~Buffer() { pool_->RelinquishProducerReservation(id()); }
int id() const { return id_; }
size_t mapped_size() { return buffer_handle_->mapped_size(); }
void* data() { return buffer_handle_->data(0); }
void* data() { return buffer_handle_->data(); }

private:
const int id_;
Expand Down Expand Up @@ -100,7 +100,7 @@ class VideoCaptureBufferPoolTest
EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop);

std::unique_ptr<media::VideoCaptureBufferHandle> buffer_handle =
pool_->GetBufferHandle(buffer_id);
pool_->GetHandleForInProcessAccess(buffer_id);
return std::unique_ptr<Buffer>(
new Buffer(pool_, std::move(buffer_handle), buffer_id));
}
Expand All @@ -113,8 +113,8 @@ class VideoCaptureBufferPoolTest
format_and_storage.pixel_storage);
if (buffer_id == media::VideoCaptureBufferPool::kInvalidId)
return std::unique_ptr<Buffer>();
return std::unique_ptr<Buffer>(
new Buffer(pool_, pool_->GetBufferHandle(buffer_id), buffer_id));
return std::unique_ptr<Buffer>(new Buffer(
pool_, pool_->GetHandleForInProcessAccess(buffer_id), buffer_id));
}

base::MessageLoop loop_;
Expand Down
Loading

0 comments on commit e1aac99

Please sign in to comment.