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

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 185403020: Make VEA client of command buffer; move sync. IPC to VDA/VEA::Initialize() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 56683e7a Rebase. Created 6 years, 9 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) 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"
11 #include "content/common/gpu/gpu_channel.h" 11 #include "content/common/gpu/gpu_channel.h"
12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
13 #include "media/base/bitstream_buffer.h" 13 #include "media/base/bitstream_buffer.h"
14 #include "media/base/limits.h" 14 #include "media/base/limits.h"
15 #include "media/video/picture.h" 15 #include "media/video/picture.h"
16 #include "ui/gl/android/scoped_java_surface.h" 16 #include "ui/gl/android/scoped_java_surface.h"
17 #include "ui/gl/android/surface_texture.h" 17 #include "ui/gl/android/surface_texture.h"
18 #include "ui/gl/gl_bindings.h" 18 #include "ui/gl/gl_bindings.h"
19 19
20 namespace content { 20 namespace content {
21 21
22 // Helper macros for dealing with failure. If |result| evaluates false, emit 22 // Helper macros for dealing with failure. If |result| evaluates false, emit
23 // |log| to ERROR, register |error| with the decoder, and return. 23 // |log| to ERROR, register |error| with the decoder, and return.
24 #define RETURN_ON_FAILURE(result, log, error) \ 24 #define RETURN_ON_FAILURE(result, log, error) \
25 do { \ 25 do { \
26 if (!(result)) { \ 26 if (!(result)) { \
27 DLOG(ERROR) << log; \ 27 DLOG(ERROR) << log; \
28 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( \ 28 base::MessageLoop::current()->PostTask( \
29 &AndroidVideoDecodeAccelerator::NotifyError, \ 29 FROM_HERE, \
30 base::AsWeakPtr(this), error)); \ 30 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, \
31 state_ = ERROR; \ 31 weak_this_factory_.GetWeakPtr(), \
32 return; \ 32 error)); \
33 } \ 33 state_ = ERROR; \
34 return; \
35 } \
34 } while (0) 36 } while (0)
35 37
36 // TODO(dwkang): We only need kMaxVideoFrames to pass media stack's prerolling 38 // TODO(dwkang): We only need kMaxVideoFrames to pass media stack's prerolling
37 // phase, but 1 is added due to crbug.com/176036. This should be tuned when we 39 // phase, but 1 is added due to crbug.com/176036. This should be tuned when we
38 // have actual use case. 40 // have actual use case.
39 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; 41 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 };
40 42
41 // Max number of bitstreams notified to the client with 43 // Max number of bitstreams notified to the client with
42 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. 44 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
43 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; 45 enum { kMaxBitstreamsNotifiedInAdvance = 32 };
(...skipping 22 matching lines...) Expand all
66 68
67 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 69 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
68 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, 70 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder,
69 const base::Callback<bool(void)>& make_context_current) 71 const base::Callback<bool(void)>& make_context_current)
70 : client_(NULL), 72 : client_(NULL),
71 make_context_current_(make_context_current), 73 make_context_current_(make_context_current),
72 codec_(media::kCodecH264), 74 codec_(media::kCodecH264),
73 state_(NO_ERROR), 75 state_(NO_ERROR),
74 surface_texture_id_(0), 76 surface_texture_id_(0),
75 picturebuffers_requested_(false), 77 picturebuffers_requested_(false),
76 gl_decoder_(decoder) {} 78 gl_decoder_(decoder),
79 weak_this_factory_(this) {}
77 80
78 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 81 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
79 DCHECK(thread_checker_.CalledOnValidThread()); 82 DCHECK(thread_checker_.CalledOnValidThread());
80 } 83 }
81 84
82 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 85 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
83 Client* client) { 86 Client* client) {
84 DCHECK(!media_codec_); 87 DCHECK(!media_codec_);
85 DCHECK(thread_checker_.CalledOnValidThread()); 88 DCHECK(thread_checker_.CalledOnValidThread());
86 89
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 gl_decoder_->RestoreTextureUnitBindings(0); 128 gl_decoder_->RestoreTextureUnitBindings(0);
126 gl_decoder_->RestoreActiveTexture(); 129 gl_decoder_->RestoreActiveTexture();
127 130
128 surface_texture_ = new gfx::SurfaceTexture(surface_texture_id_); 131 surface_texture_ = new gfx::SurfaceTexture(surface_texture_id_);
129 132
130 if (!ConfigureMediaCodec()) { 133 if (!ConfigureMediaCodec()) {
131 LOG(ERROR) << "Failed to create MediaCodec instance."; 134 LOG(ERROR) << "Failed to create MediaCodec instance.";
132 return false; 135 return false;
133 } 136 }
134 137
135 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
136 &AndroidVideoDecodeAccelerator::NotifyInitializeDone,
137 base::AsWeakPtr(this)));
138 return true; 138 return true;
139 } 139 }
140 140
141 void AndroidVideoDecodeAccelerator::DoIOTask() { 141 void AndroidVideoDecodeAccelerator::DoIOTask() {
142 DCHECK(thread_checker_.CalledOnValidThread());
142 if (state_ == ERROR) { 143 if (state_ == ERROR) {
143 return; 144 return;
144 } 145 }
145 146
146 QueueInput(); 147 QueueInput();
147 DequeueOutput(); 148 DequeueOutput();
148 } 149 }
149 150
150 void AndroidVideoDecodeAccelerator::QueueInput() { 151 void AndroidVideoDecodeAccelerator::QueueInput() {
152 DCHECK(thread_checker_.CalledOnValidThread());
151 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) 153 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
152 return; 154 return;
153 if (pending_bitstream_buffers_.empty()) 155 if (pending_bitstream_buffers_.empty())
154 return; 156 return;
155 157
156 int input_buf_index = 0; 158 int input_buf_index = 0;
157 media::MediaCodecStatus status = media_codec_->DequeueInputBuffer( 159 media::MediaCodecStatus status = media_codec_->DequeueInputBuffer(
158 NoWaitTimeOut(), &input_buf_index); 160 NoWaitTimeOut(), &input_buf_index);
159 if (status != media::MEDIA_CODEC_OK) { 161 if (status != media::MEDIA_CODEC_OK) {
160 DCHECK(status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER || 162 DCHECK(status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER ||
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 "Failed to QueueInputBuffer: " << status, 198 "Failed to QueueInputBuffer: " << status,
197 PLATFORM_FAILURE); 199 PLATFORM_FAILURE);
198 200
199 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output 201 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
200 // will be returned from the bitstream buffer. However, MediaCodec API is 202 // will be returned from the bitstream buffer. However, MediaCodec API is
201 // not enough to guarantee it. 203 // not enough to guarantee it.
202 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to 204 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
203 // keep getting more bitstreams from the client, and throttle them by using 205 // keep getting more bitstreams from the client, and throttle them by using
204 // |bitstreams_notified_in_advance_|. 206 // |bitstreams_notified_in_advance_|.
205 // TODO(dwkang): check if there is a way to remove this workaround. 207 // TODO(dwkang): check if there is a way to remove this workaround.
206 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 208 base::MessageLoop::current()->PostTask(
207 &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 209 FROM_HERE,
208 base::AsWeakPtr(this), bitstream_buffer.id())); 210 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
211 weak_this_factory_.GetWeakPtr(),
212 bitstream_buffer.id()));
209 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id()); 213 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
210 } 214 }
211 215
212 void AndroidVideoDecodeAccelerator::DequeueOutput() { 216 void AndroidVideoDecodeAccelerator::DequeueOutput() {
217 DCHECK(thread_checker_.CalledOnValidThread());
213 if (picturebuffers_requested_ && output_picture_buffers_.empty()) 218 if (picturebuffers_requested_ && output_picture_buffers_.empty())
214 return; 219 return;
215 220
216 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) { 221 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) {
217 // Don't have any picture buffer to send. Need to wait more. 222 // Don't have any picture buffer to send. Need to wait more.
218 return; 223 return;
219 } 224 }
220 225
221 bool eos = false; 226 bool eos = false;
222 base::TimeDelta timestamp; 227 base::TimeDelta timestamp;
223 int32 buf_index = 0; 228 int32 buf_index = 0;
224 do { 229 do {
225 size_t offset = 0; 230 size_t offset = 0;
226 size_t size = 0; 231 size_t size = 0;
227 232
228 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 233 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
229 NoWaitTimeOut(), &buf_index, &offset, &size, &timestamp, &eos, NULL); 234 NoWaitTimeOut(), &buf_index, &offset, &size, &timestamp, &eos, NULL);
230 switch (status) { 235 switch (status) {
231 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 236 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
232 case media::MEDIA_CODEC_ERROR: 237 case media::MEDIA_CODEC_ERROR:
233 return; 238 return;
234 239
235 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 240 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
236 int32 width, height; 241 int32 width, height;
237 media_codec_->GetOutputFormat(&width, &height); 242 media_codec_->GetOutputFormat(&width, &height);
238 243
239 if (!picturebuffers_requested_) { 244 if (!picturebuffers_requested_) {
240 picturebuffers_requested_ = true; 245 picturebuffers_requested_ = true;
241 size_ = gfx::Size(width, height); 246 size_ = gfx::Size(width, height);
242 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 247 base::MessageLoop::current()->PostTask(
243 &AndroidVideoDecodeAccelerator::RequestPictureBuffers, 248 FROM_HERE,
244 base::AsWeakPtr(this))); 249 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
250 weak_this_factory_.GetWeakPtr()));
245 } else { 251 } else {
246 // Dynamic resolution change support is not specified by the Android 252 // Dynamic resolution change support is not specified by the Android
247 // platform at and before JB-MR1, so it's not possible to smoothly 253 // platform at and before JB-MR1, so it's not possible to smoothly
248 // continue playback at this point. Instead, error out immediately, 254 // continue playback at this point. Instead, error out immediately,
249 // expecting clients to Reset() as appropriate to avoid this. 255 // expecting clients to Reset() as appropriate to avoid this.
250 // b/7093648 256 // b/7093648
251 RETURN_ON_FAILURE(size_ == gfx::Size(width, height), 257 RETURN_ON_FAILURE(size_ == gfx::Size(width, height),
252 "Dynamic resolution change is not supported.", 258 "Dynamic resolution change is not supported.",
253 PLATFORM_FAILURE); 259 PLATFORM_FAILURE);
254 } 260 }
(...skipping 26 matching lines...) Expand all
281 // Unfortunately neither is possible: 287 // Unfortunately neither is possible:
282 // 1) MediaCodec's use of SurfaceTexture is a singleton, and the texture 288 // 1) MediaCodec's use of SurfaceTexture is a singleton, and the texture
283 // written to can't change during the codec's lifetime. b/11990461 289 // written to can't change during the codec's lifetime. b/11990461
284 // 2) The ByteBuffer is likely to contain the pixels in a vendor-specific, 290 // 2) The ByteBuffer is likely to contain the pixels in a vendor-specific,
285 // opaque/non-standard format. It's not possible to negotiate the decoder 291 // opaque/non-standard format. It's not possible to negotiate the decoder
286 // to emit a specific colorspace, even using HW CSC. b/10706245 292 // to emit a specific colorspace, even using HW CSC. b/10706245
287 // So, we live with these two extra copies per picture :( 293 // So, we live with these two extra copies per picture :(
288 media_codec_->ReleaseOutputBuffer(buf_index, true); 294 media_codec_->ReleaseOutputBuffer(buf_index, true);
289 295
290 if (eos) { 296 if (eos) {
291 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 297 base::MessageLoop::current()->PostTask(
292 &AndroidVideoDecodeAccelerator::NotifyFlushDone, 298 FROM_HERE,
293 base::AsWeakPtr(this))); 299 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
300 weak_this_factory_.GetWeakPtr()));
294 } else { 301 } else {
295 int64 bitstream_buffer_id = timestamp.InMicroseconds(); 302 int64 bitstream_buffer_id = timestamp.InMicroseconds();
296 SendCurrentSurfaceToClient(static_cast<int32>(bitstream_buffer_id)); 303 SendCurrentSurfaceToClient(static_cast<int32>(bitstream_buffer_id));
297 304
298 // Removes ids former or equal than the id from decoder. Note that 305 // Removes ids former or equal than the id from decoder. Note that
299 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder 306 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder
300 // because of frame reordering issue. We just maintain this roughly and use 307 // because of frame reordering issue. We just maintain this roughly and use
301 // for the throttling purpose. 308 // for the throttling purpose.
302 std::list<int32>::iterator it; 309 std::list<int32>::iterator it;
303 for (it = bitstreams_notified_in_advance_.begin(); 310 for (it = bitstreams_notified_in_advance_.begin();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 // because: 358 // because:
352 // 1. Once we call detachFrameGLContext(), it deletes the texture previous 359 // 1. Once we call detachFrameGLContext(), it deletes the texture previous
353 // attached. 360 // attached.
354 // 2. SurfaceTexture requires us to apply a transform matrix when we show 361 // 2. SurfaceTexture requires us to apply a transform matrix when we show
355 // the texture. 362 // the texture.
356 copier_->DoCopyTexture(gl_decoder_.get(), GL_TEXTURE_EXTERNAL_OES, 363 copier_->DoCopyTexture(gl_decoder_.get(), GL_TEXTURE_EXTERNAL_OES,
357 GL_TEXTURE_2D, surface_texture_id_, 364 GL_TEXTURE_2D, surface_texture_id_,
358 picture_buffer_texture_id, 0, size_.width(), 365 picture_buffer_texture_id, 0, size_.width(),
359 size_.height(), false, false, false); 366 size_.height(), false, false, false);
360 367
361 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 368 base::MessageLoop::current()->PostTask(
362 &AndroidVideoDecodeAccelerator::NotifyPictureReady, 369 FROM_HERE,
363 base::AsWeakPtr(this), media::Picture(picture_buffer_id, bitstream_id))); 370 base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
371 weak_this_factory_.GetWeakPtr(),
372 media::Picture(picture_buffer_id, bitstream_id)));
364 } 373 }
365 374
366 void AndroidVideoDecodeAccelerator::Decode( 375 void AndroidVideoDecodeAccelerator::Decode(
367 const media::BitstreamBuffer& bitstream_buffer) { 376 const media::BitstreamBuffer& bitstream_buffer) {
368 DCHECK(thread_checker_.CalledOnValidThread()); 377 DCHECK(thread_checker_.CalledOnValidThread());
369 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) { 378 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) {
370 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 379 base::MessageLoop::current()->PostTask(
371 &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 380 FROM_HERE,
372 base::AsWeakPtr(this), bitstream_buffer.id())); 381 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
382 weak_this_factory_.GetWeakPtr(),
383 bitstream_buffer.id()));
373 return; 384 return;
374 } 385 }
375 386
376 pending_bitstream_buffers_.push( 387 pending_bitstream_buffers_.push(
377 std::make_pair(bitstream_buffer, base::Time::Now())); 388 std::make_pair(bitstream_buffer, base::Time::Now()));
378 389
379 DoIOTask(); 390 DoIOTask();
380 } 391 }
381 392
382 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 393 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 DoIOTask(); 432 DoIOTask();
422 } 433 }
423 434
424 void AndroidVideoDecodeAccelerator::Flush() { 435 void AndroidVideoDecodeAccelerator::Flush() {
425 DCHECK(thread_checker_.CalledOnValidThread()); 436 DCHECK(thread_checker_.CalledOnValidThread());
426 437
427 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 438 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
428 } 439 }
429 440
430 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { 441 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
442 DCHECK(thread_checker_.CalledOnValidThread());
431 DCHECK(surface_texture_.get()); 443 DCHECK(surface_texture_.get());
432 444
433 gfx::ScopedJavaSurface surface(surface_texture_.get()); 445 gfx::ScopedJavaSurface surface(surface_texture_.get());
434 446
435 // Pass a dummy 320x240 canvas size and let the codec signal the real size 447 // Pass a dummy 320x240 canvas size and let the codec signal the real size
436 // when it's known from the bitstream. 448 // when it's known from the bitstream.
437 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( 449 media_codec_.reset(media::VideoCodecBridge::CreateDecoder(
438 codec_, false, gfx::Size(320, 240), surface.j_surface().obj(), NULL)); 450 codec_, false, gfx::Size(320, 240), surface.j_surface().obj(), NULL));
439 if (!media_codec_) 451 if (!media_codec_)
440 return false; 452 return false;
441 453
442 io_timer_.Start(FROM_HERE, 454 io_timer_.Start(FROM_HERE,
443 DecodePollDelay(), 455 DecodePollDelay(),
444 this, 456 this,
445 &AndroidVideoDecodeAccelerator::DoIOTask); 457 &AndroidVideoDecodeAccelerator::DoIOTask);
446 return true; 458 return true;
447 } 459 }
448 460
449 void AndroidVideoDecodeAccelerator::Reset() { 461 void AndroidVideoDecodeAccelerator::Reset() {
450 DCHECK(thread_checker_.CalledOnValidThread()); 462 DCHECK(thread_checker_.CalledOnValidThread());
451 463
452 while (!pending_bitstream_buffers_.empty()) { 464 while (!pending_bitstream_buffers_.empty()) {
453 int32 bitstream_buffer_id = pending_bitstream_buffers_.front().first.id(); 465 int32 bitstream_buffer_id = pending_bitstream_buffers_.front().first.id();
454 pending_bitstream_buffers_.pop(); 466 pending_bitstream_buffers_.pop();
455 467
456 if (bitstream_buffer_id != -1) { 468 if (bitstream_buffer_id != -1) {
457 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 469 base::MessageLoop::current()->PostTask(
458 &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 470 FROM_HERE,
459 base::AsWeakPtr(this), bitstream_buffer_id)); 471 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
472 weak_this_factory_.GetWeakPtr(),
473 bitstream_buffer_id));
460 } 474 }
461 } 475 }
462 bitstreams_notified_in_advance_.clear(); 476 bitstreams_notified_in_advance_.clear();
463 477
464 for (OutputBufferMap::iterator it = output_picture_buffers_.begin(); 478 for (OutputBufferMap::iterator it = output_picture_buffers_.begin();
465 it != output_picture_buffers_.end(); 479 it != output_picture_buffers_.end();
466 ++it) { 480 ++it) {
467 client_->DismissPictureBuffer(it->first); 481 client_->DismissPictureBuffer(it->first);
468 dismissed_picture_ids_.insert(it->first); 482 dismissed_picture_ids_.insert(it->first);
469 } 483 }
470 output_picture_buffers_.clear(); 484 output_picture_buffers_.clear();
471 std::queue<int32> empty; 485 std::queue<int32> empty;
472 std::swap(free_picture_ids_, empty); 486 std::swap(free_picture_ids_, empty);
473 CHECK(free_picture_ids_.empty()); 487 CHECK(free_picture_ids_.empty());
474 picturebuffers_requested_ = false; 488 picturebuffers_requested_ = false;
475 489
476 // On some devices, and up to at least JB-MR1, 490 // On some devices, and up to at least JB-MR1,
477 // - flush() can fail after EOS (b/8125974); and 491 // - flush() can fail after EOS (b/8125974); and
478 // - mid-stream resolution change is unsupported (b/7093648). 492 // - mid-stream resolution change is unsupported (b/7093648).
479 // To cope with these facts, we always stop & restart the codec on Reset(). 493 // To cope with these facts, we always stop & restart the codec on Reset().
480 io_timer_.Stop(); 494 io_timer_.Stop();
481 media_codec_->Stop(); 495 media_codec_->Stop();
482 ConfigureMediaCodec(); 496 ConfigureMediaCodec();
483 state_ = NO_ERROR; 497 state_ = NO_ERROR;
484 498
485 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 499 base::MessageLoop::current()->PostTask(
486 &AndroidVideoDecodeAccelerator::NotifyResetDone, base::AsWeakPtr(this))); 500 FROM_HERE,
501 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
502 weak_this_factory_.GetWeakPtr()));
487 } 503 }
488 504
489 void AndroidVideoDecodeAccelerator::Destroy() { 505 void AndroidVideoDecodeAccelerator::Destroy() {
490 DCHECK(thread_checker_.CalledOnValidThread()); 506 DCHECK(thread_checker_.CalledOnValidThread());
491 507
508 weak_this_factory_.InvalidateWeakPtrs();
492 if (media_codec_) { 509 if (media_codec_) {
493 io_timer_.Stop(); 510 io_timer_.Stop();
494 media_codec_->Stop(); 511 media_codec_->Stop();
495 } 512 }
496 if (surface_texture_id_) 513 if (surface_texture_id_)
497 glDeleteTextures(1, &surface_texture_id_); 514 glDeleteTextures(1, &surface_texture_id_);
498 if (copier_) 515 if (copier_)
499 copier_->Destroy(); 516 copier_->Destroy();
500 delete this; 517 delete this;
501 } 518 }
502 519
503 void AndroidVideoDecodeAccelerator::NotifyInitializeDone() {
504 client_->NotifyInitializeDone();
505 }
506
507 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 520 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
508 client_->ProvidePictureBuffers(kNumPictureBuffers, size_, GL_TEXTURE_2D); 521 client_->ProvidePictureBuffers(kNumPictureBuffers, size_, GL_TEXTURE_2D);
509 } 522 }
510 523
511 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 524 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
512 const media::Picture& picture) { 525 const media::Picture& picture) {
513 client_->PictureReady(picture); 526 client_->PictureReady(picture);
514 } 527 }
515 528
516 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 529 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
517 int input_buffer_id) { 530 int input_buffer_id) {
518 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 531 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
519 } 532 }
520 533
521 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 534 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
522 client_->NotifyFlushDone(); 535 client_->NotifyFlushDone();
523 } 536 }
524 537
525 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 538 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
526 client_->NotifyResetDone(); 539 client_->NotifyResetDone();
527 } 540 }
528 541
529 void AndroidVideoDecodeAccelerator::NotifyError( 542 void AndroidVideoDecodeAccelerator::NotifyError(
530 media::VideoDecodeAccelerator::Error error) { 543 media::VideoDecodeAccelerator::Error error) {
531 client_->NotifyError(error); 544 client_->NotifyError(error);
532 } 545 }
533 546
534 } // namespace content 547 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698