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