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

Side by Side Diff: media/filters/gpu_video_decoder.cc

Issue 2461073002: Use MediaCodec.setOutputSurface() for fullscreen transitions on M. (Closed)
Patch Set: Cleanup terms. Created 4 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
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/gpu/android_video_decode_accelerator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "media/filters/gpu_video_decoder.h" 5 #include "media/filters/gpu_video_decoder.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <array> 8 #include <array>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 18 matching lines...) Expand all
29 #include "media/base/pipeline_status.h" 29 #include "media/base/pipeline_status.h"
30 #include "media/base/surface_manager.h" 30 #include "media/base/surface_manager.h"
31 #include "media/base/video_decoder_config.h" 31 #include "media/base/video_decoder_config.h"
32 #include "media/renderers/gpu_video_accelerator_factories.h" 32 #include "media/renderers/gpu_video_accelerator_factories.h"
33 #include "third_party/skia/include/core/SkBitmap.h" 33 #include "third_party/skia/include/core/SkBitmap.h"
34 34
35 #if defined(USE_PROPRIETARY_CODECS) 35 #if defined(USE_PROPRIETARY_CODECS)
36 #include "media/formats/mp4/box_definitions.h" 36 #include "media/formats/mp4/box_definitions.h"
37 #endif 37 #endif
38 38
39 #if defined(OS_ANDROID)
40 #include "base/android/build_info.h"
41 #endif
42
39 namespace media { 43 namespace media {
40 namespace { 44 namespace {
41 45
42 // Size of shared-memory segments we allocate. Since we reuse them we let them 46 // Size of shared-memory segments we allocate. Since we reuse them we let them
43 // be on the beefy side. 47 // be on the beefy side.
44 static const size_t kSharedMemorySegmentBytes = 100 << 10; 48 static const size_t kSharedMemorySegmentBytes = 100 << 10;
45 49
46 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) 50 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS)
47 // Extract the SPS and PPS lists from |extra_data|. Each SPS and PPS is prefixed 51 // Extract the SPS and PPS lists from |extra_data|. Each SPS and PPS is prefixed
48 // with 0x0001, the Annex B framing bytes. The out parameters are not modified 52 // with 0x0001, the Annex B framing bytes. The out parameters are not modified
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 media_log_(media_log), 123 media_log_(media_log),
120 state_(kNormal), 124 state_(kNormal),
121 decoder_texture_target_(0), 125 decoder_texture_target_(0),
122 pixel_format_(PIXEL_FORMAT_UNKNOWN), 126 pixel_format_(PIXEL_FORMAT_UNKNOWN),
123 next_picture_buffer_id_(0), 127 next_picture_buffer_id_(0),
124 next_bitstream_buffer_id_(0), 128 next_bitstream_buffer_id_(0),
125 available_pictures_(0), 129 available_pictures_(0),
126 needs_all_picture_buffers_to_decode_(false), 130 needs_all_picture_buffers_to_decode_(false),
127 supports_deferred_initialization_(false), 131 supports_deferred_initialization_(false),
128 requires_texture_copy_(false), 132 requires_texture_copy_(false),
133 cdm_id_(CdmContext::kInvalidCdmId),
129 weak_factory_(this) { 134 weak_factory_(this) {
130 DCHECK(factories_); 135 DCHECK(factories_);
131 } 136 }
132 137
133 void GpuVideoDecoder::Reset(const base::Closure& closure) { 138 void GpuVideoDecoder::Reset(const base::Closure& closure) {
134 DVLOG(3) << "Reset()"; 139 DVLOG(3) << "Reset()";
135 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 140 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
136 141
137 if (state_ == kDrainingDecoder) { 142 if (state_ == kDrainingDecoder) {
138 base::ThreadTaskRunnerHandle::Get()->PostTask( 143 base::ThreadTaskRunnerHandle::Get()->PostTask(
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 const InitCB& init_cb, 210 const InitCB& init_cb,
206 const OutputCB& output_cb) { 211 const OutputCB& output_cb) {
207 DVLOG(3) << "Initialize()"; 212 DVLOG(3) << "Initialize()";
208 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 213 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
209 DCHECK(config.IsValidConfig()); 214 DCHECK(config.IsValidConfig());
210 215
211 InitCB bound_init_cb = 216 InitCB bound_init_cb =
212 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, 217 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB,
213 BindToCurrentLoop(init_cb), media_log_); 218 BindToCurrentLoop(init_cb), media_log_);
214 219
220 bool requires_restart_for_external_output_surface = false;
215 #if !defined(OS_ANDROID) 221 #if !defined(OS_ANDROID)
216 if (config.is_encrypted()) { 222 if (config.is_encrypted()) {
217 DVLOG(1) << "Encrypted stream not supported."; 223 DVLOG(1) << "Encrypted stream not supported.";
218 bound_init_cb.Run(false); 224 bound_init_cb.Run(false);
219 return; 225 return;
220 } 226 }
227 #else
228 requires_restart_for_external_output_surface =
229 base::android::BuildInfo::GetInstance()->sdk_int() < 23;
221 #endif 230 #endif
222 231
223 bool previously_initialized = config_.IsValidConfig(); 232 bool previously_initialized = config_.IsValidConfig();
224 DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing") 233 DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing")
225 << " GVD with config: " << config.AsHumanReadableString(); 234 << " GVD with config: " << config.AsHumanReadableString();
226 235
227 // Disallow codec changes between configuration changes. 236 // Disallow codec changes between configuration changes.
228 if (previously_initialized && config_.codec() != config.codec()) { 237 if (previously_initialized && config_.codec() != config.codec()) {
229 DVLOG(1) << "Codec changed, cannot reinitialize."; 238 DVLOG(1) << "Codec changed, cannot reinitialize.";
230 bound_init_cb.Run(false); 239 bound_init_cb.Run(false);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 return; 290 return;
282 } 291 }
283 292
284 vda_ = factories_->CreateVideoDecodeAccelerator(); 293 vda_ = factories_->CreateVideoDecodeAccelerator();
285 if (!vda_) { 294 if (!vda_) {
286 DVLOG(1) << "Failed to create a VDA."; 295 DVLOG(1) << "Failed to create a VDA.";
287 bound_init_cb.Run(false); 296 bound_init_cb.Run(false);
288 return; 297 return;
289 } 298 }
290 299
291 int cdm_id = CdmContext::kInvalidCdmId;
292 if (config.is_encrypted()) { 300 if (config.is_encrypted()) {
293 DCHECK(cdm_context); 301 DCHECK(cdm_context);
294 cdm_id = cdm_context->GetCdmId(); 302 cdm_id_ = cdm_context->GetCdmId();
295 // No need to store |cdm_context| since it's not needed in reinitialization. 303 // No need to store |cdm_context| since it's not needed in reinitialization.
296 if (cdm_id == CdmContext::kInvalidCdmId) { 304 if (cdm_id_ == CdmContext::kInvalidCdmId) {
297 DVLOG(1) << "CDM ID not available."; 305 DVLOG(1) << "CDM ID not available.";
298 bound_init_cb.Run(false); 306 bound_init_cb.Run(false);
299 return; 307 return;
300 } 308 }
301 } 309 }
302 310
303 init_cb_ = bound_init_cb; 311 init_cb_ = bound_init_cb;
304 312
305 const bool supports_external_output_surface = 313 const bool supports_external_output_surface =
306 (capabilities.flags & VideoDecodeAccelerator::Capabilities:: 314 (capabilities.flags & VideoDecodeAccelerator::Capabilities::
307 SUPPORTS_EXTERNAL_OUTPUT_SURFACE) != 0; 315 SUPPORTS_EXTERNAL_OUTPUT_SURFACE) != 0;
308 if (supports_external_output_surface && !request_surface_cb_.is_null()) { 316 if (supports_external_output_surface && !request_surface_cb_.is_null()) {
309 // If we have a surface request callback we should call it and complete 317 // If we have a surface request callback we should call it and complete
310 // initialization with the returned surface. 318 // initialization with the returned surface.
311 request_surface_cb_.Run( 319 request_surface_cb_.Run(
312 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::CompleteInitialization, 320 requires_restart_for_external_output_surface,
313 weak_factory_.GetWeakPtr(), cdm_id))); 321 BindToCurrentLoop(base::Bind(&GpuVideoDecoder::OnSurfaceAvailable,
322 weak_factory_.GetWeakPtr())));
314 return; 323 return;
315 } 324 }
316 325
317 // If we don't have to wait for a surface complete initialization with a null 326 // If external surfaces are not supported we can complete initialization now.
318 // surface. 327 CompleteInitialization();
319 CompleteInitialization(cdm_id, SurfaceManager::kNoSurfaceID);
320 } 328 }
321 329
322 void GpuVideoDecoder::CompleteInitialization(int cdm_id, int surface_id) { 330 void GpuVideoDecoder::OnSurfaceAvailable(int surface_id) {
323 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 331 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
324 DCHECK(!init_cb_.is_null());
325 332
326 // It's possible for the vda to become null if NotifyError is called. 333 // It's possible for the vda to become null if NotifyError is called.
327 if (!vda_) { 334 if (!vda_) {
328 base::ResetAndReturn(&init_cb_).Run(false); 335 base::ResetAndReturn(&init_cb_).Run(false);
watk 2016/11/09 00:56:36 Need to check init_cb_ is not null before running
DaleCurtis 2016/11/09 01:12:15 Good catch, done.
329 return; 336 return;
330 } 337 }
331 338
339 vda_->SetSurface(surface_id);
340
341 // If initialization has already completed, there's nothing left to do.
342 if (init_cb_.is_null())
343 return;
344
345 // Otherwise initialization was waiting for the surface, so complete it now.
346 CompleteInitialization();
347 }
348
349 void GpuVideoDecoder::CompleteInitialization() {
350 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
351 DCHECK(vda_);
352 DCHECK(!init_cb_.is_null());
353
332 VideoDecodeAccelerator::Config vda_config; 354 VideoDecodeAccelerator::Config vda_config;
333 vda_config.profile = config_.profile(); 355 vda_config.profile = config_.profile();
334 vda_config.cdm_id = cdm_id; 356 vda_config.cdm_id = cdm_id_;
335 vda_config.is_encrypted = config_.is_encrypted(); 357 vda_config.is_encrypted = config_.is_encrypted();
336 vda_config.surface_id = surface_id;
337 vda_config.is_deferred_initialization_allowed = true; 358 vda_config.is_deferred_initialization_allowed = true;
338 vda_config.initial_expected_coded_size = config_.coded_size(); 359 vda_config.initial_expected_coded_size = config_.coded_size();
339 360
340 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS) 361 #if defined(OS_ANDROID) && defined(USE_PROPRIETARY_CODECS)
341 // We pass the SPS and PPS on Android because it lets us initialize 362 // We pass the SPS and PPS on Android because it lets us initialize
342 // MediaCodec more reliably (http://crbug.com/649185). 363 // MediaCodec more reliably (http://crbug.com/649185).
343 if (config_.codec() == kCodecH264) 364 if (config_.codec() == kCodecH264)
344 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps); 365 ExtractSpsAndPps(config_.extra_data(), &vda_config.sps, &vda_config.pps);
345 #endif 366 #endif
346 367
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 DVLOG(3) << __func__; 799 DVLOG(3) << __func__;
779 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 800 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
780 801
781 if (vda_) 802 if (vda_)
782 DestroyVDA(); 803 DestroyVDA();
783 DCHECK(assigned_picture_buffers_.empty()); 804 DCHECK(assigned_picture_buffers_.empty());
784 805
785 if (!init_cb_.is_null()) 806 if (!init_cb_.is_null())
786 base::ResetAndReturn(&init_cb_).Run(false); 807 base::ResetAndReturn(&init_cb_).Run(false);
787 if (!request_surface_cb_.is_null()) 808 if (!request_surface_cb_.is_null())
788 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB()); 809 base::ResetAndReturn(&request_surface_cb_).Run(false, SurfaceCreatedCB());
789 810
790 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 811 for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
791 delete available_shm_segments_[i]; 812 delete available_shm_segments_[i];
792 } 813 }
793 available_shm_segments_.clear(); 814 available_shm_segments_.clear();
794 815
795 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = 816 for (std::map<int32_t, PendingDecoderBuffer>::iterator it =
796 bitstream_buffers_in_decoder_.begin(); 817 bitstream_buffers_in_decoder_.begin();
797 it != bitstream_buffers_in_decoder_.end(); ++it) { 818 it != bitstream_buffers_in_decoder_.end(); ++it) {
798 delete it->second.shm_buffer; 819 delete it->second.shm_buffer;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 } 891 }
871 return false; 892 return false;
872 } 893 }
873 894
874 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() 895 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent()
875 const { 896 const {
876 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); 897 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread());
877 } 898 }
878 899
879 } // namespace media 900 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/gpu_video_decoder.h ('k') | media/gpu/android_video_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698