summaryrefslogtreecommitdiff
path: root/chromium/media/gpu/v4l2/v4l2_device.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/media/gpu/v4l2/v4l2_device.cc
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-c30a6232df03e1efbd9f3b226777b07e087a1122.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/media/gpu/v4l2/v4l2_device.cc')
-rw-r--r--chromium/media/gpu/v4l2/v4l2_device.cc104
1 files changed, 83 insertions, 21 deletions
diff --git a/chromium/media/gpu/v4l2/v4l2_device.cc b/chromium/media/gpu/v4l2/v4l2_device.cc
index 9b81f8046f2..ba9b5184914 100644
--- a/chromium/media/gpu/v4l2/v4l2_device.cc
+++ b/chromium/media/gpu/v4l2/v4l2_device.cc
@@ -27,6 +27,7 @@
#include "media/base/color_plane_layout.h"
#include "media/base/video_types.h"
#include "media/gpu/chromeos/fourcc.h"
+#include "media/gpu/chromeos/platform_video_frame_utils.h"
#include "media/gpu/macros.h"
#include "media/gpu/v4l2/generic_v4l2_device.h"
#include "ui/gfx/native_pixmap_handle.h"
@@ -313,7 +314,7 @@ class V4L2BufferRefBase {
base::WeakPtr<V4L2Queue> queue);
~V4L2BufferRefBase();
- bool QueueBuffer();
+ bool QueueBuffer(scoped_refptr<VideoFrame> video_frame);
void* GetPlaneMapping(const size_t plane);
scoped_refptr<VideoFrame> GetVideoFrame();
@@ -368,13 +369,13 @@ V4L2BufferRefBase::~V4L2BufferRefBase() {
return_to_->ReturnBuffer(BufferId());
}
-bool V4L2BufferRefBase::QueueBuffer() {
+bool V4L2BufferRefBase::QueueBuffer(scoped_refptr<VideoFrame> video_frame) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!queue_)
return false;
- queued = queue_->QueueBuffer(&v4l2_buffer_);
+ queued = queue_->QueueBuffer(&v4l2_buffer_, std::move(video_frame));
return queued;
}
@@ -484,14 +485,15 @@ enum v4l2_memory V4L2WritableBufferRef::Memory() const {
return static_cast<enum v4l2_memory>(buffer_data_->v4l2_buffer_.memory);
}
-bool V4L2WritableBufferRef::DoQueue(V4L2RequestRef* request_ref) && {
+bool V4L2WritableBufferRef::DoQueue(V4L2RequestRef* request_ref,
+ scoped_refptr<VideoFrame> video_frame) && {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(buffer_data_);
if (request_ref && buffer_data_->queue_->SupportsRequests())
request_ref->ApplyQueueBuffer(&(buffer_data_->v4l2_buffer_));
- bool queued = buffer_data_->QueueBuffer();
+ bool queued = buffer_data_->QueueBuffer(std::move(video_frame));
// Clear our own reference.
buffer_data_.reset();
@@ -512,7 +514,7 @@ bool V4L2WritableBufferRef::QueueMMap(
return false;
}
- return std::move(self).DoQueue(request_ref);
+ return std::move(self).DoQueue(request_ref, nullptr);
}
bool V4L2WritableBufferRef::QueueUserPtr(
@@ -539,7 +541,7 @@ bool V4L2WritableBufferRef::QueueUserPtr(
self.buffer_data_->v4l2_buffer_.m.planes[i].m.userptr =
reinterpret_cast<unsigned long>(ptrs[i]);
- return std::move(self).DoQueue(request_ref);
+ return std::move(self).DoQueue(request_ref, nullptr);
}
bool V4L2WritableBufferRef::QueueDMABuf(
@@ -563,7 +565,52 @@ bool V4L2WritableBufferRef::QueueDMABuf(
for (size_t i = 0; i < num_planes; i++)
self.buffer_data_->v4l2_buffer_.m.planes[i].m.fd = fds[i].get();
- return std::move(self).DoQueue(request_ref);
+ return std::move(self).DoQueue(request_ref, nullptr);
+}
+
+bool V4L2WritableBufferRef::QueueDMABuf(scoped_refptr<VideoFrame> video_frame,
+ V4L2RequestRef* request_ref) && {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(buffer_data_);
+
+ // Move ourselves so our data gets freed no matter when we return
+ V4L2WritableBufferRef self(std::move(*this));
+
+ if (self.Memory() != V4L2_MEMORY_DMABUF) {
+ VLOGF(1) << "Called on invalid buffer type!";
+ return false;
+ }
+
+ // TODO(andrescj): consider replacing this by a DCHECK.
+ if (video_frame->storage_type() != VideoFrame::STORAGE_GPU_MEMORY_BUFFER &&
+ video_frame->storage_type() != VideoFrame::STORAGE_DMABUFS) {
+ VLOGF(1) << "Only GpuMemoryBuffer and dma-buf VideoFrames are supported";
+ return false;
+ }
+
+ // The FDs duped by CreateGpuMemoryBufferHandle() will be closed after the
+ // call to DoQueue() which uses the VIDIOC_QBUF ioctl and so ends up
+ // increasing the reference count of the dma-buf. Thus, closing the FDs is
+ // safe.
+ // TODO(andrescj): for dma-buf VideoFrames, duping the FDs is unnecessary.
+ // Consider handling that path separately.
+ gfx::GpuMemoryBufferHandle gmb_handle =
+ CreateGpuMemoryBufferHandle(video_frame.get());
+ if (gmb_handle.type != gfx::GpuMemoryBufferType::NATIVE_PIXMAP) {
+ VLOGF(1) << "Failed to create GpuMemoryBufferHandle for frame!";
+ return false;
+ }
+ const std::vector<gfx::NativePixmapPlane>& planes =
+ gmb_handle.native_pixmap_handle.planes;
+
+ if (!self.buffer_data_->CheckNumFDsForFormat(planes.size()))
+ return false;
+
+ size_t num_planes = self.PlanesCount();
+ for (size_t i = 0; i < num_planes; i++)
+ self.buffer_data_->v4l2_buffer_.m.planes[i].m.fd = planes[i].fd.get();
+
+ return std::move(self).DoQueue(request_ref, std::move(video_frame));
}
bool V4L2WritableBufferRef::QueueDMABuf(
@@ -587,7 +634,7 @@ bool V4L2WritableBufferRef::QueueDMABuf(
for (size_t i = 0; i < num_planes; i++)
self.buffer_data_->v4l2_buffer_.m.planes[i].m.fd = planes[i].fd.get();
- return std::move(self).DoQueue(request_ref);
+ return std::move(self).DoQueue(request_ref, nullptr);
}
size_t V4L2WritableBufferRef::PlanesCount() const {
@@ -709,14 +756,20 @@ void V4L2WritableBufferRef::SetConfigStore(uint32_t config_store) {
}
V4L2ReadableBuffer::V4L2ReadableBuffer(const struct v4l2_buffer& v4l2_buffer,
- base::WeakPtr<V4L2Queue> queue)
+ base::WeakPtr<V4L2Queue> queue,
+ scoped_refptr<VideoFrame> video_frame)
: buffer_data_(
- std::make_unique<V4L2BufferRefBase>(v4l2_buffer, std::move(queue))) {
+ std::make_unique<V4L2BufferRefBase>(v4l2_buffer, std::move(queue))),
+ video_frame_(std::move(video_frame)) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
scoped_refptr<VideoFrame> V4L2ReadableBuffer::GetVideoFrame() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(buffer_data_);
+
+ if (buffer_data_->v4l2_buffer_.memory == V4L2_MEMORY_DMABUF && video_frame_)
+ return video_frame_;
return buffer_data_->GetVideoFrame();
}
@@ -806,8 +859,10 @@ class V4L2BufferRefFactory {
static V4L2ReadableBufferRef CreateReadableRef(
const struct v4l2_buffer& v4l2_buffer,
- base::WeakPtr<V4L2Queue> queue) {
- return new V4L2ReadableBuffer(v4l2_buffer, std::move(queue));
+ base::WeakPtr<V4L2Queue> queue,
+ scoped_refptr<VideoFrame> video_frame) {
+ return new V4L2ReadableBuffer(v4l2_buffer, std::move(queue),
+ std::move(video_frame));
}
};
@@ -1070,7 +1125,8 @@ base::Optional<V4L2WritableBufferRef> V4L2Queue::GetFreeBuffer() {
weak_this_factory_.GetWeakPtr());
}
-bool V4L2Queue::QueueBuffer(struct v4l2_buffer* v4l2_buffer) {
+bool V4L2Queue::QueueBuffer(struct v4l2_buffer* v4l2_buffer,
+ scoped_refptr<VideoFrame> video_frame) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
int ret = device_->Ioctl(VIDIOC_QBUF, v4l2_buffer);
@@ -1079,7 +1135,8 @@ bool V4L2Queue::QueueBuffer(struct v4l2_buffer* v4l2_buffer) {
return false;
}
- auto inserted = queued_buffers_.emplace(v4l2_buffer->index);
+ auto inserted =
+ queued_buffers_.emplace(v4l2_buffer->index, std::move(video_frame));
DCHECK_EQ(inserted.second, true);
device_->SchedulePoll();
@@ -1127,15 +1184,16 @@ std::pair<bool, V4L2ReadableBufferRef> V4L2Queue::DequeueBuffer() {
auto it = queued_buffers_.find(v4l2_buffer.index);
DCHECK(it != queued_buffers_.end());
- queued_buffers_.erase(*it);
+ scoped_refptr<VideoFrame> queued_frame = std::move(it->second);
+ queued_buffers_.erase(it);
if (QueuedBuffersCount() > 0)
device_->SchedulePoll();
DCHECK(free_buffers_);
- return std::make_pair(true,
- V4L2BufferRefFactory::CreateReadableRef(
- v4l2_buffer, weak_this_factory_.GetWeakPtr()));
+ return std::make_pair(true, V4L2BufferRefFactory::CreateReadableRef(
+ v4l2_buffer, weak_this_factory_.GetWeakPtr(),
+ std::move(queued_frame)));
}
bool V4L2Queue::IsStreaming() const {
@@ -1176,9 +1234,9 @@ bool V4L2Queue::Streamoff() {
return false;
}
- for (const auto& buffer_id : queued_buffers_) {
+ for (const auto& it : queued_buffers_) {
DCHECK(free_buffers_);
- free_buffers_->ReturnBuffer(buffer_id);
+ free_buffers_->ReturnBuffer(it.first);
}
queued_buffers_.clear();
@@ -1332,6 +1390,10 @@ VideoCodecProfile V4L2Device::V4L2ProfileToVideoCodecProfile(VideoCodec codec,
return H264PROFILE_EXTENDED;
case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
return H264PROFILE_HIGH;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
+ return H264PROFILE_STEREOHIGH;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
+ return H264PROFILE_MULTIVIEWHIGH;
}
break;
case kCodecVP8: