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

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: 85629196 fischman@ comments. 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 gl_decoder_->RestoreTextureUnitBindings(0); 125 gl_decoder_->RestoreTextureUnitBindings(0);
123 gl_decoder_->RestoreActiveTexture(); 126 gl_decoder_->RestoreActiveTexture();
124 127
125 surface_texture_ = gfx::SurfaceTexture::Create(surface_texture_id_); 128 surface_texture_ = gfx::SurfaceTexture::Create(surface_texture_id_);
126 129
127 if (!ConfigureMediaCodec()) { 130 if (!ConfigureMediaCodec()) {
128 LOG(ERROR) << "Failed to create MediaCodec instance."; 131 LOG(ERROR) << "Failed to create MediaCodec instance.";
129 return false; 132 return false;
130 } 133 }
131 134
132 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
133 &AndroidVideoDecodeAccelerator::NotifyInitializeDone,
134 base::AsWeakPtr(this)));
135 return true; 135 return true;
136 } 136 }
137 137
138 void AndroidVideoDecodeAccelerator::DoIOTask() { 138 void AndroidVideoDecodeAccelerator::DoIOTask() {
139 DCHECK(thread_checker_.CalledOnValidThread());
139 if (state_ == ERROR) { 140 if (state_ == ERROR) {
140 return; 141 return;
141 } 142 }
142 143
143 QueueInput(); 144 QueueInput();
144 DequeueOutput(); 145 DequeueOutput();
145 } 146 }
146 147
147 void AndroidVideoDecodeAccelerator::QueueInput() { 148 void AndroidVideoDecodeAccelerator::QueueInput() {
149 DCHECK(thread_checker_.CalledOnValidThread());
148 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) 150 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
149 return; 151 return;
150 if (pending_bitstream_buffers_.empty()) 152 if (pending_bitstream_buffers_.empty())
151 return; 153 return;
152 154
153 int input_buf_index = 0; 155 int input_buf_index = 0;
154 media::MediaCodecStatus status = media_codec_->DequeueInputBuffer( 156 media::MediaCodecStatus status = media_codec_->DequeueInputBuffer(
155 NoWaitTimeOut(), &input_buf_index); 157 NoWaitTimeOut(), &input_buf_index);
156 if (status != media::MEDIA_CODEC_OK) { 158 if (status != media::MEDIA_CODEC_OK) {
157 DCHECK(status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER || 159 DCHECK(status == media::MEDIA_CODEC_DEQUEUE_INPUT_AGAIN_LATER ||
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 "Failed to QueueInputBuffer: " << status, 195 "Failed to QueueInputBuffer: " << status,
194 PLATFORM_FAILURE); 196 PLATFORM_FAILURE);
195 197
196 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output 198 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
197 // will be returned from the bitstream buffer. However, MediaCodec API is 199 // will be returned from the bitstream buffer. However, MediaCodec API is
198 // not enough to guarantee it. 200 // not enough to guarantee it.
199 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to 201 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
200 // keep getting more bitstreams from the client, and throttle them by using 202 // keep getting more bitstreams from the client, and throttle them by using
201 // |bitstreams_notified_in_advance_|. 203 // |bitstreams_notified_in_advance_|.
202 // TODO(dwkang): check if there is a way to remove this workaround. 204 // TODO(dwkang): check if there is a way to remove this workaround.
203 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 205 base::MessageLoop::current()->PostTask(
204 &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 206 FROM_HERE,
205 base::AsWeakPtr(this), bitstream_buffer.id())); 207 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
208 weak_this_factory_.GetWeakPtr(),
209 bitstream_buffer.id()));
206 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id()); 210 bitstreams_notified_in_advance_.push_back(bitstream_buffer.id());
207 } 211 }
208 212
209 void AndroidVideoDecodeAccelerator::DequeueOutput() { 213 void AndroidVideoDecodeAccelerator::DequeueOutput() {
214 DCHECK(thread_checker_.CalledOnValidThread());
210 if (picturebuffers_requested_ && output_picture_buffers_.empty()) 215 if (picturebuffers_requested_ && output_picture_buffers_.empty())
211 return; 216 return;
212 217
213 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) { 218 if (!output_picture_buffers_.empty() && free_picture_ids_.empty()) {
214 // Don't have any picture buffer to send. Need to wait more. 219 // Don't have any picture buffer to send. Need to wait more.
215 return; 220 return;
216 } 221 }
217 222
218 bool eos = false; 223 bool eos = false;
219 base::TimeDelta timestamp; 224 base::TimeDelta timestamp;
220 int32 buf_index = 0; 225 int32 buf_index = 0;
221 do { 226 do {
222 size_t offset = 0; 227 size_t offset = 0;
223 size_t size = 0; 228 size_t size = 0;
224 229
225 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 230 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
226 NoWaitTimeOut(), &buf_index, &offset, &size, &timestamp, &eos, NULL); 231 NoWaitTimeOut(), &buf_index, &offset, &size, &timestamp, &eos, NULL);
227 switch (status) { 232 switch (status) {
228 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 233 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
229 case media::MEDIA_CODEC_ERROR: 234 case media::MEDIA_CODEC_ERROR:
230 return; 235 return;
231 236
232 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 237 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
233 int32 width, height; 238 int32 width, height;
234 media_codec_->GetOutputFormat(&width, &height); 239 media_codec_->GetOutputFormat(&width, &height);
235 240
236 if (!picturebuffers_requested_) { 241 if (!picturebuffers_requested_) {
237 picturebuffers_requested_ = true; 242 picturebuffers_requested_ = true;
238 size_ = gfx::Size(width, height); 243 size_ = gfx::Size(width, height);
239 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 244 base::MessageLoop::current()->PostTask(
240 &AndroidVideoDecodeAccelerator::RequestPictureBuffers, 245 FROM_HERE,
241 base::AsWeakPtr(this))); 246 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
247 weak_this_factory_.GetWeakPtr()));
242 } else { 248 } else {
243 // Dynamic resolution change support is not specified by the Android 249 // Dynamic resolution change support is not specified by the Android
244 // platform at and before JB-MR1, so it's not possible to smoothly 250 // platform at and before JB-MR1, so it's not possible to smoothly
245 // continue playback at this point. Instead, error out immediately, 251 // continue playback at this point. Instead, error out immediately,
246 // expecting clients to Reset() as appropriate to avoid this. 252 // expecting clients to Reset() as appropriate to avoid this.
247 // b/7093648 253 // b/7093648
248 RETURN_ON_FAILURE(size_ == gfx::Size(width, height), 254 RETURN_ON_FAILURE(size_ == gfx::Size(width, height),
249 "Dynamic resolution change is not supported.", 255 "Dynamic resolution change is not supported.",
250 PLATFORM_FAILURE); 256 PLATFORM_FAILURE);
251 } 257 }
(...skipping 26 matching lines...) Expand all
278 // Unfortunately neither is possible: 284 // Unfortunately neither is possible:
279 // 1) MediaCodec's use of SurfaceTexture is a singleton, and the texture 285 // 1) MediaCodec's use of SurfaceTexture is a singleton, and the texture
280 // written to can't change during the codec's lifetime. b/11990461 286 // written to can't change during the codec's lifetime. b/11990461
281 // 2) The ByteBuffer is likely to contain the pixels in a vendor-specific, 287 // 2) The ByteBuffer is likely to contain the pixels in a vendor-specific,
282 // opaque/non-standard format. It's not possible to negotiate the decoder 288 // opaque/non-standard format. It's not possible to negotiate the decoder
283 // to emit a specific colorspace, even using HW CSC. b/10706245 289 // to emit a specific colorspace, even using HW CSC. b/10706245
284 // So, we live with these two extra copies per picture :( 290 // So, we live with these two extra copies per picture :(
285 media_codec_->ReleaseOutputBuffer(buf_index, true); 291 media_codec_->ReleaseOutputBuffer(buf_index, true);
286 292
287 if (eos) { 293 if (eos) {
288 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 294 base::MessageLoop::current()->PostTask(
289 &AndroidVideoDecodeAccelerator::NotifyFlushDone, 295 FROM_HERE,
290 base::AsWeakPtr(this))); 296 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
297 weak_this_factory_.GetWeakPtr()));
291 } else { 298 } else {
292 int64 bitstream_buffer_id = timestamp.InMicroseconds(); 299 int64 bitstream_buffer_id = timestamp.InMicroseconds();
293 SendCurrentSurfaceToClient(static_cast<int32>(bitstream_buffer_id)); 300 SendCurrentSurfaceToClient(static_cast<int32>(bitstream_buffer_id));
294 301
295 // Removes ids former or equal than the id from decoder. Note that 302 // Removes ids former or equal than the id from decoder. Note that
296 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder 303 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder
297 // because of frame reordering issue. We just maintain this roughly and use 304 // because of frame reordering issue. We just maintain this roughly and use
298 // for the throttling purpose. 305 // for the throttling purpose.
299 std::list<int32>::iterator it; 306 std::list<int32>::iterator it;
300 for (it = bitstreams_notified_in_advance_.begin(); 307 for (it = bitstreams_notified_in_advance_.begin();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 // because: 355 // because:
349 // 1. Once we call detachFrameGLContext(), it deletes the texture previous 356 // 1. Once we call detachFrameGLContext(), it deletes the texture previous
350 // attached. 357 // attached.
351 // 2. SurfaceTexture requires us to apply a transform matrix when we show 358 // 2. SurfaceTexture requires us to apply a transform matrix when we show
352 // the texture. 359 // the texture.
353 copier_->DoCopyTexture(gl_decoder_.get(), GL_TEXTURE_EXTERNAL_OES, 360 copier_->DoCopyTexture(gl_decoder_.get(), GL_TEXTURE_EXTERNAL_OES,
354 GL_TEXTURE_2D, surface_texture_id_, 361 GL_TEXTURE_2D, surface_texture_id_,
355 picture_buffer_texture_id, 0, size_.width(), 362 picture_buffer_texture_id, 0, size_.width(),
356 size_.height(), false, false, false); 363 size_.height(), false, false, false);
357 364
358 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 365 base::MessageLoop::current()->PostTask(
359 &AndroidVideoDecodeAccelerator::NotifyPictureReady, 366 FROM_HERE,
360 base::AsWeakPtr(this), media::Picture(picture_buffer_id, bitstream_id))); 367 base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
368 weak_this_factory_.GetWeakPtr(),
369 media::Picture(picture_buffer_id, bitstream_id)));
361 } 370 }
362 371
363 void AndroidVideoDecodeAccelerator::Decode( 372 void AndroidVideoDecodeAccelerator::Decode(
364 const media::BitstreamBuffer& bitstream_buffer) { 373 const media::BitstreamBuffer& bitstream_buffer) {
365 DCHECK(thread_checker_.CalledOnValidThread()); 374 DCHECK(thread_checker_.CalledOnValidThread());
366 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) { 375 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) {
367 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 376 base::MessageLoop::current()->PostTask(
368 &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 377 FROM_HERE,
369 base::AsWeakPtr(this), bitstream_buffer.id())); 378 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
379 weak_this_factory_.GetWeakPtr(),
380 bitstream_buffer.id()));
370 return; 381 return;
371 } 382 }
372 383
373 pending_bitstream_buffers_.push( 384 pending_bitstream_buffers_.push(
374 std::make_pair(bitstream_buffer, base::Time::Now())); 385 std::make_pair(bitstream_buffer, base::Time::Now()));
375 386
376 DoIOTask(); 387 DoIOTask();
377 } 388 }
378 389
379 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 390 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 DoIOTask(); 429 DoIOTask();
419 } 430 }
420 431
421 void AndroidVideoDecodeAccelerator::Flush() { 432 void AndroidVideoDecodeAccelerator::Flush() {
422 DCHECK(thread_checker_.CalledOnValidThread()); 433 DCHECK(thread_checker_.CalledOnValidThread());
423 434
424 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 435 Decode(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
425 } 436 }
426 437
427 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() { 438 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodec() {
439 DCHECK(thread_checker_.CalledOnValidThread());
428 DCHECK(surface_texture_.get()); 440 DCHECK(surface_texture_.get());
429 441
430 gfx::ScopedJavaSurface surface(surface_texture_.get()); 442 gfx::ScopedJavaSurface surface(surface_texture_.get());
431 443
432 // Pass a dummy 320x240 canvas size and let the codec signal the real size 444 // Pass a dummy 320x240 canvas size and let the codec signal the real size
433 // when it's known from the bitstream. 445 // when it's known from the bitstream.
434 media_codec_.reset(media::VideoCodecBridge::CreateDecoder( 446 media_codec_.reset(media::VideoCodecBridge::CreateDecoder(
435 codec_, false, gfx::Size(320, 240), surface.j_surface().obj(), NULL)); 447 codec_, false, gfx::Size(320, 240), surface.j_surface().obj(), NULL));
436 if (!media_codec_) 448 if (!media_codec_)
437 return false; 449 return false;
438 450
439 io_timer_.Start(FROM_HERE, 451 io_timer_.Start(FROM_HERE,
440 DecodePollDelay(), 452 DecodePollDelay(),
441 this, 453 this,
442 &AndroidVideoDecodeAccelerator::DoIOTask); 454 &AndroidVideoDecodeAccelerator::DoIOTask);
443 return true; 455 return true;
444 } 456 }
445 457
446 void AndroidVideoDecodeAccelerator::Reset() { 458 void AndroidVideoDecodeAccelerator::Reset() {
447 DCHECK(thread_checker_.CalledOnValidThread()); 459 DCHECK(thread_checker_.CalledOnValidThread());
448 460
449 while (!pending_bitstream_buffers_.empty()) { 461 while (!pending_bitstream_buffers_.empty()) {
450 int32 bitstream_buffer_id = pending_bitstream_buffers_.front().first.id(); 462 int32 bitstream_buffer_id = pending_bitstream_buffers_.front().first.id();
451 pending_bitstream_buffers_.pop(); 463 pending_bitstream_buffers_.pop();
452 464
453 if (bitstream_buffer_id != -1) { 465 if (bitstream_buffer_id != -1) {
454 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 466 base::MessageLoop::current()->PostTask(
455 &AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 467 FROM_HERE,
456 base::AsWeakPtr(this), bitstream_buffer_id)); 468 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
469 weak_this_factory_.GetWeakPtr(),
470 bitstream_buffer_id));
457 } 471 }
458 } 472 }
459 bitstreams_notified_in_advance_.clear(); 473 bitstreams_notified_in_advance_.clear();
460 474
461 for (OutputBufferMap::iterator it = output_picture_buffers_.begin(); 475 for (OutputBufferMap::iterator it = output_picture_buffers_.begin();
462 it != output_picture_buffers_.end(); 476 it != output_picture_buffers_.end();
463 ++it) { 477 ++it) {
464 client_->DismissPictureBuffer(it->first); 478 client_->DismissPictureBuffer(it->first);
465 dismissed_picture_ids_.insert(it->first); 479 dismissed_picture_ids_.insert(it->first);
466 } 480 }
467 output_picture_buffers_.clear(); 481 output_picture_buffers_.clear();
468 std::queue<int32> empty; 482 std::queue<int32> empty;
469 std::swap(free_picture_ids_, empty); 483 std::swap(free_picture_ids_, empty);
470 CHECK(free_picture_ids_.empty()); 484 CHECK(free_picture_ids_.empty());
471 picturebuffers_requested_ = false; 485 picturebuffers_requested_ = false;
472 486
473 // On some devices, and up to at least JB-MR1, 487 // On some devices, and up to at least JB-MR1,
474 // - flush() can fail after EOS (b/8125974); and 488 // - flush() can fail after EOS (b/8125974); and
475 // - mid-stream resolution change is unsupported (b/7093648). 489 // - mid-stream resolution change is unsupported (b/7093648).
476 // To cope with these facts, we always stop & restart the codec on Reset(). 490 // To cope with these facts, we always stop & restart the codec on Reset().
477 io_timer_.Stop(); 491 io_timer_.Stop();
478 media_codec_->Stop(); 492 media_codec_->Stop();
479 ConfigureMediaCodec(); 493 ConfigureMediaCodec();
480 state_ = NO_ERROR; 494 state_ = NO_ERROR;
481 495
482 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 496 base::MessageLoop::current()->PostTask(
483 &AndroidVideoDecodeAccelerator::NotifyResetDone, base::AsWeakPtr(this))); 497 FROM_HERE,
498 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
499 weak_this_factory_.GetWeakPtr()));
484 } 500 }
485 501
486 void AndroidVideoDecodeAccelerator::Destroy() { 502 void AndroidVideoDecodeAccelerator::Destroy() {
487 DCHECK(thread_checker_.CalledOnValidThread()); 503 DCHECK(thread_checker_.CalledOnValidThread());
488 504
505 weak_this_factory_.InvalidateWeakPtrs();
489 if (media_codec_) { 506 if (media_codec_) {
490 io_timer_.Stop(); 507 io_timer_.Stop();
491 media_codec_->Stop(); 508 media_codec_->Stop();
492 } 509 }
493 if (surface_texture_id_) 510 if (surface_texture_id_)
494 glDeleteTextures(1, &surface_texture_id_); 511 glDeleteTextures(1, &surface_texture_id_);
495 if (copier_) 512 if (copier_)
496 copier_->Destroy(); 513 copier_->Destroy();
497 delete this; 514 delete this;
498 } 515 }
499 516
500 void AndroidVideoDecodeAccelerator::NotifyInitializeDone() {
501 client_->NotifyInitializeDone();
502 }
503
504 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 517 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
505 client_->ProvidePictureBuffers(kNumPictureBuffers, size_, GL_TEXTURE_2D); 518 client_->ProvidePictureBuffers(kNumPictureBuffers, size_, GL_TEXTURE_2D);
506 } 519 }
507 520
508 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 521 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
509 const media::Picture& picture) { 522 const media::Picture& picture) {
510 client_->PictureReady(picture); 523 client_->PictureReady(picture);
511 } 524 }
512 525
513 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 526 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
514 int input_buffer_id) { 527 int input_buffer_id) {
515 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 528 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
516 } 529 }
517 530
518 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 531 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
519 client_->NotifyFlushDone(); 532 client_->NotifyFlushDone();
520 } 533 }
521 534
522 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 535 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
523 client_->NotifyResetDone(); 536 client_->NotifyResetDone();
524 } 537 }
525 538
526 void AndroidVideoDecodeAccelerator::NotifyError( 539 void AndroidVideoDecodeAccelerator::NotifyError(
527 media::VideoDecodeAccelerator::Error error) { 540 media::VideoDecodeAccelerator::Error error) {
528 client_->NotifyError(error); 541 client_->NotifyError(error);
529 } 542 }
530 543
531 } // namespace content 544 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698