summaryrefslogtreecommitdiff
path: root/content/common/gpu
diff options
context:
space:
mode:
authorTorne (Richard Coles) <torne@google.com>2014-08-28 12:05:23 +0100
committerTorne (Richard Coles) <torne@google.com>2014-08-28 12:05:23 +0100
commit03b57e008b61dfcb1fbad3aea950ae0e001748b0 (patch)
tree9a740c1a5fbe659ec83484b67cbc679332f5a408 /content/common/gpu
parentca7d0c81aa30d24514c34c963f43cd24da34a2bf (diff)
downloadchromium_org-03b57e008b61dfcb1fbad3aea950ae0e001748b0.tar.gz
Merge from Chromium at DEPS revision 291560
This commit was generated by merge_to_master.py. Change-Id: Ic58269055810d51286b4109e59b90b6856887a30
Diffstat (limited to 'content/common/gpu')
-rw-r--r--content/common/gpu/client/command_buffer_proxy_impl.cc3
-rw-r--r--content/common/gpu/client/gpu_channel_host.cc4
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_factory_host.cc27
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_factory_host.h6
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl.h5
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_android.cc1
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_linux.cc1
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_mac.cc1
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_ozone.cc88
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.cc110
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h52
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_win.cc1
-rw-r--r--content/common/gpu/client/gpu_video_decode_accelerator_host.cc6
-rw-r--r--content/common/gpu/client/gpu_video_decode_accelerator_host.h4
-rw-r--r--content/common/gpu/gpu_memory_buffer_factory_ozone.cc16
-rw-r--r--content/common/gpu/gpu_messages.h7
-rw-r--r--content/common/gpu/image_transport_surface_fbo_mac.mm4
-rw-r--r--content/common/gpu/image_transport_surface_mac.mm3
-rw-r--r--content/common/gpu/media/android_video_decode_accelerator.cc7
-rw-r--r--content/common/gpu/media/dxva_video_decode_accelerator.cc3
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.cc3
-rw-r--r--content/common/gpu/media/rendering_helper.cc118
-rw-r--r--content/common/gpu/media/rendering_helper.h111
-rw-r--r--content/common/gpu/media/v4l2_image_processor.cc2
-rw-r--r--content/common/gpu/media/v4l2_video_decode_accelerator.cc4
-rw-r--r--content/common/gpu/media/v4l2_video_device.cc14
-rw-r--r--content/common/gpu/media/v4l2_video_encode_accelerator.cc1
-rw-r--r--content/common/gpu/media/vaapi_video_decode_accelerator.cc5
-rw-r--r--content/common/gpu/media/video_decode_accelerator_unittest.cc117
-rw-r--r--content/common/gpu/media/vt_video_decode_accelerator.cc3
30 files changed, 543 insertions, 184 deletions
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc
index 74a4089e56..7959fda688 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc
+++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -194,7 +194,8 @@ void CommandBufferProxyImpl::Flush(int32 put_offset) {
void CommandBufferProxyImpl::SetLatencyInfo(
const std::vector<ui::LatencyInfo>& latency_info) {
- if (last_state_.error != gpu::error::kNoError)
+ if (last_state_.error != gpu::error::kNoError ||
+ latency_info.empty())
return;
Send(new GpuCommandBufferMsg_SetLatencyInfo(route_id_, latency_info));
}
diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc
index 492e6965b7..d0ceecd262 100644
--- a/content/common/gpu/client/gpu_channel_host.cc
+++ b/content/common/gpu/client/gpu_channel_host.cc
@@ -304,6 +304,10 @@ gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess(
handle.handle = ShareToGpuProcess(source_handle.handle);
return handle;
}
+#if defined(USE_OZONE)
+ case gfx::OZONE_NATIVE_BUFFER:
+ return source_handle;
+#endif
#if defined(OS_MACOSX)
case gfx::IO_SURFACE_BUFFER:
return source_handle;
diff --git a/content/common/gpu/client/gpu_memory_buffer_factory_host.cc b/content/common/gpu/client/gpu_memory_buffer_factory_host.cc
new file mode 100644
index 0000000000..ea7a321d1c
--- /dev/null
+++ b/content/common/gpu/client/gpu_memory_buffer_factory_host.cc
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h"
+
+#include "base/logging.h"
+
+namespace content {
+namespace {
+GpuMemoryBufferFactoryHost* instance = NULL;
+}
+
+// static
+GpuMemoryBufferFactoryHost* GpuMemoryBufferFactoryHost::GetInstance() {
+ return instance;
+}
+
+GpuMemoryBufferFactoryHost::GpuMemoryBufferFactoryHost() {
+ DCHECK(instance == NULL);
+ instance = this;
+}
+
+GpuMemoryBufferFactoryHost::~GpuMemoryBufferFactoryHost() {
+ instance = NULL;
+}
+}
diff --git a/content/common/gpu/client/gpu_memory_buffer_factory_host.h b/content/common/gpu/client/gpu_memory_buffer_factory_host.h
index 6dfd58beab..9e616e27e6 100644
--- a/content/common/gpu/client/gpu_memory_buffer_factory_host.h
+++ b/content/common/gpu/client/gpu_memory_buffer_factory_host.h
@@ -6,6 +6,7 @@
#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_FACTORY_HOST_H_
#include "base/callback.h"
+#include "content/common/content_export.h"
namespace gfx {
class Size;
@@ -19,6 +20,8 @@ class CONTENT_EXPORT GpuMemoryBufferFactoryHost {
typedef base::Callback<void(const gfx::GpuMemoryBufferHandle& handle)>
CreateGpuMemoryBufferCallback;
+ static GpuMemoryBufferFactoryHost* GetInstance();
+
virtual void CreateGpuMemoryBuffer(
const gfx::GpuMemoryBufferHandle& handle,
const gfx::Size& size,
@@ -29,7 +32,8 @@ class CONTENT_EXPORT GpuMemoryBufferFactoryHost {
int32 sync_point) = 0;
protected:
- virtual ~GpuMemoryBufferFactoryHost() {}
+ GpuMemoryBufferFactoryHost();
+ virtual ~GpuMemoryBufferFactoryHost();
};
} // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl.h b/content/common/gpu/client/gpu_memory_buffer_impl.h
index 2565c02653..e3323f0fed 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl.h
+++ b/content/common/gpu/client/gpu_memory_buffer_impl.h
@@ -27,12 +27,13 @@ class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
unsigned usage);
// Allocates a GPU memory buffer with |size| and |internalformat| for |usage|
- // by |child_process|. The |handle| returned can be used by the
- // |child_process| to create an instance of this class.
+ // by |child_process| identified by |child_id|. The |handle| returned can be
+ // used by the |child_process| to create an instance of this class.
static void AllocateForChildProcess(const gfx::Size& size,
unsigned internalformat,
unsigned usage,
base::ProcessHandle child_process,
+ int child_id,
const AllocationCallback& callback);
// Notify that GPU memory buffer has been deleted by |child_process|.
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_android.cc b/content/common/gpu/client/gpu_memory_buffer_impl_android.cc
index 44efda0861..799eff5334 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_android.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_android.cc
@@ -33,6 +33,7 @@ void GpuMemoryBufferImpl::AllocateForChildProcess(
unsigned internalformat,
unsigned usage,
base::ProcessHandle child_process,
+ int child_id,
const AllocationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) {
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc b/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc
index 0fc371b99d..5c04cd8d9b 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_linux.cc
@@ -32,6 +32,7 @@ void GpuMemoryBufferImpl::AllocateForChildProcess(
unsigned internalformat,
unsigned usage,
base::ProcessHandle child_process,
+ int child_id,
const AllocationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) {
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc b/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc
index 24e39a6ce7..11949c9d6f 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_mac.cc
@@ -33,6 +33,7 @@ void GpuMemoryBufferImpl::AllocateForChildProcess(
unsigned internalformat,
unsigned usage,
base::ProcessHandle child_process,
+ int child_id,
const AllocationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) {
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_ozone.cc b/content/common/gpu/client/gpu_memory_buffer_impl_ozone.cc
new file mode 100644
index 0000000000..784f75c6c9
--- /dev/null
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_ozone.cc
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
+
+#include "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h"
+#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
+
+namespace content {
+
+// static
+scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::Create(
+ const gfx::Size& size,
+ unsigned internalformat,
+ unsigned usage) {
+ if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
+ size, internalformat, usage)) {
+ scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer(
+ new GpuMemoryBufferImplSharedMemory(size, internalformat));
+ if (!buffer->Initialize())
+ return scoped_ptr<GpuMemoryBufferImpl>();
+
+ return buffer.PassAs<GpuMemoryBufferImpl>();
+ }
+
+ return scoped_ptr<GpuMemoryBufferImpl>();
+}
+
+// static
+void GpuMemoryBufferImpl::AllocateForChildProcess(
+ const gfx::Size& size,
+ unsigned internalformat,
+ unsigned usage,
+ base::ProcessHandle child_process,
+ int child_id,
+ const AllocationCallback& callback) {
+ if (GpuMemoryBufferImplOzoneNativeBuffer::IsConfigurationSupported(
+ internalformat, usage)) {
+ GpuMemoryBufferImplOzoneNativeBuffer::AllocateOzoneNativeBufferForChildId(
+ size, internalformat, usage, child_id, callback);
+ return;
+ }
+ if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
+ size, internalformat, usage)) {
+ GpuMemoryBufferImplSharedMemory::AllocateSharedMemoryForChildProcess(
+ size, internalformat, child_process, callback);
+ return;
+ }
+
+ callback.Run(gfx::GpuMemoryBufferHandle());
+}
+
+// static
+void GpuMemoryBufferImpl::DeletedByChildProcess(
+ gfx::GpuMemoryBufferType type,
+ const gfx::GpuMemoryBufferId& id,
+ base::ProcessHandle child_process) {
+}
+
+// static
+scoped_ptr<GpuMemoryBufferImpl> GpuMemoryBufferImpl::CreateFromHandle(
+ const gfx::GpuMemoryBufferHandle& handle,
+ const gfx::Size& size,
+ unsigned internalformat) {
+ switch (handle.type) {
+ case gfx::SHARED_MEMORY_BUFFER: {
+ scoped_ptr<GpuMemoryBufferImplSharedMemory> buffer(
+ new GpuMemoryBufferImplSharedMemory(size, internalformat));
+ if (!buffer->InitializeFromHandle(handle))
+ return scoped_ptr<GpuMemoryBufferImpl>();
+
+ return buffer.PassAs<GpuMemoryBufferImpl>();
+ }
+ case gfx::OZONE_NATIVE_BUFFER: {
+ scoped_ptr<GpuMemoryBufferImplOzoneNativeBuffer> buffer(
+ new GpuMemoryBufferImplOzoneNativeBuffer(size, internalformat));
+ if (!buffer->InitializeFromHandle(handle))
+ return scoped_ptr<GpuMemoryBufferImpl>();
+
+ return buffer.PassAs<GpuMemoryBufferImpl>();
+ }
+ default:
+ return scoped_ptr<GpuMemoryBufferImpl>();
+ }
+}
+
+} // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.cc b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.cc
new file mode 100644
index 0000000000..fe2681bf05
--- /dev/null
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.cc
@@ -0,0 +1,110 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h"
+
+#include "base/atomic_sequence_num.h"
+#include "base/bind.h"
+#include "content/common/gpu/client/gpu_memory_buffer_factory_host.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace content {
+namespace {
+
+base::StaticAtomicSequenceNumber g_next_buffer_id;
+
+} // namespace
+
+GpuMemoryBufferImplOzoneNativeBuffer::GpuMemoryBufferImplOzoneNativeBuffer(
+ const gfx::Size& size,
+ unsigned internalformat)
+ : GpuMemoryBufferImpl(size, internalformat) {
+}
+
+GpuMemoryBufferImplOzoneNativeBuffer::~GpuMemoryBufferImplOzoneNativeBuffer() {
+}
+
+// static
+void GpuMemoryBufferImplOzoneNativeBuffer::AllocateOzoneNativeBufferForChildId(
+ const gfx::Size& size,
+ unsigned internalformat,
+ unsigned usage,
+ int child_id,
+ const AllocationCallback& callback) {
+ gfx::GpuMemoryBufferHandle handle;
+ // +1 ensures we always get non-zero IDs.
+ handle.global_id.primary_id = g_next_buffer_id.GetNext() + 1;
+ handle.global_id.secondary_id = child_id;
+ handle.type = gfx::OZONE_NATIVE_BUFFER;
+ GpuMemoryBufferFactoryHost::GetInstance()->CreateGpuMemoryBuffer(
+ handle,
+ size,
+ internalformat,
+ usage,
+ base::Bind(&OnGpuMemoryBufferCreated, callback));
+}
+
+// static
+bool GpuMemoryBufferImplOzoneNativeBuffer::IsFormatSupported(
+ unsigned internalformat) {
+ switch (internalformat) {
+ case GL_RGBA8_OES:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// static
+bool GpuMemoryBufferImplOzoneNativeBuffer::IsUsageSupported(unsigned usage) {
+ switch (usage) {
+ case GL_IMAGE_SCANOUT_CHROMIUM:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// static
+bool GpuMemoryBufferImplOzoneNativeBuffer::IsConfigurationSupported(
+ unsigned internalformat,
+ unsigned usage) {
+ return IsFormatSupported(internalformat) && IsUsageSupported(usage);
+}
+
+bool GpuMemoryBufferImplOzoneNativeBuffer::InitializeFromHandle(
+ const gfx::GpuMemoryBufferHandle& handle) {
+ id_ = handle.global_id;
+ return true;
+}
+
+void* GpuMemoryBufferImplOzoneNativeBuffer::Map() {
+ NOTREACHED();
+ return NULL;
+}
+
+void GpuMemoryBufferImplOzoneNativeBuffer::Unmap() {
+ NOTREACHED();
+}
+
+uint32 GpuMemoryBufferImplOzoneNativeBuffer::GetStride() const {
+ NOTREACHED();
+ return 0;
+}
+
+gfx::GpuMemoryBufferHandle GpuMemoryBufferImplOzoneNativeBuffer::GetHandle()
+ const {
+ gfx::GpuMemoryBufferHandle handle;
+ handle.type = gfx::OZONE_NATIVE_BUFFER;
+ handle.global_id = id_;
+ return handle;
+}
+
+void GpuMemoryBufferImplOzoneNativeBuffer::OnGpuMemoryBufferCreated(
+ const AllocationCallback& callback,
+ const gfx::GpuMemoryBufferHandle& handle) {
+ callback.Run(handle);
+}
+
+} // namespace content
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h
new file mode 100644
index 0000000000..ab4cc56a18
--- /dev/null
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h
@@ -0,0 +1,52 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_H_
+#define CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_H_
+
+#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
+
+namespace content {
+
+// Implementation of GPU memory buffer based on Ozone native buffers.
+class GpuMemoryBufferImplOzoneNativeBuffer : public GpuMemoryBufferImpl {
+ public:
+ GpuMemoryBufferImplOzoneNativeBuffer(const gfx::Size& size,
+ unsigned internalformat);
+ virtual ~GpuMemoryBufferImplOzoneNativeBuffer();
+
+ // Allocates an Ozone native buffer backed GPU memory buffer with |size| and
+ // |internalformat| with usage |usage| for use by |child_id|.
+ static void AllocateOzoneNativeBufferForChildId(
+ const gfx::Size& size,
+ unsigned internalformat,
+ unsigned usage,
+ int child_id,
+ const AllocationCallback& callback);
+
+ static bool IsFormatSupported(unsigned internalformat);
+ static bool IsUsageSupported(unsigned usage);
+ static bool IsConfigurationSupported(unsigned internalformat, unsigned usage);
+
+ bool InitializeFromHandle(const gfx::GpuMemoryBufferHandle& handle);
+
+ // Overridden from gfx::GpuMemoryBuffer:
+ virtual void* Map() OVERRIDE;
+ virtual void Unmap() OVERRIDE;
+ virtual uint32 GetStride() const OVERRIDE;
+ virtual gfx::GpuMemoryBufferHandle GetHandle() const OVERRIDE;
+
+ private:
+ static void OnGpuMemoryBufferCreated(
+ const AllocationCallback& callback,
+ const gfx::GpuMemoryBufferHandle& handle);
+
+ gfx::GpuMemoryBufferId id_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImplOzoneNativeBuffer);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_GPU_CLIENT_GPU_MEMORY_BUFFER_IMPL_OZONE_H_
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_win.cc b/content/common/gpu/client/gpu_memory_buffer_impl_win.cc
index 0fc371b99d..5c04cd8d9b 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_win.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_win.cc
@@ -32,6 +32,7 @@ void GpuMemoryBufferImpl::AllocateForChildProcess(
unsigned internalformat,
unsigned usage,
base::ProcessHandle child_process,
+ int child_id,
const AllocationCallback& callback) {
if (GpuMemoryBufferImplSharedMemory::IsConfigurationSupported(
size, internalformat, usage)) {
diff --git a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
index 8b714b9e19..a784467800 100644
--- a/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
+++ b/content/common/gpu/client/gpu_video_decode_accelerator_host.cc
@@ -231,11 +231,13 @@ void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer(
}
void GpuVideoDecodeAcceleratorHost::OnPictureReady(
- int32 picture_buffer_id, int32 bitstream_buffer_id) {
+ int32 picture_buffer_id,
+ int32 bitstream_buffer_id,
+ const gfx::Rect& visible_rect) {
DCHECK(CalledOnValidThread());
if (!client_)
return;
- media::Picture picture(picture_buffer_id, bitstream_buffer_id);
+ media::Picture picture(picture_buffer_id, bitstream_buffer_id, visible_rect);
client_->PictureReady(picture);
}
diff --git a/content/common/gpu/client/gpu_video_decode_accelerator_host.h b/content/common/gpu/client/gpu_video_decode_accelerator_host.h
index 571bd0c94b..e333f6b50b 100644
--- a/content/common/gpu/client/gpu_video_decode_accelerator_host.h
+++ b/content/common/gpu/client/gpu_video_decode_accelerator_host.h
@@ -64,7 +64,9 @@ class GpuVideoDecodeAcceleratorHost
const gfx::Size& dimensions,
uint32 texture_target);
void OnDismissPictureBuffer(int32 picture_buffer_id);
- void OnPictureReady(int32 picture_buffer_id, int32 bitstream_buffer_id);
+ void OnPictureReady(int32 picture_buffer_id,
+ int32 bitstream_buffer_id,
+ const gfx::Rect& visible_rect);
void OnFlushDone();
void OnResetDone();
void OnNotifyError(uint32 error);
diff --git a/content/common/gpu/gpu_memory_buffer_factory_ozone.cc b/content/common/gpu/gpu_memory_buffer_factory_ozone.cc
index 8f4232dc45..ca119e8999 100644
--- a/content/common/gpu/gpu_memory_buffer_factory_ozone.cc
+++ b/content/common/gpu/gpu_memory_buffer_factory_ozone.cc
@@ -22,9 +22,8 @@ class GpuMemoryBufferFactoryImpl : public GpuMemoryBufferFactory {
unsigned usage) OVERRIDE {
switch (handle.type) {
case gfx::OZONE_NATIVE_BUFFER:
- return ui::GpuMemoryBufferFactoryOzoneNativeBuffer::GetInstance()
- ->CreateGpuMemoryBuffer(
- handle.global_id, size, internalformat, usage)
+ return ozone_buffer_factory.CreateGpuMemoryBuffer(
+ handle.global_id, size, internalformat, usage)
? handle
: gfx::GpuMemoryBufferHandle();
default:
@@ -36,8 +35,7 @@ class GpuMemoryBufferFactoryImpl : public GpuMemoryBufferFactory {
const gfx::GpuMemoryBufferHandle& handle) OVERRIDE {
switch (handle.type) {
case gfx::OZONE_NATIVE_BUFFER:
- ui::GpuMemoryBufferFactoryOzoneNativeBuffer::GetInstance()
- ->DestroyGpuMemoryBuffer(handle.global_id);
+ ozone_buffer_factory.DestroyGpuMemoryBuffer(handle.global_id);
break;
default:
NOTREACHED();
@@ -63,14 +61,16 @@ class GpuMemoryBufferFactoryImpl : public GpuMemoryBufferFactory {
if (handle.global_id.secondary_id != client_id)
return scoped_refptr<gfx::GLImage>();
- return ui::GpuMemoryBufferFactoryOzoneNativeBuffer::GetInstance()
- ->CreateImageForGpuMemoryBuffer(
- handle.global_id, size, internalformat);
+ return ozone_buffer_factory.CreateImageForGpuMemoryBuffer(
+ handle.global_id, size, internalformat);
default:
NOTREACHED();
return scoped_refptr<gfx::GLImage>();
}
}
+
+ private:
+ ui::GpuMemoryBufferFactoryOzoneNativeBuffer ozone_buffer_factory;
};
} // namespace
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index 164052e644..a91bd1f419 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -696,9 +696,10 @@ IPC_MESSAGE_ROUTED1(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer,
int32) /* Picture buffer ID */
// Decoder reports that a picture is ready.
-IPC_MESSAGE_ROUTED2(AcceleratedVideoDecoderHostMsg_PictureReady,
- int32, /* Picture buffer ID */
- int32) /* Bitstream buffer ID */
+IPC_MESSAGE_ROUTED3(AcceleratedVideoDecoderHostMsg_PictureReady,
+ int32, /* Picture buffer ID */
+ int32, /* Bitstream buffer ID */
+ gfx::Rect) /* Visible rectangle */
// Confirm decoder has been flushed.
IPC_MESSAGE_ROUTED0(AcceleratedVideoDecoderHostMsg_FlushDone)
diff --git a/content/common/gpu/image_transport_surface_fbo_mac.mm b/content/common/gpu/image_transport_surface_fbo_mac.mm
index c62205c470..fc7e5ec4bf 100644
--- a/content/common/gpu/image_transport_surface_fbo_mac.mm
+++ b/content/common/gpu/image_transport_surface_fbo_mac.mm
@@ -184,8 +184,6 @@ void ImageTransportSurfaceFBO::UnblockContextAfterPendingSwap() {
void ImageTransportSurfaceFBO::OnResize(gfx::Size size,
float scale_factor) {
- // This trace event is used in gpu_feature_browsertest.cc - the test will need
- // to be updated if this event is changed or moved.
TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::OnResize",
"old_width", size_.width(), "new_width", size.width());
// Caching |context_| from OnMakeCurrent. It should still be current.
@@ -248,8 +246,6 @@ void ImageTransportSurfaceFBO::CreateFramebuffer() {
if (has_complete_framebuffer_ && new_rounded_size == rounded_size_)
return;
- // This trace event is used in gpu_feature_browsertest.cc - the test will need
- // to be updated if this event is changed or moved.
TRACE_EVENT2("gpu", "ImageTransportSurfaceFBO::CreateFramebuffer",
"width", new_rounded_size.width(),
"height", new_rounded_size.height());
diff --git a/content/common/gpu/image_transport_surface_mac.mm b/content/common/gpu/image_transport_surface_mac.mm
index c193f6f70d..3a48063c7a 100644
--- a/content/common/gpu/image_transport_surface_mac.mm
+++ b/content/common/gpu/image_transport_surface_mac.mm
@@ -18,7 +18,8 @@ namespace {
class DRTSurfaceOSMesa : public gfx::GLSurfaceOSMesa {
public:
// Size doesn't matter, the surface is resized to the right size later.
- DRTSurfaceOSMesa() : GLSurfaceOSMesa(GL_RGBA, gfx::Size(1, 1)) {}
+ DRTSurfaceOSMesa()
+ : GLSurfaceOSMesa(gfx::OSMesaSurfaceFormatRGBA, gfx::Size(1, 1)) {}
// Implement a subset of GLSurface.
virtual bool SwapBuffers() OVERRIDE;
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc
index b1de5b1354..0eee64152f 100644
--- a/content/common/gpu/media/android_video_decode_accelerator.cc
+++ b/content/common/gpu/media/android_video_decode_accelerator.cc
@@ -377,9 +377,10 @@ void AndroidVideoDecodeAccelerator::SendCurrentSurfaceToClient(
base::MessageLoop::current()->PostTask(
FROM_HERE,
- base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
- weak_this_factory_.GetWeakPtr(),
- media::Picture(picture_buffer_id, bitstream_id)));
+ base::Bind(
+ &AndroidVideoDecodeAccelerator::NotifyPictureReady,
+ weak_this_factory_.GetWeakPtr(),
+ media::Picture(picture_buffer_id, bitstream_id, gfx::Rect(size_))));
}
void AndroidVideoDecodeAccelerator::Decode(
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc
index 2e667d0bd1..1c9f6f313a 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
@@ -943,7 +943,8 @@ void DXVAVideoDecodeAccelerator::ProcessPendingSamples() {
PLATFORM_FAILURE, );
media::Picture output_picture(index->second->id(),
- sample_info.input_buffer_id);
+ sample_info.input_buffer_id,
+ gfx::Rect(index->second->size()));
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&DXVAVideoDecodeAccelerator::NotifyPictureReady,
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 6ce9330f8c..c1cd5538e1 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -212,7 +212,8 @@ void GpuVideoDecodeAccelerator::PictureReady(
if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady(
host_route_id_,
picture.picture_buffer_id(),
- picture.bitstream_buffer_id()))) {
+ picture.bitstream_buffer_id(),
+ picture.visible_rect()))) {
DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed";
}
}
diff --git a/content/common/gpu/media/rendering_helper.cc b/content/common/gpu/media/rendering_helper.cc
index 7ee940148d..ce2f94b16d 100644
--- a/content/common/gpu/media/rendering_helper.cc
+++ b/content/common/gpu/media/rendering_helper.cc
@@ -9,6 +9,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/message_loop/message_loop.h"
@@ -60,6 +61,25 @@ RenderingHelperParams::RenderingHelperParams() {}
RenderingHelperParams::~RenderingHelperParams() {}
+VideoFrameTexture::VideoFrameTexture(uint32 texture_target,
+ uint32 texture_id,
+ const base::Closure& no_longer_needed_cb)
+ : texture_target_(texture_target),
+ texture_id_(texture_id),
+ no_longer_needed_cb_(no_longer_needed_cb) {
+ DCHECK(!no_longer_needed_cb_.is_null());
+}
+
+VideoFrameTexture::~VideoFrameTexture() {
+ base::ResetAndReturn(&no_longer_needed_cb_).Run();
+}
+
+RenderingHelper::RenderedVideo::RenderedVideo() : last_frame_rendered(false) {
+}
+
+RenderingHelper::RenderedVideo::~RenderedVideo() {
+}
+
// static
bool RenderingHelper::InitializeOneOff() {
base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
@@ -78,15 +98,15 @@ RenderingHelper::RenderingHelper() {
}
RenderingHelper::~RenderingHelper() {
- CHECK_EQ(clients_.size(), 0U) << "Must call UnInitialize before dtor.";
+ CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor.";
Clear();
}
void RenderingHelper::Initialize(const RenderingHelperParams& params,
base::WaitableEvent* done) {
- // Use cients_.size() != 0 as a proxy for the class having already been
+ // Use videos_.size() != 0 as a proxy for the class having already been
// Initialize()'d, and UnInitialize() before continuing.
- if (clients_.size()) {
+ if (videos_.size()) {
base::WaitableEvent done(false, false);
UnInitialize(&done);
done.Wait();
@@ -153,12 +173,12 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params,
NULL, gl_surface_, gfx::PreferIntegratedGpu);
gl_context_->MakeCurrent(gl_surface_);
- clients_ = params.clients;
- CHECK_GT(clients_.size(), 0U);
- LayoutRenderingAreas();
+ CHECK_GT(params.window_sizes.size(), 0U);
+ videos_.resize(params.window_sizes.size());
+ LayoutRenderingAreas(params.window_sizes);
if (render_as_thumbnails_) {
- CHECK_EQ(clients_.size(), 1U);
+ CHECK_EQ(videos_.size(), 1U);
GLint max_texture_size;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
@@ -370,6 +390,31 @@ void RenderingHelper::RenderThumbnail(uint32 texture_target,
++frame_count_;
}
+void RenderingHelper::QueueVideoFrame(
+ size_t window_id,
+ scoped_refptr<VideoFrameTexture> video_frame) {
+ CHECK_EQ(base::MessageLoop::current(), message_loop_);
+ RenderedVideo* video = &videos_[window_id];
+
+ // Pop the last frame if it has been rendered.
+ if (video->last_frame_rendered) {
+ // When last_frame_rendered is true, we should have only one pending frame.
+ // Since we are going to have a new frame, we can release the pending one.
+ DCHECK(video->pending_frames.size() == 1);
+ video->pending_frames.pop();
+ video->last_frame_rendered = false;
+ }
+
+ video->pending_frames.push(video_frame);
+}
+
+void RenderingHelper::DropPendingFrames(size_t window_id) {
+ CHECK_EQ(base::MessageLoop::current(), message_loop_);
+ RenderedVideo* video = &videos_[window_id];
+ video->pending_frames = std::queue<scoped_refptr<VideoFrameTexture> >();
+ video->last_frame_rendered = false;
+}
+
void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
// The ExternalOES sampler is bound to GL_TEXTURE1 and the Texture2D sampler
// is bound to GL_TEXTURE0.
@@ -385,6 +430,7 @@ void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
}
void RenderingHelper::DeleteTexture(uint32 texture_id) {
+ CHECK_EQ(base::MessageLoop::current(), message_loop_);
glDeleteTextures(1, &texture_id);
CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
}
@@ -398,7 +444,7 @@ void* RenderingHelper::GetGLDisplay() {
}
void RenderingHelper::Clear() {
- clients_.clear();
+ videos_.clear();
message_loop_ = NULL;
gl_context_ = NULL;
gl_surface_ = NULL;
@@ -461,16 +507,30 @@ void RenderingHelper::RenderContent() {
CHECK_EQ(base::MessageLoop::current(), message_loop_);
glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
+ // Frames that will be returned to the client (via the no_longer_needed_cb)
+ // after this vector falls out of scope at the end of this method. We need
+ // to keep references to them until after SwapBuffers() call below.
+ std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned;
+
if (render_as_thumbnails_) {
// In render_as_thumbnails_ mode, we render the FBO content on the
// screen instead of the decoded textures.
- GLSetViewPort(render_areas_[0]);
+ GLSetViewPort(videos_[0].render_area);
RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_);
} else {
- for (size_t i = 0; i < clients_.size(); ++i) {
- if (clients_[i]) {
- GLSetViewPort(render_areas_[i]);
- clients_[i]->RenderContent(this);
+ for (size_t i = 0; i < videos_.size(); ++i) {
+ RenderedVideo* video = &videos_[i];
+ if (video->pending_frames.empty())
+ continue;
+ scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front();
+ GLSetViewPort(video->render_area);
+ RenderTexture(frame->texture_target(), frame->texture_id());
+
+ if (video->pending_frames.size() > 1) {
+ frames_to_be_returned.push_back(video->pending_frames.front());
+ video->pending_frames.pop();
+ } else {
+ video->last_frame_rendered = true;
}
}
}
@@ -492,11 +552,12 @@ static void ScaleAndCalculateOffsets(std::vector<int>* lengths,
}
}
-void RenderingHelper::LayoutRenderingAreas() {
+void RenderingHelper::LayoutRenderingAreas(
+ const std::vector<gfx::Size>& window_sizes) {
// Find the number of colums and rows.
- // The smallest n * n or n * (n + 1) > number of clients.
- size_t cols = sqrt(clients_.size() - 1) + 1;
- size_t rows = (clients_.size() + cols - 1) / cols;
+ // The smallest n * n or n * (n + 1) > number of windows.
+ size_t cols = sqrt(videos_.size() - 1) + 1;
+ size_t rows = (videos_.size() + cols - 1) / cols;
// Find the widths and heights of the grid.
std::vector<int> widths(cols);
@@ -504,31 +565,30 @@ void RenderingHelper::LayoutRenderingAreas() {
std::vector<int> offset_x(cols);
std::vector<int> offset_y(rows);
- for (size_t i = 0; i < clients_.size(); ++i) {
- const gfx::Size& window_size = clients_[i]->GetWindowSize();
- widths[i % cols] = std::max(widths[i % cols], window_size.width());
- heights[i / cols] = std::max(heights[i / cols], window_size.height());
+ for (size_t i = 0; i < window_sizes.size(); ++i) {
+ const gfx::Size& size = window_sizes[i];
+ widths[i % cols] = std::max(widths[i % cols], size.width());
+ heights[i / cols] = std::max(heights[i / cols], size.height());
}
ScaleAndCalculateOffsets(&widths, &offset_x, screen_size_.width());
ScaleAndCalculateOffsets(&heights, &offset_y, screen_size_.height());
// Put each render_area_ in the center of each cell.
- render_areas_.clear();
- for (size_t i = 0; i < clients_.size(); ++i) {
- const gfx::Size& window_size = clients_[i]->GetWindowSize();
+ for (size_t i = 0; i < window_sizes.size(); ++i) {
+ const gfx::Size& size = window_sizes[i];
float scale =
- std::min(static_cast<float>(widths[i % cols]) / window_size.width(),
- static_cast<float>(heights[i / cols]) / window_size.height());
+ std::min(static_cast<float>(widths[i % cols]) / size.width(),
+ static_cast<float>(heights[i / cols]) / size.height());
// Don't scale up the texture.
scale = std::min(1.0f, scale);
- size_t w = scale * window_size.width();
- size_t h = scale * window_size.height();
+ size_t w = scale * size.width();
+ size_t h = scale * size.height();
size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2;
size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2;
- render_areas_.push_back(gfx::Rect(x, y, w, h));
+ videos_[i].render_area = gfx::Rect(x, y, w, h);
}
}
} // namespace content
diff --git a/content/common/gpu/media/rendering_helper.h b/content/common/gpu/media/rendering_helper.h
index a2dfb1bbf4..6b0013f5b9 100644
--- a/content/common/gpu/media/rendering_helper.h
+++ b/content/common/gpu/media/rendering_helper.h
@@ -6,6 +6,7 @@
#define CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
#include <map>
+#include <queue>
#include <vector>
#include "base/basictypes.h"
@@ -24,25 +25,53 @@ class WaitableEvent;
namespace content {
-struct RenderingHelperParams;
+class VideoFrameTexture : public base::RefCounted<VideoFrameTexture> {
+ public:
+ uint32 texture_id() const { return texture_id_; }
+ uint32 texture_target() const { return texture_target_; }
+
+ VideoFrameTexture(uint32 texture_target,
+ uint32 texture_id,
+ const base::Closure& no_longer_needed_cb);
+
+ private:
+ friend class base::RefCounted<VideoFrameTexture>;
+
+ uint32 texture_target_;
+ uint32 texture_id_;
+ base::Closure no_longer_needed_cb_;
+
+ ~VideoFrameTexture();
+};
+
+struct RenderingHelperParams {
+ RenderingHelperParams();
+ ~RenderingHelperParams();
+
+ // The rendering FPS.
+ int rendering_fps;
+
+ // The desired size of each window. We play each stream in its own window
+ // on the screen.
+ std::vector<gfx::Size> window_sizes;
+
+ // The members below are only used for the thumbnail mode where all frames
+ // are rendered in sequence onto one FBO for comparison/verification purposes.
+
+ // Whether the frames are rendered as scaled thumbnails within a
+ // larger FBO that is in turn rendered to the window.
+ bool render_as_thumbnails;
+ // The size of the FBO containing all visible thumbnails.
+ gfx::Size thumbnails_page_size;
+ // The size of each thumbnail within the FBO.
+ gfx::Size thumbnail_size;
+};
// Creates and draws textures used by the video decoder.
// This class is not thread safe and thus all the methods of this class
// (except for ctor/dtor) ensure they're being run on a single thread.
class RenderingHelper {
public:
- // Interface for the content provider of the RenderingHelper.
- class Client {
- public:
- // Callback to tell client to render the content.
- virtual void RenderContent(RenderingHelper* helper) = 0;
-
- // Callback to get the desired window size of the client.
- virtual const gfx::Size& GetWindowSize() = 0;
-
- protected:
- virtual ~Client() {}
- };
RenderingHelper();
~RenderingHelper();
@@ -67,9 +96,12 @@ class RenderingHelper {
// |texture_target|.
void RenderThumbnail(uint32 texture_target, uint32 texture_id);
- // Render |texture_id| to the current view port of the screen using target
- // |texture_target|.
- void RenderTexture(uint32 texture_target, uint32 texture_id);
+ // Queues the |video_frame| for rendering.
+ void QueueVideoFrame(size_t window_id,
+ scoped_refptr<VideoFrameTexture> video_frame);
+
+ // Drops all the pending video frames of the specified window.
+ void DropPendingFrames(size_t window_id);
// Delete |texture_id|.
void DeleteTexture(uint32 texture_id);
@@ -87,11 +119,33 @@ class RenderingHelper {
base::WaitableEvent* done);
private:
+ struct RenderedVideo {
+ // The rect on the screen where the video will be rendered.
+ gfx::Rect render_area;
+
+ // True if the last (and the only one) frame in pending_frames has
+ // been rendered. We keep the last remaining frame in pending_frames even
+ // after it has been rendered, so that we have something to display if the
+ // client is falling behind on providing us with new frames during
+ // timer-driven playback.
+ bool last_frame_rendered;
+
+ // The video frames pending for rendering.
+ std::queue<scoped_refptr<VideoFrameTexture> > pending_frames;
+
+ RenderedVideo();
+ ~RenderedVideo();
+ };
+
void Clear();
void RenderContent();
- void LayoutRenderingAreas();
+ void LayoutRenderingAreas(const std::vector<gfx::Size>& window_sizes);
+
+ // Render |texture_id| to the current view port of the screen using target
+ // |texture_target|.
+ void RenderTexture(uint32 texture_target, uint32 texture_id);
// Timer to trigger the RenderContent() repeatly.
scoped_ptr<base::RepeatingTimer<RenderingHelper> > render_timer_;
@@ -104,10 +158,7 @@ class RenderingHelper {
gfx::Size screen_size_;
- // The rendering area of each window on the screen.
- std::vector<gfx::Rect> render_areas_;
-
- std::vector<base::WeakPtr<Client> > clients_;
+ std::vector<RenderedVideo> videos_;
bool render_as_thumbnails_;
int frame_count_;
@@ -121,24 +172,6 @@ class RenderingHelper {
DISALLOW_COPY_AND_ASSIGN(RenderingHelper);
};
-struct RenderingHelperParams {
- RenderingHelperParams();
- ~RenderingHelperParams();
-
- // The rendering FPS.
- int rendering_fps;
-
- // The clients who provide the content for rendering.
- std::vector<base::WeakPtr<RenderingHelper::Client> > clients;
-
- // Whether the frames are rendered as scaled thumbnails within a
- // larger FBO that is in turn rendered to the window.
- bool render_as_thumbnails;
- // The size of the FBO containing all visible thumbnails.
- gfx::Size thumbnails_page_size;
- // The size of each thumbnail within the FBO.
- gfx::Size thumbnail_size;
-};
} // namespace content
#endif // CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
diff --git a/content/common/gpu/media/v4l2_image_processor.cc b/content/common/gpu/media/v4l2_image_processor.cc
index 1a9dd29218..f988e90421 100644
--- a/content/common/gpu/media/v4l2_image_processor.cc
+++ b/content/common/gpu/media/v4l2_image_processor.cc
@@ -214,6 +214,7 @@ void V4L2ImageProcessor::DestroyTask() {
}
bool V4L2ImageProcessor::CreateInputBuffers() {
+ DVLOG(3) << __func__;
DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
DCHECK(!input_streamon_);
@@ -284,6 +285,7 @@ bool V4L2ImageProcessor::CreateInputBuffers() {
}
bool V4L2ImageProcessor::CreateOutputBuffers() {
+ DVLOG(3) << __func__;
DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
DCHECK(!output_streamon_);
diff --git a/content/common/gpu/media/v4l2_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
index 315b2f516e..cea1c7b3bb 100644
--- a/content/common/gpu/media/v4l2_video_decode_accelerator.cc
+++ b/content/common/gpu/media/v4l2_video_decode_accelerator.cc
@@ -1092,7 +1092,9 @@ void V4L2VideoDecodeAccelerator::Dequeue() {
DVLOG(3) << "Dequeue(): returning input_id=" << dqbuf.timestamp.tv_sec
<< " as picture_id=" << output_record.picture_id;
const media::Picture& picture =
- media::Picture(output_record.picture_id, dqbuf.timestamp.tv_sec);
+ media::Picture(output_record.picture_id,
+ dqbuf.timestamp.tv_sec,
+ gfx::Rect(frame_buffer_size_));
pending_picture_ready_.push(
PictureRecord(output_record.cleared, picture));
SendPictureReady();
diff --git a/content/common/gpu/media/v4l2_video_device.cc b/content/common/gpu/media/v4l2_video_device.cc
index e9c54229c7..0a094ba6e4 100644
--- a/content/common/gpu/media/v4l2_video_device.cc
+++ b/content/common/gpu/media/v4l2_video_device.cc
@@ -106,6 +106,11 @@ gfx::Size V4L2Device::CodedSizeFromV4L2Format(struct v4l2_format format) {
int horiz_bpp =
media::VideoFrame::PlaneHorizontalBitsPerPixel(frame_format, 0);
+ DVLOG(3) << __func__ << ": bytesperline=" << bytesperline
+ << ", sizeimage=" << sizeimage
+ << ", visible_size=" << visible_size.ToString() << ", frame_format="
+ << media::VideoFrame::FormatToString(frame_format)
+ << ", horiz_bpp=" << horiz_bpp;
if (sizeimage == 0 || bytesperline == 0 || horiz_bpp == 0 ||
(bytesperline * 8) % horiz_bpp != 0) {
DLOG(ERROR) << "Invalid format provided";
@@ -118,6 +123,7 @@ gfx::Size V4L2Device::CodedSizeFromV4L2Format(struct v4l2_format format) {
sizeimage = ((sizeimage + bytesperline - 1) / bytesperline) * bytesperline;
coded_size.SetSize(bytesperline * 8 / horiz_bpp, sizeimage / bytesperline);
+ DVLOG(3) << "coded_size=" << coded_size.ToString();
// Sanity checks. Calculated coded size has to contain given visible size
// and fulfill buffer byte size requirements for each plane.
@@ -125,11 +131,9 @@ gfx::Size V4L2Device::CodedSizeFromV4L2Format(struct v4l2_format format) {
if (V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
for (size_t i = 0; i < format.fmt.pix_mp.num_planes; ++i) {
- DCHECK_LE(
- format.fmt.pix_mp.plane_fmt[i].sizeimage,
- media::VideoFrame::PlaneAllocationSize(frame_format, i, coded_size));
- DCHECK_LE(format.fmt.pix_mp.plane_fmt[i].bytesperline,
- base::checked_cast<__u32>(coded_size.width()));
+ DCHECK_EQ(format.fmt.pix_mp.plane_fmt[i].bytesperline,
+ base::checked_cast<__u32>(media::VideoFrame::RowBytes(
+ i, frame_format, coded_size.width())));
}
}
diff --git a/content/common/gpu/media/v4l2_video_encode_accelerator.cc b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
index 25320f4603..1f10e840bf 100644
--- a/content/common/gpu/media/v4l2_video_encode_accelerator.cc
+++ b/content/common/gpu/media/v4l2_video_encode_accelerator.cc
@@ -860,6 +860,7 @@ bool V4L2VideoEncodeAccelerator::SetOutputFormat(
bool V4L2VideoEncodeAccelerator::NegotiateInputFormat(
media::VideoFrame::Format input_format) {
+ DVLOG(3) << "NegotiateInputFormat()";
DCHECK(child_message_loop_proxy_->BelongsToCurrentThread());
DCHECK(!input_streamon_);
DCHECK(!output_streamon_);
diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
index afcfc8a3b0..0b3001272a 100644
--- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc
@@ -371,8 +371,11 @@ void VaapiVideoDecodeAccelerator::OutputPicture(
TRACE_COUNTER1("Video Decoder", "Textures at client", num_frames_at_client_);
DVLOG(4) << "Notifying output picture id " << output_id
<< " for input "<< input_id << " is ready";
+ // TODO(posciak): Use visible size from decoder here instead
+ // (crbug.com/402760).
if (client_)
- client_->PictureReady(media::Picture(output_id, input_id));
+ client_->PictureReady(
+ media::Picture(output_id, input_id, gfx::Rect(tfp_picture->size())));
}
void VaapiVideoDecodeAccelerator::TryOutputSurface() {
diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc
index 071dced9f0..65cc9397a6 100644
--- a/content/common/gpu/media/video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -193,9 +193,10 @@ enum ClientState {
// the TESTs below.
class GLRenderingVDAClient
: public VideoDecodeAccelerator::Client,
- public RenderingHelper::Client,
public base::SupportsWeakPtr<GLRenderingVDAClient> {
public:
+ // |window_id| the window_id of the client, which is used to identify the
+ // rendering area in the |rendering_helper|.
// Doesn't take ownership of |rendering_helper| or |note|, which must outlive
// |*this|.
// |num_play_throughs| indicates how many times to play through the video.
@@ -212,7 +213,8 @@ class GLRenderingVDAClient
// will start delaying the call to ReusePictureBuffer() for kReuseDelay.
// |decode_calls_per_second| is the number of VDA::Decode calls per second.
// If |decode_calls_per_second| > 0, |num_in_flight_decodes| must be 1.
- GLRenderingVDAClient(RenderingHelper* rendering_helper,
+ GLRenderingVDAClient(size_t window_id,
+ RenderingHelper* rendering_helper,
ClientStateNotification<ClientState>* note,
const std::string& encoded_data,
int num_in_flight_decodes,
@@ -242,14 +244,8 @@ class GLRenderingVDAClient
virtual void NotifyResetDone() OVERRIDE;
virtual void NotifyError(VideoDecodeAccelerator::Error error) OVERRIDE;
- // RenderingHelper::Client implementation.
- virtual void RenderContent(RenderingHelper*) OVERRIDE;
- virtual const gfx::Size& GetWindowSize() OVERRIDE;
-
void OutputFrameDeliveryTimes(base::File* output);
- void NotifyFrameDropped(int32 picture_buffer_id);
-
// Simple getters for inspecting the state of the Client.
int num_done_bitstream_buffers() { return num_done_bitstream_buffers_; }
int num_skipped_fragments() { return num_skipped_fragments_; }
@@ -285,6 +281,7 @@ class GLRenderingVDAClient
// Request decode of the next fragment in the encoded data.
void DecodeNextFragment();
+ size_t window_id_;
RenderingHelper* rendering_helper_;
gfx::Size frame_size_;
std::string encoded_data_;
@@ -319,13 +316,12 @@ class GLRenderingVDAClient
// The number of VDA::Decode calls per second. This is to simulate webrtc.
int decode_calls_per_second_;
bool render_as_thumbnails_;
- bool pending_picture_updated_;
- std::deque<int32> pending_picture_buffer_ids_;
DISALLOW_IMPLICIT_CONSTRUCTORS(GLRenderingVDAClient);
};
GLRenderingVDAClient::GLRenderingVDAClient(
+ size_t window_id,
RenderingHelper* rendering_helper,
ClientStateNotification<ClientState>* note,
const std::string& encoded_data,
@@ -340,7 +336,8 @@ GLRenderingVDAClient::GLRenderingVDAClient(
int delay_reuse_after_frame_num,
int decode_calls_per_second,
bool render_as_thumbnails)
- : rendering_helper_(rendering_helper),
+ : window_id_(window_id),
+ rendering_helper_(rendering_helper),
frame_size_(frame_width, frame_height),
encoded_data_(encoded_data),
num_in_flight_decodes_(num_in_flight_decodes),
@@ -360,8 +357,7 @@ GLRenderingVDAClient::GLRenderingVDAClient(
suppress_rendering_(suppress_rendering),
delay_reuse_after_frame_num_(delay_reuse_after_frame_num),
decode_calls_per_second_(decode_calls_per_second),
- render_as_thumbnails_(render_as_thumbnails),
- pending_picture_updated_(true) {
+ render_as_thumbnails_(render_as_thumbnails) {
CHECK_GT(num_in_flight_decodes, 0);
CHECK_GT(num_play_throughs, 0);
// |num_in_flight_decodes_| is unsupported if |decode_calls_per_second_| > 0.
@@ -459,42 +455,6 @@ void GLRenderingVDAClient::DismissPictureBuffer(int32 picture_buffer_id) {
picture_buffers_by_id_.erase(it);
}
-void GLRenderingVDAClient::RenderContent(RenderingHelper*) {
- CHECK(!render_as_thumbnails_);
-
- // No decoded texture for rendering yet, just skip.
- if (pending_picture_buffer_ids_.size() == 0)
- return;
-
- int32 buffer_id = pending_picture_buffer_ids_.front();
- media::PictureBuffer* picture_buffer = picture_buffers_by_id_[buffer_id];
-
- CHECK(picture_buffer);
- if (!pending_picture_updated_) {
- // Frame dropped, just redraw the last texture.
- rendering_helper_->RenderTexture(texture_target_,
- picture_buffer->texture_id());
- return;
- }
-
- base::TimeTicks now = base::TimeTicks::Now();
- frame_delivery_times_.push_back(now);
-
- rendering_helper_->RenderTexture(texture_target_,
- picture_buffer->texture_id());
-
- if (pending_picture_buffer_ids_.size() == 1) {
- pending_picture_updated_ = false;
- } else {
- pending_picture_buffer_ids_.pop_front();
- ReturnPicture(buffer_id);
- }
-}
-
-const gfx::Size& GLRenderingVDAClient::GetWindowSize() {
- return render_as_thumbnails_ ? kThumbnailsPageSize : frame_size_;
-}
-
void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
// We shouldn't be getting pictures delivered after Reset has completed.
CHECK_LT(state_, CS_RESET);
@@ -503,6 +463,9 @@ void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
return;
base::TimeTicks now = base::TimeTicks::Now();
+
+ frame_delivery_times_.push_back(now);
+
// Save the decode time of this picture.
std::map<int, base::TimeTicks>::iterator it =
decode_start_time_.find(picture.bitstream_buffer_id());
@@ -524,25 +487,22 @@ void GLRenderingVDAClient::PictureReady(const media::Picture& picture) {
encoded_data_next_pos_to_decode_ = 0;
}
+ media::PictureBuffer* picture_buffer =
+ picture_buffers_by_id_[picture.picture_buffer_id()];
+ CHECK(picture_buffer);
+
+ scoped_refptr<VideoFrameTexture> video_frame =
+ new VideoFrameTexture(texture_target_,
+ picture_buffer->texture_id(),
+ base::Bind(&GLRenderingVDAClient::ReturnPicture,
+ AsWeakPtr(),
+ picture.picture_buffer_id()));
+
if (render_as_thumbnails_) {
- frame_delivery_times_.push_back(now);
- media::PictureBuffer* picture_buffer =
- picture_buffers_by_id_[picture.picture_buffer_id()];
- CHECK(picture_buffer);
- rendering_helper_->RenderThumbnail(texture_target_,
- picture_buffer->texture_id());
- ReturnPicture(picture.picture_buffer_id());
+ rendering_helper_->RenderThumbnail(video_frame->texture_target(),
+ video_frame->texture_id());
} else if (!suppress_rendering_) {
- // Keep the picture for rendering.
- pending_picture_buffer_ids_.push_back(picture.picture_buffer_id());
- if (pending_picture_buffer_ids_.size() > 1 && !pending_picture_updated_) {
- ReturnPicture(pending_picture_buffer_ids_.front());
- pending_picture_buffer_ids_.pop_front();
- pending_picture_updated_ = true;
- }
- } else {
- frame_delivery_times_.push_back(now);
- ReturnPicture(picture.picture_buffer_id());
+ rendering_helper_->QueueVideoFrame(window_id_, video_frame);
}
}
@@ -590,12 +550,7 @@ void GLRenderingVDAClient::NotifyResetDone() {
if (decoder_deleted())
return;
- // Clear pending_pictures and reuse them.
- while (!pending_picture_buffer_ids_.empty()) {
- decoder_->ReusePictureBuffer(pending_picture_buffer_ids_.front());
- pending_picture_buffer_ids_.pop_front();
- }
- pending_picture_updated_ = true;
+ rendering_helper_->DropPendingFrames(window_id_);
if (reset_after_frame_num_ == MID_STREAM_RESET) {
reset_after_frame_num_ = END_OF_STREAM_RESET;
@@ -637,10 +592,6 @@ void GLRenderingVDAClient::OutputFrameDeliveryTimes(base::File* output) {
}
}
-void GLRenderingVDAClient::NotifyFrameDropped(int32 picture_buffer_id) {
- decoder_->ReusePictureBuffer(picture_buffer_id);
-}
-
static bool LookingAtNAL(const std::string& encoded, size_t pos) {
return encoded[pos] == 0 && encoded[pos + 1] == 0 &&
encoded[pos + 2] == 0 && encoded[pos + 3] == 1;
@@ -1127,7 +1078,8 @@ TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) {
}
GLRenderingVDAClient* client =
- new GLRenderingVDAClient(&rendering_helper_,
+ new GLRenderingVDAClient(index,
+ &rendering_helper_,
note,
video_file->data_str,
num_in_flight_decodes,
@@ -1143,7 +1095,10 @@ TEST_P(VideoDecodeAcceleratorParamTest, TestSimpleDecode) {
render_as_thumbnails);
clients[index] = client;
- helper_params.clients.push_back(client->AsWeakPtr());
+ helper_params.window_sizes.push_back(
+ render_as_thumbnails
+ ? kThumbnailsPageSize
+ : gfx::Size(video_file->width, video_file->height));
}
InitializeRenderingHelper(helper_params);
@@ -1376,7 +1331,8 @@ TEST_F(VideoDecodeAcceleratorTest, TestDecodeTimeMedian) {
ClientStateNotification<ClientState>* note =
new ClientStateNotification<ClientState>();
GLRenderingVDAClient* client =
- new GLRenderingVDAClient(&rendering_helper_,
+ new GLRenderingVDAClient(0,
+ &rendering_helper_,
note,
test_video_files_[0]->data_str,
1,
@@ -1390,7 +1346,8 @@ TEST_F(VideoDecodeAcceleratorTest, TestDecodeTimeMedian) {
std::numeric_limits<int>::max(),
kWebRtcDecodeCallsPerSecond,
false /* render_as_thumbnail */);
- helper_params.clients.push_back(client->AsWeakPtr());
+ helper_params.window_sizes.push_back(
+ gfx::Size(test_video_files_[0]->width, test_video_files_[0]->height));
InitializeRenderingHelper(helper_params);
CreateAndStartDecoder(client, note);
WaitUntilDecodeFinish(note);
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.cc b/content/common/gpu/media/vt_video_decode_accelerator.cc
index 5b916501b1..8e4c40819c 100644
--- a/content/common/gpu/media/vt_video_decode_accelerator.cc
+++ b/content/common/gpu/media/vt_video_decode_accelerator.cc
@@ -376,7 +376,8 @@ void VTVideoDecodeAccelerator::SendPictures() {
0)); // plane
picture_bindings_[picture_id] = frame.image_buffer;
- client_->PictureReady(media::Picture(picture_id, frame.bitstream_id));
+ client_->PictureReady(media::Picture(
+ picture_id, frame.bitstream_id, gfx::Rect(texture_size_)));
client_->NotifyEndOfBitstreamBuffer(frame.bitstream_id);
}