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

Side by Side Diff: content/renderer/media/rtc_video_decoder.cc

Issue 65803002: Replace MessageLoopProxy with SingleThreadTaskRunner for media/filters/ + associated code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/rtc_video_decoder.h" 5 #include "content/renderer/media/rtc_video_decoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/message_loop/message_loop_proxy.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 RTCVideoDecoder::BufferData::BufferData() {} 70 RTCVideoDecoder::BufferData::BufferData() {}
71 71
72 RTCVideoDecoder::BufferData::~BufferData() {} 72 RTCVideoDecoder::BufferData::~BufferData() {}
73 73
74 RTCVideoDecoder::RTCVideoDecoder( 74 RTCVideoDecoder::RTCVideoDecoder(
75 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories) 75 const scoped_refptr<media::GpuVideoAcceleratorFactories>& factories)
76 : weak_factory_(this), 76 : weak_factory_(this),
77 weak_this_(weak_factory_.GetWeakPtr()), 77 weak_this_(weak_factory_.GetWeakPtr()),
78 factories_(factories), 78 factories_(factories),
79 vda_loop_proxy_(factories->GetMessageLoop()), 79 vda_task_runner_(factories->GetTaskRunner()),
80 decoder_texture_target_(0), 80 decoder_texture_target_(0),
81 next_picture_buffer_id_(0), 81 next_picture_buffer_id_(0),
82 state_(UNINITIALIZED), 82 state_(UNINITIALIZED),
83 decode_complete_callback_(NULL), 83 decode_complete_callback_(NULL),
84 num_shm_buffers_(0), 84 num_shm_buffers_(0),
85 next_bitstream_buffer_id_(0), 85 next_bitstream_buffer_id_(0),
86 reset_bitstream_buffer_id_(ID_INVALID) { 86 reset_bitstream_buffer_id_(ID_INVALID) {
87 DCHECK(!vda_loop_proxy_->BelongsToCurrentThread()); 87 DCHECK(!vda_task_runner_->BelongsToCurrentThread());
88 base::WaitableEvent message_loop_async_waiter(false, false); 88 base::WaitableEvent message_loop_async_waiter(false, false);
89 // Waiting here is safe. The media thread is stopped in the child thread and 89 // Waiting here is safe. The media thread is stopped in the child thread and
90 // the child thread is blocked when VideoDecoderFactory::CreateVideoDecoder 90 // the child thread is blocked when VideoDecoderFactory::CreateVideoDecoder
91 // runs. 91 // runs.
92 vda_loop_proxy_->PostTask(FROM_HERE, 92 vda_task_runner_->PostTask(FROM_HERE,
93 base::Bind(&RTCVideoDecoder::Initialize, 93 base::Bind(&RTCVideoDecoder::Initialize,
94 base::Unretained(this), 94 base::Unretained(this),
95 &message_loop_async_waiter)); 95 &message_loop_async_waiter));
96 message_loop_async_waiter.Wait(); 96 message_loop_async_waiter.Wait();
97 } 97 }
98 98
99 RTCVideoDecoder::~RTCVideoDecoder() { 99 RTCVideoDecoder::~RTCVideoDecoder() {
100 DVLOG(2) << "~RTCVideoDecoder"; 100 DVLOG(2) << "~RTCVideoDecoder";
101 // Destroy VDA and remove |this| from the observer if this is vda thread. 101 // Destroy VDA and remove |this| from the observer if this is vda thread.
102 if (vda_loop_proxy_->BelongsToCurrentThread()) { 102 if (vda_task_runner_->BelongsToCurrentThread()) {
103 base::MessageLoop::current()->RemoveDestructionObserver(this); 103 base::MessageLoop::current()->RemoveDestructionObserver(this);
104 DestroyVDA(); 104 DestroyVDA();
105 } else { 105 } else {
106 // VDA should have been destroyed in WillDestroyCurrentMessageLoop. 106 // VDA should have been destroyed in WillDestroyCurrentMessageLoop.
107 DCHECK(!vda_); 107 DCHECK(!vda_);
108 } 108 }
109 109
110 // Delete all shared memories. 110 // Delete all shared memories.
111 STLDeleteElements(&available_shm_segments_); 111 STLDeleteElements(&available_shm_segments_);
112 STLDeleteValues(&bitstream_buffers_in_decoder_); 112 STLDeleteValues(&bitstream_buffers_in_decoder_);
(...skipping 25 matching lines...) Expand all
138 return decoder.Pass(); 138 return decoder.Pass();
139 } 139 }
140 140
141 decoder.reset(new RTCVideoDecoder(factories)); 141 decoder.reset(new RTCVideoDecoder(factories));
142 decoder->vda_ = 142 decoder->vda_ =
143 factories->CreateVideoDecodeAccelerator(profile, decoder.get()).Pass(); 143 factories->CreateVideoDecodeAccelerator(profile, decoder.get()).Pass();
144 // vda can be NULL if VP8 is not supported. 144 // vda can be NULL if VP8 is not supported.
145 if (decoder->vda_ != NULL) { 145 if (decoder->vda_ != NULL) {
146 decoder->state_ = INITIALIZED; 146 decoder->state_ = INITIALIZED;
147 } else { 147 } else {
148 factories->GetMessageLoop()->DeleteSoon(FROM_HERE, decoder.release()); 148 factories->GetTaskRunner()->DeleteSoon(FROM_HERE, decoder.release());
149 } 149 }
150 return decoder.Pass(); 150 return decoder.Pass();
151 } 151 }
152 152
153 int32_t RTCVideoDecoder::InitDecode(const webrtc::VideoCodec* codecSettings, 153 int32_t RTCVideoDecoder::InitDecode(const webrtc::VideoCodec* codecSettings,
154 int32_t /*numberOfCores*/) { 154 int32_t /*numberOfCores*/) {
155 DVLOG(2) << "InitDecode"; 155 DVLOG(2) << "InitDecode";
156 DCHECK_EQ(codecSettings->codecType, webrtc::kVideoCodecVP8); 156 DCHECK_EQ(codecSettings->codecType, webrtc::kVideoCodecVP8);
157 if (codecSettings->codecSpecific.VP8.feedbackModeOn) { 157 if (codecSettings->codecSpecific.VP8.feedbackModeOn) {
158 LOG(ERROR) << "Feedback mode not supported"; 158 LOG(ERROR) << "Feedback mode not supported";
159 return RecordInitDecodeUMA(WEBRTC_VIDEO_CODEC_ERROR); 159 return RecordInitDecodeUMA(WEBRTC_VIDEO_CODEC_ERROR);
160 } 160 }
161 161
162 base::AutoLock auto_lock(lock_); 162 base::AutoLock auto_lock(lock_);
163 if (state_ == UNINITIALIZED || state_ == DECODE_ERROR) { 163 if (state_ == UNINITIALIZED || state_ == DECODE_ERROR) {
164 LOG(ERROR) << "VDA is not initialized. state=" << state_; 164 LOG(ERROR) << "VDA is not initialized. state=" << state_;
165 return RecordInitDecodeUMA(WEBRTC_VIDEO_CODEC_UNINITIALIZED); 165 return RecordInitDecodeUMA(WEBRTC_VIDEO_CODEC_UNINITIALIZED);
166 } 166 }
167 // Create some shared memory if the queue is empty. 167 // Create some shared memory if the queue is empty.
168 if (available_shm_segments_.size() == 0) { 168 if (available_shm_segments_.size() == 0) {
169 vda_loop_proxy_->PostTask(FROM_HERE, 169 vda_task_runner_->PostTask(FROM_HERE,
170 base::Bind(&RTCVideoDecoder::CreateSHM, 170 base::Bind(&RTCVideoDecoder::CreateSHM,
171 weak_this_, 171 weak_this_,
172 kMaxInFlightDecodes, 172 kMaxInFlightDecodes,
173 kSharedMemorySegmentBytes)); 173 kSharedMemorySegmentBytes));
174 } 174 }
175 return RecordInitDecodeUMA(WEBRTC_VIDEO_CODEC_OK); 175 return RecordInitDecodeUMA(WEBRTC_VIDEO_CODEC_OK);
176 } 176 }
177 177
178 int32_t RTCVideoDecoder::Decode( 178 int32_t RTCVideoDecoder::Decode(
179 const webrtc::EncodedImage& inputImage, 179 const webrtc::EncodedImage& inputImage,
180 bool missingFrames, 180 bool missingFrames,
181 const webrtc::RTPFragmentationHeader* /*fragmentation*/, 181 const webrtc::RTPFragmentationHeader* /*fragmentation*/,
182 const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/, 182 const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/,
183 int64_t /*renderTimeMs*/) { 183 int64_t /*renderTimeMs*/) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (!SaveToPendingBuffers_Locked(inputImage, buffer_data)) 249 if (!SaveToPendingBuffers_Locked(inputImage, buffer_data))
250 return WEBRTC_VIDEO_CODEC_ERROR; 250 return WEBRTC_VIDEO_CODEC_ERROR;
251 if (need_to_reset_for_midstream_resize) { 251 if (need_to_reset_for_midstream_resize) {
252 base::AutoUnlock auto_unlock(lock_); 252 base::AutoUnlock auto_unlock(lock_);
253 Reset(); 253 Reset();
254 } 254 }
255 return WEBRTC_VIDEO_CODEC_OK; 255 return WEBRTC_VIDEO_CODEC_OK;
256 } 256 }
257 257
258 SaveToDecodeBuffers_Locked(inputImage, shm_buffer.Pass(), buffer_data); 258 SaveToDecodeBuffers_Locked(inputImage, shm_buffer.Pass(), buffer_data);
259 vda_loop_proxy_->PostTask( 259 vda_task_runner_->PostTask(
260 FROM_HERE, base::Bind(&RTCVideoDecoder::RequestBufferDecode, weak_this_)); 260 FROM_HERE, base::Bind(&RTCVideoDecoder::RequestBufferDecode, weak_this_));
261 return WEBRTC_VIDEO_CODEC_OK; 261 return WEBRTC_VIDEO_CODEC_OK;
262 } 262 }
263 263
264 int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback( 264 int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback(
265 webrtc::DecodedImageCallback* callback) { 265 webrtc::DecodedImageCallback* callback) {
266 DVLOG(2) << "RegisterDecodeCompleteCallback"; 266 DVLOG(2) << "RegisterDecodeCompleteCallback";
267 base::AutoLock auto_lock(lock_); 267 base::AutoLock auto_lock(lock_);
268 decode_complete_callback_ = callback; 268 decode_complete_callback_ = callback;
269 return WEBRTC_VIDEO_CODEC_OK; 269 return WEBRTC_VIDEO_CODEC_OK;
(...skipping 13 matching lines...) Expand all
283 LOG(ERROR) << "Decoder not initialized."; 283 LOG(ERROR) << "Decoder not initialized.";
284 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 284 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
285 } 285 }
286 if (next_bitstream_buffer_id_ != 0) 286 if (next_bitstream_buffer_id_ != 0)
287 reset_bitstream_buffer_id_ = next_bitstream_buffer_id_ - 1; 287 reset_bitstream_buffer_id_ = next_bitstream_buffer_id_ - 1;
288 else 288 else
289 reset_bitstream_buffer_id_ = ID_LAST; 289 reset_bitstream_buffer_id_ = ID_LAST;
290 // If VDA is already resetting, no need to request the reset again. 290 // If VDA is already resetting, no need to request the reset again.
291 if (state_ != RESETTING) { 291 if (state_ != RESETTING) {
292 state_ = RESETTING; 292 state_ = RESETTING;
293 vda_loop_proxy_->PostTask( 293 vda_task_runner_->PostTask(
294 FROM_HERE, base::Bind(&RTCVideoDecoder::ResetInternal, weak_this_)); 294 FROM_HERE, base::Bind(&RTCVideoDecoder::ResetInternal, weak_this_));
295 } 295 }
296 return WEBRTC_VIDEO_CODEC_OK; 296 return WEBRTC_VIDEO_CODEC_OK;
297 } 297 }
298 298
299 void RTCVideoDecoder::NotifyInitializeDone() { 299 void RTCVideoDecoder::NotifyInitializeDone() {
300 DVLOG(2) << "NotifyInitializeDone"; 300 DVLOG(2) << "NotifyInitializeDone";
301 NOTREACHED(); 301 NOTREACHED();
302 } 302 }
303 303
304 void RTCVideoDecoder::ProvidePictureBuffers(uint32 count, 304 void RTCVideoDecoder::ProvidePictureBuffers(uint32 count,
305 const gfx::Size& size, 305 const gfx::Size& size,
306 uint32 texture_target) { 306 uint32 texture_target) {
307 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 307 DCHECK(vda_task_runner_->BelongsToCurrentThread());
308 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target; 308 DVLOG(3) << "ProvidePictureBuffers. texture_target=" << texture_target;
309 309
310 if (!vda_) 310 if (!vda_)
311 return; 311 return;
312 312
313 std::vector<uint32> texture_ids; 313 std::vector<uint32> texture_ids;
314 std::vector<gpu::Mailbox> texture_mailboxes; 314 std::vector<gpu::Mailbox> texture_mailboxes;
315 decoder_texture_target_ = texture_target; 315 decoder_texture_target_ = texture_target;
316 // Discards the sync point returned here since PictureReady will imply that 316 // Discards the sync point returned here since PictureReady will imply that
317 // the produce has already happened, and the texture is ready for use. 317 // the produce has already happened, and the texture is ready for use.
(...skipping 14 matching lines...) Expand all
332 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i])); 332 next_picture_buffer_id_++, size, texture_ids[i], texture_mailboxes[i]));
333 bool inserted = assigned_picture_buffers_.insert(std::make_pair( 333 bool inserted = assigned_picture_buffers_.insert(std::make_pair(
334 picture_buffers.back().id(), picture_buffers.back())).second; 334 picture_buffers.back().id(), picture_buffers.back())).second;
335 DCHECK(inserted); 335 DCHECK(inserted);
336 } 336 }
337 vda_->AssignPictureBuffers(picture_buffers); 337 vda_->AssignPictureBuffers(picture_buffers);
338 } 338 }
339 339
340 void RTCVideoDecoder::DismissPictureBuffer(int32 id) { 340 void RTCVideoDecoder::DismissPictureBuffer(int32 id) {
341 DVLOG(3) << "DismissPictureBuffer. id=" << id; 341 DVLOG(3) << "DismissPictureBuffer. id=" << id;
342 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 342 DCHECK(vda_task_runner_->BelongsToCurrentThread());
343 343
344 std::map<int32, media::PictureBuffer>::iterator it = 344 std::map<int32, media::PictureBuffer>::iterator it =
345 assigned_picture_buffers_.find(id); 345 assigned_picture_buffers_.find(id);
346 if (it == assigned_picture_buffers_.end()) { 346 if (it == assigned_picture_buffers_.end()) {
347 NOTREACHED() << "Missing picture buffer: " << id; 347 NOTREACHED() << "Missing picture buffer: " << id;
348 return; 348 return;
349 } 349 }
350 350
351 media::PictureBuffer buffer_to_dismiss = it->second; 351 media::PictureBuffer buffer_to_dismiss = it->second;
352 assigned_picture_buffers_.erase(it); 352 assigned_picture_buffers_.erase(it);
353 353
354 std::set<int32>::iterator at_display_it = 354 std::set<int32>::iterator at_display_it =
355 picture_buffers_at_display_.find(id); 355 picture_buffers_at_display_.find(id);
356 356
357 if (at_display_it == picture_buffers_at_display_.end()) { 357 if (at_display_it == picture_buffers_at_display_.end()) {
358 // We can delete the texture immediately as it's not being displayed. 358 // We can delete the texture immediately as it's not being displayed.
359 factories_->DeleteTexture(buffer_to_dismiss.texture_id()); 359 factories_->DeleteTexture(buffer_to_dismiss.texture_id());
360 } else { 360 } else {
361 // Texture in display. Postpone deletion until after it's returned to us. 361 // Texture in display. Postpone deletion until after it's returned to us.
362 bool inserted = dismissed_picture_buffers_ 362 bool inserted = dismissed_picture_buffers_
363 .insert(std::make_pair(id, buffer_to_dismiss)).second; 363 .insert(std::make_pair(id, buffer_to_dismiss)).second;
364 DCHECK(inserted); 364 DCHECK(inserted);
365 } 365 }
366 } 366 }
367 367
368 void RTCVideoDecoder::PictureReady(const media::Picture& picture) { 368 void RTCVideoDecoder::PictureReady(const media::Picture& picture) {
369 DVLOG(3) << "PictureReady"; 369 DVLOG(3) << "PictureReady";
370 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 370 DCHECK(vda_task_runner_->BelongsToCurrentThread());
371 371
372 std::map<int32, media::PictureBuffer>::iterator it = 372 std::map<int32, media::PictureBuffer>::iterator it =
373 assigned_picture_buffers_.find(picture.picture_buffer_id()); 373 assigned_picture_buffers_.find(picture.picture_buffer_id());
374 if (it == assigned_picture_buffers_.end()) { 374 if (it == assigned_picture_buffers_.end()) {
375 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id(); 375 NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id();
376 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 376 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
377 return; 377 return;
378 } 378 }
379 const media::PictureBuffer& pb = it->second; 379 const media::PictureBuffer& pb = it->second;
380 380
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 timestamp_ms, 433 timestamp_ms,
434 base::Bind(&media::GpuVideoAcceleratorFactories::ReadPixels, 434 base::Bind(&media::GpuVideoAcceleratorFactories::ReadPixels,
435 factories_, 435 factories_,
436 pb.texture_id(), 436 pb.texture_id(),
437 natural_size), 437 natural_size),
438 base::Closure()); 438 base::Closure());
439 } 439 }
440 440
441 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) { 441 void RTCVideoDecoder::NotifyEndOfBitstreamBuffer(int32 id) {
442 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id; 442 DVLOG(3) << "NotifyEndOfBitstreamBuffer. id=" << id;
443 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 443 DCHECK(vda_task_runner_->BelongsToCurrentThread());
444 444
445 std::map<int32, SHMBuffer*>::iterator it = 445 std::map<int32, SHMBuffer*>::iterator it =
446 bitstream_buffers_in_decoder_.find(id); 446 bitstream_buffers_in_decoder_.find(id);
447 if (it == bitstream_buffers_in_decoder_.end()) { 447 if (it == bitstream_buffers_in_decoder_.end()) {
448 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); 448 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
449 NOTREACHED() << "Missing bitstream buffer: " << id; 449 NOTREACHED() << "Missing bitstream buffer: " << id;
450 return; 450 return;
451 } 451 }
452 452
453 { 453 {
454 base::AutoLock auto_lock(lock_); 454 base::AutoLock auto_lock(lock_);
455 PutSHM_Locked(scoped_ptr<SHMBuffer>(it->second)); 455 PutSHM_Locked(scoped_ptr<SHMBuffer>(it->second));
456 } 456 }
457 bitstream_buffers_in_decoder_.erase(it); 457 bitstream_buffers_in_decoder_.erase(it);
458 458
459 RequestBufferDecode(); 459 RequestBufferDecode();
460 } 460 }
461 461
462 void RTCVideoDecoder::NotifyFlushDone() { 462 void RTCVideoDecoder::NotifyFlushDone() {
463 DVLOG(3) << "NotifyFlushDone"; 463 DVLOG(3) << "NotifyFlushDone";
464 NOTREACHED() << "Unexpected flush done notification."; 464 NOTREACHED() << "Unexpected flush done notification.";
465 } 465 }
466 466
467 void RTCVideoDecoder::NotifyResetDone() { 467 void RTCVideoDecoder::NotifyResetDone() {
468 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 468 DCHECK(vda_task_runner_->BelongsToCurrentThread());
469 DVLOG(3) << "NotifyResetDone"; 469 DVLOG(3) << "NotifyResetDone";
470 470
471 if (!vda_) 471 if (!vda_)
472 return; 472 return;
473 473
474 input_buffer_data_.clear(); 474 input_buffer_data_.clear();
475 { 475 {
476 base::AutoLock auto_lock(lock_); 476 base::AutoLock auto_lock(lock_);
477 state_ = INITIALIZED; 477 state_ = INITIALIZED;
478 } 478 }
479 // Send the pending buffers for decoding. 479 // Send the pending buffers for decoding.
480 RequestBufferDecode(); 480 RequestBufferDecode();
481 } 481 }
482 482
483 void RTCVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) { 483 void RTCVideoDecoder::NotifyError(media::VideoDecodeAccelerator::Error error) {
484 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 484 DCHECK(vda_task_runner_->BelongsToCurrentThread());
485 if (!vda_) 485 if (!vda_)
486 return; 486 return;
487 487
488 LOG(ERROR) << "VDA Error:" << error; 488 LOG(ERROR) << "VDA Error:" << error;
489 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoDecoderError", 489 UMA_HISTOGRAM_ENUMERATION("Media.RTCVideoDecoderError",
490 error, 490 error,
491 media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM); 491 media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM);
492 DestroyVDA(); 492 DestroyVDA();
493 493
494 base::AutoLock auto_lock(lock_); 494 base::AutoLock auto_lock(lock_);
495 state_ = DECODE_ERROR; 495 state_ = DECODE_ERROR;
496 } 496 }
497 497
498 void RTCVideoDecoder::WillDestroyCurrentMessageLoop() { 498 void RTCVideoDecoder::WillDestroyCurrentMessageLoop() {
499 DVLOG(2) << "WillDestroyCurrentMessageLoop"; 499 DVLOG(2) << "WillDestroyCurrentMessageLoop";
500 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 500 DCHECK(vda_task_runner_->BelongsToCurrentThread());
501 factories_->Abort(); 501 factories_->Abort();
502 weak_factory_.InvalidateWeakPtrs(); 502 weak_factory_.InvalidateWeakPtrs();
503 DestroyVDA(); 503 DestroyVDA();
504 } 504 }
505 505
506 void RTCVideoDecoder::Initialize(base::WaitableEvent* waiter) { 506 void RTCVideoDecoder::Initialize(base::WaitableEvent* waiter) {
507 DVLOG(2) << "Initialize"; 507 DVLOG(2) << "Initialize";
508 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 508 DCHECK(vda_task_runner_->BelongsToCurrentThread());
509 base::MessageLoop::current()->AddDestructionObserver(this); 509 base::MessageLoop::current()->AddDestructionObserver(this);
510 waiter->Signal(); 510 waiter->Signal();
511 } 511 }
512 512
513 void RTCVideoDecoder::RequestBufferDecode() { 513 void RTCVideoDecoder::RequestBufferDecode() {
514 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 514 DCHECK(vda_task_runner_->BelongsToCurrentThread());
515 if (!vda_) 515 if (!vda_)
516 return; 516 return;
517 517
518 MovePendingBuffersToDecodeBuffers(); 518 MovePendingBuffersToDecodeBuffers();
519 519
520 while (CanMoreDecodeWorkBeDone()) { 520 while (CanMoreDecodeWorkBeDone()) {
521 // Get a buffer and data from the queue. 521 // Get a buffer and data from the queue.
522 SHMBuffer* shm_buffer = NULL; 522 SHMBuffer* shm_buffer = NULL;
523 BufferData buffer_data; 523 BufferData buffer_data;
524 { 524 {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 scoped_ptr<SHMBuffer> shm_buffer = GetSHM_Locked(input_image._length); 626 scoped_ptr<SHMBuffer> shm_buffer = GetSHM_Locked(input_image._length);
627 if (!shm_buffer) 627 if (!shm_buffer)
628 return; 628 return;
629 SaveToDecodeBuffers_Locked(input_image, shm_buffer.Pass(), buffer_data); 629 SaveToDecodeBuffers_Locked(input_image, shm_buffer.Pass(), buffer_data);
630 delete[] input_image._buffer; 630 delete[] input_image._buffer;
631 pending_buffers_.pop_front(); 631 pending_buffers_.pop_front();
632 } 632 }
633 } 633 }
634 634
635 void RTCVideoDecoder::ResetInternal() { 635 void RTCVideoDecoder::ResetInternal() {
636 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 636 DCHECK(vda_task_runner_->BelongsToCurrentThread());
637 DVLOG(2) << "ResetInternal"; 637 DVLOG(2) << "ResetInternal";
638 if (vda_) 638 if (vda_)
639 vda_->Reset(); 639 vda_->Reset();
640 } 640 }
641 641
642 void RTCVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id, 642 void RTCVideoDecoder::ReusePictureBuffer(int64 picture_buffer_id,
643 uint32 sync_point) { 643 uint32 sync_point) {
644 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 644 DCHECK(vda_task_runner_->BelongsToCurrentThread());
645 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id; 645 DVLOG(3) << "ReusePictureBuffer. id=" << picture_buffer_id;
646 646
647 if (!vda_) 647 if (!vda_)
648 return; 648 return;
649 649
650 CHECK(!picture_buffers_at_display_.empty()); 650 CHECK(!picture_buffers_at_display_.empty());
651 651
652 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id); 652 size_t num_erased = picture_buffers_at_display_.erase(picture_buffer_id);
653 DCHECK(num_erased); 653 DCHECK(num_erased);
654 654
655 std::map<int32, media::PictureBuffer>::iterator it = 655 std::map<int32, media::PictureBuffer>::iterator it =
656 assigned_picture_buffers_.find(picture_buffer_id); 656 assigned_picture_buffers_.find(picture_buffer_id);
657 657
658 if (it == assigned_picture_buffers_.end()) { 658 if (it == assigned_picture_buffers_.end()) {
659 // This picture was dismissed while in display, so we postponed deletion. 659 // This picture was dismissed while in display, so we postponed deletion.
660 it = dismissed_picture_buffers_.find(picture_buffer_id); 660 it = dismissed_picture_buffers_.find(picture_buffer_id);
661 DCHECK(it != dismissed_picture_buffers_.end()); 661 DCHECK(it != dismissed_picture_buffers_.end());
662 factories_->DeleteTexture(it->second.texture_id()); 662 factories_->DeleteTexture(it->second.texture_id());
663 dismissed_picture_buffers_.erase(it); 663 dismissed_picture_buffers_.erase(it);
664 return; 664 return;
665 } 665 }
666 666
667 factories_->WaitSyncPoint(sync_point); 667 factories_->WaitSyncPoint(sync_point);
668 668
669 vda_->ReusePictureBuffer(picture_buffer_id); 669 vda_->ReusePictureBuffer(picture_buffer_id);
670 } 670 }
671 671
672 void RTCVideoDecoder::DestroyTextures() { 672 void RTCVideoDecoder::DestroyTextures() {
673 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 673 DCHECK(vda_task_runner_->BelongsToCurrentThread());
674 std::map<int32, media::PictureBuffer>::iterator it; 674 std::map<int32, media::PictureBuffer>::iterator it;
675 675
676 for (it = assigned_picture_buffers_.begin(); 676 for (it = assigned_picture_buffers_.begin();
677 it != assigned_picture_buffers_.end(); 677 it != assigned_picture_buffers_.end();
678 ++it) { 678 ++it) {
679 factories_->DeleteTexture(it->second.texture_id()); 679 factories_->DeleteTexture(it->second.texture_id());
680 } 680 }
681 assigned_picture_buffers_.clear(); 681 assigned_picture_buffers_.clear();
682 682
683 for (it = dismissed_picture_buffers_.begin(); 683 for (it = dismissed_picture_buffers_.begin();
684 it != dismissed_picture_buffers_.end(); 684 it != dismissed_picture_buffers_.end();
685 ++it) { 685 ++it) {
686 factories_->DeleteTexture(it->second.texture_id()); 686 factories_->DeleteTexture(it->second.texture_id());
687 } 687 }
688 dismissed_picture_buffers_.clear(); 688 dismissed_picture_buffers_.clear();
689 } 689 }
690 690
691 void RTCVideoDecoder::DestroyVDA() { 691 void RTCVideoDecoder::DestroyVDA() {
692 DVLOG(2) << "DestroyVDA"; 692 DVLOG(2) << "DestroyVDA";
693 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 693 DCHECK(vda_task_runner_->BelongsToCurrentThread());
694 if (vda_) 694 if (vda_)
695 vda_.release()->Destroy(); 695 vda_.release()->Destroy();
696 DestroyTextures(); 696 DestroyTextures();
697 base::AutoLock auto_lock(lock_); 697 base::AutoLock auto_lock(lock_);
698 state_ = UNINITIALIZED; 698 state_ = UNINITIALIZED;
699 } 699 }
700 700
701 scoped_ptr<RTCVideoDecoder::SHMBuffer> RTCVideoDecoder::GetSHM_Locked( 701 scoped_ptr<RTCVideoDecoder::SHMBuffer> RTCVideoDecoder::GetSHM_Locked(
702 size_t min_size) { 702 size_t min_size) {
703 // Reuse a SHM if possible. 703 // Reuse a SHM if possible.
704 SHMBuffer* ret = NULL; 704 SHMBuffer* ret = NULL;
705 if (!available_shm_segments_.empty() && 705 if (!available_shm_segments_.empty() &&
706 available_shm_segments_.back()->size >= min_size) { 706 available_shm_segments_.back()->size >= min_size) {
707 ret = available_shm_segments_.back(); 707 ret = available_shm_segments_.back();
708 available_shm_segments_.pop_back(); 708 available_shm_segments_.pop_back();
709 } 709 }
710 // Post to vda thread to create shared memory if SHM cannot be reused or the 710 // Post to vda thread to create shared memory if SHM cannot be reused or the
711 // queue is almost empty. 711 // queue is almost empty.
712 if (num_shm_buffers_ < kMaxNumSharedMemorySegments && 712 if (num_shm_buffers_ < kMaxNumSharedMemorySegments &&
713 (ret == NULL || available_shm_segments_.size() <= 1)) { 713 (ret == NULL || available_shm_segments_.size() <= 1)) {
714 vda_loop_proxy_->PostTask( 714 vda_task_runner_->PostTask(
715 FROM_HERE, 715 FROM_HERE,
716 base::Bind(&RTCVideoDecoder::CreateSHM, weak_this_, 1, min_size)); 716 base::Bind(&RTCVideoDecoder::CreateSHM, weak_this_, 1, min_size));
717 } 717 }
718 return scoped_ptr<SHMBuffer>(ret); 718 return scoped_ptr<SHMBuffer>(ret);
719 } 719 }
720 720
721 void RTCVideoDecoder::PutSHM_Locked(scoped_ptr<SHMBuffer> shm_buffer) { 721 void RTCVideoDecoder::PutSHM_Locked(scoped_ptr<SHMBuffer> shm_buffer) {
722 available_shm_segments_.push_back(shm_buffer.release()); 722 available_shm_segments_.push_back(shm_buffer.release());
723 } 723 }
724 724
725 void RTCVideoDecoder::CreateSHM(int number, size_t min_size) { 725 void RTCVideoDecoder::CreateSHM(int number, size_t min_size) {
726 DCHECK(vda_loop_proxy_->BelongsToCurrentThread()); 726 DCHECK(vda_task_runner_->BelongsToCurrentThread());
727 DVLOG(2) << "CreateSHM. size=" << min_size; 727 DVLOG(2) << "CreateSHM. size=" << min_size;
728 int number_to_allocate; 728 int number_to_allocate;
729 { 729 {
730 base::AutoLock auto_lock(lock_); 730 base::AutoLock auto_lock(lock_);
731 number_to_allocate = 731 number_to_allocate =
732 std::min(kMaxNumSharedMemorySegments - num_shm_buffers_, number); 732 std::min(kMaxNumSharedMemorySegments - num_shm_buffers_, number);
733 } 733 }
734 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes); 734 size_t size_to_allocate = std::max(min_size, kSharedMemorySegmentBytes);
735 for (int i = 0; i < number_to_allocate; i++) { 735 for (int i = 0; i < number_to_allocate; i++) {
736 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate); 736 base::SharedMemory* shm = factories_->CreateSharedMemory(size_to_allocate);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 777
778 int32_t RTCVideoDecoder::RecordInitDecodeUMA(int32_t status) { 778 int32_t RTCVideoDecoder::RecordInitDecodeUMA(int32_t status) {
779 // Logging boolean is enough to know if HW decoding has been used. Also, 779 // Logging boolean is enough to know if HW decoding has been used. Also,
780 // InitDecode is less likely to return an error so enum is not used here. 780 // InitDecode is less likely to return an error so enum is not used here.
781 bool sample = (status == WEBRTC_VIDEO_CODEC_OK) ? true : false; 781 bool sample = (status == WEBRTC_VIDEO_CODEC_OK) ? true : false;
782 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderInitDecodeSuccess", sample); 782 UMA_HISTOGRAM_BOOLEAN("Media.RTCVideoDecoderInitDecodeSuccess", sample);
783 return status; 783 return status;
784 } 784 }
785 785
786 } // namespace content 786 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698