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

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

Issue 1655083002: Enable SurfaceView fullscreen video on Android with WebMediaPlayerImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@avda-sv
Patch Set: cleaned up Created 4 years, 10 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 unified diff | Download patch
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 <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/callback_helpers.h" 11 #include "base/callback_helpers.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/cpu.h" 13 #include "base/cpu.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/task_runner_util.h" 17 #include "base/task_runner_util.h"
18 #include "build/build_config.h" 18 #include "build/build_config.h"
19 #include "gpu/command_buffer/common/mailbox_holder.h" 19 #include "gpu/command_buffer/common/mailbox_holder.h"
20 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
21 #include "media/base/decoder_buffer.h" 21 #include "media/base/decoder_buffer.h"
22 #include "media/base/media_switches.h" 22 #include "media/base/media_switches.h"
23 #include "media/base/pipeline.h" 23 #include "media/base/pipeline.h"
24 #include "media/base/surface_manager.h"
24 #include "media/base/video_decoder_config.h" 25 #include "media/base/video_decoder_config.h"
25 #include "media/renderers/gpu_video_accelerator_factories.h" 26 #include "media/renderers/gpu_video_accelerator_factories.h"
26 #include "third_party/skia/include/core/SkBitmap.h" 27 #include "third_party/skia/include/core/SkBitmap.h"
27 28
28 namespace media { 29 namespace media {
29 30
30 const char GpuVideoDecoder::kDecoderName[] = "GpuVideoDecoder"; 31 const char GpuVideoDecoder::kDecoderName[] = "GpuVideoDecoder";
31 32
32 // Maximum number of concurrent VDA::Decode() operations GVD will maintain. 33 // Maximum number of concurrent VDA::Decode() operations GVD will maintain.
33 // Higher values allow better pipelining in the GPU, but also require more 34 // Higher values allow better pipelining in the GPU, but also require more
(...skipping 23 matching lines...) Expand all
57 base::TimeDelta ts, 58 base::TimeDelta ts,
58 const gfx::Rect& vr, 59 const gfx::Rect& vr,
59 const gfx::Size& ns) 60 const gfx::Size& ns)
60 : bitstream_buffer_id(bbid), 61 : bitstream_buffer_id(bbid),
61 timestamp(ts), 62 timestamp(ts),
62 visible_rect(vr), 63 visible_rect(vr),
63 natural_size(ns) {} 64 natural_size(ns) {}
64 65
65 GpuVideoDecoder::BufferData::~BufferData() {} 66 GpuVideoDecoder::BufferData::~BufferData() {}
66 67
67 GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories) 68 GpuVideoDecoder::GpuVideoDecoder(GpuVideoAcceleratorFactories* factories,
69 const RequestSurfaceCB& request_surface_cb)
68 : needs_bitstream_conversion_(false), 70 : needs_bitstream_conversion_(false),
69 factories_(factories), 71 factories_(factories),
70 state_(kNormal), 72 state_(kNormal),
73 request_surface_cb_(request_surface_cb),
71 decoder_texture_target_(0), 74 decoder_texture_target_(0),
72 next_picture_buffer_id_(0), 75 next_picture_buffer_id_(0),
73 next_bitstream_buffer_id_(0), 76 next_bitstream_buffer_id_(0),
74 available_pictures_(0), 77 available_pictures_(0),
75 needs_all_picture_buffers_to_decode_(false), 78 needs_all_picture_buffers_to_decode_(false),
76 weak_factory_(this) { 79 weak_factory_(this) {
77 DCHECK(factories_); 80 DCHECK(factories_);
78 } 81 }
79 82
80 void GpuVideoDecoder::Reset(const base::Closure& closure) { 83 void GpuVideoDecoder::Reset(const base::Closure& closure) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 144
142 #if !defined(OS_ANDROID) 145 #if !defined(OS_ANDROID)
143 if (config.is_encrypted()) { 146 if (config.is_encrypted()) {
144 DVLOG(1) << "Encrypted stream not supported."; 147 DVLOG(1) << "Encrypted stream not supported.";
145 bound_init_cb.Run(false); 148 bound_init_cb.Run(false);
146 return; 149 return;
147 } 150 }
148 #endif 151 #endif
149 152
150 bool previously_initialized = config_.IsValidConfig(); 153 bool previously_initialized = config_.IsValidConfig();
151 DVLOG(1) << "(Re)initializing GVD with config: " 154 DVLOG(1) << (previously_initialized ? "Reinitializing" : "Initializing")
152 << config.AsHumanReadableString(); 155 << "GVD with config: " << config.AsHumanReadableString();
153 156
154 // TODO(posciak): destroy and create a new VDA on codec/profile change 157 // TODO(posciak): destroy and create a new VDA on codec/profile change
155 // (http://crbug.com/260224). 158 // (http://crbug.com/260224).
156 if (previously_initialized && (config_.profile() != config.profile())) { 159 if (previously_initialized && (config_.profile() != config.profile())) {
157 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; 160 DVLOG(1) << "Codec or profile changed, cannot reinitialize.";
158 bound_init_cb.Run(false); 161 bound_init_cb.Run(false);
159 return; 162 return;
160 } 163 }
161 164
162 VideoDecodeAccelerator::Capabilities capabilities = 165 VideoDecodeAccelerator::Capabilities capabilities =
(...skipping 17 matching lines...) Expand all
180 DVLOG(3) << __FUNCTION__ 183 DVLOG(3) << __FUNCTION__
181 << " Expecting initialized VDA to detect in-stream config change."; 184 << " Expecting initialized VDA to detect in-stream config change.";
182 // Reinitialization with a different config (but same codec and profile). 185 // Reinitialization with a different config (but same codec and profile).
183 // VDA should handle it by detecting this in-stream by itself, 186 // VDA should handle it by detecting this in-stream by itself,
184 // no need to notify it. 187 // no need to notify it.
185 bound_init_cb.Run(true); 188 bound_init_cb.Run(true);
186 return; 189 return;
187 } 190 }
188 191
189 vda_ = factories_->CreateVideoDecodeAccelerator(); 192 vda_ = factories_->CreateVideoDecodeAccelerator();
190 193 if (!vda_) {
191 VideoDecodeAccelerator::Config vda_config(config); 194 DVLOG(1) << "Failed to create a VDA.";
192
193 if (!vda_ || !vda_->Initialize(vda_config, this)) {
194 DVLOG(1) << "VDA initialization failed.";
195 bound_init_cb.Run(false); 195 bound_init_cb.Run(false);
196 return; 196 return;
197 } 197 }
198 198
199 // CompleteInitialization will clear both of these callbacks.
200 init_cb_ = bound_init_cb;
199 if (config.is_encrypted()) { 201 if (config.is_encrypted()) {
200 init_cb_ = bound_init_cb;
201 set_cdm_ready_cb_ = set_cdm_ready_cb; 202 set_cdm_ready_cb_ = set_cdm_ready_cb;
203 }
204
205 const bool supports_external_output_surface =
206 capabilities.flags &
207 VideoDecodeAccelerator::Capabilities::SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
208 if (supports_external_output_surface && !request_surface_cb_.is_null()) {
209 // If we have surface request callback we should call it and complete
210 // initialization with the returned surface.
211 request_surface_cb_.Run(BindToCurrentLoop(base::Bind(
212 &GpuVideoDecoder::CompleteInitialization, weak_factory_.GetWeakPtr())));
213 return;
214 }
215
216 // Complete initialization with a null surface.
217 CompleteInitialization(SurfaceManager::kNoSurfaceID);
218 }
219
220 void GpuVideoDecoder::CompleteInitialization(int surface_id) {
221 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
222 DCHECK(!init_cb_.is_null());
223
224 VideoDecodeAccelerator::Config vda_config(config_);
225 vda_config.surface_id = surface_id;
226 if (!vda_->Initialize(vda_config, this)) {
227 DVLOG(1) << "VDA::Initialize failed.";
228 set_cdm_ready_cb_.Reset();
229 base::ResetAndReturn(&init_cb_).Run(false);
230 return;
231 }
232
233 // The VDA is now initialized, but If the stream is encrypted we need to
234 // request and attach the CDM before completing GVD's initialization.
235 if (config_.is_encrypted()) {
202 set_cdm_ready_cb_.Run(BindToCurrentLoop( 236 set_cdm_ready_cb_.Run(BindToCurrentLoop(
203 base::Bind(&GpuVideoDecoder::SetCdm, weak_factory_.GetWeakPtr()))); 237 base::Bind(&GpuVideoDecoder::SetCdm, weak_factory_.GetWeakPtr())));
204 return; 238 return;
205 } 239 }
206 240
207 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; 241 base::ResetAndReturn(&init_cb_).Run(true);
208 bound_init_cb.Run(true);
209 } 242 }
210 243
211 void GpuVideoDecoder::SetCdm(CdmContext* cdm_context, 244 void GpuVideoDecoder::SetCdm(CdmContext* cdm_context,
212 const CdmAttachedCB& cdm_attached_cb) { 245 const CdmAttachedCB& cdm_attached_cb) {
213 DVLOG(2) << __FUNCTION__; 246 DVLOG(2) << __FUNCTION__;
214 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); 247 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
215 248
216 DCHECK(!init_cb_.is_null()); 249 DCHECK(!init_cb_.is_null());
217 DCHECK(!set_cdm_ready_cb_.is_null()); 250 DCHECK(!set_cdm_ready_cb_.is_null());
218 set_cdm_ready_cb_.Reset(); 251 set_cdm_ready_cb_.Reset();
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 if (vda_) 638 if (vda_)
606 DestroyVDA(); 639 DestroyVDA();
607 DCHECK(assigned_picture_buffers_.empty()); 640 DCHECK(assigned_picture_buffers_.empty());
608 641
609 if (!set_cdm_ready_cb_.is_null()) 642 if (!set_cdm_ready_cb_.is_null())
610 base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB()); 643 base::ResetAndReturn(&set_cdm_ready_cb_).Run(CdmReadyCB());
611 if (!cdm_attached_cb_.is_null()) 644 if (!cdm_attached_cb_.is_null())
612 base::ResetAndReturn(&cdm_attached_cb_).Run(false); 645 base::ResetAndReturn(&cdm_attached_cb_).Run(false);
613 if (!init_cb_.is_null()) 646 if (!init_cb_.is_null())
614 base::ResetAndReturn(&init_cb_).Run(false); 647 base::ResetAndReturn(&init_cb_).Run(false);
648 if (!request_surface_cb_.is_null())
649 base::ResetAndReturn(&request_surface_cb_).Run(SurfaceCreatedCB());
615 650
616 for (size_t i = 0; i < available_shm_segments_.size(); ++i) { 651 for (size_t i = 0; i < available_shm_segments_.size(); ++i) {
617 delete available_shm_segments_[i]; 652 delete available_shm_segments_[i];
618 } 653 }
619 available_shm_segments_.clear(); 654 available_shm_segments_.clear();
620 655
621 for (std::map<int32_t, PendingDecoderBuffer>::iterator it = 656 for (std::map<int32_t, PendingDecoderBuffer>::iterator it =
622 bitstream_buffers_in_decoder_.begin(); 657 bitstream_buffers_in_decoder_.begin();
623 it != bitstream_buffers_in_decoder_.end(); ++it) { 658 it != bitstream_buffers_in_decoder_.end(); ++it) {
624 delete it->second.shm_buffer; 659 delete it->second.shm_buffer;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 } 721 }
687 return false; 722 return false;
688 } 723 }
689 724
690 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() 725 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent()
691 const { 726 const {
692 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); 727 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread());
693 } 728 }
694 729
695 } // namespace media 730 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698