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

Unified Diff: content/renderer/media/renderer_gpu_video_accelerator_factories.cc

Issue 20632002: Add media::VideoEncodeAccelerator with WebRTC integration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@git-svn
Patch Set: d3982027 CQ nits. Created 7 years, 4 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: content/renderer/media/renderer_gpu_video_accelerator_factories.cc
diff --git a/content/renderer/media/renderer_gpu_video_decoder_factories.cc b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
similarity index 54%
rename from content/renderer/media/renderer_gpu_video_decoder_factories.cc
rename to content/renderer/media/renderer_gpu_video_accelerator_factories.cc
index d33e5901b2af82388a5364012575a4c9cf109e4e..a99bea6c8bcd125dddea8da283cffc9ddd543f4a 100644
--- a/content/renderer/media/renderer_gpu_video_decoder_factories.cc
+++ b/content/renderer/media/renderer_gpu_video_accelerator_factories.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/renderer_gpu_video_decoder_factories.h"
+#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -17,8 +17,8 @@
namespace content {
-RendererGpuVideoDecoderFactories::~RendererGpuVideoDecoderFactories() {}
-RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories(
+RendererGpuVideoAcceleratorFactories::~RendererGpuVideoAcceleratorFactories() {}
+RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories(
GpuChannelHost* gpu_channel_host,
const scoped_refptr<base::MessageLoopProxy>& message_loop,
WebGraphicsContext3DCommandBufferImpl* context)
@@ -28,32 +28,37 @@ RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories(
aborted_waiter_(true, false),
message_loop_async_waiter_(false, false),
render_thread_async_waiter_(false, false) {
+ // |context| is only required to support HW-accelerated decode.
+ if (!context)
+ return;
+
if (message_loop_->BelongsToCurrentThread()) {
AsyncGetContext(context);
message_loop_async_waiter_.Reset();
return;
}
// Wait for the context to be acquired.
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncGetContext,
- // Unretained to avoid ref/deref'ing |*this|, which is not yet stored in a
- // scoped_refptr. Safe because the Wait() below keeps us alive until this
- // task completes.
- base::Unretained(this),
- // OK to pass raw because the pointee is only deleted on the compositor
- // thread, and only as the result of a PostTask from the render thread
- // which can only happen after this function returns, so our PostTask will
- // run first.
- context));
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncGetContext,
+ // Unretained to avoid ref/deref'ing |*this|, which is not yet
+ // stored in a scoped_refptr. Safe because the Wait() below
+ // keeps us alive until this task completes.
+ base::Unretained(this),
+ // OK to pass raw because the pointee is only deleted on the
+ // compositor thread, and only as the result of a PostTask from
+ // the render thread which can only happen after this function
+ // returns, so our PostTask will run first.
+ context));
message_loop_async_waiter_.Wait();
}
-RendererGpuVideoDecoderFactories::RendererGpuVideoDecoderFactories()
+RendererGpuVideoAcceleratorFactories::RendererGpuVideoAcceleratorFactories()
: aborted_waiter_(true, false),
message_loop_async_waiter_(false, false),
render_thread_async_waiter_(false, false) {}
-void RendererGpuVideoDecoderFactories::AsyncGetContext(
+void RendererGpuVideoAcceleratorFactories::AsyncGetContext(
WebGraphicsContext3DCommandBufferImpl* context) {
context_ = context->AsWeakPtr();
if (context_.get()) {
@@ -66,20 +71,23 @@ void RendererGpuVideoDecoderFactories::AsyncGetContext(
message_loop_async_waiter_.Signal();
}
-media::VideoDecodeAccelerator*
-RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator(
+scoped_ptr<media::VideoDecodeAccelerator>
+RendererGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator(
media::VideoCodecProfile profile,
media::VideoDecodeAccelerator::Client* client) {
if (message_loop_->BelongsToCurrentThread()) {
AsyncCreateVideoDecodeAccelerator(profile, client);
message_loop_async_waiter_.Reset();
- return vda_.release();
+ return vda_.Pass();
}
// The VDA is returned in the vda_ member variable by the
// AsyncCreateVideoDecodeAccelerator() function.
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator,
- this, profile, client));
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::
+ AsyncCreateVideoDecodeAccelerator,
+ this,
+ profile,
+ client));
base::WaitableEvent* objects[] = {&aborted_waiter_,
&message_loop_async_waiter_};
@@ -87,17 +95,49 @@ RendererGpuVideoDecoderFactories::CreateVideoDecodeAccelerator(
// If we are aborting and the VDA is created by the
// AsyncCreateVideoDecodeAccelerator() function later we need to ensure
// that it is destroyed on the same thread.
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator,
- this));
- return NULL;
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::
+ AsyncDestroyVideoDecodeAccelerator,
+ this));
+ return scoped_ptr<media::VideoDecodeAccelerator>();
}
- return vda_.release();
+ return vda_.Pass();
}
-void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator(
- media::VideoCodecProfile profile,
- media::VideoDecodeAccelerator::Client* client) {
+scoped_ptr<media::VideoEncodeAccelerator>
+RendererGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator(
+ media::VideoEncodeAccelerator::Client* client) {
+ if (message_loop_->BelongsToCurrentThread()) {
+ AsyncCreateVideoEncodeAccelerator(client);
+ message_loop_async_waiter_.Reset();
+ return vea_.Pass();
+ }
+ // The VEA is returned in the vea_ member variable by the
+ // AsyncCreateVideoEncodeAccelerator() function.
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::
+ AsyncCreateVideoEncodeAccelerator,
+ this,
+ client));
+
+ base::WaitableEvent* objects[] = {&aborted_waiter_,
+ &message_loop_async_waiter_};
+ if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0) {
+ // If we are aborting and the VDA is created by the
+ // AsyncCreateVideoEncodeAccelerator() function later we need to ensure
+ // that it is destroyed on the same thread.
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::
+ AsyncDestroyVideoEncodeAccelerator,
+ this));
+ return scoped_ptr<media::VideoEncodeAccelerator>();
+ }
+ return vea_.Pass();
+}
+
+void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoDecodeAccelerator(
+ media::VideoCodecProfile profile,
+ media::VideoDecodeAccelerator::Client* client) {
DCHECK(message_loop_->BelongsToCurrentThread());
if (context_.get() && context_->GetCommandBufferProxy()) {
@@ -107,8 +147,17 @@ void RendererGpuVideoDecoderFactories::AsyncCreateVideoDecodeAccelerator(
message_loop_async_waiter_.Signal();
}
-uint32 RendererGpuVideoDecoderFactories::CreateTextures(
- int32 count, const gfx::Size& size,
+void RendererGpuVideoAcceleratorFactories::AsyncCreateVideoEncodeAccelerator(
+ media::VideoEncodeAccelerator::Client* client) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
+ vea_ = gpu_channel_host_->CreateVideoEncoder(client).Pass();
+ message_loop_async_waiter_.Signal();
+}
+
+uint32 RendererGpuVideoAcceleratorFactories::CreateTextures(
+ int32 count,
+ const gfx::Size& size,
std::vector<uint32>* texture_ids,
std::vector<gpu::Mailbox>* texture_mailboxes,
uint32 texture_target) {
@@ -121,9 +170,14 @@ uint32 RendererGpuVideoDecoderFactories::CreateTextures(
message_loop_async_waiter_.Reset();
return sync_point;
}
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncCreateTextures, this,
- count, size, texture_target, &sync_point));
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateTextures,
+ this,
+ count,
+ size,
+ texture_target,
+ &sync_point));
base::WaitableEvent* objects[] = {&aborted_waiter_,
&message_loop_async_waiter_};
@@ -134,8 +188,10 @@ uint32 RendererGpuVideoDecoderFactories::CreateTextures(
return sync_point;
}
-void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
- int32 count, const gfx::Size& size, uint32 texture_target,
+void RendererGpuVideoAcceleratorFactories::AsyncCreateTextures(
+ int32 count,
+ const gfx::Size& size,
+ uint32 texture_target,
uint32* sync_point) {
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(texture_target);
@@ -157,8 +213,15 @@ void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (texture_target == GL_TEXTURE_2D) {
- gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(),
- 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ gles2->TexImage2D(texture_target,
+ 0,
+ GL_RGBA,
+ size.width(),
+ size.height(),
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ NULL);
}
gles2->GenMailboxCHROMIUM(created_texture_mailboxes_[i].name);
gles2->ProduceTextureCHROMIUM(texture_target,
@@ -175,16 +238,20 @@ void RendererGpuVideoDecoderFactories::AsyncCreateTextures(
message_loop_async_waiter_.Signal();
}
-void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
+void RendererGpuVideoAcceleratorFactories::DeleteTexture(uint32 texture_id) {
if (message_loop_->BelongsToCurrentThread()) {
AsyncDeleteTexture(texture_id);
return;
}
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id));
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture,
+ this,
+ texture_id));
}
-void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
+void RendererGpuVideoAcceleratorFactories::AsyncDeleteTexture(
+ uint32 texture_id) {
DCHECK(message_loop_->BelongsToCurrentThread());
if (!context_.get())
return;
@@ -194,23 +261,25 @@ void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
}
-void RendererGpuVideoDecoderFactories::WaitSyncPoint(uint32 sync_point) {
+void RendererGpuVideoAcceleratorFactories::WaitSyncPoint(uint32 sync_point) {
if (message_loop_->BelongsToCurrentThread()) {
AsyncWaitSyncPoint(sync_point);
message_loop_async_waiter_.Reset();
return;
}
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint,
- this,
- sync_point));
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint,
+ this,
+ sync_point));
base::WaitableEvent* objects[] = {&aborted_waiter_,
&message_loop_async_waiter_};
base::WaitableEvent::WaitMany(objects, arraysize(objects));
}
-void RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) {
+void RendererGpuVideoAcceleratorFactories::AsyncWaitSyncPoint(
+ uint32 sync_point) {
DCHECK(message_loop_->BelongsToCurrentThread());
if (!context_) {
message_loop_async_waiter_.Signal();
@@ -222,9 +291,10 @@ void RendererGpuVideoDecoderFactories::AsyncWaitSyncPoint(uint32 sync_point) {
message_loop_async_waiter_.Signal();
}
-void RendererGpuVideoDecoderFactories::ReadPixels(
- uint32 texture_id, uint32 texture_target, const gfx::Size& size,
- const SkBitmap& pixels) {
+void RendererGpuVideoAcceleratorFactories::ReadPixels(uint32 texture_id,
+ uint32 texture_target,
+ const gfx::Size& size,
+ const SkBitmap& pixels) {
// SkBitmaps use the SkPixelRef object to refcount the underlying pixels.
// Multiple SkBitmaps can share a SkPixelRef instance. We use this to
// ensure that the underlying pixels in the SkBitmap passed in remain valid
@@ -232,9 +302,13 @@ void RendererGpuVideoDecoderFactories::ReadPixels(
read_pixels_bitmap_.setPixelRef(pixels.pixelRef());
if (!message_loop_->BelongsToCurrentThread()) {
- message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncReadPixels, this,
- texture_id, texture_target, size));
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncReadPixels,
+ this,
+ texture_id,
+ texture_target,
+ size));
base::WaitableEvent* objects[] = {&aborted_waiter_,
&message_loop_async_waiter_};
if (base::WaitableEvent::WaitMany(objects, arraysize(objects)) == 0)
@@ -246,8 +320,10 @@ void RendererGpuVideoDecoderFactories::ReadPixels(
read_pixels_bitmap_.setPixelRef(NULL);
}
-void RendererGpuVideoDecoderFactories::AsyncReadPixels(
- uint32 texture_id, uint32 texture_target, const gfx::Size& size) {
+void RendererGpuVideoAcceleratorFactories::AsyncReadPixels(
+ uint32 texture_id,
+ uint32 texture_target,
+ const gfx::Size& size) {
DCHECK(message_loop_->BelongsToCurrentThread());
if (!context_.get()) {
message_loop_async_waiter_.Signal();
@@ -269,25 +345,32 @@ void RendererGpuVideoDecoderFactories::AsyncReadPixels(
GLuint fb;
gles2->GenFramebuffers(1, &fb);
gles2->BindFramebuffer(GL_FRAMEBUFFER, fb);
- gles2->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- texture_target, tmp_texture, 0);
+ gles2->FramebufferTexture2D(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, tmp_texture, 0);
gles2->PixelStorei(GL_PACK_ALIGNMENT, 4);
- gles2->ReadPixels(0, 0, size.width(), size.height(), GL_BGRA_EXT,
- GL_UNSIGNED_BYTE, read_pixels_bitmap_.pixelRef()->pixels());
+ gles2->ReadPixels(0,
+ 0,
+ size.width(),
+ size.height(),
+ GL_BGRA_EXT,
+ GL_UNSIGNED_BYTE,
+ read_pixels_bitmap_.pixelRef()->pixels());
gles2->DeleteFramebuffers(1, &fb);
gles2->DeleteTextures(1, &tmp_texture);
DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
message_loop_async_waiter_.Signal();
}
-base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory(
+base::SharedMemory* RendererGpuVideoAcceleratorFactories::CreateSharedMemory(
size_t size) {
if (main_message_loop_->BelongsToCurrentThread()) {
return ChildThread::current()->AllocateSharedMemory(size);
}
- main_message_loop_->PostTask(FROM_HERE, base::Bind(
- &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this,
- size));
+ main_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory,
+ this,
+ size));
base::WaitableEvent* objects[] = {&aborted_waiter_,
&render_thread_async_waiter_};
@@ -296,7 +379,8 @@ base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory(
return shared_memory_segment_.release();
}
-void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) {
+void RendererGpuVideoAcceleratorFactories::AsyncCreateSharedMemory(
+ size_t size) {
DCHECK_EQ(base::MessageLoop::current(),
ChildThread::current()->message_loop());
@@ -306,22 +390,20 @@ void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(size_t size) {
}
scoped_refptr<base::MessageLoopProxy>
-RendererGpuVideoDecoderFactories::GetMessageLoop() {
+RendererGpuVideoAcceleratorFactories::GetMessageLoop() {
return message_loop_;
}
-void RendererGpuVideoDecoderFactories::Abort() {
- aborted_waiter_.Signal();
-}
+void RendererGpuVideoAcceleratorFactories::Abort() { aborted_waiter_.Signal(); }
-bool RendererGpuVideoDecoderFactories::IsAborted() {
+bool RendererGpuVideoAcceleratorFactories::IsAborted() {
return aborted_waiter_.IsSignaled();
}
-scoped_refptr<media::GpuVideoDecoderFactories>
-RendererGpuVideoDecoderFactories::Clone() {
- scoped_refptr<RendererGpuVideoDecoderFactories> factories =
- new RendererGpuVideoDecoderFactories();
+scoped_refptr<RendererGpuVideoAcceleratorFactories>
+RendererGpuVideoAcceleratorFactories::Clone() {
+ scoped_refptr<RendererGpuVideoAcceleratorFactories> factories =
+ new RendererGpuVideoAcceleratorFactories();
factories->message_loop_ = message_loop_;
factories->main_message_loop_ = main_message_loop_;
factories->gpu_channel_host_ = gpu_channel_host_;
@@ -329,10 +411,18 @@ RendererGpuVideoDecoderFactories::Clone() {
return factories;
}
-void RendererGpuVideoDecoderFactories::AsyncDestroyVideoDecodeAccelerator() {
+void
+RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoDecodeAccelerator() {
// OK to release because Destroy() will delete the VDA instance.
if (vda_)
vda_.release()->Destroy();
}
+void
+RendererGpuVideoAcceleratorFactories::AsyncDestroyVideoEncodeAccelerator() {
+ // OK to release because Destroy() will delete the VDA instance.
+ if (vea_)
+ vea_.release()->Destroy();
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698