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

Unified Diff: media/gpu/video_encode_accelerator_unittest.cc

Issue 2427053002: Move video encode accelerator IPC messages to GPU IO thread (Closed)
Patch Set: posciak@ comments. Created 4 years, 2 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
« no previous file with comments | « media/gpu/media_foundation_video_encode_accelerator_win.cc ('k') | media/video/video_encode_accelerator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/gpu/video_encode_accelerator_unittest.cc
diff --git a/media/gpu/video_encode_accelerator_unittest.cc b/media/gpu/video_encode_accelerator_unittest.cc
index 45da3ff52968fed7391297723afc9de12f694273..d69d4937a084c4f4fae0e4723a21f2f79b7b6203 100644
--- a/media/gpu/video_encode_accelerator_unittest.cc
+++ b/media/gpu/video_encode_accelerator_unittest.cc
@@ -20,6 +20,7 @@
#include "base/macros.h"
#include "base/memory/aligned_memory.h"
#include "base/memory/scoped_vector.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_conversions.h"
#include "base/process/process_handle.h"
@@ -845,6 +846,9 @@ class VEAClient : public VideoEncodeAccelerator::Client {
void CreateEncoder();
void DestroyEncoder();
+ void TryToSetupEncodeOnSeperateThread();
+ void DestroyEncodeOnSeperateThread();
+
// VideoDecodeAccelerator::Client implementation.
void RequireBitstreamBuffers(unsigned int input_count,
const gfx::Size& input_coded_size,
@@ -1046,6 +1050,24 @@ class VEAClient : public VideoEncodeAccelerator::Client {
// The last timestamp popped from |frame_timestamps_|.
base::TimeDelta previous_timestamp_;
+
+ // Indicates if encode is setup on on |io_thread_|.
+ bool encode_setup_on_io_thread_;
+
+ // Dummy thread used to redirect encode tasks, represents GPU IO thread.
+ base::Thread io_thread_;
+
+ // Task runner used for TryToSetupEncodeOnSeperateThread().
+ scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
+
+ // Task runner used for trampolining from |io_thread_|.
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
+
+ // Weak factories to use for TryToSetupEncodeOnSeperateThread() on
+ // |io_thread_|.
+ std::unique_ptr<base::WeakPtrFactory<VideoEncodeAccelerator>>
+ encoder_weak_factory_;
+ base::WeakPtrFactory<VEAClient> client_weak_factory_;
};
VEAClient::VEAClient(TestStream* test_stream,
@@ -1084,7 +1106,10 @@ VEAClient::VEAClient(TestStream* test_stream,
requested_bitrate_(0),
requested_framerate_(0),
requested_subsequent_bitrate_(0),
- requested_subsequent_framerate_(0) {
+ requested_subsequent_framerate_(0),
+ encode_setup_on_io_thread_(false),
+ io_thread_("IOThread"),
+ client_weak_factory_(this) {
if (keyframe_period_)
LOG_ASSERT(kMaxKeyframeDelay < keyframe_period_);
@@ -1167,6 +1192,8 @@ void VEAClient::CreateEncoder() {
DCHECK(thread_checker_.CalledOnValidThread());
LOG_ASSERT(!has_encoder());
+ main_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+
std::unique_ptr<VideoEncodeAccelerator> encoders[] = {
CreateFakeVEA(), CreateV4L2VEA(), CreateVaapiVEA(), CreateVTVEA(),
CreateMFVEA()};
@@ -1182,6 +1209,7 @@ void VEAClient::CreateEncoder() {
if (encoder_->Initialize(kInputFormat, test_stream_->visible_size,
test_stream_->requested_profile,
requested_bitrate_, this)) {
+ TryToSetupEncodeOnSeperateThread();
SetStreamParameters(requested_bitrate_, requested_framerate_);
SetState(CS_INITIALIZED);
@@ -1202,6 +1230,25 @@ void VEAClient::DecodeCompleted() {
SetState(CS_VALIDATED);
}
+void VEAClient::TryToSetupEncodeOnSeperateThread() {
+ // Start dummy thread if not started.
+ if (!io_thread_.IsRunning()) {
+ ASSERT_TRUE(io_thread_.Start());
+ io_thread_task_runner_ = io_thread_.task_runner();
+ }
+
+ if (!encoder_->TryToSetupEncodeOnSeparateThread(
+ client_weak_factory_.GetWeakPtr(), io_thread_task_runner_)) {
+ io_thread_.Stop();
+ encode_setup_on_io_thread_ = false;
+ return;
+ }
+
+ encoder_weak_factory_.reset(
+ new base::WeakPtrFactory<VideoEncodeAccelerator>(encoder_.get()));
+ encode_setup_on_io_thread_ = true;
+}
+
void VEAClient::DecodeFailed() {
SetState(CS_ERROR);
}
@@ -1210,12 +1257,25 @@ void VEAClient::DestroyEncoder() {
DCHECK(thread_checker_.CalledOnValidThread());
if (!has_encoder())
return;
+
+ if (encode_setup_on_io_thread_) {
+ io_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VEAClient::DestroyEncodeOnSeperateThread,
+ client_weak_factory_.GetWeakPtr()));
+ io_thread_.Stop();
+ }
+
// Clear the objects that should be destroyed on the same thread as creation.
encoder_.reset();
input_timer_.reset();
quality_validator_.reset();
}
+void VEAClient::DestroyEncodeOnSeperateThread() {
+ client_weak_factory_.InvalidateWeakPtrs();
+ encoder_weak_factory_->InvalidateWeakPtrs();
+}
+
void VEAClient::UpdateTestStreamData(bool mid_stream_bitrate_switch,
bool mid_stream_framerate_switch) {
// Use defaults for bitrate/framerate if they are not provided.
@@ -1336,7 +1396,16 @@ void VEAClient::BitstreamBufferReady(int32_t bitstream_buffer_id,
size_t payload_size,
bool key_frame,
base::TimeDelta timestamp) {
+ if (encode_setup_on_io_thread_ &&
Pawel Osciak 2016/10/31 07:40:22 If you'd accept my suggestion below, we could ASSE
emircan 2016/10/31 19:45:08 Done.
+ io_thread_task_runner_->BelongsToCurrentThread()) {
+ main_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&VEAClient::BitstreamBufferReady, base::Unretained(this),
+ bitstream_buffer_id, payload_size, key_frame, timestamp));
+ return;
+ }
DCHECK(thread_checker_.CalledOnValidThread());
+
ASSERT_LE(payload_size, output_buffer_size_);
IdToSHM::iterator it = output_buffers_at_client_.find(bitstream_buffer_id);
@@ -1405,8 +1474,15 @@ void VEAClient::SetStreamParameters(unsigned int bitrate,
current_framerate_ = framerate;
LOG_ASSERT(current_requested_bitrate_ > 0UL);
LOG_ASSERT(current_framerate_ > 0UL);
- encoder_->RequestEncodingParametersChange(current_requested_bitrate_,
- current_framerate_);
+ if (encode_setup_on_io_thread_) {
+ io_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&VideoEncodeAccelerator::RequestEncodingParametersChange,
+ encoder_weak_factory_->GetWeakPtr(), bitrate, framerate));
+ } else {
+ encoder_->RequestEncodingParametersChange(current_requested_bitrate_,
+ current_framerate_);
+ }
DVLOG(1) << "Switched parameters to " << current_requested_bitrate_
<< " bps @ " << current_framerate_ << " FPS";
}
@@ -1505,7 +1581,15 @@ void VEAClient::FeedEncoderWithOneInput() {
LOG_ASSERT(input_id == static_cast<int32_t>(encode_start_time_.size()));
encode_start_time_.push_back(base::TimeTicks::Now());
}
- encoder_->Encode(video_frame, force_keyframe);
+
+ if (encode_setup_on_io_thread_) {
Pawel Osciak 2016/10/31 07:40:21 Perhaps we could remove encode_setup_on_io_thread_
emircan 2016/10/31 19:45:08 Done.
+ io_thread_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VideoEncodeAccelerator::Encode,
+ encoder_weak_factory_->GetWeakPtr(), video_frame,
+ force_keyframe));
+ } else {
+ encoder_->Encode(video_frame, force_keyframe);
+ }
}
void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) {
@@ -1523,7 +1607,15 @@ void VEAClient::FeedEncoderWithOutput(base::SharedMemory* shm) {
LOG_ASSERT(output_buffers_at_client_
.insert(std::make_pair(bitstream_buffer.id(), shm))
.second);
- encoder_->UseOutputBitstreamBuffer(bitstream_buffer);
+
+ if (encode_setup_on_io_thread_) {
+ io_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&VideoEncodeAccelerator::UseOutputBitstreamBuffer,
+ encoder_weak_factory_->GetWeakPtr(), bitstream_buffer));
+ } else {
+ encoder_->UseOutputBitstreamBuffer(bitstream_buffer);
+ }
}
bool VEAClient::HandleEncodedFrame(bool keyframe) {
« no previous file with comments | « media/gpu/media_foundation_video_encode_accelerator_win.cc ('k') | media/video/video_encode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698