OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/renderer/pepper/video_decoder_shim.h" | 5 #include "content/renderer/pepper/video_decoder_shim.h" |
6 | 6 |
7 #include <GLES2/gl2.h> | 7 #include <GLES2/gl2.h> |
8 #include <GLES2/gl2ext.h> | 8 #include <GLES2/gl2ext.h> |
9 #include <GLES2/gl2extchromium.h> | 9 #include <GLES2/gl2extchromium.h> |
10 | 10 |
(...skipping 29 matching lines...) Expand all Loading... |
40 uint32_t decode_id, | 40 uint32_t decode_id, |
41 const scoped_refptr<media::DecoderBuffer>& buffer) | 41 const scoped_refptr<media::DecoderBuffer>& buffer) |
42 : decode_id(decode_id), buffer(buffer) { | 42 : decode_id(decode_id), buffer(buffer) { |
43 } | 43 } |
44 | 44 |
45 VideoDecoderShim::PendingDecode::~PendingDecode() { | 45 VideoDecoderShim::PendingDecode::~PendingDecode() { |
46 } | 46 } |
47 | 47 |
48 struct VideoDecoderShim::PendingFrame { | 48 struct VideoDecoderShim::PendingFrame { |
49 explicit PendingFrame(uint32_t decode_id); | 49 explicit PendingFrame(uint32_t decode_id); |
50 PendingFrame(uint32_t decode_id, | 50 PendingFrame(uint32_t decode_id, const gfx::Size& size); |
51 const gfx::Size& coded_size, | |
52 const gfx::Rect& visible_rect); | |
53 ~PendingFrame(); | 51 ~PendingFrame(); |
54 | 52 |
55 const uint32_t decode_id; | 53 const uint32_t decode_id; |
56 const gfx::Size coded_size; | 54 const gfx::Size size; |
57 const gfx::Rect visible_rect; | |
58 std::vector<uint8_t> argb_pixels; | 55 std::vector<uint8_t> argb_pixels; |
59 | 56 |
60 private: | 57 private: |
61 // This could be expensive to copy, so guard against that. | 58 // This could be expensive to copy, so guard against that. |
62 DISALLOW_COPY_AND_ASSIGN(PendingFrame); | 59 DISALLOW_COPY_AND_ASSIGN(PendingFrame); |
63 }; | 60 }; |
64 | 61 |
65 VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id) | 62 VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id) |
66 : decode_id(decode_id) { | 63 : decode_id(decode_id) { |
67 } | 64 } |
68 | 65 |
69 VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id, | 66 VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id, |
70 const gfx::Size& coded_size, | 67 const gfx::Size& size) |
71 const gfx::Rect& visible_rect) | |
72 : decode_id(decode_id), | 68 : decode_id(decode_id), |
73 coded_size(coded_size), | 69 size(size), |
74 visible_rect(visible_rect), | 70 argb_pixels(size.width() * size.height() * 4) { |
75 argb_pixels(coded_size.width() * coded_size.height() * 4) { | |
76 } | 71 } |
77 | 72 |
78 VideoDecoderShim::PendingFrame::~PendingFrame() { | 73 VideoDecoderShim::PendingFrame::~PendingFrame() { |
79 } | 74 } |
80 | 75 |
81 // DecoderImpl runs the underlying VideoDecoder on the media thread, receiving | 76 // DecoderImpl runs the underlying VideoDecoder on the media thread, receiving |
82 // calls from the VideoDecodeShim on the main thread and sending results back. | 77 // calls from the VideoDecodeShim on the main thread and sending results back. |
83 // This class is constructed on the main thread, but used and destructed on the | 78 // This class is constructed on the main thread, but used and destructed on the |
84 // media thread. | 79 // media thread. |
85 class VideoDecoderShim::DecoderImpl { | 80 class VideoDecoderShim::DecoderImpl { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 base::Bind( | 251 base::Bind( |
257 &VideoDecoderShim::OnDecodeComplete, shim_, result, decode_id)); | 252 &VideoDecoderShim::OnDecodeComplete, shim_, result, decode_id)); |
258 | 253 |
259 DoDecode(); | 254 DoDecode(); |
260 } | 255 } |
261 | 256 |
262 void VideoDecoderShim::DecoderImpl::OnOutputComplete( | 257 void VideoDecoderShim::DecoderImpl::OnOutputComplete( |
263 const scoped_refptr<media::VideoFrame>& frame) { | 258 const scoped_refptr<media::VideoFrame>& frame) { |
264 scoped_ptr<PendingFrame> pending_frame; | 259 scoped_ptr<PendingFrame> pending_frame; |
265 if (!frame->end_of_stream()) { | 260 if (!frame->end_of_stream()) { |
266 pending_frame.reset(new PendingFrame( | 261 pending_frame.reset(new PendingFrame(decode_id_, frame->coded_size())); |
267 decode_id_, frame->coded_size(), frame->visible_rect())); | |
268 // Convert the VideoFrame pixels to ABGR to match VideoDecodeAccelerator. | 262 // Convert the VideoFrame pixels to ABGR to match VideoDecodeAccelerator. |
269 libyuv::I420ToABGR(frame->data(media::VideoFrame::kYPlane), | 263 libyuv::I420ToABGR(frame->data(media::VideoFrame::kYPlane), |
270 frame->stride(media::VideoFrame::kYPlane), | 264 frame->stride(media::VideoFrame::kYPlane), |
271 frame->data(media::VideoFrame::kUPlane), | 265 frame->data(media::VideoFrame::kUPlane), |
272 frame->stride(media::VideoFrame::kUPlane), | 266 frame->stride(media::VideoFrame::kUPlane), |
273 frame->data(media::VideoFrame::kVPlane), | 267 frame->data(media::VideoFrame::kVPlane), |
274 frame->stride(media::VideoFrame::kVPlane), | 268 frame->stride(media::VideoFrame::kVPlane), |
275 &pending_frame->argb_pixels.front(), | 269 &pending_frame->argb_pixels.front(), |
276 frame->coded_size().width() * 4, | 270 frame->coded_size().width() * 4, |
277 frame->coded_size().width(), | 271 frame->coded_size().width(), |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 // the host from sending buffers that will cause pending_frames_ to grow. | 463 // the host from sending buffers that will cause pending_frames_ to grow. |
470 if (pending_frames_.empty()) | 464 if (pending_frames_.empty()) |
471 NotifyCompletedDecodes(); | 465 NotifyCompletedDecodes(); |
472 } | 466 } |
473 | 467 |
474 void VideoDecoderShim::OnOutputComplete(scoped_ptr<PendingFrame> frame) { | 468 void VideoDecoderShim::OnOutputComplete(scoped_ptr<PendingFrame> frame) { |
475 DCHECK(RenderThreadImpl::current()); | 469 DCHECK(RenderThreadImpl::current()); |
476 DCHECK(host_); | 470 DCHECK(host_); |
477 | 471 |
478 if (!frame->argb_pixels.empty()) { | 472 if (!frame->argb_pixels.empty()) { |
479 if (texture_size_ != frame->coded_size) { | 473 if (texture_size_ != frame->size) { |
480 // If the size has changed, all current textures must be dismissed. Add | 474 // If the size has changed, all current textures must be dismissed. Add |
481 // all textures to |textures_to_dismiss_| and dismiss any that aren't in | 475 // all textures to |textures_to_dismiss_| and dismiss any that aren't in |
482 // use by the plugin. We will dismiss the rest as they are recycled. | 476 // use by the plugin. We will dismiss the rest as they are recycled. |
483 for (TextureIdMap::const_iterator it = texture_id_map_.begin(); | 477 for (TextureIdMap::const_iterator it = texture_id_map_.begin(); |
484 it != texture_id_map_.end(); | 478 it != texture_id_map_.end(); |
485 ++it) { | 479 ++it) { |
486 textures_to_dismiss_.insert(it->second); | 480 textures_to_dismiss_.insert(it->second); |
487 } | 481 } |
488 for (TextureIdSet::const_iterator it = available_textures_.begin(); | 482 for (TextureIdSet::const_iterator it = available_textures_.begin(); |
489 it != available_textures_.end(); | 483 it != available_textures_.end(); |
490 ++it) { | 484 ++it) { |
491 DismissTexture(*it); | 485 DismissTexture(*it); |
492 } | 486 } |
493 available_textures_.clear(); | 487 available_textures_.clear(); |
494 FlushCommandBuffer(); | 488 FlushCommandBuffer(); |
495 | 489 |
496 DCHECK(pending_texture_mailboxes_.empty()); | 490 DCHECK(pending_texture_mailboxes_.empty()); |
497 for (uint32_t i = 0; i < texture_pool_size_; i++) | 491 for (uint32_t i = 0; i < texture_pool_size_; i++) |
498 pending_texture_mailboxes_.push_back(gpu::Mailbox::Generate()); | 492 pending_texture_mailboxes_.push_back(gpu::Mailbox::Generate()); |
499 | 493 |
500 host_->RequestTextures(texture_pool_size_, | 494 host_->RequestTextures(texture_pool_size_, |
501 frame->coded_size, | 495 frame->size, |
502 GL_TEXTURE_2D, | 496 GL_TEXTURE_2D, |
503 pending_texture_mailboxes_); | 497 pending_texture_mailboxes_); |
504 texture_size_ = frame->coded_size; | 498 texture_size_ = frame->size; |
505 } | 499 } |
506 | 500 |
507 pending_frames_.push(linked_ptr<PendingFrame>(frame.release())); | 501 pending_frames_.push(linked_ptr<PendingFrame>(frame.release())); |
508 SendPictures(); | 502 SendPictures(); |
509 } | 503 } |
510 } | 504 } |
511 | 505 |
512 void VideoDecoderShim::SendPictures() { | 506 void VideoDecoderShim::SendPictures() { |
513 DCHECK(RenderThreadImpl::current()); | 507 DCHECK(RenderThreadImpl::current()); |
514 DCHECK(host_); | 508 DCHECK(host_); |
(...skipping 11 matching lines...) Expand all Loading... |
526 gles2->TexImage2D(GL_TEXTURE_2D, | 520 gles2->TexImage2D(GL_TEXTURE_2D, |
527 0, | 521 0, |
528 GL_RGBA, | 522 GL_RGBA, |
529 texture_size_.width(), | 523 texture_size_.width(), |
530 texture_size_.height(), | 524 texture_size_.height(), |
531 0, | 525 0, |
532 GL_RGBA, | 526 GL_RGBA, |
533 GL_UNSIGNED_BYTE, | 527 GL_UNSIGNED_BYTE, |
534 &frame->argb_pixels.front()); | 528 &frame->argb_pixels.front()); |
535 | 529 |
536 host_->PictureReady( | 530 host_->PictureReady(media::Picture(texture_id, frame->decode_id)); |
537 media::Picture(texture_id, frame->decode_id, frame->visible_rect)); | |
538 pending_frames_.pop(); | 531 pending_frames_.pop(); |
539 } | 532 } |
540 | 533 |
541 FlushCommandBuffer(); | 534 FlushCommandBuffer(); |
542 | 535 |
543 if (pending_frames_.empty()) { | 536 if (pending_frames_.empty()) { |
544 // If frames aren't backing up, notify the host of any completed decodes so | 537 // If frames aren't backing up, notify the host of any completed decodes so |
545 // it can send more buffers. | 538 // it can send more buffers. |
546 NotifyCompletedDecodes(); | 539 NotifyCompletedDecodes(); |
547 | 540 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { | 580 void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { |
588 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); | 581 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); |
589 gles2->DeleteTextures(1, &texture_id); | 582 gles2->DeleteTextures(1, &texture_id); |
590 } | 583 } |
591 | 584 |
592 void VideoDecoderShim::FlushCommandBuffer() { | 585 void VideoDecoderShim::FlushCommandBuffer() { |
593 context_provider_->ContextGL()->Flush(); | 586 context_provider_->ContextGL()->Flush(); |
594 } | 587 } |
595 | 588 |
596 } // namespace content | 589 } // namespace content |
OLD | NEW |