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

Side by Side Diff: content/common/gpu/media/mac_video_decode_accelerator.mm

Issue 10749019: VideoDecodeAccelerator now SupportsWeakPtr instead of being RefCountedThreadSafe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 5 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 | Annotate | Revision Log
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 "content/common/gpu/media/mac_video_decode_accelerator.h" 5 #include "content/common/gpu/media/mac_video_decode_accelerator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_path.h" 8 #include "base/file_path.h"
9 #import "base/mac/foundation_util.h" 9 #import "base/mac/foundation_util.h"
10 #import "base/memory/ref_counted_memory.h" 10 #import "base/memory/ref_counted_memory.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 105 }
106 106
107 bool MacVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile) { 107 bool MacVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile) {
108 DCHECK(CalledOnValidThread()); 108 DCHECK(CalledOnValidThread());
109 109
110 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); 110 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize();
111 if (!io_surface_support) 111 if (!io_surface_support)
112 return false; 112 return false;
113 113
114 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 114 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
115 &MacVideoDecodeAccelerator::NotifyInitializeDone, this)); 115 &MacVideoDecodeAccelerator::NotifyInitializeDone, base::AsWeakPtr(this)));
116 return true; 116 return true;
117 } 117 }
118 118
119 void MacVideoDecodeAccelerator::Decode( 119 void MacVideoDecodeAccelerator::Decode(
120 const media::BitstreamBuffer& bitstream_buffer) { 120 const media::BitstreamBuffer& bitstream_buffer) {
121 DCHECK(CalledOnValidThread()); 121 DCHECK(CalledOnValidThread());
122 RETURN_ON_FAILURE(client_, 122 RETURN_ON_FAILURE(client_,
123 "Call to Decode() during invalid state.", ILLEGAL_STATE,); 123 "Call to Decode() during invalid state.", ILLEGAL_STATE,);
124 124
125 base::SharedMemory memory(bitstream_buffer.handle(), true); 125 base::SharedMemory memory(bitstream_buffer.handle(), true);
126 RETURN_ON_FAILURE(memory.Map(bitstream_buffer.size()), 126 RETURN_ON_FAILURE(memory.Map(bitstream_buffer.size()),
127 "Failed to SharedMemory::Map().", UNREADABLE_INPUT,); 127 "Failed to SharedMemory::Map().", UNREADABLE_INPUT,);
128 128
129 h264_parser_.SetStream(static_cast<const uint8_t*>(memory.memory()), 129 h264_parser_.SetStream(static_cast<const uint8_t*>(memory.memory()),
130 bitstream_buffer.size()); 130 bitstream_buffer.size());
131 while (true) { 131 while (true) {
132 content::H264NALU nalu; 132 content::H264NALU nalu;
133 content::H264Parser::Result result = h264_parser_.AdvanceToNextNALU(&nalu); 133 content::H264Parser::Result result = h264_parser_.AdvanceToNextNALU(&nalu);
134 if (result == content::H264Parser::kEOStream) { 134 if (result == content::H264Parser::kEOStream) {
135 if (bitstream_nalu_count_.count(bitstream_buffer.id()) == 0) { 135 if (bitstream_nalu_count_.count(bitstream_buffer.id()) == 0) {
136 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 136 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
137 &MacVideoDecodeAccelerator::NotifyInputBufferRead, this, 137 &MacVideoDecodeAccelerator::NotifyInputBufferRead,
138 bitstream_buffer.id())); 138 base::AsWeakPtr(this), bitstream_buffer.id()));
139 } 139 }
140 return; 140 return;
141 } 141 }
142 RETURN_ON_FAILURE(result == content::H264Parser::kOk, 142 RETURN_ON_FAILURE(result == content::H264Parser::kOk,
143 "Unable to parse bitstream.", UNREADABLE_INPUT,); 143 "Unable to parse bitstream.", UNREADABLE_INPUT,);
144 if (!did_build_config_record_) { 144 if (!did_build_config_record_) {
145 std::vector<uint8_t> config_record; 145 std::vector<uint8_t> config_record;
146 RETURN_ON_FAILURE(config_record_builder_.ProcessNALU(&h264_parser_, nalu, 146 RETURN_ON_FAILURE(config_record_builder_.ProcessNALU(&h264_parser_, nalu,
147 &config_record), 147 &config_record),
148 "Unable to build AVC configuraiton record.", 148 "Unable to build AVC configuraiton record.",
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 available_pictures_.push_back(info.picture_buffer); 190 available_pictures_.push_back(info.picture_buffer);
191 SendImages(); 191 SendImages();
192 } 192 }
193 193
194 void MacVideoDecodeAccelerator::Flush() { 194 void MacVideoDecodeAccelerator::Flush() {
195 DCHECK(CalledOnValidThread()); 195 DCHECK(CalledOnValidThread());
196 RETURN_ON_FAILURE(vda_support_, 196 RETURN_ON_FAILURE(vda_support_,
197 "Call to Flush() during invalid state.", ILLEGAL_STATE,); 197 "Call to Flush() during invalid state.", ILLEGAL_STATE,);
198 vda_support_->Flush(true); 198 vda_support_->Flush(true);
199 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 199 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
200 &MacVideoDecodeAccelerator::NotifyFlushDone, this)); 200 &MacVideoDecodeAccelerator::NotifyFlushDone, base::AsWeakPtr(this)));
201 } 201 }
202 202
203 void MacVideoDecodeAccelerator::Reset() { 203 void MacVideoDecodeAccelerator::Reset() {
204 DCHECK(CalledOnValidThread()); 204 DCHECK(CalledOnValidThread());
205 RETURN_ON_FAILURE(vda_support_, 205 RETURN_ON_FAILURE(vda_support_,
206 "Call to Reset() during invalid state.", ILLEGAL_STATE,); 206 "Call to Reset() during invalid state.", ILLEGAL_STATE,);
207 vda_support_->Flush(false); 207 vda_support_->Flush(false);
208 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 208 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
209 &MacVideoDecodeAccelerator::NotifyResetDone, this)); 209 &MacVideoDecodeAccelerator::NotifyResetDone, base::AsWeakPtr(this)));
210 } 210 }
211 211
212 void MacVideoDecodeAccelerator::Destroy() { 212 void MacVideoDecodeAccelerator::Cleanup() {
213 DCHECK(CalledOnValidThread()); 213 DCHECK(CalledOnValidThread());
214 if (vda_support_) { 214 if (vda_support_) {
215 vda_support_->Destroy(); 215 vda_support_->Destroy();
216 vda_support_ = NULL; 216 vda_support_ = NULL;
217 } 217 }
218 client_ = NULL; 218 client_ = NULL;
219 decoded_images_.clear(); 219 decoded_images_.clear();
220 } 220 }
221 221
222 void MacVideoDecodeAccelerator::Destroy() {
223 DCHECK(CalledOnValidThread());
224 Cleanup();
225 delete this;
226 }
227
222 MacVideoDecodeAccelerator::~MacVideoDecodeAccelerator() { 228 MacVideoDecodeAccelerator::~MacVideoDecodeAccelerator() {
223 DCHECK(CalledOnValidThread()); 229 DCHECK(CalledOnValidThread());
224 Destroy(); 230 DCHECK(!vda_support_);
231 DCHECK(!client_);
232 DCHECK(decoded_images_.empty());
225 } 233 }
226 234
227 void MacVideoDecodeAccelerator::OnFrameReady( 235 void MacVideoDecodeAccelerator::OnFrameReady(
228 int32 bitstream_buffer_id, 236 int32 bitstream_buffer_id,
229 scoped_refptr<base::RefCountedBytes> bytes, 237 scoped_refptr<base::RefCountedBytes> bytes,
230 CVImageBufferRef image, 238 CVImageBufferRef image,
231 int status) { 239 int status) {
232 DCHECK(CalledOnValidThread()); 240 DCHECK(CalledOnValidThread());
233 RETURN_ON_FAILURE(status == noErr, 241 RETURN_ON_FAILURE(status == noErr,
234 "Decoding image failed with error code: " << status, 242 "Decoding image failed with error code: " << status,
235 PLATFORM_FAILURE,); 243 PLATFORM_FAILURE,);
236 if (!client_) 244 if (!client_)
237 return; 245 return;
238 if (image) { 246 if (image) {
239 DecodedImageInfo info; 247 DecodedImageInfo info;
240 info.image.reset(image, base::scoped_policy::RETAIN); 248 info.image.reset(image, base::scoped_policy::RETAIN);
241 info.bitstream_buffer_id = bitstream_buffer_id; 249 info.bitstream_buffer_id = bitstream_buffer_id;
242 decoded_images_.push_back(info); 250 decoded_images_.push_back(info);
243 SendImages(); 251 SendImages();
244 } 252 }
245 std::map<int32, int>::iterator bitstream_count_it = 253 std::map<int32, int>::iterator bitstream_count_it =
246 bitstream_nalu_count_.find(bitstream_buffer_id); 254 bitstream_nalu_count_.find(bitstream_buffer_id);
247 if (--bitstream_count_it->second == 0) { 255 if (--bitstream_count_it->second == 0) {
248 bitstream_nalu_count_.erase(bitstream_count_it); 256 bitstream_nalu_count_.erase(bitstream_count_it);
249 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 257 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
250 &MacVideoDecodeAccelerator::NotifyInputBufferRead, this, 258 &MacVideoDecodeAccelerator::NotifyInputBufferRead,
251 bitstream_buffer_id)); 259 base::AsWeakPtr(this), bitstream_buffer_id));
252 } 260 }
253 } 261 }
254 262
255 void MacVideoDecodeAccelerator::SendImages() { 263 void MacVideoDecodeAccelerator::SendImages() {
256 if (!client_) { 264 if (!client_) {
257 DCHECK(decoded_images_.empty()); 265 DCHECK(decoded_images_.empty());
258 return; 266 return;
259 } 267 }
260 268
261 while (available_pictures_.size() && decoded_images_.size()) { 269 while (available_pictures_.size() && decoded_images_.size()) {
(...skipping 10 matching lines...) Expand all
272 picture_buffer.id(), UsedPictureInfo(picture_buffer, info.image))); 280 picture_buffer.id(), UsedPictureInfo(picture_buffer, info.image)));
273 client_->PictureReady( 281 client_->PictureReady(
274 media::Picture(picture_buffer.id(), info.bitstream_buffer_id)); 282 media::Picture(picture_buffer.id(), info.bitstream_buffer_id));
275 } 283 }
276 } 284 }
277 285
278 void MacVideoDecodeAccelerator::StopOnError( 286 void MacVideoDecodeAccelerator::StopOnError(
279 media::VideoDecodeAccelerator::Error error) { 287 media::VideoDecodeAccelerator::Error error) {
280 if (client_) 288 if (client_)
281 client_->NotifyError(error); 289 client_->NotifyError(error);
282 Destroy(); 290 Cleanup();
283 } 291 }
284 292
285 bool MacVideoDecodeAccelerator::CreateDecoder( 293 bool MacVideoDecodeAccelerator::CreateDecoder(
286 const std::vector<uint8_t>& extra_data) { 294 const std::vector<uint8_t>& extra_data) {
287 DCHECK(client_); 295 DCHECK(client_);
288 DCHECK(!vda_support_.get()); 296 DCHECK(!vda_support_.get());
289 297
290 vda_support_ = new gfx::VideoDecodeAccelerationSupport(); 298 vda_support_ = new gfx::VideoDecodeAccelerationSupport();
291 gfx::VideoDecodeAccelerationSupport::Status status = vda_support_->Create( 299 gfx::VideoDecodeAccelerationSupport::Status status = vda_support_->Create(
292 config_record_builder_.coded_width(), 300 config_record_builder_.coded_width(),
293 config_record_builder_.coded_height(), 301 config_record_builder_.coded_height(),
294 kCVPixelFormatType_422YpCbCr8, 302 kCVPixelFormatType_422YpCbCr8,
295 &extra_data[0], extra_data.size()); 303 &extra_data[0], extra_data.size());
296 RETURN_ON_FAILURE(status == gfx::VideoDecodeAccelerationSupport::SUCCESS, 304 RETURN_ON_FAILURE(status == gfx::VideoDecodeAccelerationSupport::SUCCESS,
297 "Creating video decoder failed with error: " << status, 305 "Creating video decoder failed with error: " << status,
298 PLATFORM_FAILURE, false); 306 PLATFORM_FAILURE, false);
299 307
300 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 308 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
301 &MacVideoDecodeAccelerator::RequestPictures, this)); 309 &MacVideoDecodeAccelerator::RequestPictures, base::AsWeakPtr(this)));
302 return true; 310 return true;
303 } 311 }
304 312
305 void MacVideoDecodeAccelerator::DecodeNALU(const content::H264NALU& nalu, 313 void MacVideoDecodeAccelerator::DecodeNALU(const content::H264NALU& nalu,
306 int32 bitstream_buffer_id) { 314 int32 bitstream_buffer_id) {
307 // Assume the NALU length field size is 4 bytes. 315 // Assume the NALU length field size is 4 bytes.
308 const int kNALULengthFieldSize = 4; 316 const int kNALULengthFieldSize = 4;
309 std::vector<uint8_t> data(kNALULengthFieldSize + nalu.size); 317 std::vector<uint8_t> data(kNALULengthFieldSize + nalu.size);
310 318
311 // Store the buffer size at the beginning of the buffer as the decoder 319 // Store the buffer size at the beginning of the buffer as the decoder
312 // expects. 320 // expects.
313 for (size_t i = 0; i < kNALULengthFieldSize; ++i) { 321 for (size_t i = 0; i < kNALULengthFieldSize; ++i) {
314 size_t shift = kNALULengthFieldSize * 8 - (i + 1) * 8; 322 size_t shift = kNALULengthFieldSize * 8 - (i + 1) * 8;
315 data[i] = (nalu.size >> shift) & 0xff; 323 data[i] = (nalu.size >> shift) & 0xff;
316 } 324 }
317 325
318 // Copy the NALU data. 326 // Copy the NALU data.
319 memcpy(&data[kNALULengthFieldSize], nalu.data, nalu.size); 327 memcpy(&data[kNALULengthFieldSize], nalu.data, nalu.size);
320 328
321 // Keep a ref counted copy of the buffer. 329 // Keep a ref counted copy of the buffer.
322 scoped_refptr<base::RefCountedBytes> bytes( 330 scoped_refptr<base::RefCountedBytes> bytes(
323 base::RefCountedBytes::TakeVector(&data)); 331 base::RefCountedBytes::TakeVector(&data));
324 vda_support_->Decode(bytes->front(), bytes->size(), 332 vda_support_->Decode(bytes->front(), bytes->size(), base::Bind(
325 base::Bind(&MacVideoDecodeAccelerator::OnFrameReady, 333 &MacVideoDecodeAccelerator::OnFrameReady,
326 this, bitstream_buffer_id, bytes)); 334 base::AsWeakPtr(this), bitstream_buffer_id, bytes));
327 } 335 }
328 336
329 void MacVideoDecodeAccelerator::NotifyInitializeDone() { 337 void MacVideoDecodeAccelerator::NotifyInitializeDone() {
330 if (client_) 338 if (client_)
331 client_->NotifyInitializeDone(); 339 client_->NotifyInitializeDone();
332 } 340 }
333 341
334 void MacVideoDecodeAccelerator::RequestPictures() { 342 void MacVideoDecodeAccelerator::RequestPictures() {
335 if (client_) { 343 if (client_) {
336 client_->ProvidePictureBuffers( 344 client_->ProvidePictureBuffers(
(...skipping 28 matching lines...) Expand all
365 } 373 }
366 374
367 MacVideoDecodeAccelerator::UsedPictureInfo::~UsedPictureInfo() { 375 MacVideoDecodeAccelerator::UsedPictureInfo::~UsedPictureInfo() {
368 } 376 }
369 377
370 MacVideoDecodeAccelerator::DecodedImageInfo::DecodedImageInfo() { 378 MacVideoDecodeAccelerator::DecodedImageInfo::DecodedImageInfo() {
371 } 379 }
372 380
373 MacVideoDecodeAccelerator::DecodedImageInfo::~DecodedImageInfo() { 381 MacVideoDecodeAccelerator::DecodedImageInfo::~DecodedImageInfo() {
374 } 382 }
OLDNEW
« no previous file with comments | « content/common/gpu/media/mac_video_decode_accelerator.h ('k') | content/common/gpu/media/omx_video_decode_accelerator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698