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

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

Issue 19534002: Make RendererGpuVideoDecoderFactories live on arbitrary threads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 5 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/rtc_video_decoder.cc
diff --git a/content/renderer/media/rtc_video_decoder.cc b/content/renderer/media/rtc_video_decoder.cc
index 4a43f431395cbc78d898b61b2fb5784359575ae3..e03001531a90f86758a819a79dcdbbbc3bce22c2 100644
--- a/content/renderer/media/rtc_video_decoder.cc
+++ b/content/renderer/media/rtc_video_decoder.cc
@@ -73,7 +73,6 @@ RTCVideoDecoder::RTCVideoDecoder(
weak_this_(weak_factory_.GetWeakPtr()),
factories_(factories),
vda_loop_proxy_(factories_->GetMessageLoop()),
- create_shm_thread_("CreateSHMThread"),
decoder_texture_target_(0),
next_picture_buffer_id_(0),
state_(UNINITIALIZED),
@@ -81,35 +80,23 @@ RTCVideoDecoder::RTCVideoDecoder(
num_shm_buffers_(0),
next_bitstream_buffer_id_(0),
reset_bitstream_buffer_id_(ID_INVALID) {
- create_shm_thread_.Start();
- // Initialize directly if |vda_loop_proxy_| is the renderer thread.
- base::WaitableEvent compositor_loop_async_waiter(false, false);
- if (vda_loop_proxy_->BelongsToCurrentThread()) {
- Initialize(&compositor_loop_async_waiter);
- return;
- }
- // Post the task if |vda_loop_proxy_| is the compositor thread. Waiting here
- // is safe because the compositor thread will not be stopped until the
- // renderer thread shuts down.
+ DCHECK(!vda_loop_proxy_->BelongsToCurrentThread());
+ base::WaitableEvent message_loop_async_waiter(false, false);
+ // Waiting here is safe because RTCVideoDecoderFactory owns the thread.
vda_loop_proxy_->PostTask(FROM_HERE,
base::Bind(&RTCVideoDecoder::Initialize,
base::Unretained(this),
- &compositor_loop_async_waiter));
- compositor_loop_async_waiter.Wait();
+ &message_loop_async_waiter));
+ message_loop_async_waiter.Wait();
}
RTCVideoDecoder::~RTCVideoDecoder() {
DVLOG(2) << "~RTCVideoDecoder";
- factories_->Abort();
- create_shm_thread_.Stop();
- // Delete vda and remove |this| from the observer if vda thread is alive.
- if (vda_loop_proxy_->BelongsToCurrentThread()) {
+ // Remove |this| from the observer if vda thread is alive.
+ if (vda_loop_proxy_->BelongsToCurrentThread())
base::MessageLoop::current()->RemoveDestructionObserver(this);
- DestroyVDA();
- } else {
- // VDA should have been destroyed in WillDestroyCurrentMessageLoop.
- DCHECK(!vda_);
- }
+ // VDA should have been destroyed.
+ DCHECK(!vda_);
// Delete all shared memories.
STLDeleteElements(&available_shm_segments_);
@@ -128,10 +115,23 @@ RTCVideoDecoder::~RTCVideoDecoder() {
}
scoped_ptr<RTCVideoDecoder> RTCVideoDecoder::Create(
+ webrtc::VideoCodecType type,
const scoped_refptr<media::GpuVideoDecoder::Factories>& factories) {
- scoped_ptr<RTCVideoDecoder> decoder(new RTCVideoDecoder(factories));
- decoder->vda_.reset(factories->CreateVideoDecodeAccelerator(
- media::VP8PROFILE_MAIN, decoder.get()));
+ scoped_ptr<RTCVideoDecoder> decoder;
+ // Convert WebRTC codec type to media codec profile.
+ media::VideoCodecProfile profile;
+ switch (type) {
+ case webrtc::kVideoCodecVP8:
+ profile = media::VP8PROFILE_MAIN;
+ break;
+ default:
+ DVLOG(2) << "Video codec not supported:" << type;
+ return decoder.Pass();
+ }
+
+ decoder.reset(new RTCVideoDecoder(factories));
+ decoder->vda_
+ .reset(factories->CreateVideoDecodeAccelerator(profile, decoder.get()));
// vda can be NULL if VP8 is not supported.
if (decoder->vda_ != NULL) {
decoder->state_ = INITIALIZED;
@@ -157,14 +157,11 @@ int32_t RTCVideoDecoder::InitDecode(const webrtc::VideoCodec* codecSettings,
}
// Create some shared memory if the queue is empty.
if (available_shm_segments_.size() == 0) {
- // Unretained is safe because the destructor will wait until
- // |create_shm_thread_| stops.
- create_shm_thread_.message_loop_proxy()
- ->PostTask(FROM_HERE,
- base::Bind(&RTCVideoDecoder::CreateSHM,
- base::Unretained(this),
- kMaxInFlightDecodes,
- kSharedMemorySegmentBytes));
+ vda_loop_proxy_->PostTask(FROM_HERE,
+ base::Bind(&RTCVideoDecoder::CreateSHM,
+ weak_this_,
+ kMaxInFlightDecodes,
+ kSharedMemorySegmentBytes));
}
return WEBRTC_VIDEO_CODEC_OK;
}
@@ -231,9 +228,19 @@ int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback(
int32_t RTCVideoDecoder::Release() {
DVLOG(2) << "Release";
- // Do not destroy VDA because the decoder will be recycled by
- // RTCVideoDecoderFactory. Just reset VDA.
- return Reset();
+ base::AutoLock auto_lock(lock_);
+ if (state_ == UNINITIALIZED) {
+ LOG(ERROR) << "Decoder not initialized.";
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+ }
+ if (next_bitstream_buffer_id_ != 0)
+ reset_bitstream_buffer_id_ = next_bitstream_buffer_id_ - 1;
+ else
+ reset_bitstream_buffer_id_ = ID_LAST;
+ factories_->Abort();
+ vda_loop_proxy_->PostTask(
+ FROM_HERE, base::Bind(&RTCVideoDecoder::ReleaseInternal, weak_this_));
+ return WEBRTC_VIDEO_CODEC_OK;
}
int32_t RTCVideoDecoder::Reset() {
@@ -594,6 +601,12 @@ void RTCVideoDecoder::ResetInternal() {
vda_->Reset();
}
+void RTCVideoDecoder::ReleaseInternal() {
+ DCHECK(vda_loop_proxy_->BelongsToCurrentThread());
+ DVLOG(2) << "ReleaseInternal";
+ DestroyVDA();
+}
+
void RTCVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id,
uint32 sync_point) {
DCHECK(vda_loop_proxy_->BelongsToCurrentThread());
@@ -660,16 +673,13 @@ scoped_ptr<RTCVideoDecoder::SHMBuffer> RTCVideoDecoder::GetSHM_Locked(
ret = available_shm_segments_.back();
available_shm_segments_.pop_back();
}
- // Post to the child thread to create shared memory if SHM cannot be reused
- // or the queue is almost empty.
+ // Post to vda thread to create shared memory if SHM cannot be reused or the
+ // queue is almost empty.
if (num_shm_buffers_ < kMaxNumSharedMemorySegments &&
(ret == NULL || available_shm_segments_.size() <= 1)) {
- create_shm_thread_.message_loop_proxy()->PostTask(
+ vda_loop_proxy_->PostTask(
FROM_HERE,
- // Unretained is safe because the destructor will wait until
- // |create_shm_thread_| stops.
- base::Bind(
- &RTCVideoDecoder::CreateSHM, base::Unretained(this), 1, min_size));
+ base::Bind(&RTCVideoDecoder::CreateSHM, weak_this_, 1, min_size));
}
return scoped_ptr<SHMBuffer>(ret);
}
@@ -679,7 +689,7 @@ void RTCVideoDecoder::PutSHM_Locked(scoped_ptr<SHMBuffer> shm_buffer) {
}
void RTCVideoDecoder::CreateSHM(int number, size_t min_size) {
- DCHECK(create_shm_thread_.message_loop_proxy()->BelongsToCurrentThread());
+ DCHECK(vda_loop_proxy_->BelongsToCurrentThread());
DVLOG(2) << "CreateSHM. size=" << min_size;
int number_to_allocate;
{
@@ -695,12 +705,10 @@ void RTCVideoDecoder::CreateSHM(int number, size_t min_size) {
num_shm_buffers_++;
PutSHM_Locked(
scoped_ptr<SHMBuffer>(new SHMBuffer(shm, size_to_allocate)));
- // Kick off the decoding.
- vda_loop_proxy_->PostTask(
- FROM_HERE,
- base::Bind(&RTCVideoDecoder::RequestBufferDecode, weak_this_));
}
}
+ // Kick off the decoding.
+ RequestBufferDecode();
}
void RTCVideoDecoder::RecordBufferData(const BufferData& buffer_data) {

Powered by Google App Engine
This is Rietveld 408576698