From 8bb3e51628226abcc38a66b2a50adbdbefe5152f Mon Sep 17 00:00:00 2001 From: "schenney@chromium.org" Date: Fri, 13 Jun 2014 14:35:15 +0000 Subject: [PATCH] Revert of Implement software fallback for PPB_VideoDecoder. (https://codereview.chromium.org/311853005/) Reason for revert: Broke blink Linux tests compile.http://build.chromium.org/p/chromium.webkit/builders/Linux%20Tests/builds/37259 Original issue's description: > Implement software fallback for PPB_VideoDecoder. > This modifies the proxy to implement software fallback mode. > The main change is to the host, which now can work with > media::VideoDecoders. > > media::VideoDecoder works differently from media::VideoDecodeAccelerator > so an adapter object, content::VideoDecoderShim is defined. It lives on the main thread and drives the actual decoder on the media thread via a child DecoderImpl class, which sends back frames of video. VideoDecoderShim receives those and converts frames to GL textures. > > gpu::Mailboxes are used so the host can create textures that are aliased > to the plugin's textures. > > The test plugin has been changed to include bitstream data for VP8 in order to > test the software decoder. The data is in ppapi/examples/video_decode/testdata.h > alongside the H264 data. The file diff is too large for this site but is structured > something like this: > > const unsigned char kData[] = { > #if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 > ... lots of VP8 data > > #else // !USE_VP8_TESTDATA_INSTEAD_OF_H264 > ... lots of H264 data > > #endif // USE_VP8_TESTDATA_INSTEAD_OF_H264 > }; > > > There is a TODO to convert the example to load a file. I'm not sure how to go > about that but am willing to do the work if someone can point the way. > > BUG=281689 > R=dmichael@chromium.org, fischman@chromium.org, sievers@chromium.org, tsepez@chromium.org > > Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=277012 TBR=dmichael@chromium.org,fischman@chromium.org,igorc@chromium.org,piman@chromium.org,sievers@chromium.org,tsepez@chromium.org,bbudge@chromium.org NOTREECHECKS=true NOTRY=true BUG=281689 Review URL: https://codereview.chromium.org/337683002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277015 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/test/ppapi/ppapi_browsertest.cc | 2 - content/content_renderer.gypi | 6 +- .../renderer/pepper/pepper_video_decoder_host.cc | 116 ++--- .../renderer/pepper/pepper_video_decoder_host.h | 21 +- content/renderer/pepper/video_decoder_shim.cc | 576 --------------------- content/renderer/pepper/video_decoder_shim.h | 129 ----- content/test/ppapi/ppapi_browsertest.cc | 2 - gpu/command_buffer/common/cmd_buffer_common.cc | 2 - gpu/gpu.gyp | 23 - ppapi/examples/video_decode/video_decode.cc | 81 +-- ppapi/ppapi_sources.gypi | 2 - ppapi/proxy/ppapi_messages.h | 5 +- ppapi/proxy/video_decoder_resource.cc | 11 +- ppapi/proxy/video_decoder_resource.h | 4 +- ppapi/proxy/video_decoder_resource_unittest.cc | 5 +- ppapi/tests/test_video_decoder.cc | 70 --- ppapi/tests/test_video_decoder.h | 32 -- 17 files changed, 76 insertions(+), 1011 deletions(-) delete mode 100644 content/renderer/pepper/video_decoder_shim.cc delete mode 100644 content/renderer/pepper/video_decoder_shim.h delete mode 100644 ppapi/tests/test_video_decoder.cc delete mode 100644 ppapi/tests/test_video_decoder.h diff --git a/chrome/test/ppapi/ppapi_browsertest.cc b/chrome/test/ppapi/ppapi_browsertest.cc index d23323bd6e6f..119f0c92c08b 100644 --- a/chrome/test/ppapi/ppapi_browsertest.cc +++ b/chrome/test/ppapi/ppapi_browsertest.cc @@ -1206,8 +1206,6 @@ TEST_PPAPI_NACL(NetworkProxy) TEST_PPAPI_NACL(TrueTypeFont) -TEST_PPAPI_NACL(VideoDecoder) - // VideoDestination doesn't work in content_browsertests. TEST_PPAPI_OUT_OF_PROCESS(VideoDestination) TEST_PPAPI_NACL(VideoDestination) diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index c7a3bfaef57c..dd10f21be746 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -322,7 +322,7 @@ 'renderer/mouse_lock_dispatcher.cc', 'renderer/mouse_lock_dispatcher.h', 'renderer/net_info_helper.cc', - 'renderer/net_info_helper.h', + 'renderer/net_info_helper.h', 'renderer/notification_provider.cc', 'renderer/notification_provider.h', 'renderer/push_messaging_dispatcher.cc', @@ -566,8 +566,6 @@ 'renderer/pepper/usb_key_code_conversion_win.cc', 'renderer/pepper/v8_var_converter.cc', 'renderer/pepper/v8_var_converter.h', - 'renderer/pepper/video_decoder_shim.cc', - 'renderer/pepper/video_decoder_shim.h', 'renderer/render_widget_fullscreen_pepper.cc', 'renderer/render_widget_fullscreen_pepper.h', ], @@ -646,7 +644,7 @@ 'renderer/media/webrtc/webrtc_video_track_adapter.cc', 'renderer/media/webrtc/webrtc_video_track_adapter.h', 'renderer/media/webrtc/media_stream_remote_video_source.cc', - 'renderer/media/webrtc/media_stream_remote_video_source.h', + 'renderer/media/webrtc/media_stream_remote_video_source.h', 'renderer/media/webrtc/media_stream_track_metrics.cc', 'renderer/media/webrtc/media_stream_track_metrics.h', 'renderer/media/webrtc/peer_connection_dependency_factory.cc', diff --git a/content/renderer/pepper/pepper_video_decoder_host.cc b/content/renderer/pepper/pepper_video_decoder_host.cc index d3364e12be0e..16019f720b29 100644 --- a/content/renderer/pepper/pepper_video_decoder_host.cc +++ b/content/renderer/pepper/pepper_video_decoder_host.cc @@ -10,7 +10,9 @@ #include "content/public/renderer/render_thread.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/ppb_graphics_3d_impl.h" -#include "content/renderer/pepper/video_decoder_shim.h" +#include "content/renderer/render_thread_impl.h" +#include "content/renderer/render_view_impl.h" +#include "media/video/picture.h" #include "media/video/video_decode_accelerator.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" @@ -117,10 +119,9 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize( graphics_context.host_resource(), true); if (enter_graphics.failed()) return PP_ERROR_FAILED; - PPB_Graphics3D_Impl* graphics3d = - static_cast(enter_graphics.object()); + graphics3d_ = static_cast(enter_graphics.object()); - int command_buffer_route_id = graphics3d->GetCommandBufferRouteId(); + int command_buffer_route_id = graphics3d_->GetCommandBufferRouteId(); if (!command_buffer_route_id) return PP_ERROR_FAILED; @@ -128,7 +129,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize( // This is not synchronous, but subsequent IPC messages will be buffered, so // it is okay to immediately send IPC messages through the returned channel. - GpuChannelHost* channel = graphics3d->channel(); + GpuChannelHost* channel = graphics3d_->channel(); DCHECK(channel); decoder_ = channel->CreateVideoDecoder(command_buffer_route_id); if (decoder_ && decoder_->Initialize(media_profile, this)) { @@ -137,14 +138,8 @@ int32_t PepperVideoDecoderHost::OnHostMsgInitialize( } decoder_.reset(); - if (!allow_software_fallback) - return PP_ERROR_NOTSUPPORTED; - - decoder_.reset(new VideoDecoderShim(this)); - initialize_reply_context_ = context->MakeReplyMessageContext(); - decoder_->Initialize(media_profile, this); - - return PP_OK_COMPLETIONPENDING; + // TODO(bbudge) Implement software fallback. + return PP_ERROR_NOTSUPPORTED; } int32_t PepperVideoDecoderHost::OnHostMsgGetShm( @@ -181,8 +176,8 @@ int32_t PepperVideoDecoderHost::OnHostMsgGetShm( shm_buffers_.push_back(shm.release()); shm_buffer_busy_.push_back(false); } else { - // Remove the old buffer. Delete manually since ScopedVector won't delete - // the existing element if we just assign over it. + // Fill in the new resized buffer. Delete it manually since ScopedVector + // won't delete the existing element if we just assign it. delete shm_buffers_[shm_id]; shm_buffers_[shm_id] = shm.release(); } @@ -267,6 +262,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture( return PP_ERROR_FAILED; decoder_->ReusePictureBuffer(texture_id); + return PP_OK; } @@ -302,13 +298,17 @@ void PepperVideoDecoderHost::ProvidePictureBuffers( uint32 requested_num_of_buffers, const gfx::Size& dimensions, uint32 texture_target) { - RequestTextures(requested_num_of_buffers, - dimensions, - texture_target, - std::vector()); + DCHECK(RenderThreadImpl::current()); + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_VideoDecoder_RequestTextures( + requested_num_of_buffers, + PP_MakeSize(dimensions.width(), dimensions.height()), + texture_target)); } void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) { + DCHECK(RenderThreadImpl::current()); host()->SendUnsolicitedReply( pp_resource(), PpapiPluginMsg_VideoDecoder_PictureReady(picture.bitstream_buffer_id(), @@ -316,40 +316,15 @@ void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) { } void PepperVideoDecoderHost::DismissPictureBuffer(int32 picture_buffer_id) { + DCHECK(RenderThreadImpl::current()); host()->SendUnsolicitedReply( pp_resource(), PpapiPluginMsg_VideoDecoder_DismissPicture(picture_buffer_id)); } -void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer( - int32 bitstream_buffer_id) { - PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id); - if (it == pending_decodes_.end()) { - NOTREACHED(); - return; - } - const PendingDecode& pending_decode = it->second; - host()->SendReply( - pending_decode.reply_context, - PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id)); - shm_buffer_busy_[pending_decode.shm_id] = false; - pending_decodes_.erase(it); -} - -void PepperVideoDecoderHost::NotifyFlushDone() { - host()->SendReply(flush_reply_context_, - PpapiPluginMsg_VideoDecoder_FlushReply()); - flush_reply_context_ = ppapi::host::ReplyMessageContext(); -} - -void PepperVideoDecoderHost::NotifyResetDone() { - host()->SendReply(reset_reply_context_, - PpapiPluginMsg_VideoDecoder_ResetReply()); - reset_reply_context_ = ppapi::host::ReplyMessageContext(); -} - void PepperVideoDecoderHost::NotifyError( media::VideoDecodeAccelerator::Error error) { + DCHECK(RenderThreadImpl::current()); int32_t pp_error = PP_ERROR_FAILED; switch (error) { case media::VideoDecodeAccelerator::UNREADABLE_INPUT: @@ -367,35 +342,34 @@ void PepperVideoDecoderHost::NotifyError( pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error)); } -void PepperVideoDecoderHost::OnInitializeComplete(int32_t result) { - if (!initialized_) { - if (result == PP_OK) - initialized_ = true; - initialize_reply_context_.params.set_result(result); - host()->SendReply(initialize_reply_context_, - PpapiPluginMsg_VideoDecoder_InitializeReply()); - } +void PepperVideoDecoderHost::NotifyResetDone() { + DCHECK(RenderThreadImpl::current()); + host()->SendReply(reset_reply_context_, + PpapiPluginMsg_VideoDecoder_ResetReply()); + reset_reply_context_ = ppapi::host::ReplyMessageContext(); } -const uint8_t* PepperVideoDecoderHost::DecodeIdToAddress(uint32_t decode_id) { - PendingDecodeMap::const_iterator it = pending_decodes_.find(decode_id); - DCHECK(it != pending_decodes_.end()); - uint32_t shm_id = it->second.shm_id; - return static_cast(shm_buffers_[shm_id]->memory()); +void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer( + int32 bitstream_buffer_id) { + DCHECK(RenderThreadImpl::current()); + PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id); + if (it == pending_decodes_.end()) { + NOTREACHED(); + return; + } + const PendingDecode& pending_decode = it->second; + host()->SendReply( + pending_decode.reply_context, + PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id)); + shm_buffer_busy_[pending_decode.shm_id] = false; + pending_decodes_.erase(it); } -void PepperVideoDecoderHost::RequestTextures( - uint32 requested_num_of_buffers, - const gfx::Size& dimensions, - uint32 texture_target, - const std::vector& mailboxes) { - host()->SendUnsolicitedReply( - pp_resource(), - PpapiPluginMsg_VideoDecoder_RequestTextures( - requested_num_of_buffers, - PP_MakeSize(dimensions.width(), dimensions.height()), - texture_target, - mailboxes)); +void PepperVideoDecoderHost::NotifyFlushDone() { + DCHECK(RenderThreadImpl::current()); + host()->SendReply(flush_reply_context_, + PpapiPluginMsg_VideoDecoder_FlushReply()); + flush_reply_context_ = ppapi::host::ReplyMessageContext(); } } // namespace content diff --git a/content/renderer/pepper/pepper_video_decoder_host.h b/content/renderer/pepper/pepper_video_decoder_host.h index e76f95c4bf66..bc44fe848dff 100644 --- a/content/renderer/pepper/pepper_video_decoder_host.h +++ b/content/renderer/pepper/pepper_video_decoder_host.h @@ -10,9 +10,11 @@ #include "base/basictypes.h" #include "base/containers/hash_tables.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "content/common/content_export.h" +#include "gpu/command_buffer/common/mailbox.h" #include "media/video/video_decode_accelerator.h" #include "ppapi/c/pp_codecs.h" #include "ppapi/host/host_message_context.h" @@ -28,7 +30,6 @@ namespace content { class PPB_Graphics3D_Impl; class RendererPpapiHost; class RenderViewImpl; -class VideoDecoderShim; class CONTENT_EXPORT PepperVideoDecoderHost : public ppapi::host::ResourceHost, @@ -49,8 +50,6 @@ class CONTENT_EXPORT PepperVideoDecoderHost const ppapi::host::ReplyMessageContext reply_context; }; - friend class VideoDecoderShim; - // ResourceHost implementation. virtual int32_t OnResourceMessageReceived( const IPC::Message& msg, @@ -62,10 +61,10 @@ class CONTENT_EXPORT PepperVideoDecoderHost uint32 texture_target) OVERRIDE; virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; virtual void PictureReady(const media::Picture& picture) OVERRIDE; - virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; + virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE; virtual void NotifyFlushDone() OVERRIDE; + virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; virtual void NotifyResetDone() OVERRIDE; - virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE; int32_t OnHostMsgInitialize(ppapi::host::HostMessageContext* context, const ppapi::HostResource& graphics_context, @@ -86,19 +85,11 @@ class CONTENT_EXPORT PepperVideoDecoderHost int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context); int32_t OnHostMsgReset(ppapi::host::HostMessageContext* context); - // These methods are needed by VideoDecodeShim, to look like a - // VideoDecodeAccelerator. - void OnInitializeComplete(int32_t result); - const uint8_t* DecodeIdToAddress(uint32_t decode_id); - void RequestTextures(uint32 requested_num_of_buffers, - const gfx::Size& dimensions, - uint32 texture_target, - const std::vector& mailboxes); - // Non-owning pointer. RendererPpapiHost* renderer_ppapi_host_; scoped_ptr decoder_; + scoped_refptr graphics3d_; // A vector holding our shm buffers, in sync with a similar vector in the // resource. We use a buffer's index in these vectors as its id on both sides @@ -115,8 +106,6 @@ class CONTENT_EXPORT PepperVideoDecoderHost ppapi::host::ReplyMessageContext flush_reply_context_; ppapi::host::ReplyMessageContext reset_reply_context_; - // Only used when in software fallback mode. - ppapi::host::ReplyMessageContext initialize_reply_context_; bool initialized_; diff --git a/content/renderer/pepper/video_decoder_shim.cc b/content/renderer/pepper/video_decoder_shim.cc deleted file mode 100644 index a82932cae815..000000000000 --- a/content/renderer/pepper/video_decoder_shim.cc +++ /dev/null @@ -1,576 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/pepper/video_decoder_shim.h" - -#include -#include -#include - -#include "base/bind.h" -#include "base/numerics/safe_conversions.h" -#include "content/public/renderer/render_thread.h" -#include "content/renderer/pepper/pepper_video_decoder_host.h" -#include "content/renderer/render_thread_impl.h" -#include "gpu/command_buffer/client/gles2_implementation.h" -#include "media/base/decoder_buffer.h" -#include "media/base/limits.h" -#include "media/base/video_decoder.h" -#include "media/filters/ffmpeg_video_decoder.h" -#include "media/video/picture.h" -#include "media/video/video_decode_accelerator.h" -#include "ppapi/c/pp_errors.h" -#include "third_party/libyuv/include/libyuv.h" -#include "webkit/common/gpu/context_provider_web_context.h" - -namespace content { - -struct VideoDecoderShim::PendingDecode { - PendingDecode(uint32_t decode_id, - const scoped_refptr& buffer); - ~PendingDecode(); - - const uint32_t decode_id; - const scoped_refptr buffer; -}; - -VideoDecoderShim::PendingDecode::PendingDecode( - uint32_t decode_id, - const scoped_refptr& buffer) - : decode_id(decode_id), buffer(buffer) { -} - -VideoDecoderShim::PendingDecode::~PendingDecode() { -} - -struct VideoDecoderShim::PendingFrame { - explicit PendingFrame(uint32_t decode_id); - PendingFrame(uint32_t decode_id, const gfx::Size& size); - ~PendingFrame(); - - const uint32_t decode_id; - const gfx::Size size; - std::vector argb_pixels; - - private: - // This could be expensive to copy, so guard against that. - DISALLOW_COPY_AND_ASSIGN(PendingFrame); -}; - -VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id) - : decode_id(decode_id) { -} - -VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id, - const gfx::Size& size) - : decode_id(decode_id), - size(size), - argb_pixels(size.width() * size.height() * 4) { -} - -VideoDecoderShim::PendingFrame::~PendingFrame() { -} - -// DecoderImpl runs the underlying VideoDecoder on the media thread, receiving -// calls from the VideoDecodeShim on the main thread and sending results back. -// This class is constructed on the main thread, but used and destructed on the -// media thread. -class VideoDecoderShim::DecoderImpl { - public: - explicit DecoderImpl(const base::WeakPtr& proxy); - ~DecoderImpl(); - - void Initialize(media::VideoDecoderConfig config); - void Decode(uint32_t decode_id, scoped_refptr buffer); - void Reset(); - void Stop(); - - private: - void OnPipelineStatus(media::PipelineStatus status); - void DoDecode(); - void OnDecodeComplete(uint32_t decode_id, media::VideoDecoder::Status status); - void OnOutputComplete(const scoped_refptr& frame); - void OnResetComplete(); - - // WeakPtr is bound to main_message_loop_. Use only in shim callbacks. - base::WeakPtr shim_; - scoped_ptr decoder_; - scoped_refptr main_message_loop_; - // Queue of decodes waiting for the decoder. - typedef std::queue PendingDecodeQueue; - PendingDecodeQueue pending_decodes_; - int max_decodes_at_decoder_; - int num_decodes_at_decoder_; - // VideoDecoder returns pictures without information about the decode buffer - // that generated it. Save the decode_id from the last decode that completed, - // which is close for most decoders, which only decode one buffer at a time. - uint32_t decode_id_; -}; - -VideoDecoderShim::DecoderImpl::DecoderImpl( - const base::WeakPtr& proxy) - : shim_(proxy), - main_message_loop_(base::MessageLoopProxy::current()), - max_decodes_at_decoder_(0), - num_decodes_at_decoder_(0), - decode_id_(0) { -} - -VideoDecoderShim::DecoderImpl::~DecoderImpl() { - DCHECK(pending_decodes_.empty()); -} - -void VideoDecoderShim::DecoderImpl::Initialize( - media::VideoDecoderConfig config) { - DCHECK(!decoder_); - scoped_ptr ffmpeg_video_decoder( - new media::FFmpegVideoDecoder(base::MessageLoopProxy::current())); - ffmpeg_video_decoder->set_decode_nalus(true); - decoder_ = ffmpeg_video_decoder.Pass(); - max_decodes_at_decoder_ = decoder_->GetMaxDecodeRequests(); - // We can use base::Unretained() safely in decoder callbacks because we call - // VideoDecoder::Stop() before deletion. Stop() guarantees there will be no - // outstanding callbacks after it returns. - decoder_->Initialize( - config, - true /* low_delay */, - base::Bind(&VideoDecoderShim::DecoderImpl::OnPipelineStatus, - base::Unretained(this)), - base::Bind(&VideoDecoderShim::DecoderImpl::OnOutputComplete, - base::Unretained(this))); -} - -void VideoDecoderShim::DecoderImpl::Decode( - uint32_t decode_id, - scoped_refptr buffer) { - DCHECK(decoder_); - pending_decodes_.push(PendingDecode(decode_id, buffer)); - DoDecode(); -} - -void VideoDecoderShim::DecoderImpl::Reset() { - DCHECK(decoder_); - // Abort all pending decodes. - while (!pending_decodes_.empty()) { - const PendingDecode& decode = pending_decodes_.front(); - scoped_ptr pending_frame(new PendingFrame(decode.decode_id)); - main_message_loop_->PostTask(FROM_HERE, - base::Bind(&VideoDecoderShim::OnDecodeComplete, - shim_, - media::VideoDecoder::kAborted, - decode.decode_id)); - pending_decodes_.pop(); - } - decoder_->Reset(base::Bind(&VideoDecoderShim::DecoderImpl::OnResetComplete, - base::Unretained(this))); -} - -void VideoDecoderShim::DecoderImpl::Stop() { - DCHECK(decoder_); - // Clear pending decodes now. We don't want OnDecodeComplete to call DoDecode - // again. - while (!pending_decodes_.empty()) - pending_decodes_.pop(); - decoder_->Stop(); - // This instance is deleted once we exit this scope. -} - -void VideoDecoderShim::DecoderImpl::OnPipelineStatus( - media::PipelineStatus status) { - int32_t result; - switch (status) { - case media::PIPELINE_OK: - result = PP_OK; - break; - case media::DECODER_ERROR_NOT_SUPPORTED: - result = PP_ERROR_NOTSUPPORTED; - break; - default: - result = PP_ERROR_FAILED; - break; - } - - // Calculate how many textures the shim should create. - uint32_t shim_texture_pool_size = - max_decodes_at_decoder_ + media::limits::kMaxVideoFrames; - main_message_loop_->PostTask( - FROM_HERE, - base::Bind(&VideoDecoderShim::OnInitializeComplete, - shim_, - result, - shim_texture_pool_size)); -} - -void VideoDecoderShim::DecoderImpl::DoDecode() { - while (!pending_decodes_.empty() && - num_decodes_at_decoder_ < max_decodes_at_decoder_) { - num_decodes_at_decoder_++; - const PendingDecode& decode = pending_decodes_.front(); - decoder_->Decode( - decode.buffer, - base::Bind(&VideoDecoderShim::DecoderImpl::OnDecodeComplete, - base::Unretained(this), - decode.decode_id)); - pending_decodes_.pop(); - } -} - -void VideoDecoderShim::DecoderImpl::OnDecodeComplete( - uint32_t decode_id, - media::VideoDecoder::Status status) { - num_decodes_at_decoder_--; - decode_id_ = decode_id; - - int32_t result; - switch (status) { - case media::VideoDecoder::kOk: - case media::VideoDecoder::kAborted: - result = PP_OK; - break; - case media::VideoDecoder::kDecodeError: - result = PP_ERROR_RESOURCE_FAILED; - break; - default: - NOTREACHED(); - result = PP_ERROR_FAILED; - break; - } - - main_message_loop_->PostTask( - FROM_HERE, - base::Bind( - &VideoDecoderShim::OnDecodeComplete, shim_, result, decode_id)); - - DoDecode(); -} - -void VideoDecoderShim::DecoderImpl::OnOutputComplete( - const scoped_refptr& frame) { - scoped_ptr pending_frame; - if (!frame->end_of_stream()) { - pending_frame.reset(new PendingFrame(decode_id_, frame->coded_size())); - // Convert the VideoFrame pixels to ARGB. - libyuv::I420ToARGB(frame->data(media::VideoFrame::kYPlane), - frame->stride(media::VideoFrame::kYPlane), - frame->data(media::VideoFrame::kUPlane), - frame->stride(media::VideoFrame::kUPlane), - frame->data(media::VideoFrame::kVPlane), - frame->stride(media::VideoFrame::kVPlane), - &pending_frame->argb_pixels.front(), - frame->coded_size().width() * 4, - frame->coded_size().width(), - frame->coded_size().height()); - } else { - pending_frame.reset(new PendingFrame(decode_id_)); - } - - main_message_loop_->PostTask(FROM_HERE, - base::Bind(&VideoDecoderShim::OnOutputComplete, - shim_, - base::Passed(&pending_frame))); -} - -void VideoDecoderShim::DecoderImpl::OnResetComplete() { - main_message_loop_->PostTask( - FROM_HERE, base::Bind(&VideoDecoderShim::OnResetComplete, shim_)); -} - -VideoDecoderShim::VideoDecoderShim(PepperVideoDecoderHost* host) - : state_(UNINITIALIZED), - host_(host), - media_message_loop_( - RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), - context_provider_( - RenderThreadImpl::current()->SharedMainThreadContextProvider()), - texture_pool_size_(0), - num_pending_decodes_(0), - weak_ptr_factory_(this) { - DCHECK(host_); - DCHECK(media_message_loop_); - DCHECK(context_provider_); - decoder_impl_.reset(new DecoderImpl(weak_ptr_factory_.GetWeakPtr())); -} - -VideoDecoderShim::~VideoDecoderShim() { - DCHECK(RenderThreadImpl::current()); - // Delete any remaining textures. - TextureIdMap::iterator it = texture_id_map_.begin(); - for (; it != texture_id_map_.end(); ++it) - DeleteTexture(it->second); - texture_id_map_.clear(); - - FlushCommandBuffer(); - - weak_ptr_factory_.InvalidateWeakPtrs(); - // No more callbacks from the delegate will be received now. - - // The callback now holds the only reference to the DecoderImpl, which will be - // deleted when Stop completes. - media_message_loop_->PostTask( - FROM_HERE, - base::Bind(&VideoDecoderShim::DecoderImpl::Stop, - base::Owned(decoder_impl_.release()))); -} - -bool VideoDecoderShim::Initialize( - media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) { - DCHECK_EQ(client, host_); - DCHECK(RenderThreadImpl::current()); - DCHECK_EQ(state_, UNINITIALIZED); - media::VideoCodec codec = media::kUnknownVideoCodec; - if (profile <= media::H264PROFILE_MAX) - codec = media::kCodecH264; - else if (profile <= media::VP8PROFILE_MAX) - codec = media::kCodecVP8; - DCHECK_NE(codec, media::kUnknownVideoCodec); - - media::VideoDecoderConfig config( - codec, - profile, - media::VideoFrame::YV12, - gfx::Size(32, 24), // Small sizes that won't fail. - gfx::Rect(32, 24), - gfx::Size(32, 24), - NULL /* extra_data */, // TODO(bbudge) Verify this isn't needed. - 0 /* extra_data_size */, - false /* decryption */); - - media_message_loop_->PostTask( - FROM_HERE, - base::Bind(&VideoDecoderShim::DecoderImpl::Initialize, - base::Unretained(decoder_impl_.get()), - config)); - // Return success, even though we are asynchronous, to mimic - // media::VideoDecodeAccelerator. - return true; -} - -void VideoDecoderShim::Decode(const media::BitstreamBuffer& bitstream_buffer) { - DCHECK(RenderThreadImpl::current()); - DCHECK_EQ(state_, DECODING); - - // We need the address of the shared memory, so we can copy the buffer. - const uint8_t* buffer = host_->DecodeIdToAddress(bitstream_buffer.id()); - DCHECK(buffer); - - media_message_loop_->PostTask( - FROM_HERE, - base::Bind( - &VideoDecoderShim::DecoderImpl::Decode, - base::Unretained(decoder_impl_.get()), - bitstream_buffer.id(), - media::DecoderBuffer::CopyFrom(buffer, bitstream_buffer.size()))); - num_pending_decodes_++; -} - -void VideoDecoderShim::AssignPictureBuffers( - const std::vector& buffers) { - DCHECK(RenderThreadImpl::current()); - DCHECK_EQ(state_, DECODING); - if (buffers.empty()) { - NOTREACHED(); - return; - } - DCHECK_EQ(buffers.size(), pending_texture_mailboxes_.size()); - GLuint num_textures = base::checked_cast(buffers.size()); - std::vector local_texture_ids(num_textures); - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->GenTextures(num_textures, &local_texture_ids.front()); - for (uint32_t i = 0; i < num_textures; i++) { - gles2->ActiveTexture(GL_TEXTURE0); - gles2->BindTexture(GL_TEXTURE_2D, local_texture_ids[i]); - gles2->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, - pending_texture_mailboxes_[i].name); - // Map the plugin texture id to the local texture id. - uint32_t plugin_texture_id = buffers[i].texture_id(); - texture_id_map_[plugin_texture_id] = local_texture_ids[i]; - available_textures_.push_back(plugin_texture_id); - } - pending_texture_mailboxes_.clear(); - SendPictures(); -} - -void VideoDecoderShim::ReusePictureBuffer(int32 picture_buffer_id) { - DCHECK(RenderThreadImpl::current()); - uint32_t texture_id = static_cast(picture_buffer_id); - if (textures_to_dismiss_.find(texture_id) != textures_to_dismiss_.end()) { - DismissTexture(texture_id); - } else if (texture_id_map_.find(texture_id) != texture_id_map_.end()) { - available_textures_.push_back(texture_id); - SendPictures(); - } else { - NOTREACHED(); - } -} - -void VideoDecoderShim::Flush() { - DCHECK(RenderThreadImpl::current()); - DCHECK_EQ(state_, DECODING); - state_ = FLUSHING; -} - -void VideoDecoderShim::Reset() { - DCHECK(RenderThreadImpl::current()); - DCHECK_EQ(state_, DECODING); - state_ = RESETTING; - media_message_loop_->PostTask( - FROM_HERE, - base::Bind(&VideoDecoderShim::DecoderImpl::Reset, - base::Unretained(decoder_impl_.get()))); -} - -void VideoDecoderShim::Destroy() { - // This will be called, but our destructor does the actual work. -} - -void VideoDecoderShim::OnInitializeComplete(int32_t result, - uint32_t texture_pool_size) { - DCHECK(RenderThreadImpl::current()); - DCHECK(host_); - - if (result == PP_OK) { - state_ = DECODING; - texture_pool_size_ = texture_pool_size; - } - - host_->OnInitializeComplete(result); -} - -void VideoDecoderShim::OnDecodeComplete(int32_t result, uint32_t decode_id) { - DCHECK(RenderThreadImpl::current()); - DCHECK(host_); - - num_pending_decodes_--; - completed_decodes_.push(decode_id); - - if (result == PP_OK) { - // If frames are being queued because we're out of textures, don't notify - // the host that decode has completed. This exerts "back pressure" to keep - // the host from sending buffers that will cause pending_frames_ to grow. - if (pending_frames_.empty()) - NotifyCompletedDecodes(); - } else if (result == PP_ERROR_RESOURCE_FAILED) { - host_->NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); - } -} - -void VideoDecoderShim::OnOutputComplete(scoped_ptr frame) { - DCHECK(RenderThreadImpl::current()); - DCHECK(host_); - - if (!frame->argb_pixels.empty()) { - if (texture_size_ != frame->size) { - // If the size has changed, all current textures must be dismissed. Add - // all textures to |textures_to_dismiss_| and dismiss any that aren't in - // use by the plugin. We will dismiss the rest as they are recycled. - for (TextureIdMap::const_iterator it = texture_id_map_.begin(); - it != texture_id_map_.end(); - ++it) { - textures_to_dismiss_.insert(it->second); - } - for (std::vector::const_iterator it = - available_textures_.begin(); - it != available_textures_.end(); - ++it) { - DismissTexture(*it); - } - available_textures_.clear(); - FlushCommandBuffer(); - - DCHECK(pending_texture_mailboxes_.empty()); - for (uint32_t i = 0; i < texture_pool_size_; i++) - pending_texture_mailboxes_.push_back(gpu::Mailbox::Generate()); - - host_->RequestTextures(texture_pool_size_, - frame->size, - GL_TEXTURE_2D, - pending_texture_mailboxes_); - texture_size_ = frame->size; - } - - pending_frames_.push(linked_ptr(frame.release())); - SendPictures(); - } -} - -void VideoDecoderShim::SendPictures() { - DCHECK(RenderThreadImpl::current()); - DCHECK(host_); - while (!pending_frames_.empty() && !available_textures_.empty()) { - const linked_ptr& frame = pending_frames_.front(); - - uint32_t texture_id = available_textures_.back(); - available_textures_.pop_back(); - - uint32_t local_texture_id = texture_id_map_[texture_id]; - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->ActiveTexture(GL_TEXTURE0); - gles2->BindTexture(GL_TEXTURE_2D, local_texture_id); - gles2->TexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, - texture_size_.width(), - texture_size_.height(), - 0, - GL_RGBA, - GL_UNSIGNED_BYTE, - &frame->argb_pixels.front()); - - host_->PictureReady(media::Picture(texture_id, frame->decode_id)); - pending_frames_.pop(); - } - - FlushCommandBuffer(); - - if (pending_frames_.empty()) { - // If frames aren't backing up, notify the host of any completed decodes so - // it can send more buffers. - NotifyCompletedDecodes(); - - if (state_ == FLUSHING && !num_pending_decodes_) { - state_ = DECODING; - host_->NotifyFlushDone(); - } - } -} - -void VideoDecoderShim::OnResetComplete() { - DCHECK(RenderThreadImpl::current()); - DCHECK(host_); - - while (!pending_frames_.empty()) - pending_frames_.pop(); - NotifyCompletedDecodes(); - - state_ = DECODING; - host_->NotifyResetDone(); -} - -void VideoDecoderShim::NotifyCompletedDecodes() { - while (!completed_decodes_.empty()) { - host_->NotifyEndOfBitstreamBuffer(completed_decodes_.front()); - completed_decodes_.pop(); - } -} - -void VideoDecoderShim::DismissTexture(uint32_t texture_id) { - DCHECK(host_); - textures_to_dismiss_.erase(texture_id); - DCHECK(texture_id_map_.find(texture_id) != texture_id_map_.end()); - DeleteTexture(texture_id_map_[texture_id]); - texture_id_map_.erase(texture_id); - host_->DismissPictureBuffer(texture_id); -} - -void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->DeleteTextures(1, &texture_id); -} - -void VideoDecoderShim::FlushCommandBuffer() { - context_provider_->ContextGL()->Flush(); -} - -} // namespace content diff --git a/content/renderer/pepper/video_decoder_shim.h b/content/renderer/pepper/video_decoder_shim.h deleted file mode 100644 index e02af527bbaf..000000000000 --- a/content/renderer/pepper/video_decoder_shim.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_ -#define CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_ - -#include -#include - -#include "base/basictypes.h" -#include "base/containers/hash_tables.h" -#include "base/memory/linked_ptr.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop_proxy.h" -#include "gpu/command_buffer/common/mailbox.h" -#include "media/base/video_decoder_config.h" -#include "media/video/video_decode_accelerator.h" - -#include "ppapi/c/pp_codecs.h" - -namespace gpu { -namespace gles2 { -class GLES2Interface; -} -} - -namespace media { -class DecoderBuffer; -} - -namespace webkit { -namespace gpu { -class ContextProviderWebContext; -} -} - -namespace content { - -class PepperVideoDecoderHost; - -// This class is a shim to wrap a media::VideoDecoder so that it can be used -// by PepperVideoDecoderHost in place of a media::VideoDecodeAccelerator. -// This class should be constructed, used, and destructed on the main (render) -// thread. -class VideoDecoderShim : public media::VideoDecodeAccelerator { - public: - explicit VideoDecoderShim(PepperVideoDecoderHost* host); - virtual ~VideoDecoderShim(); - - // media::VideoDecodeAccelerator implementation. - virtual bool Initialize( - media::VideoCodecProfile profile, - media::VideoDecodeAccelerator::Client* client) OVERRIDE; - virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; - virtual void AssignPictureBuffers( - const std::vector& buffers) OVERRIDE; - virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; - virtual void Flush() OVERRIDE; - virtual void Reset() OVERRIDE; - virtual void Destroy() OVERRIDE; - - private: - enum State { - UNINITIALIZED, - DECODING, - FLUSHING, - RESETTING, - }; - - struct PendingDecode; - struct PendingFrame; - class DecoderImpl; - - void OnInitializeComplete(int32_t result, uint32_t texture_pool_size); - void OnDecodeComplete(int32_t result, uint32_t decode_id); - void OnOutputComplete(scoped_ptr frame); - void SendPictures(); - void OnResetComplete(); - void NotifyCompletedDecodes(); - void DismissTexture(uint32_t texture_id); - void DeleteTexture(uint32_t texture_id); - // Call this whenever we change GL state that the plugin relies on, such as - // creating picture textures. - void FlushCommandBuffer(); - - scoped_ptr decoder_impl_; - State state_; - - PepperVideoDecoderHost* host_; - scoped_refptr media_message_loop_; - scoped_refptr context_provider_; - - // The current decoded frame size. - gfx::Size texture_size_; - // Map that takes the plugin's GL texture id to the renderer's GL texture id. - typedef base::hash_map TextureIdMap; - TextureIdMap texture_id_map_; - // Available textures (these are plugin ids.) - std::vector available_textures_; - // Track textures that are no longer needed (these are plugin ids.) - typedef base::hash_set TextureIdSet; - TextureIdSet textures_to_dismiss_; - // Mailboxes for pending texture requests, to write to plugin's textures. - std::vector pending_texture_mailboxes_; - - // Queue of completed decode ids, for notifying the host. - typedef std::queue CompletedDecodeQueue; - CompletedDecodeQueue completed_decodes_; - - // Queue of decoded frames that have been converted to RGB and await upload to - // a GL texture. - typedef std::queue > PendingFrameQueue; - PendingFrameQueue pending_frames_; - - // The optimal number of textures to allocate for decoder_impl_. - uint32_t texture_pool_size_; - - uint32_t num_pending_decodes_; - - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(VideoDecoderShim); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_ diff --git a/content/test/ppapi/ppapi_browsertest.cc b/content/test/ppapi/ppapi_browsertest.cc index 95947be69071..0dd7047d6a9c 100644 --- a/content/test/ppapi/ppapi_browsertest.cc +++ b/content/test/ppapi/ppapi_browsertest.cc @@ -141,8 +141,6 @@ TEST_PPAPI_OUT_OF_PROCESS(MAYBE_VarDeprecated) TEST_PPAPI_IN_PROCESS(VarResource) TEST_PPAPI_OUT_OF_PROCESS(VarResource) -TEST_PPAPI_OUT_OF_PROCESS(VideoDecoder) - TEST_PPAPI_IN_PROCESS(VideoDecoderDev) TEST_PPAPI_OUT_OF_PROCESS(VideoDecoderDev) diff --git a/gpu/command_buffer/common/cmd_buffer_common.cc b/gpu/command_buffer/common/cmd_buffer_common.cc index f337e86dbf73..80a1e16dc3cf 100644 --- a/gpu/command_buffer/common/cmd_buffer_common.cc +++ b/gpu/command_buffer/common/cmd_buffer_common.cc @@ -31,7 +31,6 @@ const char* GetCommandName(CommandId command_id) { } // namespace cmd -#if !defined(NACL_WIN64) // TODO(apatrick): this is a temporary optimization while skia is calling // RendererGLContext::MakeCurrent prior to every GL call. It saves returning 6 // ints redundantly when only the error is needed for the CommandBufferProxy @@ -39,7 +38,6 @@ const char* GetCommandName(CommandId command_id) { error::Error CommandBuffer::GetLastError() { return GetLastState().error; } -#endif } // namespace gpu diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 7d0695e10896..773182516e3b 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -567,28 +567,6 @@ ['disable_nacl!=1 and OS=="win" and target_arch=="ia32"', { 'targets': [ { - 'target_name': 'command_buffer_common_win64', - 'type': 'static_library', - 'variables': { - 'nacl_win64_target': 1, - }, - 'includes': [ - 'command_buffer_common.gypi', - ], - 'dependencies': [ - '../base/base.gyp:base_win64', - ], - 'defines': [ - '<@(nacl_win64_defines)', - 'GPU_IMPLEMENTATION', - ], - 'configurations': { - 'Common_Base': { - 'msvs_target_platform': 'x64', - }, - }, - }, - { 'target_name': 'gpu_ipc_win64', 'type': 'static_library', 'variables': { @@ -600,7 +578,6 @@ 'dependencies': [ '../base/base.gyp:base_win64', '../ipc/ipc.gyp:ipc_win64', - 'command_buffer_common_win64', ], 'defines': [ '<@(nacl_win64_defines)', diff --git a/ppapi/examples/video_decode/video_decode.cc b/ppapi/examples/video_decode/video_decode.cc index 0e47dcfe194e..de9bb8df2c0c 100644 --- a/ppapi/examples/video_decode/video_decode.cc +++ b/ppapi/examples/video_decode/video_decode.cc @@ -20,12 +20,7 @@ #include "ppapi/cpp/rect.h" #include "ppapi/cpp/var.h" #include "ppapi/cpp/video_decoder.h" - -// VP8 is more likely to work on different versions of Chrome. Undefine this -// to decode H264. -#define USE_VP8_TESTDATA_INSTEAD_OF_H264 #include "ppapi/examples/video_decode/testdata.h" - #include "ppapi/lib/gl/include/GLES2/gl2.h" #include "ppapi/lib/gl/include/GLES2/gl2ext.h" #include "ppapi/utility/completion_callback_factory.h" @@ -61,7 +56,6 @@ class MyInstance : public pp::Instance, public pp::Graphics3DClient { // pp::Instance implementation. virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip_ignored); - virtual bool HandleInputEvent(const pp::InputEvent& event); // pp::Graphics3DClient implementation. virtual void Graphics3DContextLost() { @@ -145,12 +139,12 @@ class Decoder { int id() const { return id_; } bool decoding() const { return !flushing_ && !resetting_; } - void Reset(); + void Seek(int frame); void RecyclePicture(const PP_VideoPicture& picture); private: void InitializeDone(int32_t result); - void Start(); + void Start(int frame); void DecodeNextFrame(); void DecodeDone(int32_t result); void PictureReady(int32_t result, PP_VideoPicture picture); @@ -165,29 +159,11 @@ class Decoder { size_t encoded_data_next_pos_to_decode_; int next_picture_id_; + int seek_frame_; bool flushing_; bool resetting_; }; -#if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 - -// VP8 is stored in an IVF container. -// Helpful description: http://wiki.multimedia.cx/index.php?title=IVF - -static void GetNextFrame(size_t* start_pos, size_t* end_pos) { - size_t current_pos = *start_pos; - if (current_pos == 0) - current_pos = 32; // Skip stream header. - uint32_t frame_size = kData[current_pos] + (kData[current_pos + 1] << 8) + - (kData[current_pos + 2] << 16) + - (kData[current_pos + 3] << 24); - current_pos += 12; // Skip frame header. - *start_pos = current_pos; - *end_pos = current_pos + frame_size; -} - -#else // !USE_VP8_TESTDATA_INSTEAD_OF_H264 - // Returns true if the current position is at the start of a NAL unit. static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { // H264 frames start with 0, 0, 0, 1 in our test data. @@ -195,6 +171,7 @@ static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { encoded[pos + 2] == 0 && encoded[pos + 3] == 1; } +// Find the start and end of the next frame. static void GetNextFrame(size_t* start_pos, size_t* end_pos) { assert(LookingAtNAL(kData, *start_pos)); *end_pos = *start_pos; @@ -204,8 +181,6 @@ static void GetNextFrame(size_t* start_pos, size_t* end_pos) { } } -#endif // USE_VP8_TESTDATA_INSTEAD_OF_H264 - Decoder::Decoder(MyInstance* instance, int id, const pp::Graphics3D& graphics_3d) @@ -215,19 +190,14 @@ Decoder::Decoder(MyInstance* instance, callback_factory_(this), encoded_data_next_pos_to_decode_(0), next_picture_id_(0), + seek_frame_(0), flushing_(false), resetting_(false) { -// TODO(bbudge) Remove this for final patch. -#if defined USE_VP8_TESTDATA_INSTEAD_OF_H264 - const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_VP8MAIN; -#else - const PP_VideoProfile kBitstreamProfile = PP_VIDEOPROFILE_H264MAIN; -#endif - assert(!decoder_->is_null()); + const PP_VideoProfile profile = PP_VIDEOPROFILE_H264MAIN; decoder_->Initialize(graphics_3d, - kBitstreamProfile, - PP_TRUE /* allow_software_fallback */, + profile, + PP_FALSE /* allow_software_fallback */, callback_factory_.NewCallback(&Decoder::InitializeDone)); } @@ -239,13 +209,18 @@ void Decoder::InitializeDone(int32_t result) { assert(decoder_); assert(result == PP_OK); assert(decoding()); - Start(); + Start(0); } -void Decoder::Start() { +void Decoder::Start(int frame) { assert(decoder_); - encoded_data_next_pos_to_decode_ = 0; + // Skip to |frame|. + size_t start_pos = 0; + size_t end_pos = 0; + for (int i = 0; i < frame; i++) + GetNextFrame(&start_pos, &end_pos); + encoded_data_next_pos_to_decode_ = end_pos; // Register callback to get the first picture. We call GetPicture again in // PictureReady to continuously receive pictures as they're decoded. @@ -256,8 +231,9 @@ void Decoder::Start() { DecodeNextFrame(); } -void Decoder::Reset() { +void Decoder::Seek(int frame) { assert(decoder_); + seek_frame_ = frame; resetting_ = true; decoder_->Reset(callback_factory_.NewCallback(&Decoder::ResetDone)); } @@ -323,8 +299,6 @@ void Decoder::ResetDone(int32_t result) { assert(decoder_); assert(result == PP_OK); resetting_ = false; - - Start(); } MyInstance::MyInstance(PP_Instance instance, pp::Module* module) @@ -379,25 +353,6 @@ void MyInstance::DidChangeView(const pp::Rect& position, InitializeDecoders(); } -bool MyInstance::HandleInputEvent(const pp::InputEvent& event) { - switch (event.GetType()) { - case PP_INPUTEVENT_TYPE_MOUSEDOWN: { - pp::MouseInputEvent mouse_event(event); - // Reset all decoders on mouse down. - if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) { - for (size_t i = 0; i < video_decoders_.size(); i++) { - if (video_decoders_[i]->decoding()) - video_decoders_[i]->Reset(); - } - } - return true; - } - - default: - return false; - } -} - void MyInstance::InitializeDecoders() { assert(video_decoders_.empty()); // Create two decoders with ids 0 and 1. diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi index 03609b038f0b..3ce2288286ef 100644 --- a/ppapi/ppapi_sources.gypi +++ b/ppapi/ppapi_sources.gypi @@ -508,8 +508,6 @@ 'tests/test_var.h', 'tests/test_var_resource.cc', 'tests/test_var_resource.h', - 'tests/test_video_decoder.cc', - 'tests/test_video_decoder.h', 'tests/test_video_destination.cc', 'tests/test_video_destination.h', 'tests/test_video_source.cc', diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 41b40ce53724..2e18fd4eaea7 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1861,11 +1861,10 @@ IPC_MESSAGE_CONTROL3(PpapiHostMsg_VideoDecoder_Decode, int32_t /* decode_id */) IPC_MESSAGE_CONTROL1(PpapiPluginMsg_VideoDecoder_DecodeReply, uint32_t /* shm_id */) -IPC_MESSAGE_CONTROL4(PpapiPluginMsg_VideoDecoder_RequestTextures, +IPC_MESSAGE_CONTROL3(PpapiPluginMsg_VideoDecoder_RequestTextures, uint32_t /* num_textures */, PP_Size /* size */, - uint32_t /* texture_target */, - std::vector /* mailboxes*/) + uint32_t /* texture_target */) IPC_MESSAGE_CONTROL2(PpapiHostMsg_VideoDecoder_AssignTextures, PP_Size /* size */, std::vector /* texture_ids */) diff --git a/ppapi/proxy/video_decoder_resource.cc b/ppapi/proxy/video_decoder_resource.cc index 2ca5ce2de8e0..95365e8bba8e 100644 --- a/ppapi/proxy/video_decoder_resource.cc +++ b/ppapi/proxy/video_decoder_resource.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/common/mailbox.h" #include "ipc/ipc_message.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_opengles2.h" @@ -113,7 +112,7 @@ int32_t VideoDecoderResource::Initialize( enter_create.functions()->CreateGraphics3D( pp_instance(), graphics_context, attrib_list)); EnterResourceNoLock enter_graphics(graphics3d_.get(), - false); + true); if (enter_graphics.failed()) return PP_ERROR_BADRESOURCE; @@ -333,10 +332,8 @@ void VideoDecoderResource::OnPluginMsgRequestTextures( const ResourceMessageReplyParams& params, uint32_t num_textures, const PP_Size& size, - uint32_t texture_target, - const std::vector& mailboxes) { + uint32_t texture_target) { DCHECK(num_textures); - DCHECK(mailboxes.empty() || mailboxes.size() == num_textures); std::vector texture_ids(num_textures); if (gles2_impl_) { gles2_impl_->GenTextures(num_textures, &texture_ids.front()); @@ -363,10 +360,6 @@ void VideoDecoderResource::OnPluginMsgRequestTextures( GL_UNSIGNED_BYTE, NULL); } - if (!mailboxes.empty()) { - gles2_impl_->ProduceTextureCHROMIUM( - GL_TEXTURE_2D, reinterpret_cast(mailboxes[i].name)); - } textures_.insert( std::make_pair(texture_ids[i], Texture(texture_target, size))); diff --git a/ppapi/proxy/video_decoder_resource.h b/ppapi/proxy/video_decoder_resource.h index a466eb2774ff..19ccffb94ad4 100644 --- a/ppapi/proxy/video_decoder_resource.h +++ b/ppapi/proxy/video_decoder_resource.h @@ -19,7 +19,6 @@ #include "ppapi/thunk/ppb_video_decoder_api.h" namespace gpu { -struct Mailbox; namespace gles2 { class GLES2Implementation; } @@ -108,8 +107,7 @@ class PPAPI_PROXY_EXPORT VideoDecoderResource void OnPluginMsgRequestTextures(const ResourceMessageReplyParams& params, uint32_t num_textures, const PP_Size& size, - uint32_t texture_target, - const std::vector& mailboxes); + uint32_t texture_target); void OnPluginMsgPictureReady(const ResourceMessageReplyParams& params, int32_t decode_id, uint32_t texture_id); diff --git a/ppapi/proxy/video_decoder_resource_unittest.cc b/ppapi/proxy/video_decoder_resource_unittest.cc index b9f0e7918d44..228da923fe27 100644 --- a/ppapi/proxy/video_decoder_resource_unittest.cc +++ b/ppapi/proxy/video_decoder_resource_unittest.cc @@ -236,10 +236,7 @@ class VideoDecoderResourceTest : public PluginProxyTest { SendReply(params, PP_OK, PpapiPluginMsg_VideoDecoder_RequestTextures( - kNumRequestedTextures, - PP_MakeSize(320, 240), - GL_TEXTURE_2D, - std::vector())); + kNumRequestedTextures, PP_MakeSize(320, 240), GL_TEXTURE_2D)); } void SendNotifyError(const ResourceMessageCallParams& params, int32_t error) { diff --git a/ppapi/tests/test_video_decoder.cc b/ppapi/tests/test_video_decoder.cc deleted file mode 100644 index 01dee3e229be..000000000000 --- a/ppapi/tests/test_video_decoder.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ppapi/tests/test_video_decoder.h" - -#include "ppapi/c/pp_errors.h" -#include "ppapi/cpp/video_decoder.h" -#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h" -#include "ppapi/tests/testing_instance.h" - -REGISTER_TEST_CASE(VideoDecoder); - -static const bool kAllowSoftwareFallback = true; - -bool TestVideoDecoder::Init() { - video_decoder_interface_ = static_cast( - pp::Module::Get()->GetBrowserInterface(PPB_VIDEODECODER_INTERFACE_0_1)); - const int width = 16; - const int height = 16; - const int32_t attribs[] = {PP_GRAPHICS3DATTRIB_WIDTH, width, - PP_GRAPHICS3DATTRIB_HEIGHT, height, - PP_GRAPHICS3DATTRIB_NONE}; - graphics_3d_ = pp::Graphics3D(instance_, attribs); - return video_decoder_interface_ && CheckTestingInterface(); -} - -void TestVideoDecoder::RunTests(const std::string& filter) { - RUN_CALLBACK_TEST(TestVideoDecoder, Create, filter); -} - -std::string TestVideoDecoder::TestCreate() { - // Test that Initialize fails with a bad Graphics3D resource. - { - pp::VideoDecoder video_decoder(instance_); - ASSERT_FALSE(video_decoder.is_null()); - - TestCompletionCallback callback(instance_->pp_instance(), callback_type()); - pp::Graphics3D null_graphics_3d; - callback.WaitForResult(video_decoder.Initialize(null_graphics_3d, - PP_VIDEOPROFILE_VP8MAIN, - kAllowSoftwareFallback, - callback.GetCallback())); - ASSERT_EQ(PP_ERROR_BADRESOURCE, callback.result()); - } - // Test that Initialize fails with a bad profile enum value. - { - pp::VideoDecoder video_decoder(instance_); - TestCompletionCallback callback(instance_->pp_instance(), callback_type()); - const PP_VideoProfile kInvalidProfile = static_cast(-1); - callback.WaitForResult(video_decoder.Initialize(graphics_3d_, - kInvalidProfile, - kAllowSoftwareFallback, - callback.GetCallback())); - ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); - } - // Test that Initialize succeeds if we can create a Graphics3D resources and - // if we allow software fallback to VP8, which should always be supported. - if (!graphics_3d_.is_null()) { - pp::VideoDecoder video_decoder(instance_); - TestCompletionCallback callback(instance_->pp_instance(), callback_type()); - callback.WaitForResult(video_decoder.Initialize(graphics_3d_, - PP_VIDEOPROFILE_VP8MAIN, - kAllowSoftwareFallback, - callback.GetCallback())); - ASSERT_EQ(PP_OK, callback.result()); - } - - PASS(); -} diff --git a/ppapi/tests/test_video_decoder.h b/ppapi/tests/test_video_decoder.h deleted file mode 100644 index d93b7055e53e..000000000000 --- a/ppapi/tests/test_video_decoder.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef PPAPI_TESTS_TEST_VIDEO_DECODER_H_ -#define PPAPI_TESTS_TEST_VIDEO_DECODER_H_ - -#include - -#include "ppapi/c/pp_stdint.h" -#include "ppapi/c/ppb_video_decoder.h" -#include "ppapi/cpp/graphics_3d.h" -#include "ppapi/tests/test_case.h" - -class TestVideoDecoder : public TestCase { - public: - explicit TestVideoDecoder(TestingInstance* instance) : TestCase(instance) {} - - private: - // TestCase implementation. - virtual bool Init(); - virtual void RunTests(const std::string& filter); - - std::string TestCreate(); - - // Used by the tests that access the C API directly. - const PPB_VideoDecoder_0_1* video_decoder_interface_; - - pp::Graphics3D graphics_3d_; -}; - -#endif // PPAPI_TESTS_TEST_VIDEO_DECODER_H_ -- 2.11.4.GIT