OLD | NEW |
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 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 | 98 |
99 static bool IsCodedSizeSupported(const gfx::Size& coded_size, | 99 static bool IsCodedSizeSupported(const gfx::Size& coded_size, |
100 const gfx::Size& min_resolution, | 100 const gfx::Size& min_resolution, |
101 const gfx::Size& max_resolution) { | 101 const gfx::Size& max_resolution) { |
102 return (coded_size.width() <= max_resolution.width() && | 102 return (coded_size.width() <= max_resolution.width() && |
103 coded_size.height() <= max_resolution.height() && | 103 coded_size.height() <= max_resolution.height() && |
104 coded_size.width() >= min_resolution.width() && | 104 coded_size.width() >= min_resolution.width() && |
105 coded_size.height() >= min_resolution.height()); | 105 coded_size.height() >= min_resolution.height()); |
106 } | 106 } |
107 | 107 |
108 // Report |success| to UMA and run |cb| with it. This is super-specific to the | 108 // Report |status| to UMA and run |cb| with it. This is super-specific to the |
109 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a | 109 // UMA stat reported because the UMA_HISTOGRAM_ENUMERATION API requires a |
110 // callsite to always be called with the same stat name (can't parameterize it). | 110 // callsite to always be called with the same stat name (can't parameterize it). |
111 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( | 111 static void ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB( |
112 const VideoDecoder::InitCB& cb, | 112 const PipelineStatusCB& cb, |
113 bool success) { | 113 PipelineStatus status) { |
114 // TODO(xhwang): Report |success| directly. | |
115 PipelineStatus status = success ? PIPELINE_OK : DECODER_ERROR_NOT_SUPPORTED; | |
116 UMA_HISTOGRAM_ENUMERATION( | 114 UMA_HISTOGRAM_ENUMERATION( |
117 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); | 115 "Media.GpuVideoDecoderInitializeStatus", status, PIPELINE_STATUS_MAX + 1); |
118 cb.Run(success); | 116 cb.Run(status); |
119 } | 117 } |
120 | 118 |
121 std::string GpuVideoDecoder::GetDisplayName() const { | 119 std::string GpuVideoDecoder::GetDisplayName() const { |
122 return kDecoderName; | 120 return kDecoderName; |
123 } | 121 } |
124 | 122 |
125 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, | 123 void GpuVideoDecoder::Initialize(const VideoDecoderConfig& config, |
126 bool /* low_delay */, | 124 bool /* low_delay */, |
127 const InitCB& init_cb, | 125 const PipelineStatusCB& orig_status_cb, |
128 const OutputCB& output_cb) { | 126 const OutputCB& output_cb) { |
129 DVLOG(3) << "Initialize()"; | 127 DVLOG(3) << "Initialize()"; |
130 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 128 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
131 DCHECK(config.IsValidConfig()); | 129 DCHECK(config.IsValidConfig()); |
132 DCHECK(!config.is_encrypted()); | 130 DCHECK(!config.is_encrypted()); |
133 | 131 |
134 InitCB bound_init_cb = | 132 PipelineStatusCB status_cb = |
135 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, | 133 base::Bind(&ReportGpuVideoDecoderInitializeStatusToUMAAndRunCB, |
136 BindToCurrentLoop(init_cb)); | 134 BindToCurrentLoop(orig_status_cb)); |
137 | 135 |
138 bool previously_initialized = config_.IsValidConfig(); | 136 bool previously_initialized = config_.IsValidConfig(); |
139 DVLOG(1) << "(Re)initializing GVD with config: " | 137 DVLOG(1) << "(Re)initializing GVD with config: " |
140 << config.AsHumanReadableString(); | 138 << config.AsHumanReadableString(); |
141 | 139 |
142 // TODO(posciak): destroy and create a new VDA on codec/profile change | 140 // TODO(posciak): destroy and create a new VDA on codec/profile change |
143 // (http://crbug.com/260224). | 141 // (http://crbug.com/260224). |
144 if (previously_initialized && (config_.profile() != config.profile())) { | 142 if (previously_initialized && (config_.profile() != config.profile())) { |
145 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; | 143 DVLOG(1) << "Codec or profile changed, cannot reinitialize."; |
146 bound_init_cb.Run(false); | 144 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
147 return; | 145 return; |
148 } | 146 } |
149 | 147 |
150 if (!IsProfileSupported(config.profile(), config.coded_size())) { | 148 if (!IsProfileSupported(config.profile(), config.coded_size())) { |
151 bound_init_cb.Run(false); | 149 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
152 return; | 150 return; |
153 } | 151 } |
154 | 152 |
155 config_ = config; | 153 config_ = config; |
156 needs_bitstream_conversion_ = (config.codec() == kCodecH264); | 154 needs_bitstream_conversion_ = (config.codec() == kCodecH264); |
157 output_cb_ = BindToCurrentLoop(output_cb); | 155 output_cb_ = BindToCurrentLoop(output_cb); |
158 | 156 |
159 if (previously_initialized) { | 157 if (previously_initialized) { |
160 // Reinitialization with a different config (but same codec and profile). | 158 // Reinitialization with a different config (but same codec and profile). |
161 // VDA should handle it by detecting this in-stream by itself, | 159 // VDA should handle it by detecting this in-stream by itself, |
162 // no need to notify it. | 160 // no need to notify it. |
163 bound_init_cb.Run(true); | 161 status_cb.Run(PIPELINE_OK); |
164 return; | 162 return; |
165 } | 163 } |
166 | 164 |
167 vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); | 165 vda_ = factories_->CreateVideoDecodeAccelerator().Pass(); |
168 if (!vda_ || !vda_->Initialize(config.profile(), this)) { | 166 if (!vda_ || !vda_->Initialize(config.profile(), this)) { |
169 bound_init_cb.Run(false); | 167 status_cb.Run(DECODER_ERROR_NOT_SUPPORTED); |
170 return; | 168 return; |
171 } | 169 } |
172 | 170 |
173 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; | 171 DVLOG(3) << "GpuVideoDecoder::Initialize() succeeded."; |
174 bound_init_cb.Run(true); | 172 status_cb.Run(PIPELINE_OK); |
175 } | 173 } |
176 | 174 |
177 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { | 175 void GpuVideoDecoder::DestroyPictureBuffers(PictureBufferMap* buffers) { |
178 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); | 176 DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent(); |
179 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); | 177 for (PictureBufferMap::iterator it = buffers->begin(); it != buffers->end(); |
180 ++it) { | 178 ++it) { |
181 factories_->DeleteTexture(it->second.texture_id()); | 179 factories_->DeleteTexture(it->second.texture_id()); |
182 } | 180 } |
183 | 181 |
184 buffers->clear(); | 182 buffers->clear(); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 } | 583 } |
586 return false; | 584 return false; |
587 } | 585 } |
588 | 586 |
589 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() | 587 void GpuVideoDecoder::DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent() |
590 const { | 588 const { |
591 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); | 589 DCHECK(factories_->GetTaskRunner()->BelongsToCurrentThread()); |
592 } | 590 } |
593 | 591 |
594 } // namespace media | 592 } // namespace media |
OLD | NEW |