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

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

Issue 1313913003: Begin refactor of AVDA to support zero-copy. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cl feedback + rebased. Created 5 years, 3 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) 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 "base/trace_event/trace_event.h"
11 #include "content/common/gpu/gpu_channel.h" 12 #include "content/common/gpu/gpu_channel.h"
13 #include "content/common/gpu/media/avda_return_on_failure.h"
12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
13 #include "media/base/bitstream_buffer.h" 15 #include "media/base/bitstream_buffer.h"
14 #include "media/base/limits.h" 16 #include "media/base/limits.h"
15 #include "media/base/timestamp_constants.h" 17 #include "media/base/timestamp_constants.h"
16 #include "media/base/video_decoder_config.h" 18 #include "media/base/video_decoder_config.h"
17 #include "media/video/picture.h" 19 #include "media/video/picture.h"
18 #include "ui/gl/android/scoped_java_surface.h" 20 #include "ui/gl/android/scoped_java_surface.h"
19 #include "ui/gl/android/surface_texture.h" 21 #include "ui/gl/android/surface_texture.h"
20 #include "ui/gl/gl_bindings.h" 22 #include "ui/gl/gl_bindings.h"
21 23
22 namespace content { 24 namespace content {
23 25
24 // Helper macros for dealing with failure. If |result| evaluates false, emit
25 // |log| to ERROR, register |error| with the decoder, and return.
26 #define RETURN_ON_FAILURE(result, log, error) \
27 do { \
28 if (!(result)) { \
29 DLOG(ERROR) << log; \
30 base::MessageLoop::current()->PostTask( \
31 FROM_HERE, \
32 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, \
33 weak_this_factory_.GetWeakPtr(), \
34 error)); \
35 state_ = ERROR; \
36 return; \
37 } \
38 } while (0)
39
40 // TODO(dwkang): We only need kMaxVideoFrames to pass media stack's prerolling
41 // phase, but 1 is added due to crbug.com/176036. This should be tuned when we
42 // have actual use case.
43 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 };
44
45 // Max number of bitstreams notified to the client with 26 // Max number of bitstreams notified to the client with
46 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. 27 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
47 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; 28 enum { kMaxBitstreamsNotifiedInAdvance = 32 };
48 29
49 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) 30 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID)
50 // MediaCodec is only guaranteed to support baseline, but some devices may 31 // MediaCodec is only guaranteed to support baseline, but some devices may
51 // support others. Advertise support for all H264 profiles and let the 32 // support others. Advertise support for all H264 profiles and let the
52 // MediaCodec fail when decoding if it's not actually supported. It's assumed 33 // MediaCodec fail when decoding if it's not actually supported. It's assumed
53 // that consumers won't have software fallback for H264 on Android anyway. 34 // that consumers won't have software fallback for H264 on Android anyway.
54 static const media::VideoCodecProfile kSupportedH264Profiles[] = { 35 static const media::VideoCodecProfile kSupportedH264Profiles[] = {
(...skipping 28 matching lines...) Expand all
83 // reasonably device-agnostic way to fill in the "believes" above). 64 // reasonably device-agnostic way to fill in the "believes" above).
84 return base::TimeDelta::FromMilliseconds(10); 65 return base::TimeDelta::FromMilliseconds(10);
85 } 66 }
86 67
87 static inline const base::TimeDelta NoWaitTimeOut() { 68 static inline const base::TimeDelta NoWaitTimeOut() {
88 return base::TimeDelta::FromMicroseconds(0); 69 return base::TimeDelta::FromMicroseconds(0);
89 } 70 }
90 71
91 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 72 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
92 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder, 73 const base::WeakPtr<gpu::gles2::GLES2Decoder> decoder,
93 const base::Callback<bool(void)>& make_context_current) 74 const base::Callback<bool(void)>& make_context_current,
75 scoped_ptr<BackingStrategy> strategy)
94 : client_(NULL), 76 : client_(NULL),
95 make_context_current_(make_context_current), 77 make_context_current_(make_context_current),
96 codec_(media::kCodecH264), 78 codec_(media::kCodecH264),
97 state_(NO_ERROR), 79 state_(NO_ERROR),
98 surface_texture_id_(0), 80 surface_texture_id_(0),
99 picturebuffers_requested_(false), 81 picturebuffers_requested_(false),
100 gl_decoder_(decoder), 82 gl_decoder_(decoder),
83 strategy_(strategy.Pass()),
101 weak_this_factory_(this) {} 84 weak_this_factory_(this) {}
102 85
103 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 86 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
104 DCHECK(thread_checker_.CalledOnValidThread()); 87 DCHECK(thread_checker_.CalledOnValidThread());
105 } 88 }
106 89
107 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, 90 bool AndroidVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile,
108 Client* client) { 91 Client* client) {
109 DCHECK(!media_codec_); 92 DCHECK(!media_codec_);
110 DCHECK(thread_checker_.CalledOnValidThread()); 93 DCHECK(thread_checker_.CalledOnValidThread());
111 TRACE_EVENT0("media", "AVDA::Initialize"); 94 TRACE_EVENT0("media", "AVDA::Initialize");
112 95
113 client_ = client; 96 client_ = client;
114 codec_ = VideoCodecProfileToVideoCodec(profile); 97 codec_ = VideoCodecProfileToVideoCodec(profile);
115 98
99 strategy_->SetStateProvider(this);
100
116 bool profile_supported = codec_ == media::kCodecVP8; 101 bool profile_supported = codec_ == media::kCodecVP8;
117 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID) 102 #if defined(ENABLE_MEDIA_PIPELINE_ON_ANDROID)
118 profile_supported |= 103 profile_supported |=
119 (codec_ == media::kCodecVP9 || codec_ == media::kCodecH264); 104 (codec_ == media::kCodecVP9 || codec_ == media::kCodecH264);
120 #endif 105 #endif
121 106
122 if (!profile_supported) { 107 if (!profile_supported) {
123 LOG(ERROR) << "Unsupported profile: " << profile; 108 LOG(ERROR) << "Unsupported profile: " << profile;
124 return false; 109 return false;
125 } 110 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 188 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
204 pending_bitstream_buffers_.size()); 189 pending_bitstream_buffers_.size());
205 190
206 if (bitstream_buffer.id() == -1) { 191 if (bitstream_buffer.id() == -1) {
207 media_codec_->QueueEOS(input_buf_index); 192 media_codec_->QueueEOS(input_buf_index);
208 return; 193 return;
209 } 194 }
210 195
211 scoped_ptr<base::SharedMemory> shm( 196 scoped_ptr<base::SharedMemory> shm(
212 new base::SharedMemory(bitstream_buffer.handle(), true)); 197 new base::SharedMemory(bitstream_buffer.handle(), true));
213 RETURN_ON_FAILURE(shm->Map(bitstream_buffer.size()), 198 RETURN_ON_FAILURE(this, shm->Map(bitstream_buffer.size()),
214 "Failed to SharedMemory::Map()", UNREADABLE_INPUT); 199 "Failed to SharedMemory::Map()", UNREADABLE_INPUT);
215 200
216 const base::TimeDelta presentation_timestamp = 201 const base::TimeDelta presentation_timestamp =
217 bitstream_buffer.presentation_timestamp(); 202 bitstream_buffer.presentation_timestamp();
218 DCHECK(presentation_timestamp != media::kNoTimestamp()) 203 DCHECK(presentation_timestamp != media::kNoTimestamp())
219 << "Bitstream buffers must have valid presentation timestamps"; 204 << "Bitstream buffers must have valid presentation timestamps";
220 // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt 205 // There may already be a bitstream buffer with this timestamp, e.g., VP9 alt
221 // ref frames, but it's OK to overwrite it because we only expect a single 206 // ref frames, but it's OK to overwrite it because we only expect a single
222 // output frame to have that timestamp. AVDA clients only use the bitstream 207 // output frame to have that timestamp. AVDA clients only use the bitstream
223 // buffer id in the returned Pictures to map a bitstream buffer back to a 208 // buffer id in the returned Pictures to map a bitstream buffer back to a
224 // timestamp on their side, so either one of the bitstream buffer ids will 209 // timestamp on their side, so either one of the bitstream buffer ids will
225 // result in them finding the right timestamp. 210 // result in them finding the right timestamp.
226 bitstream_buffers_in_decoder_[presentation_timestamp] = bitstream_buffer.id(); 211 bitstream_buffers_in_decoder_[presentation_timestamp] = bitstream_buffer.id();
227 212
228 status = media_codec_->QueueInputBuffer( 213 status = media_codec_->QueueInputBuffer(
229 input_buf_index, static_cast<const uint8*>(shm->memory()), 214 input_buf_index, static_cast<const uint8*>(shm->memory()),
230 bitstream_buffer.size(), presentation_timestamp); 215 bitstream_buffer.size(), presentation_timestamp);
231 RETURN_ON_FAILURE(status == media::MEDIA_CODEC_OK, 216 RETURN_ON_FAILURE(this, status == media::MEDIA_CODEC_OK,
232 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE); 217 "Failed to QueueInputBuffer: " << status, PLATFORM_FAILURE);
233 218
234 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output 219 // We should call NotifyEndOfBitstreamBuffer(), when no more decoded output
235 // will be returned from the bitstream buffer. However, MediaCodec API is 220 // will be returned from the bitstream buffer. However, MediaCodec API is
236 // not enough to guarantee it. 221 // not enough to guarantee it.
237 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to 222 // So, here, we calls NotifyEndOfBitstreamBuffer() in advance in order to
238 // keep getting more bitstreams from the client, and throttle them by using 223 // keep getting more bitstreams from the client, and throttle them by using
239 // |bitstreams_notified_in_advance_|. 224 // |bitstreams_notified_in_advance_|.
240 // TODO(dwkang): check if there is a way to remove this workaround. 225 // TODO(dwkang): check if there is a way to remove this workaround.
241 base::MessageLoop::current()->PostTask( 226 base::MessageLoop::current()->PostTask(
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 base::MessageLoop::current()->PostTask( 271 base::MessageLoop::current()->PostTask(
287 FROM_HERE, 272 FROM_HERE,
288 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, 273 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
289 weak_this_factory_.GetWeakPtr())); 274 weak_this_factory_.GetWeakPtr()));
290 } else { 275 } else {
291 // Dynamic resolution change support is not specified by the Android 276 // Dynamic resolution change support is not specified by the Android
292 // platform at and before JB-MR1, so it's not possible to smoothly 277 // platform at and before JB-MR1, so it's not possible to smoothly
293 // continue playback at this point. Instead, error out immediately, 278 // continue playback at this point. Instead, error out immediately,
294 // expecting clients to Reset() as appropriate to avoid this. 279 // expecting clients to Reset() as appropriate to avoid this.
295 // b/7093648 280 // b/7093648
296 RETURN_ON_FAILURE(size_ == gfx::Size(width, height), 281 RETURN_ON_FAILURE(this, size_ == gfx::Size(width, height),
297 "Dynamic resolution change is not supported.", 282 "Dynamic resolution change is not supported.",
298 PLATFORM_FAILURE); 283 PLATFORM_FAILURE);
299 } 284 }
300 return; 285 return;
301 } 286 }
302 287
303 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 288 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
304 break; 289 break;
305 290
306 case media::MEDIA_CODEC_OK: 291 case media::MEDIA_CODEC_OK:
307 DCHECK_GE(buf_index, 0); 292 DCHECK_GE(buf_index, 0);
308 break; 293 break;
309 294
310 default: 295 default:
311 NOTREACHED(); 296 NOTREACHED();
312 break; 297 break;
313 } 298 }
314 } while (buf_index < 0); 299 } while (buf_index < 0);
315 300
316 // This ignores the emitted ByteBuffer and instead relies on rendering to the
317 // codec's SurfaceTexture and then copying from that texture to the client's
318 // PictureBuffer's texture. This means that each picture's data is written
319 // three times: once to the ByteBuffer, once to the SurfaceTexture, and once
320 // to the client's texture. It would be nicer to either:
321 // 1) Render directly to the client's texture from MediaCodec (one write); or
322 // 2) Upload the ByteBuffer to the client's texture (two writes).
323 // Unfortunately neither is possible:
324 // 1) MediaCodec's use of SurfaceTexture is a singleton, and the texture
325 // written to can't change during the codec's lifetime. b/11990461
326 // 2) The ByteBuffer is likely to contain the pixels in a vendor-specific,
327 // opaque/non-standard format. It's not possible to negotiate the decoder
328 // to emit a specific colorspace, even using HW CSC. b/10706245
329 // So, we live with these two extra copies per picture :(
330 {
331 TRACE_EVENT0("media", "AVDA::ReleaseOutputBuffer");
332 media_codec_->ReleaseOutputBuffer(buf_index, true);
333 }
334
335 if (eos) { 301 if (eos) {
302 media_codec_->ReleaseOutputBuffer(buf_index, false);
336 base::MessageLoop::current()->PostTask( 303 base::MessageLoop::current()->PostTask(
337 FROM_HERE, 304 FROM_HERE,
338 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone, 305 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
339 weak_this_factory_.GetWeakPtr())); 306 weak_this_factory_.GetWeakPtr()));
340 } else { 307 } else {
341 // Get the bitstream buffer id from the timestamp. 308 // Get the bitstream buffer id from the timestamp.
342 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); 309 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp);
343 // Require the decoder to output at most one frame for each distinct input 310 // Require the decoder to output at most one frame for each distinct input
344 // buffer timestamp. A VP9 alt ref frame is a case where an input buffer, 311 // buffer timestamp. A VP9 alt ref frame is a case where an input buffer,
345 // with a possibly unique timestamp, will not result in a corresponding 312 // with a possibly unique timestamp, will not result in a corresponding
346 // output frame. 313 // output frame.
347 CHECK(it != bitstream_buffers_in_decoder_.end()) 314 CHECK(it != bitstream_buffers_in_decoder_.end())
348 << "Unexpected output frame timestamp"; 315 << "Unexpected output frame timestamp";
349 const int32 bitstream_buffer_id = it->second; 316 const int32 bitstream_buffer_id = it->second;
350 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(), 317 bitstream_buffers_in_decoder_.erase(bitstream_buffers_in_decoder_.begin(),
351 ++it); 318 ++it);
352 SendCurrentSurfaceToClient(bitstream_buffer_id); 319 SendCurrentSurfaceToClient(buf_index, bitstream_buffer_id);
353 320
354 // Removes ids former or equal than the id from decoder. Note that 321 // Removes ids former or equal than the id from decoder. Note that
355 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder 322 // |bitstreams_notified_in_advance_| does not mean bitstream ids in decoder
356 // because of frame reordering issue. We just maintain this roughly and use 323 // because of frame reordering issue. We just maintain this roughly and use
357 // for the throttling purpose. 324 // for the throttling purpose.
358 for (auto bitstream_it = bitstreams_notified_in_advance_.begin(); 325 for (auto bitstream_it = bitstreams_notified_in_advance_.begin();
359 bitstream_it != bitstreams_notified_in_advance_.end(); 326 bitstream_it != bitstreams_notified_in_advance_.end();
360 ++bitstream_it) { 327 ++bitstream_it) {
361 if (*bitstream_it == bitstream_buffer_id) { 328 if (*bitstream_it == bitstream_buffer_id) {
362 bitstreams_notified_in_advance_.erase( 329 bitstreams_notified_in_advance_.erase(
363 bitstreams_notified_in_advance_.begin(), ++bitstream_it); 330 bitstreams_notified_in_advance_.begin(), ++bitstream_it);
364 break; 331 break;
365 } 332 }
366 } 333 }
367 } 334 }
368 } 335 }
369 336
370 void AndroidVideoDecodeAccelerator::SendCurrentSurfaceToClient( 337 void AndroidVideoDecodeAccelerator::SendCurrentSurfaceToClient(
338 int32 codec_buffer_index,
371 int32 bitstream_id) { 339 int32 bitstream_id) {
372 DCHECK(thread_checker_.CalledOnValidThread()); 340 DCHECK(thread_checker_.CalledOnValidThread());
373 DCHECK_NE(bitstream_id, -1); 341 DCHECK_NE(bitstream_id, -1);
374 DCHECK(!free_picture_ids_.empty()); 342 DCHECK(!free_picture_ids_.empty());
375 TRACE_EVENT0("media", "AVDA::SendCurrentSurfaceToClient"); 343 TRACE_EVENT0("media", "AVDA::SendCurrentSurfaceToClient");
376 344
377 RETURN_ON_FAILURE(make_context_current_.Run(), 345 RETURN_ON_FAILURE(this, make_context_current_.Run(),
378 "Failed to make this decoder's GL context current.", 346 "Failed to make this decoder's GL context current.",
379 PLATFORM_FAILURE); 347 PLATFORM_FAILURE);
380 348
381 int32 picture_buffer_id = free_picture_ids_.front(); 349 int32 picture_buffer_id = free_picture_ids_.front();
382 free_picture_ids_.pop(); 350 free_picture_ids_.pop();
383 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 351 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
384 352
385 {
386 TRACE_EVENT0("media", "AVDA::UpdateTexImage");
387 surface_texture_->UpdateTexImage();
388 }
389 float transfrom_matrix[16];
390 surface_texture_->GetTransformMatrix(transfrom_matrix);
391
392 OutputBufferMap::const_iterator i = 353 OutputBufferMap::const_iterator i =
393 output_picture_buffers_.find(picture_buffer_id); 354 output_picture_buffers_.find(picture_buffer_id);
394 RETURN_ON_FAILURE(i != output_picture_buffers_.end(), 355 RETURN_ON_FAILURE(this, i != output_picture_buffers_.end(),
395 "Can't find a PictureBuffer for " << picture_buffer_id, 356 "Can't find a PictureBuffer for " << picture_buffer_id,
396 PLATFORM_FAILURE); 357 PLATFORM_FAILURE);
397 uint32 picture_buffer_texture_id = i->second.texture_id();
398 358
399 RETURN_ON_FAILURE(gl_decoder_.get(), 359 // Connect the PictureBuffer to the decoded frame, via whatever
400 "Failed to get gles2 decoder instance.", 360 // mechanism the strategy likes.
401 ILLEGAL_STATE); 361 strategy_->AssignCurrentSurfaceToPictureBuffer(codec_buffer_index, i->second);
402 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
403 // needed because it takes 10s of milliseconds to initialize.
404 if (!copier_) {
405 copier_.reset(new gpu::CopyTextureCHROMIUMResourceManager());
406 copier_->Initialize(gl_decoder_.get());
407 }
408
409 // Here, we copy |surface_texture_id_| to the picture buffer instead of
410 // setting new texture to |surface_texture_| by calling attachToGLContext()
411 // because:
412 // 1. Once we call detachFrameGLContext(), it deletes the texture previous
413 // attached.
414 // 2. SurfaceTexture requires us to apply a transform matrix when we show
415 // the texture.
416 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
417 // instead of using default matrix crbug.com/226218.
418 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
419 0.0f, 1.0f, 0.0f, 0.0f,
420 0.0f, 0.0f, 1.0f, 0.0f,
421 0.0f, 0.0f, 0.0f, 1.0f};
422 copier_->DoCopyTextureWithTransform(gl_decoder_.get(),
423 GL_TEXTURE_EXTERNAL_OES,
424 surface_texture_id_,
425 picture_buffer_texture_id,
426 size_.width(),
427 size_.height(),
428 false,
429 false,
430 false,
431 default_matrix);
432 362
433 // TODO(henryhsu): Pass (0, 0) as visible size will cause several test 363 // TODO(henryhsu): Pass (0, 0) as visible size will cause several test
434 // cases failed. We should make sure |size_| is coded size or visible size. 364 // cases failed. We should make sure |size_| is coded size or visible size.
435 base::MessageLoop::current()->PostTask( 365 base::MessageLoop::current()->PostTask(
436 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, 366 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
437 weak_this_factory_.GetWeakPtr(), 367 weak_this_factory_.GetWeakPtr(),
438 media::Picture(picture_buffer_id, bitstream_id, 368 media::Picture(picture_buffer_id, bitstream_id,
439 gfx::Rect(size_), false))); 369 gfx::Rect(size_), false)));
440 } 370 }
441 371
442 void AndroidVideoDecodeAccelerator::Decode( 372 void AndroidVideoDecodeAccelerator::Decode(
443 const media::BitstreamBuffer& bitstream_buffer) { 373 const media::BitstreamBuffer& bitstream_buffer) {
444 DCHECK(thread_checker_.CalledOnValidThread()); 374 DCHECK(thread_checker_.CalledOnValidThread());
445 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) { 375 if (bitstream_buffer.id() != -1 && bitstream_buffer.size() == 0) {
446 base::MessageLoop::current()->PostTask( 376 base::MessageLoop::current()->PostTask(
447 FROM_HERE, 377 FROM_HERE,
448 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 378 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
449 weak_this_factory_.GetWeakPtr(), 379 weak_this_factory_.GetWeakPtr(), bitstream_buffer.id()));
450 bitstream_buffer.id()));
451 return; 380 return;
452 } 381 }
453 382
454 pending_bitstream_buffers_.push( 383 pending_bitstream_buffers_.push(
455 std::make_pair(bitstream_buffer, base::Time::Now())); 384 std::make_pair(bitstream_buffer, base::Time::Now()));
456 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 385 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
457 pending_bitstream_buffers_.size()); 386 pending_bitstream_buffers_.size());
458 387
459 DoIOTask(); 388 DoIOTask();
460 } 389 }
461 390
391 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
392 client_->ProvidePictureBuffers(strategy_->GetNumPictureBuffers(), size_,
393 strategy_->GetTextureTarget());
394 }
395
462 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 396 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
463 const std::vector<media::PictureBuffer>& buffers) { 397 const std::vector<media::PictureBuffer>& buffers) {
464 DCHECK(thread_checker_.CalledOnValidThread()); 398 DCHECK(thread_checker_.CalledOnValidThread());
465 DCHECK(output_picture_buffers_.empty()); 399 DCHECK(output_picture_buffers_.empty());
466 DCHECK(free_picture_ids_.empty()); 400 DCHECK(free_picture_ids_.empty());
467 401
468 for (size_t i = 0; i < buffers.size(); ++i) { 402 for (size_t i = 0; i < buffers.size(); ++i) {
469 RETURN_ON_FAILURE(buffers[i].size() == size_, 403 RETURN_ON_FAILURE(this, buffers[i].size() == size_,
470 "Invalid picture buffer size was passed.", 404 "Invalid picture buffer size was passed.",
471 INVALID_ARGUMENT); 405 INVALID_ARGUMENT);
472 int32 id = buffers[i].id(); 406 int32 id = buffers[i].id();
473 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); 407 output_picture_buffers_.insert(std::make_pair(id, buffers[i]));
474 free_picture_ids_.push(id); 408 free_picture_ids_.push(id);
475 // Since the client might be re-using |picture_buffer_id| values, forget 409 // Since the client might be re-using |picture_buffer_id| values, forget
476 // about previously-dismissed IDs now. See ReusePictureBuffer() comment 410 // about previously-dismissed IDs now. See ReusePictureBuffer() comment
477 // about "zombies" for why we maintain this set in the first place. 411 // about "zombies" for why we maintain this set in the first place.
478 dismissed_picture_ids_.erase(id); 412 dismissed_picture_ids_.erase(id);
479 } 413 }
480 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 414 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
481 415
482 RETURN_ON_FAILURE(output_picture_buffers_.size() >= kNumPictureBuffers, 416 RETURN_ON_FAILURE(
483 "Invalid picture buffers were passed.", 417 this, output_picture_buffers_.size() >= strategy_->GetNumPictureBuffers(),
484 INVALID_ARGUMENT); 418 "Invalid picture buffers were passed.", INVALID_ARGUMENT);
485 419
486 DoIOTask(); 420 DoIOTask();
487 } 421 }
488 422
489 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( 423 void AndroidVideoDecodeAccelerator::ReusePictureBuffer(
490 int32 picture_buffer_id) { 424 int32 picture_buffer_id) {
491 DCHECK(thread_checker_.CalledOnValidThread()); 425 DCHECK(thread_checker_.CalledOnValidThread());
492 426
493 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in 427 // This ReusePictureBuffer() might have been in a pipe somewhere (queued in
494 // IPC, or in a PostTask either at the sender or receiver) when we sent a 428 // IPC, or in a PostTask either at the sender or receiver) when we sent a
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 TRACE_EVENT0("media", "AVDA::Reset"); 469 TRACE_EVENT0("media", "AVDA::Reset");
536 470
537 while (!pending_bitstream_buffers_.empty()) { 471 while (!pending_bitstream_buffers_.empty()) {
538 int32 bitstream_buffer_id = pending_bitstream_buffers_.front().first.id(); 472 int32 bitstream_buffer_id = pending_bitstream_buffers_.front().first.id();
539 pending_bitstream_buffers_.pop(); 473 pending_bitstream_buffers_.pop();
540 474
541 if (bitstream_buffer_id != -1) { 475 if (bitstream_buffer_id != -1) {
542 base::MessageLoop::current()->PostTask( 476 base::MessageLoop::current()->PostTask(
543 FROM_HERE, 477 FROM_HERE,
544 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 478 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
545 weak_this_factory_.GetWeakPtr(), 479 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
546 bitstream_buffer_id));
547 } 480 }
548 } 481 }
549 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 482 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
550 bitstreams_notified_in_advance_.clear(); 483 bitstreams_notified_in_advance_.clear();
551 484
552 for (OutputBufferMap::iterator it = output_picture_buffers_.begin(); 485 for (OutputBufferMap::iterator it = output_picture_buffers_.begin();
553 it != output_picture_buffers_.end(); 486 it != output_picture_buffers_.end();
554 ++it) { 487 ++it) {
555 client_->DismissPictureBuffer(it->first); 488 client_->DismissPictureBuffer(it->first);
556 dismissed_picture_ids_.insert(it->first); 489 dismissed_picture_ids_.insert(it->first);
(...skipping 16 matching lines...) Expand all
573 506
574 base::MessageLoop::current()->PostTask( 507 base::MessageLoop::current()->PostTask(
575 FROM_HERE, 508 FROM_HERE,
576 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 509 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
577 weak_this_factory_.GetWeakPtr())); 510 weak_this_factory_.GetWeakPtr()));
578 } 511 }
579 512
580 void AndroidVideoDecodeAccelerator::Destroy() { 513 void AndroidVideoDecodeAccelerator::Destroy() {
581 DCHECK(thread_checker_.CalledOnValidThread()); 514 DCHECK(thread_checker_.CalledOnValidThread());
582 515
516 strategy_->Cleanup();
517
583 weak_this_factory_.InvalidateWeakPtrs(); 518 weak_this_factory_.InvalidateWeakPtrs();
584 if (media_codec_) { 519 if (media_codec_) {
585 io_timer_.Stop(); 520 io_timer_.Stop();
586 media_codec_->Stop(); 521 media_codec_->Stop();
587 } 522 }
588 if (surface_texture_id_) 523 if (surface_texture_id_)
589 glDeleteTextures(1, &surface_texture_id_); 524 glDeleteTextures(1, &surface_texture_id_);
590 if (copier_)
591 copier_->Destroy();
592 delete this; 525 delete this;
593 } 526 }
594 527
595 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() { 528 bool AndroidVideoDecodeAccelerator::CanDecodeOnIOThread() {
596 return false; 529 return false;
597 } 530 }
598 531
599 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 532 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const {
600 client_->ProvidePictureBuffers(kNumPictureBuffers, size_, GL_TEXTURE_2D); 533 return size_;
534 }
535
536 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
537 const {
538 return thread_checker_;
539 }
540
541 gfx::SurfaceTexture* AndroidVideoDecodeAccelerator::GetSurfaceTexture() const {
542 return surface_texture_.get();
543 }
544
545 uint32 AndroidVideoDecodeAccelerator::GetSurfaceTextureId() const {
546 return surface_texture_id_;
547 }
548
549 gpu::gles2::GLES2Decoder* AndroidVideoDecodeAccelerator::GetGlDecoder() const {
550 return gl_decoder_.get();
551 }
552
553 media::VideoCodecBridge* AndroidVideoDecodeAccelerator::GetMediaCodec() {
554 return media_codec_.get();
555 }
556
557 void AndroidVideoDecodeAccelerator::PostError(
558 const ::tracked_objects::Location& from_here,
559 media::VideoDecodeAccelerator::Error error) {
560 base::MessageLoop::current()->PostTask(
561 from_here, base::Bind(&AndroidVideoDecodeAccelerator::NotifyError,
562 weak_this_factory_.GetWeakPtr(), error));
563 state_ = ERROR;
601 } 564 }
602 565
603 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 566 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
604 const media::Picture& picture) { 567 const media::Picture& picture) {
605 client_->PictureReady(picture); 568 client_->PictureReady(picture);
606 } 569 }
607 570
608 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 571 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
609 int input_buffer_id) { 572 int input_buffer_id) {
610 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 573 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 // software fallback for H264 on Android anyway. 619 // software fallback for H264 on Android anyway.
657 profile.max_resolution.SetSize(3840, 2160); 620 profile.max_resolution.SetSize(3840, 2160);
658 profiles.push_back(profile); 621 profiles.push_back(profile);
659 } 622 }
660 #endif 623 #endif
661 624
662 return profiles; 625 return profiles;
663 } 626 }
664 627
665 } // namespace content 628 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698