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

Unified Diff: media/video/capture/fake_video_capture_device.cc

Issue 1106563002: FakeVideoCaptureDevice: add support for capturing into Dma-Bufs using VGEM in CrOs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 side-by-side diff with in-line comments
Download patch
Index: media/video/capture/fake_video_capture_device.cc
diff --git a/media/video/capture/fake_video_capture_device.cc b/media/video/capture/fake_video_capture_device.cc
index a2cd37d65a035a6b1bab5000be54e57fe715205e..64e33a1d1e95b534511c89add38156d4d55ed701 100644
--- a/media/video/capture/fake_video_capture_device.cc
+++ b/media/video/capture/fake_video_capture_device.cc
@@ -6,6 +6,14 @@
#include <string>
+#if defined (OS_POSIX)
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <drm/drm.h>
+#include <drm/drm_mode.h>
+#endif
+
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
@@ -15,10 +23,105 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPaint.h"
+#if defined (OS_POSIX)
+#include "base/posix/eintr_wrapper.h"
+#endif
+
namespace media {
static const int kFakeCaptureBeepCycle = 10; // Visual beep every 0.5s.
+#if defined (OS_POSIX)
+class MmapedFile {
emircan 2015/04/27 16:35:42 Mmapped or mmaped? They both sound wrong tbh.
+ public:
+ MmapedFile(base::PlatformFile platform_file, size_t size)
+ : platform_file_(platform_file), size_(size), data_(nullptr) {
+ data_ = mmap(NULL, size_, PROT_READ | PROT_WRITE, MAP_SHARED,
+ platform_file_, 0);
+ DPLOG_IF(ERROR, data_ == MAP_FAILED) << "mmap() " << platform_file;
+ }
+ ~MmapedFile() {
+ if (data_ != MAP_FAILED)
+ munmap(data_, size_);
+ }
+ bool IsValid() const { return (data_ == MAP_FAILED); }
+ void* data() const { return data_; }
+
+ private:
+ base::PlatformFile platform_file_;
+ size_t size_;
+ void* data_;
+};
+
+class FakeVideoCaptureDevice::DrmDumbBuffer {
+ public:
+ explicit DrmDumbBuffer(const char* device_path);
+ ~DrmDumbBuffer();
+ bool Init(media::VideoCaptureFormat format);
+ void* Map(size_t size);
+
+ private:
+ base::ScopedFD drm_fd_;
+ uint32 handle_;
+};
+
+FakeVideoCaptureDevice::DrmDumbBuffer::DrmDumbBuffer(const char* device_path)
+ : handle_(0) {
+ drm_fd_.reset(HANDLE_EINTR(open(device_path, O_RDWR)));
emircan 2015/04/27 16:35:42 I think we need the handle to dma_buf_fd conversio
mcasas 2015/05/07 15:59:45 Yeah we needed to jump through many hoops... See a
+ DPLOG_IF(ERROR, !drm_fd_.is_valid())
+ << "Failed to open DRM device driver file.";
+}
+
+FakeVideoCaptureDevice::DrmDumbBuffer::~DrmDumbBuffer() {
+ struct drm_mode_destroy_dumb creq = {};
+ creq.handle = handle_;
+ if (HANDLE_EINTR(ioctl(drm_fd_.get(), DRM_IOCTL_MODE_DESTROY_DUMB, &creq)) <
+ 0) {
+ DPLOG(ERROR) << "Unable to Destroy DUMB buffer object";
+ }
+}
+
+bool FakeVideoCaptureDevice::DrmDumbBuffer::Init(
+ media::VideoCaptureFormat format) {
+ DCHECK_EQ(handle_, 0u);
+ if (!drm_fd_.is_valid())
+ return false;
+
+ struct drm_mode_create_dumb creq = {};
emircan 2015/04/27 16:35:42 memset(&creq, 0, sizeof(creq));
mcasas 2015/05/07 15:59:45 No need for that when using the = {} syntax above
+ creq.width = format.frame_size.width();
+ creq.height = format.frame_size.height();
+ creq.bpp = 32;
+ if (HANDLE_EINTR(ioctl(drm_fd_.get(), DRM_IOCTL_MODE_CREATE_DUMB, &creq))
+ < 0) {
+ DPLOG(ERROR) << "Unable to create DUMB buffer object";
+ return false;
+ }
+ handle_ = creq.handle;
+ DCHECK_GE(creq.size, format.frame_size.GetArea() * 4u);
+ return true;
+}
+
+void* FakeVideoCaptureDevice::DrmDumbBuffer::Map(size_t size) {
+ DCHECK_NE(handle_, 0u);
+ if (!drm_fd_.is_valid())
+ return nullptr;
+
+ struct drm_mode_map_dumb mreq ={};
+ mreq.handle = handle_;
+ if (HANDLE_EINTR(ioctl(drm_fd_.get(), DRM_IOCTL_MODE_MAP_DUMB, &mreq)) < 0) {
+ DPLOG(ERROR) << "Unable to Map DUMB buffer object";
+ return nullptr;
+ }
+ void* pixels = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ drm_fd_.get(), mreq.offset);
+ if (pixels == MAP_FAILED) {
+ DPLOG(ERROR) << "Unable to mmap() buffer object";
+ return nullptr;
+ }
+ return pixels;
+}
+#endif
+
void DrawPacman(bool use_argb,
uint8_t* const data,
int frame_count,
@@ -101,6 +204,11 @@ void FakeVideoCaptureDevice::AllocateAndStart(
else
capture_format_.frame_size.SetSize(320, 240);
+#if defined (OS_POSIX)
+ drm_buffer_.reset(new DrmDumbBuffer("/dev/dri/card0"));
+ drm_buffer_->Init(capture_format_);
+#endif
+
if (device_type_ == USING_OWN_BUFFERS ||
device_type_ == USING_OWN_BUFFERS_TRIPLANAR) {
fake_frame_.reset(new uint8[VideoFrame::AllocationSize(
@@ -172,8 +280,20 @@ void FakeVideoCaptureDevice::CaptureUsingClientBuffers(
DLOG_IF(ERROR, !capture_buffer) << "Couldn't allocate Capture Buffer";
if (capture_buffer.get()) {
- uint8_t* const data_ptr = static_cast<uint8_t*>(capture_buffer->data());
- DCHECK(data_ptr) << "Buffer has NO backing memory";
+ uint8_t* data_ptr = static_cast<uint8_t*>(capture_buffer->data());
+#if defined (OS_POSIX)
+ scoped_ptr<MmapedFile> mmaped_file;
+ if (!data_ptr) {
+ // Try mmap()ing the |capture_buffer| AsPlatformFile().
+ mmaped_file = make_scoped_ptr(new MmapedFile(
+ capture_buffer->AsPlatformFile(), capture_buffer->size()));
+ if (!mmaped_file->IsValid()) // Game Over
+ return;
+ data_ptr = static_cast<uint8*>(mmaped_file->data());
+ }
+#else
+ DCHECK(data_ptr);
+#endif
memset(data_ptr, 0, capture_buffer->size());
DrawPacman(

Powered by Google App Engine
This is Rietveld 408576698