| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_decode_accelerator.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/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 } | 70 } |
| 71 | 71 |
| 72 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( | 72 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( |
| 73 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, | 73 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, |
| 74 const base::Callback<bool(void)>& make_context_current, | 74 const base::Callback<bool(void)>& make_context_current, |
| 75 scoped_ptr<BackingStrategy> strategy) | 75 scoped_ptr<BackingStrategy> strategy) |
| 76 : client_(NULL), | 76 : client_(NULL), |
| 77 make_context_current_(make_context_current), | 77 make_context_current_(make_context_current), |
| 78 codec_(media::kCodecH264), | 78 codec_(media::kCodecH264), |
| 79 state_(NO_ERROR), | 79 state_(NO_ERROR), |
| 80 surface_texture_id_(0), | |
| 81 picturebuffers_requested_(false), | 80 picturebuffers_requested_(false), |
| 82 gl_decoder_(decoder), | 81 gl_decoder_(decoder), |
| 83 strategy_(strategy.Pass()), | 82 strategy_(strategy.Pass()), |
| 84 weak_this_factory_(this) {} | 83 weak_this_factory_(this) {} |
| 85 | 84 |
| 86 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 85 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 87 DCHECK(thread_checker_.CalledOnValidThread()); | 86 DCHECK(thread_checker_.CalledOnValidThread()); |
| 88 } | 87 } |
| 89 | 88 |
| 90 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, | 89 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 121 | 120 |
| 122 if (!make_context_current_.Run()) { | 121 if (!make_context_current_.Run()) { |
| 123 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 122 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 124 return false; | 123 return false; |
| 125 } | 124 } |
| 126 | 125 |
| 127 if (!gl_decoder_) { | 126 if (!gl_decoder_) { |
| 128 LOG(ERROR) << "Failed to get gles2 decoder instance."; | 127 LOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 129 return false; | 128 return false; |
| 130 } | 129 } |
| 131 glGenTextures(1, &surface_texture_id_); | 130 surface_texture_ = strategy_->CreateSurfaceTexture(); |
| 132 glActiveTexture(GL_TEXTURE0); | |
| 133 glBindTexture(GL_TEXTURE_EXTERNAL_OES, surface_texture_id_); | |
| 134 | |
| 135 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 136 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 137 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, | |
| 138 GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 139 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, | |
| 140 GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 141 gl_decoder_->RestoreTextureUnitBindings(0); | |
| 142 gl_decoder_->RestoreActiveTexture(); | |
| 143 | |
| 144 surface_texture_ = gfx::SurfaceTexture::Create(surface_texture_id_); | |
| 145 | 131 |
| 146 if (!ConfigureMediaCodec()) { | 132 if (!ConfigureMediaCodec()) { |
| 147 LOG(ERROR) << "Failed to create MediaCodec instance."; | 133 LOG(ERROR) << "Failed to create MediaCodec instance."; |
| 148 return false; | 134 return false; |
| 149 } | 135 } |
| 150 | 136 |
| 151 return true; | 137 return true; |
| 152 } | 138 } |
| 153 | 139 |
| 154 void AndroidVideoDecodeAccelerator::DoIOTask() { | 140 void AndroidVideoDecodeAccelerator::DoIOTask() { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 337 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| 352 | 338 |
| 353 OutputBufferMap::const_iterator i = | 339 OutputBufferMap::const_iterator i = |
| 354 output_picture_buffers_.find(picture_buffer_id); | 340 output_picture_buffers_.find(picture_buffer_id); |
| 355 RETURN_ON_FAILURE(this, i != output_picture_buffers_.end(), | 341 RETURN_ON_FAILURE(this, i != output_picture_buffers_.end(), |
| 356 "Can't find a PictureBuffer for " << picture_buffer_id, | 342 "Can't find a PictureBuffer for " << picture_buffer_id, |
| 357 PLATFORM_FAILURE); | 343 PLATFORM_FAILURE); |
| 358 | 344 |
| 359 // Connect the PictureBuffer to the decoded frame, via whatever | 345 // Connect the PictureBuffer to the decoded frame, via whatever |
| 360 // mechanism the strategy likes. | 346 // mechanism the strategy likes. |
| 361 strategy_->AssignCurrentSurfaceToPictureBuffer(codec_buffer_index, i->second); | 347 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); |
| 362 | 348 |
| 363 // TODO(henryhsu): Pass (0, 0) as visible size will cause several test | 349 // TODO(henryhsu): Pass (0, 0) as visible size will cause several test |
| 364 // cases failed. We should make sure |size_| is coded size or visible size. | 350 // cases failed. We should make sure |size_| is coded size or visible size. |
| 365 base::MessageLoop::current()->PostTask( | 351 base::MessageLoop::current()->PostTask( |
| 366 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, | 352 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, |
| 367 weak_this_factory_.GetWeakPtr(), | 353 weak_this_factory_.GetWeakPtr(), |
| 368 media::Picture(picture_buffer_id, bitstream_id, | 354 media::Picture(picture_buffer_id, bitstream_id, |
| 369 gfx::Rect(size_), false))); | 355 gfx::Rect(size_), false))); |
| 370 } | 356 } |
| 371 | 357 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 | 492 |
| 507 base::MessageLoop::current()->PostTask( | 493 base::MessageLoop::current()->PostTask( |
| 508 FROM_HERE, | 494 FROM_HERE, |
| 509 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 495 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 510 weak_this_factory_.GetWeakPtr())); | 496 weak_this_factory_.GetWeakPtr())); |
| 511 } | 497 } |
| 512 | 498 |
| 513 void AndroidVideoDecodeAccelerator::Destroy() { | 499 void AndroidVideoDecodeAccelerator::Destroy() { |
| 514 DCHECK(thread_checker_.CalledOnValidThread()); | 500 DCHECK(thread_checker_.CalledOnValidThread()); |
| 515 | 501 |
| 516 strategy_->Cleanup(); | |
| 517 | |
| 518 weak_this_factory_.InvalidateWeakPtrs(); | 502 weak_this_factory_.InvalidateWeakPtrs(); |
| 519 if (media_codec_) { | 503 if (media_codec_) { |
| 520 io_timer_.Stop(); | 504 io_timer_.Stop(); |
| 521 media_codec_->Stop(); | 505 media_codec_->Stop(); |
| 522 } | 506 } |
| 523 if (surface_texture_id_) | 507 strategy_->Cleanup(); |
| 524 glDeleteTextures(1, &surface_texture_id_); | |
| 525 delete this; | 508 delete this; |
| 526 } | 509 } |
| 527 | 510 |
| 528 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { | 511 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { |
| 529 return false; | 512 return false; |
| 530 } | 513 } |
| 531 | 514 |
| 532 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { | 515 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { |
| 533 return size_; | 516 return size_; |
| 534 } | 517 } |
| 535 | 518 |
| 536 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() | 519 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() |
| 537 const { | 520 const { |
| 538 return thread_checker_; | 521 return thread_checker_; |
| 539 } | 522 } |
| 540 | 523 |
| 541 gfx::SurfaceTexture* AndroidVideoDecodeAccelerator::GetSurfaceTexture() const { | |
| 542 return surface_texture_.get(); | |
| 543 } | |
| 544 | |
| 545 uint32 AndroidVideoDecodeAccelerator::GetSurfaceTextureId() const { | |
| 546 return surface_texture_id_; | |
| 547 } | |
| 548 | |
| 549 gpu::gles2::GLES2Decoder* AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 524 gpu::gles2::GLES2Decoder* AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
| 550 return gl_decoder_.get(); | 525 return gl_decoder_.get(); |
| 551 } | 526 } |
| 552 | 527 |
| 553 media::VideoCodecBridge* AndroidVideoDecodeAccelerator::GetMediaCodec() { | 528 media::VideoCodecBridge* AndroidVideoDecodeAccelerator::GetMediaCodec() { |
| 554 return media_codec_.get(); | 529 return media_codec_.get(); |
| 555 } | 530 } |
| 556 | 531 |
| 557 void AndroidVideoDecodeAccelerator::PostError( | 532 void AndroidVideoDecodeAccelerator::PostError( |
| 558 const ::tracked_objects::Location& from_here, | 533 const ::tracked_objects::Location& from_here, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 // software fallback for H264 on Android anyway. | 594 // software fallback for H264 on Android anyway. |
| 620 profile.max_resolution.SetSize(3840, 2160); | 595 profile.max_resolution.SetSize(3840, 2160); |
| 621 profiles.push_back(profile); | 596 profiles.push_back(profile); |
| 622 } | 597 } |
| 623 #endif | 598 #endif |
| 624 | 599 |
| 625 return profiles; | 600 return profiles; |
| 626 } | 601 } |
| 627 | 602 |
| 628 } // namespace content | 603 } // namespace content |
| OLD | NEW |