| 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 |