Chromium Code Reviews| 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& size, | |
|
Pawel Osciak
2014/08/14 07:15:36
s/size/coded_size/
kcwu
2014/08/14 12:31:01
Done.
| |
| 52 const gfx::Rect& rect); | |
|
Pawel Osciak
2014/08/14 07:15:36
s/rect/visible_rect/
kcwu
2014/08/14 12:31:01
Done.
| |
| 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 |