summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-22 03:20:25 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-22 03:20:25 +0000
commitaed4fd65e2faeefe32c6b139a3f1e4047f137ae1 (patch)
tree2013ef267a30c6933d64991f6626eac1e5959c4c
parentdb0545b0baa94fd24c8d06824dd90bbccd36dce2 (diff)
downloadchromium_src-aed4fd65e2faeefe32c6b139a3f1e4047f137ae1.zip
chromium_src-aed4fd65e2faeefe32c6b139a3f1e4047f137ae1.tar.gz
chromium_src-aed4fd65e2faeefe32c6b139a3f1e4047f137ae1.tar.bz2
Cast: Enable use of VideoEncodeAccelerator for hardware video encoding
Cast streaming library is currently using GpuVideoAcceleratorFactories as the interface to access a VideoEncodeAccelerator. This interface is not actually correct since Content API in Chrome doesn't provide that. Moreover GpuVideoAcceleratorFactories also covers accelerated video decoding which is not needed for a cast sender. This code removes the use of GpuVideoAcceleratorFactories. It is replaced by two callbacks. One for allocating a VideoEncodeAccelerator and the second one allocates base::SharedMemory to store output data. BUG=354267 Review URL: https://codereview.chromium.org/207593002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258762 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/renderer/media/cast_rtp_stream.cc2
-rw-r--r--chrome/renderer/media/cast_session_delegate.cc19
-rw-r--r--media/cast/cast.gyp2
-rw-r--r--media/cast/cast_config.h16
-rw-r--r--media/cast/cast_sender.h5
-rw-r--r--media/cast/cast_sender_impl.cc6
-rw-r--r--media/cast/cast_sender_impl.h3
-rw-r--r--media/cast/test/end2end_unittest.cc7
-rw-r--r--media/cast/test/fake_gpu_video_accelerator_factories.cc58
-rw-r--r--media/cast/test/fake_gpu_video_accelerator_factories.h62
-rw-r--r--media/cast/test/fake_video_encode_accelerator.h3
-rw-r--r--media/cast/test/sender.cc7
-rw-r--r--media/cast/test/utility/default_config.cc25
-rw-r--r--media/cast/test/utility/default_config.h7
-rw-r--r--media/cast/video_sender/external_video_encoder.cc209
-rw-r--r--media/cast/video_sender/external_video_encoder.h11
-rw-r--r--media/cast/video_sender/external_video_encoder_unittest.cc32
-rw-r--r--media/cast/video_sender/video_sender.cc10
-rw-r--r--media/cast/video_sender/video_sender.h5
-rw-r--r--media/cast/video_sender/video_sender_unittest.cc48
20 files changed, 263 insertions, 274 deletions
diff --git a/chrome/renderer/media/cast_rtp_stream.cc b/chrome/renderer/media/cast_rtp_stream.cc
index de71a43..aabcbd9 100644
--- a/chrome/renderer/media/cast_rtp_stream.cc
+++ b/chrome/renderer/media/cast_rtp_stream.cc
@@ -18,11 +18,13 @@
#include "media/base/audio_fifo.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/multi_channel_resampler.h"
+#include "media/base/video_frame.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_defines.h"
#include "media/cast/cast_sender.h"
#include "media/cast/transport/cast_transport_config.h"
#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
+#include "ui/gfx/geometry/size.h"
using media::cast::AudioSenderConfig;
using media::cast::VideoSenderConfig;
diff --git a/chrome/renderer/media/cast_session_delegate.cc b/chrome/renderer/media/cast_session_delegate.cc
index ed70c1e..c43d440 100644
--- a/chrome/renderer/media/cast_session_delegate.cc
+++ b/chrome/renderer/media/cast_session_delegate.cc
@@ -38,6 +38,20 @@ const int kMaxVideoEventEntries = kMaxSerializedBytes / 150;
// Assume serialized log data for each frame will take up to 75 bytes.
const int kMaxAudioEventEntries = kMaxSerializedBytes / 75;
+void CreateVideoEncodeAccelerator(const base::Callback<
+ void(scoped_refptr<base::SingleThreadTaskRunner>,
+ scoped_ptr<media::VideoEncodeAccelerator>)>& callback) {
+ NOTIMPLEMENTED();
+ // Delegate the call to content API on the render thread.
+}
+
+void CreateVideoEncodeMemory(
+ size_t size,
+ const base::Callback<void(scoped_ptr<base::SharedMemory>)>&) {
+ NOTIMPLEMENTED();
+ // Delegate the call to content API on the render thread.
+}
+
} // namespace
CastSessionDelegate::CastSessionDelegate()
@@ -103,13 +117,12 @@ void CastSessionDelegate::StartVideo(
transport_config.codec = config.codec;
transport_config.base.rtp_config = config.rtp_config;
cast_transport_->InitializeVideo(transport_config);
- // TODO(mikhal): Pass in a valid GpuVideoAcceleratorFactories to support
- // hardware video encoding.
cast_sender_->InitializeVideo(
config,
base::Bind(&CastSessionDelegate::InitializationResultCB,
weak_factory_.GetWeakPtr()),
- NULL /* GPU*/);
+ base::Bind(&CreateVideoEncodeAccelerator),
+ base::Bind(&CreateVideoEncodeMemory));
}
void CastSessionDelegate::StartUDP(const net::IPEndPoint& remote_endpoint) {
diff --git a/media/cast/cast.gyp b/media/cast/cast.gyp
index ef67982..6aa2f83 100644
--- a/media/cast/cast.gyp
+++ b/media/cast/cast.gyp
@@ -66,8 +66,6 @@
'rtp_receiver/rtp_parser/rtp_parser_unittest.cc',
'test/encode_decode_test.cc',
'test/end2end_unittest.cc',
- 'test/fake_gpu_video_accelerator_factories.cc',
- 'test/fake_gpu_video_accelerator_factories.h',
'test/fake_single_thread_task_runner.cc',
'test/fake_single_thread_task_runner.h',
'test/fake_video_encode_accelerator.cc',
diff --git a/media/cast/cast_config.h b/media/cast/cast_config.h
index 21caea0..88bbdbc 100644
--- a/media/cast/cast_config.h
+++ b/media/cast/cast_config.h
@@ -12,10 +12,14 @@
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/shared_memory.h"
+#include "base/single_thread_task_runner.h"
#include "media/cast/cast_defines.h"
#include "media/cast/transport/cast_transport_config.h"
namespace media {
+class VideoEncodeAccelerator;
+
namespace cast {
enum RtcpMode {
@@ -137,6 +141,18 @@ typedef transport::PacketList PacketList;
typedef base::Callback<void(CastInitializationStatus)>
CastInitializationCallback;
+typedef base::Callback<void(scoped_refptr<base::SingleThreadTaskRunner>,
+ scoped_ptr<media::VideoEncodeAccelerator>)>
+ ReceiveVideoEncodeAcceleratorCallback;
+typedef base::Callback<void(const ReceiveVideoEncodeAcceleratorCallback&)>
+ CreateVideoEncodeAcceleratorCallback;
+
+typedef base::Callback<void(scoped_ptr<base::SharedMemory>)>
+ ReceiveVideoEncodeMemoryCallback;
+typedef base::Callback<void(size_t size,
+ const ReceiveVideoEncodeMemoryCallback&)>
+ CreateVideoEncodeMemoryCallback;
+
} // namespace cast
} // namespace media
diff --git a/media/cast/cast_sender.h b/media/cast/cast_sender.h
index ae6baf3..eb3327f 100644
--- a/media/cast/cast_sender.h
+++ b/media/cast/cast_sender.h
@@ -20,10 +20,8 @@
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/transport/cast_transport_sender.h"
-#include "media/filters/gpu_video_accelerator_factories.h"
namespace media {
-class GpuVideoAcceleratorFactories;
class VideoFrame;
namespace cast {
@@ -90,7 +88,8 @@ class CastSender {
virtual void InitializeVideo(
const VideoSenderConfig& video_config,
const CastInitializationCallback& cast_initialization_cb,
- const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories) = 0;
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) = 0;
};
} // namespace cast
diff --git a/media/cast/cast_sender_impl.cc b/media/cast/cast_sender_impl.cc
index 7a60ffc..0b5a2ac 100644
--- a/media/cast/cast_sender_impl.cc
+++ b/media/cast/cast_sender_impl.cc
@@ -113,14 +113,16 @@ void CastSenderImpl::InitializeAudio(
void CastSenderImpl::InitializeVideo(
const VideoSenderConfig& video_config,
const CastInitializationCallback& cast_initialization_cb,
- const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories) {
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb) {
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
CHECK(video_config.use_external_encoder ||
cast_environment_->HasVideoThread());
video_sender_.reset(new VideoSender(cast_environment_,
video_config,
- gpu_factories,
+ create_vea_cb,
+ create_video_encode_mem_cb,
cast_initialization_cb,
transport_sender_));
diff --git a/media/cast/cast_sender_impl.h b/media/cast/cast_sender_impl.h
index b90bec4..d09a869 100644
--- a/media/cast/cast_sender_impl.h
+++ b/media/cast/cast_sender_impl.h
@@ -33,7 +33,8 @@ class CastSenderImpl : public CastSender {
virtual void InitializeVideo(
const VideoSenderConfig& video_config,
const CastInitializationCallback& cast_initialization_cb,
- const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories)
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb)
OVERRIDE;
virtual ~CastSenderImpl();
diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc
index 216be89..bfdcf0c 100644
--- a/media/cast/test/end2end_unittest.cc
+++ b/media/cast/test/end2end_unittest.cc
@@ -28,6 +28,7 @@
#include "media/cast/logging/simple_event_subscriber.h"
#include "media/cast/test/fake_single_thread_task_runner.h"
#include "media/cast/test/utility/audio_utility.h"
+#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/video_utility.h"
#include "media/cast/transport/cast_transport_config.h"
#include "media/cast/transport/cast_transport_defines.h"
@@ -514,8 +515,10 @@ class End2EndTest : public ::testing::Test {
// Initializing audio and video senders.
cast_sender_->InitializeAudio(audio_sender_config_,
base::Bind(&AudioInitializationStatus));
- cast_sender_->InitializeVideo(
- video_sender_config_, base::Bind(&VideoInitializationStatus), NULL);
+ cast_sender_->InitializeVideo(video_sender_config_,
+ base::Bind(&VideoInitializationStatus),
+ CreateDefaultVideoEncodeAcceleratorCallback(),
+ CreateDefaultVideoEncodeMemoryCallback());
receiver_to_sender_.SetPacketReceiver(cast_sender_->packet_receiver());
sender_to_receiver_.SetPacketReceiver(cast_receiver_->packet_receiver());
diff --git a/media/cast/test/fake_gpu_video_accelerator_factories.cc b/media/cast/test/fake_gpu_video_accelerator_factories.cc
deleted file mode 100644
index 9718a56..0000000
--- a/media/cast/test/fake_gpu_video_accelerator_factories.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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 "media/cast/test/fake_gpu_video_accelerator_factories.h"
-
-#include "base/logging.h"
-#include "media/cast/test/fake_video_encode_accelerator.h"
-#include "media/video/video_decode_accelerator.h"
-
-namespace media {
-namespace cast {
-namespace test {
-
-FakeGpuVideoAcceleratorFactories::FakeGpuVideoAcceleratorFactories(
- const scoped_refptr<base::SingleThreadTaskRunner>& fake_task_runner)
- : fake_task_runner_(fake_task_runner) {}
-
-FakeGpuVideoAcceleratorFactories::~FakeGpuVideoAcceleratorFactories() {}
-
-scoped_ptr<VideoEncodeAccelerator>
-FakeGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator() {
- return scoped_ptr<VideoEncodeAccelerator>(new FakeVideoEncodeAccelerator());
-}
-
-base::SharedMemory* FakeGpuVideoAcceleratorFactories::CreateSharedMemory(
- size_t size) {
- base::SharedMemory* shm = new base::SharedMemory();
- if (!shm->CreateAndMapAnonymous(size)) {
- NOTREACHED();
- }
- return shm;
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-FakeGpuVideoAcceleratorFactories::GetTaskRunner() {
- return fake_task_runner_;
-}
-
-bool FakeGpuVideoAcceleratorFactories::CreateTextures(
- int32 count,
- const gfx::Size& size,
- std::vector<uint32>* texture_ids,
- std::vector<gpu::Mailbox>* texture_mailboxes,
- uint32 texture_target) {
- return false;
-}
-
-scoped_ptr<VideoDecodeAccelerator>
-FakeGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator(
- VideoCodecProfile profile) {
- return scoped_ptr<VideoDecodeAccelerator>(
- static_cast<media::VideoDecodeAccelerator*>(NULL));
-}
-
-} // namespace test
-} // namespace cast
-} // namespace media
diff --git a/media/cast/test/fake_gpu_video_accelerator_factories.h b/media/cast/test/fake_gpu_video_accelerator_factories.h
deleted file mode 100644
index ebcadfd..0000000
--- a/media/cast/test/fake_gpu_video_accelerator_factories.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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 MEDIA_CAST_TEST_FAKE_GPU_VIDEO_ACCELERATOR_FACTORIES_H_
-#define MEDIA_CAST_TEST_FAKE_GPU_VIDEO_ACCELERATOR_FACTORIES_H_
-
-#include "media/filters/gpu_video_accelerator_factories.h"
-
-#include "base/message_loop/message_loop.h"
-#include "media/cast/test/fake_single_thread_task_runner.h"
-
-namespace media {
-namespace cast {
-namespace test {
-
-class FakeGpuVideoAcceleratorFactories : public GpuVideoAcceleratorFactories {
- public:
- explicit FakeGpuVideoAcceleratorFactories(
- const scoped_refptr<base::SingleThreadTaskRunner>& fake_task_runner);
-
- virtual scoped_ptr<VideoEncodeAccelerator> CreateVideoEncodeAccelerator()
- OVERRIDE;
-
- virtual base::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE;
-
- virtual scoped_refptr<base::SingleThreadTaskRunner>
- GetTaskRunner() OVERRIDE;
- //
- // The following functions are no-op.
- //
- virtual bool CreateTextures(int32 count,
- const gfx::Size& size,
- std::vector<uint32>* texture_ids,
- std::vector<gpu::Mailbox>* texture_mailboxes,
- uint32 texture_target) OVERRIDE;
-
- virtual void DeleteTexture(uint32 texture_id) OVERRIDE {}
-
- virtual void WaitSyncPoint(uint32 sync_point) OVERRIDE {}
-
- virtual void ReadPixels(uint32 texture_id,
- const gfx::Rect& visible_rect,
- const SkBitmap& pixels) OVERRIDE {};
-
- virtual scoped_ptr<VideoDecodeAccelerator> CreateVideoDecodeAccelerator(
- VideoCodecProfile profile) OVERRIDE;
-
- private:
- friend class base::RefCountedThreadSafe<FakeGpuVideoAcceleratorFactories>;
- virtual ~FakeGpuVideoAcceleratorFactories();
-
- const scoped_refptr<base::SingleThreadTaskRunner> fake_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeGpuVideoAcceleratorFactories);
-};
-
-} // namespace test
-} // namespace cast
-} // namespace media
-
-#endif // MEDIA_CAST_TEST_FAKE_GPU_VIDEO_ACCELERATOR_FACTORIES_H_
diff --git a/media/cast/test/fake_video_encode_accelerator.h b/media/cast/test/fake_video_encode_accelerator.h
index 20ad7c3..2e0c93a 100644
--- a/media/cast/test/fake_video_encode_accelerator.h
+++ b/media/cast/test/fake_video_encode_accelerator.h
@@ -18,6 +18,7 @@ namespace test {
class FakeVideoEncodeAccelerator : public VideoEncodeAccelerator {
public:
FakeVideoEncodeAccelerator();
+ virtual ~FakeVideoEncodeAccelerator();
virtual void Initialize(media::VideoFrame::Format input_format,
const gfx::Size& input_visible_size,
@@ -36,8 +37,6 @@ class FakeVideoEncodeAccelerator : public VideoEncodeAccelerator {
virtual void Destroy() OVERRIDE;
private:
- virtual ~FakeVideoEncodeAccelerator();
-
VideoEncodeAccelerator::Client* client_;
bool first_;
diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc
index f2ec901..15a1a8f 100644
--- a/media/cast/test/sender.cc
+++ b/media/cast/test/sender.cc
@@ -22,6 +22,7 @@
#include "media/cast/logging/logging_defines.h"
#include "media/cast/logging/proto/raw_events.pb.h"
#include "media/cast/test/utility/audio_utility.h"
+#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/input_builder.h"
#include "media/cast/test/utility/video_utility.h"
#include "media/cast/transport/cast_transport_defines.h"
@@ -495,7 +496,11 @@ int main(int argc, char** argv) {
media::cast::CastSender::Create(cast_environment, transport_sender.get());
cast_sender->InitializeVideo(
- video_config, base::Bind(&InitializationResult), NULL);
+ video_config,
+ base::Bind(&InitializationResult),
+ media::cast::CreateDefaultVideoEncodeAcceleratorCallback(),
+ media::cast::CreateDefaultVideoEncodeMemoryCallback());
+
cast_sender->InitializeAudio(audio_config, base::Bind(&InitializationResult));
transport_sender->SetPacketReceiver(cast_sender->packet_receiver());
diff --git a/media/cast/test/utility/default_config.cc b/media/cast/test/utility/default_config.cc
index 34eaedc..1631bfe 100644
--- a/media/cast/test/utility/default_config.cc
+++ b/media/cast/test/utility/default_config.cc
@@ -4,8 +4,24 @@
#include "media/cast/test/utility/default_config.h"
+#include "base/bind.h"
#include "media/cast/transport/cast_transport_config.h"
+namespace {
+
+void CreateVideoEncodeAccelerator(
+ const media::cast::ReceiveVideoEncodeAcceleratorCallback& callback) {
+ // Do nothing.
+}
+
+void CreateVideoEncodeMemory(
+ size_t size,
+ const media::cast::ReceiveVideoEncodeMemoryCallback& callback) {
+ // Do nothing.
+}
+
+} // namespace
+
namespace media {
namespace cast {
@@ -33,5 +49,14 @@ VideoReceiverConfig GetDefaultVideoReceiverConfig() {
return config;
}
+CreateVideoEncodeAcceleratorCallback
+CreateDefaultVideoEncodeAcceleratorCallback() {
+ return base::Bind(&CreateVideoEncodeAccelerator);
+}
+
+CreateVideoEncodeMemoryCallback CreateDefaultVideoEncodeMemoryCallback() {
+ return base::Bind(&CreateVideoEncodeMemory);
+}
+
} // namespace cast
} // namespace media
diff --git a/media/cast/test/utility/default_config.h b/media/cast/test/utility/default_config.h
index ef7c79a..59a24404 100644
--- a/media/cast/test/utility/default_config.h
+++ b/media/cast/test/utility/default_config.h
@@ -20,6 +20,13 @@ AudioReceiverConfig GetDefaultAudioReceiverConfig();
// name.
VideoReceiverConfig GetDefaultVideoReceiverConfig();
+// Returns a callback that does nothing.
+CreateVideoEncodeAcceleratorCallback
+ CreateDefaultVideoEncodeAcceleratorCallback();
+
+// Returns a callback that does nothing.
+CreateVideoEncodeMemoryCallback CreateDefaultVideoEncodeMemoryCallback();
+
} // namespace cast
} // namespace media
diff --git a/media/cast/video_sender/external_video_encoder.cc b/media/cast/video_sender/external_video_encoder.cc
index 4f97dace..353775a 100644
--- a/media/cast/video_sender/external_video_encoder.cc
+++ b/media/cast/video_sender/external_video_encoder.cc
@@ -15,10 +15,13 @@
#include "media/cast/transport/cast_transport_config.h"
#include "media/video/video_encode_accelerator.h"
+namespace media {
+namespace cast {
+class LocalVideoEncodeAcceleratorClient;
+} // namespace cast
+} // namespace media
+
namespace {
-// We allocate more input buffers than what is asked for by
-// RequireBitstreamBuffers() due to potential threading timing.
-static const int kInputBufferExtraCount = 1;
static const int kOutputBufferCount = 3;
void LogFrameEncodedEvent(media::cast::CastEnvironment* const cast_environment,
@@ -29,6 +32,25 @@ void LogFrameEncodedEvent(media::cast::CastEnvironment* const cast_environment,
media::cast::GetVideoRtpTimestamp(capture_time),
media::cast::kFrameIdUnknown);
}
+
+// Proxy this call to ExternalVideoEncoder on the cast main thread.
+void ProxyCreateVideoEncodeAccelerator(
+ const scoped_refptr<media::cast::CastEnvironment>& cast_environment,
+ const base::WeakPtr<media::cast::ExternalVideoEncoder>& weak_ptr,
+ const media::cast::CreateVideoEncodeMemoryCallback&
+ create_video_encode_mem_cb,
+ scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
+ scoped_ptr<media::VideoEncodeAccelerator> vea) {
+ cast_environment->PostTask(
+ media::cast::CastEnvironment::MAIN,
+ FROM_HERE,
+ base::Bind(
+ &media::cast::ExternalVideoEncoder::OnCreateVideoEncodeAccelerator,
+ weak_ptr,
+ create_video_encode_mem_cb,
+ encoder_task_runner,
+ base::Passed(&vea)));
+}
} // namespace
namespace media {
@@ -54,11 +76,14 @@ class LocalVideoEncodeAcceleratorClient
public:
LocalVideoEncodeAcceleratorClient(
scoped_refptr<CastEnvironment> cast_environment,
- scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories,
+ scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
+ scoped_ptr<media::VideoEncodeAccelerator> vea,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
const base::WeakPtr<ExternalVideoEncoder>& weak_owner)
: cast_environment_(cast_environment),
- gpu_factories_(gpu_factories),
- encoder_task_runner_(gpu_factories->GetTaskRunner()),
+ encoder_task_runner_(encoder_task_runner),
+ video_encode_accelerator_(vea.Pass()),
+ create_video_encode_memory_cb_(create_video_encode_mem_cb),
weak_owner_(weak_owner),
last_encoded_frame_id_(kStartFrameId) {
DCHECK(encoder_task_runner_);
@@ -66,16 +91,9 @@ class LocalVideoEncodeAcceleratorClient
// Initialize the real HW encoder.
void Initialize(const VideoSenderConfig& video_config) {
- DCHECK(gpu_factories_);
DCHECK(encoder_task_runner_);
-
DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
- video_encode_accelerator_ =
- gpu_factories_->CreateVideoEncodeAccelerator().Pass();
- if (!video_encode_accelerator_)
- return;
-
VideoCodecProfile output_profile = media::VIDEO_CODEC_PROFILE_UNKNOWN;
switch (video_config.codec) {
case transport::kVp8:
@@ -124,55 +142,11 @@ class LocalVideoEncodeAcceleratorClient
DCHECK(encoder_task_runner_);
DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
- if (input_buffers_free_.empty()) {
- NOTREACHED();
- VLOG(2) << "EncodeVideoFrame(): drop frame due to no hw buffers";
- return;
- }
- const int index = input_buffers_free_.back();
- base::SharedMemory* input_buffer = input_buffers_[index];
-
- // TODO(pwestin): this allocation and copy can be removed once we don't
- // pass the video frame through liblingle.
-
- scoped_refptr<media::VideoFrame> frame =
- media::VideoFrame::WrapExternalPackedMemory(
- video_frame->format(),
- video_frame->coded_size(),
- video_frame->visible_rect(),
- video_frame->natural_size(),
- reinterpret_cast<uint8*>(input_buffer->memory()),
- input_buffer->mapped_size(),
- input_buffer->handle(),
- video_frame->GetTimestamp(),
- base::Bind(&LocalVideoEncodeAcceleratorClient::FinishedWithInBuffer,
- this,
- index));
-
- if (!frame) {
- VLOG(1) << "EncodeVideoFrame(): failed to create frame";
- NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError);
- return;
- }
- // Do a stride copy of the input frame to match the input requirements.
- media::CopyYPlane(video_frame->data(VideoFrame::kYPlane),
- video_frame->stride(VideoFrame::kYPlane),
- video_frame->natural_size().height(),
- frame.get());
- media::CopyUPlane(video_frame->data(VideoFrame::kUPlane),
- video_frame->stride(VideoFrame::kUPlane),
- video_frame->natural_size().height(),
- frame.get());
- media::CopyVPlane(video_frame->data(VideoFrame::kVPlane),
- video_frame->stride(VideoFrame::kVPlane),
- video_frame->natural_size().height(),
- frame.get());
-
encoded_frame_data_storage_.push_back(
EncodedFrameReturnData(capture_time, frame_encoded_callback));
// BitstreamBufferReady will be called once the encoder is done.
- video_encode_accelerator_->Encode(frame, key_frame_requested);
+ video_encode_accelerator_->Encode(video_frame, key_frame_requested);
}
protected:
@@ -180,10 +154,8 @@ class LocalVideoEncodeAcceleratorClient
DCHECK(encoder_task_runner_);
DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
- cast_environment_->PostTask(
- CastEnvironment::MAIN,
- FROM_HERE,
- base::Bind(&ExternalVideoEncoder::EncoderInitialized, weak_owner_));
+ // Wait until shared memory is allocated to indicate that encoder is
+ // initialized.
}
virtual void NotifyError(VideoEncodeAccelerator::Error error) OVERRIDE {
@@ -208,33 +180,11 @@ class LocalVideoEncodeAcceleratorClient
DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
DCHECK(video_encode_accelerator_);
- for (unsigned int i = 0; i < input_count + kInputBufferExtraCount; ++i) {
- base::SharedMemory* shm =
- gpu_factories_->CreateSharedMemory(media::VideoFrame::AllocationSize(
- media::VideoFrame::I420, input_coded_size));
- if (!shm) {
- VLOG(1) << "RequireBitstreamBuffers(): failed to create input buffer ";
- return;
- }
- input_buffers_.push_back(shm);
- input_buffers_free_.push_back(i);
- }
-
for (int j = 0; j < kOutputBufferCount; ++j) {
- base::SharedMemory* shm =
- gpu_factories_->CreateSharedMemory(output_buffer_size);
- if (!shm) {
- VLOG(1) << "RequireBitstreamBuffers(): failed to create input buffer ";
- return;
- }
- output_buffers_.push_back(shm);
- }
- // Immediately provide all output buffers to the VEA.
- for (size_t i = 0; i < output_buffers_.size(); ++i) {
- video_encode_accelerator_->UseOutputBitstreamBuffer(
- media::BitstreamBuffer(static_cast<int32>(i),
- output_buffers_[i]->handle(),
- output_buffers_[i]->mapped_size()));
+ create_video_encode_memory_cb_.Run(
+ output_buffer_size,
+ base::Bind(&LocalVideoEncodeAcceleratorClient::OnCreateSharedMemory,
+ this));
}
}
@@ -309,14 +259,37 @@ class LocalVideoEncodeAcceleratorClient
}
private:
- // Encoder is done with the provided input buffer.
- void FinishedWithInBuffer(int input_index) {
+ // Note: This method can be called on any thread.
+ void OnCreateSharedMemory(scoped_ptr<base::SharedMemory> memory) {
+ encoder_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&LocalVideoEncodeAcceleratorClient::ReceivedSharedMemory,
+ this,
+ base::Passed(&memory)));
+ }
+
+ void ReceivedSharedMemory(scoped_ptr<base::SharedMemory> memory) {
DCHECK(encoder_task_runner_);
DCHECK(encoder_task_runner_->RunsTasksOnCurrentThread());
- DCHECK_GE(input_index, 0);
- DCHECK_LT(input_index, static_cast<int>(input_buffers_.size()));
- VLOG(2) << "EncodeFrameFinished(): index=" << input_index;
- input_buffers_free_.push_back(input_index);
+
+ output_buffers_.push_back(memory.release());
+
+ // Wait until all requested buffers are received.
+ if (output_buffers_.size() < kOutputBufferCount)
+ return;
+
+ // Immediately provide all output buffers to the VEA.
+ for (size_t i = 0; i < output_buffers_.size(); ++i) {
+ video_encode_accelerator_->UseOutputBitstreamBuffer(
+ media::BitstreamBuffer(static_cast<int32>(i),
+ output_buffers_[i]->handle(),
+ output_buffers_[i]->mapped_size()));
+ }
+
+ cast_environment_->PostTask(
+ CastEnvironment::MAIN,
+ FROM_HERE,
+ base::Bind(&ExternalVideoEncoder::EncoderInitialized, weak_owner_));
}
friend class base::RefCountedThreadSafe<LocalVideoEncodeAcceleratorClient>;
@@ -324,23 +297,17 @@ class LocalVideoEncodeAcceleratorClient
virtual ~LocalVideoEncodeAcceleratorClient() {}
const scoped_refptr<CastEnvironment> cast_environment_;
- scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories_;
scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner_;
- const base::WeakPtr<ExternalVideoEncoder> weak_owner_;
-
scoped_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_;
+ const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
+ const base::WeakPtr<ExternalVideoEncoder> weak_owner_;
int max_frame_rate_;
transport::VideoCodec codec_;
uint32 last_encoded_frame_id_;
- // Shared memory buffers for input/output with the VideoAccelerator.
- ScopedVector<base::SharedMemory> input_buffers_;
+ // Shared memory buffers for output with the VideoAccelerator.
ScopedVector<base::SharedMemory> output_buffers_;
- // Input buffers ready to be filled with input from Encode(). As a LIFO since
- // we don't care about ordering.
- std::vector<int> input_buffers_free_;
-
// FIFO list.
std::list<EncodedFrameReturnData> encoded_frame_data_storage_;
@@ -350,25 +317,21 @@ class LocalVideoEncodeAcceleratorClient
ExternalVideoEncoder::ExternalVideoEncoder(
scoped_refptr<CastEnvironment> cast_environment,
const VideoSenderConfig& video_config,
- scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories)
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb)
: video_config_(video_config),
cast_environment_(cast_environment),
encoder_active_(false),
key_frame_requested_(false),
skip_next_frame_(false),
skip_count_(0),
- encoder_task_runner_(gpu_factories->GetTaskRunner()),
weak_factory_(this) {
- DCHECK(gpu_factories);
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
- video_accelerator_client_ = new LocalVideoEncodeAcceleratorClient(
- cast_environment, gpu_factories, weak_factory_.GetWeakPtr());
- encoder_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&LocalVideoEncodeAcceleratorClient::Initialize,
- video_accelerator_client_,
- video_config));
+ create_vea_cb.Run(base::Bind(&ProxyCreateVideoEncodeAccelerator,
+ cast_environment,
+ weak_factory_.GetWeakPtr(),
+ create_video_encode_mem_cb));
}
ExternalVideoEncoder::~ExternalVideoEncoder() {
@@ -388,6 +351,26 @@ void ExternalVideoEncoder::EncoderError() {
encoder_active_ = false;
}
+void ExternalVideoEncoder::OnCreateVideoEncodeAccelerator(
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
+ scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
+ scoped_ptr<media::VideoEncodeAccelerator> vea) {
+ DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
+ encoder_task_runner_ = encoder_task_runner;
+
+ video_accelerator_client_ =
+ new LocalVideoEncodeAcceleratorClient(cast_environment_,
+ encoder_task_runner,
+ vea.Pass(),
+ create_video_encode_mem_cb,
+ weak_factory_.GetWeakPtr());
+ encoder_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&LocalVideoEncodeAcceleratorClient::Initialize,
+ video_accelerator_client_,
+ video_config_));
+}
+
bool ExternalVideoEncoder::EncodeVideoFrame(
const scoped_refptr<media::VideoFrame>& video_frame,
const base::TimeTicks& capture_time,
diff --git a/media/cast/video_sender/external_video_encoder.h b/media/cast/video_sender/external_video_encoder.h
index 6c4c97e..0a71026 100644
--- a/media/cast/video_sender/external_video_encoder.h
+++ b/media/cast/video_sender/external_video_encoder.h
@@ -10,7 +10,7 @@
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/video_sender/video_encoder.h"
-#include "media/filters/gpu_video_accelerator_factories.h"
+#include "media/video/video_encode_accelerator.h"
namespace media {
class VideoFrame;
@@ -28,7 +28,8 @@ class ExternalVideoEncoder : public VideoEncoder {
ExternalVideoEncoder(
scoped_refptr<CastEnvironment> cast_environment,
const VideoSenderConfig& video_config,
- scoped_refptr<GpuVideoAcceleratorFactories> gpu_factories);
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb);
virtual ~ExternalVideoEncoder();
@@ -51,6 +52,12 @@ class ExternalVideoEncoder : public VideoEncoder {
virtual void LatestFrameIdToReference(uint32 frame_id) OVERRIDE;
virtual int NumberOfSkippedFrames() const OVERRIDE;
+ // Called when a VEA is created.
+ void OnCreateVideoEncodeAccelerator(
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
+ scoped_refptr<base::SingleThreadTaskRunner> encoder_task_runner,
+ scoped_ptr<media::VideoEncodeAccelerator> vea);
+
protected:
void EncoderInitialized();
void EncoderError();
diff --git a/media/cast/video_sender/external_video_encoder_unittest.cc b/media/cast/video_sender/external_video_encoder_unittest.cc
index 7130331..71f8779 100644
--- a/media/cast/video_sender/external_video_encoder_unittest.cc
+++ b/media/cast/video_sender/external_video_encoder_unittest.cc
@@ -10,7 +10,6 @@
#include "media/base/video_frame.h"
#include "media/cast/cast_defines.h"
#include "media/cast/cast_environment.h"
-#include "media/cast/test/fake_gpu_video_accelerator_factories.h"
#include "media/cast/test/fake_single_thread_task_runner.h"
#include "media/cast/test/fake_video_encode_accelerator.h"
#include "media/cast/test/utility/video_utility.h"
@@ -23,6 +22,24 @@ namespace cast {
using testing::_;
namespace {
+
+void CreateVideoEncodeAccelerator(
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+ scoped_ptr<VideoEncodeAccelerator> fake_vea,
+ const ReceiveVideoEncodeAcceleratorCallback& callback) {
+ callback.Run(task_runner, fake_vea.Pass());
+}
+
+void CreateSharedMemory(
+ size_t size, const ReceiveVideoEncodeMemoryCallback& callback) {
+ scoped_ptr<base::SharedMemory> shm(new base::SharedMemory());
+ if (!shm->CreateAndMapAnonymous(size)) {
+ NOTREACHED();
+ return;
+ }
+ callback.Run(shm.Pass());
+}
+
class TestVideoEncoderCallback
: public base::RefCountedThreadSafe<TestVideoEncoderCallback> {
public:
@@ -94,10 +111,15 @@ class ExternalVideoEncoderTest : public ::testing::Test {
task_runner_,
task_runner_,
GetDefaultCastSenderLoggingConfig());
- video_encoder_.reset(new ExternalVideoEncoder(
- cast_environment_,
- video_config_,
- new test::FakeGpuVideoAcceleratorFactories(task_runner_)));
+ scoped_ptr<VideoEncodeAccelerator> fake_vea(
+ new test::FakeVideoEncodeAccelerator());
+ video_encoder_.reset(
+ new ExternalVideoEncoder(cast_environment_,
+ video_config_,
+ base::Bind(&CreateVideoEncodeAccelerator,
+ task_runner_,
+ base::Passed(&fake_vea)),
+ base::Bind(&CreateSharedMemory)));
}
virtual ~ExternalVideoEncoderTest() {}
diff --git a/media/cast/video_sender/video_sender.cc b/media/cast/video_sender/video_sender.cc
index 4d338435..b35ce55 100644
--- a/media/cast/video_sender/video_sender.cc
+++ b/media/cast/video_sender/video_sender.cc
@@ -47,7 +47,8 @@ class LocalRtcpVideoSenderFeedback : public RtcpSenderFeedback {
VideoSender::VideoSender(
scoped_refptr<CastEnvironment> cast_environment,
const VideoSenderConfig& video_config,
- const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories,
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
const CastInitializationCallback& cast_initialization_cb,
transport::CastTransportSender* const transport_sender)
: rtp_max_delay_(base::TimeDelta::FromMilliseconds(
@@ -77,9 +78,10 @@ VideoSender::VideoSender(
DCHECK_GT(max_unacked_frames_, 0) << "Invalid argument";
if (video_config.use_external_encoder) {
- CHECK(gpu_factories);
- video_encoder_.reset(new ExternalVideoEncoder(
- cast_environment, video_config, gpu_factories));
+ video_encoder_.reset(new ExternalVideoEncoder(cast_environment,
+ video_config,
+ create_vea_cb,
+ create_video_encode_mem_cb));
} else {
video_encoder_.reset(new VideoEncoderImpl(
cast_environment, video_config, max_unacked_frames_));
diff --git a/media/cast/video_sender/video_sender.h b/media/cast/video_sender/video_sender.h
index 73c8510..1ef4a73 100644
--- a/media/cast/video_sender/video_sender.h
+++ b/media/cast/video_sender/video_sender.h
@@ -18,8 +18,6 @@
#include "media/cast/logging/logging_defines.h"
#include "media/cast/rtcp/rtcp.h"
#include "media/cast/rtcp/sender_rtcp_event_subscriber.h"
-#include "media/filters/gpu_video_accelerator_factories.h"
-#include "media/video/video_encode_accelerator.h"
namespace media {
class VideoFrame;
@@ -44,7 +42,8 @@ class VideoSender : public base::NonThreadSafe,
public:
VideoSender(scoped_refptr<CastEnvironment> cast_environment,
const VideoSenderConfig& video_config,
- const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories,
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
const CastInitializationCallback& cast_initialization_cb,
transport::CastTransportSender* const transport_sender);
diff --git a/media/cast/video_sender/video_sender_unittest.cc b/media/cast/video_sender/video_sender_unittest.cc
index 28c7861..8fd6cd7 100644
--- a/media/cast/video_sender/video_sender_unittest.cc
+++ b/media/cast/video_sender/video_sender_unittest.cc
@@ -10,8 +10,9 @@
#include "media/base/video_frame.h"
#include "media/cast/cast_environment.h"
#include "media/cast/logging/simple_event_subscriber.h"
-#include "media/cast/test/fake_gpu_video_accelerator_factories.h"
#include "media/cast/test/fake_single_thread_task_runner.h"
+#include "media/cast/test/fake_video_encode_accelerator.h"
+#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/video_utility.h"
#include "media/cast/transport/cast_transport_config.h"
#include "media/cast/transport/cast_transport_sender_impl.h"
@@ -32,6 +33,23 @@ static const int kHeight = 240;
using testing::_;
using testing::AtLeast;
+void CreateVideoEncodeAccelerator(
+ const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+ scoped_ptr<VideoEncodeAccelerator> fake_vea,
+ const ReceiveVideoEncodeAcceleratorCallback& callback) {
+ callback.Run(task_runner, fake_vea.Pass());
+}
+
+void CreateSharedMemory(
+ size_t size, const ReceiveVideoEncodeMemoryCallback& callback) {
+ scoped_ptr<base::SharedMemory> shm(new base::SharedMemory());
+ if (!shm->CreateAndMapAnonymous(size)) {
+ NOTREACHED();
+ return;
+ }
+ callback.Run(shm.Pass());
+}
+
class TestPacketSender : public transport::PacketSender {
public:
TestPacketSender() : number_of_rtp_packets_(0), number_of_rtcp_packets_(0) {}
@@ -62,12 +80,14 @@ class PeerVideoSender : public VideoSender {
PeerVideoSender(
scoped_refptr<CastEnvironment> cast_environment,
const VideoSenderConfig& video_config,
- const scoped_refptr<GpuVideoAcceleratorFactories>& gpu_factories,
+ const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
+ const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
const CastInitializationCallback& cast_initialization_cb,
transport::CastTransportSender* const transport_sender)
: VideoSender(cast_environment,
video_config,
- gpu_factories,
+ create_vea_cb,
+ create_video_encode_mem_cb,
cast_initialization_cb,
transport_sender) {}
using VideoSender::OnReceivedCastFeedback;
@@ -134,18 +154,24 @@ class VideoSenderTest : public ::testing::Test {
video_config.codec = transport::kVp8;
if (external) {
- video_sender_.reset(new PeerVideoSender(
- cast_environment_,
- video_config,
- new test::FakeGpuVideoAcceleratorFactories(task_runner_),
- base::Bind(&VideoSenderTest::InitializationResult,
- base::Unretained(this)),
- transport_sender_.get()));
+ scoped_ptr<VideoEncodeAccelerator> fake_vea(
+ new test::FakeVideoEncodeAccelerator());
+ video_sender_.reset(
+ new PeerVideoSender(cast_environment_,
+ video_config,
+ base::Bind(&CreateVideoEncodeAccelerator,
+ task_runner_,
+ base::Passed(&fake_vea)),
+ base::Bind(&CreateSharedMemory),
+ base::Bind(&VideoSenderTest::InitializationResult,
+ base::Unretained(this)),
+ transport_sender_.get()));
} else {
video_sender_.reset(
new PeerVideoSender(cast_environment_,
video_config,
- NULL,
+ CreateDefaultVideoEncodeAcceleratorCallback(),
+ CreateDefaultVideoEncodeMemoryCallback(),
base::Bind(&VideoSenderTest::InitializationResult,
base::Unretained(this)),
transport_sender_.get()));