| Index: content/renderer/pepper/video_decoder_proxy.h
|
| diff --git a/content/renderer/pepper/video_decoder_proxy.h b/content/renderer/pepper/video_decoder_proxy.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..98320cbbb2f64d6fddebcfffcb28f3f1958ead7b
|
| --- /dev/null
|
| +++ b/content/renderer/pepper/video_decoder_proxy.h
|
| @@ -0,0 +1,173 @@
|
| +// 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_PROXY_H_
|
| +#define CONTENT_RENDERER_PEPPER_VIDEO_DECODER_PROXY_H_
|
| +
|
| +#include <queue>
|
| +#include <vector>
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/containers/hash_tables.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +#include "gpu/command_buffer/common/mailbox.h"
|
| +#include "media/base/decoder_buffer.h"
|
| +#include "media/base/video_decoder.h"
|
| +#include "media/base/video_decoder_config.h"
|
| +
|
| +#include "ppapi/c/pp_codecs.h"
|
| +
|
| +namespace gpu {
|
| +namespace gles2 {
|
| +class GLES2Interface;
|
| +}
|
| +}
|
| +
|
| +namespace webkit {
|
| +namespace gpu {
|
| +class ContextProviderWebContext;
|
| +}
|
| +}
|
| +
|
| +namespace content {
|
| +
|
| +class PepperVideoDecoderHost;
|
| +
|
| +// This class proxies calls to a media::VideoDecoder on the media thread.
|
| +// Instances should be constructed, used, and destructed on the main (render)
|
| +// thread.
|
| +class VideoDecoderProxy {
|
| + public:
|
| + explicit VideoDecoderProxy(PepperVideoDecoderHost* host);
|
| +
|
| + void Initialize(media::VideoCodecProfile profile);
|
| + void Decode(uint32_t decode_id, const uint8_t* buffer, uint32_t size);
|
| + void AssignTextures(const std::vector<uint32_t>& texture_ids);
|
| + void RecycleTexture(uint32_t texture_id);
|
| + void Flush();
|
| + void Reset();
|
| + void Destroy();
|
| +
|
| + protected:
|
| + // Do not delete directly; use Destroy() or own it with a scoped_ptr, which
|
| + // will Destroy() it properly by default.
|
| + ~VideoDecoderProxy();
|
| +
|
| + private:
|
| + enum State {
|
| + UNINITIALIZED,
|
| + DECODING,
|
| + FLUSHING,
|
| + RESETTING,
|
| + };
|
| +
|
| + struct PendingDecode {
|
| + PendingDecode(uint32_t decode_id,
|
| + const scoped_refptr<media::DecoderBuffer>& buffer);
|
| + ~PendingDecode();
|
| +
|
| + uint32_t decode_id;
|
| + scoped_refptr<media::DecoderBuffer> buffer;
|
| + };
|
| +
|
| + struct PendingFrame {
|
| + PendingFrame(uint32_t decode_id, const gfx::Size& size);
|
| + ~PendingFrame();
|
| +
|
| + uint32_t decode_id;
|
| + gfx::Size size;
|
| + std::vector<uint8_t> pixels;
|
| + };
|
| +
|
| + // This class is constructed and destructed on the main (render) thread, but
|
| + // used only on the media thread.
|
| + class Delegate {
|
| + public:
|
| + Delegate(VideoDecoderProxy* proxy);
|
| + ~Delegate();
|
| +
|
| + void Initialize(media::VideoDecoderConfig config,
|
| + scoped_ptr<media::VideoDecoder> decoder);
|
| + void ReceiveBuffer(uint32_t decode_id,
|
| + scoped_refptr<media::DecoderBuffer> buffer);
|
| + void Decode();
|
| + void Reset();
|
| + void Destroy();
|
| +
|
| + private:
|
| + void OnPipelineStatus(media::PipelineStatus status);
|
| + void ConvertFrame(uint32_t decode_id,
|
| + media::VideoDecoder::Status status,
|
| + const scoped_refptr<media::VideoFrame>& frame);
|
| + void OnResetComplete();
|
| +
|
| + VideoDecoderProxy* proxy_;
|
| + scoped_ptr<media::VideoDecoder> decoder_;
|
| + scoped_refptr<base::MessageLoopProxy> main_message_loop_;
|
| + // Queue of decodes waiting for the decoder.
|
| + typedef std::queue<PendingDecode> PendingDecodeQueue;
|
| + PendingDecodeQueue pending_decodes_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Delegate);
|
| + };
|
| +
|
| + void OnPipelineStatus(media::PipelineStatus status);
|
| + void ReceiveFrame(media::VideoDecoder::Status status,
|
| + scoped_ptr<PendingFrame> frame);
|
| + void SendPictures();
|
| + void OnResetComplete();
|
| + void OnDestroyComplete();
|
| + void DismissTexture(uint32_t texture_id);
|
| + void DeleteTexture(uint32_t texture_id);
|
| + void FlushCommandBuffer();
|
| +
|
| + Delegate delegate_;
|
| + State state_;
|
| +
|
| + PepperVideoDecoderHost* host_;
|
| + scoped_refptr<base::MessageLoopProxy> media_message_loop_;
|
| + scoped_refptr<webkit::gpu::ContextProviderWebContext> 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<uint32_t, uint32_t> TextureIdMap;
|
| + TextureIdMap texture_id_map_;
|
| + // Available textures (these are plugin ids.)
|
| + std::vector<uint32_t> available_textures_;
|
| + // Track textures that are no longer needed (these are plugin ids.)
|
| + typedef base::hash_set<uint32_t> TextureIdSet;
|
| + TextureIdSet textures_to_dismiss_;
|
| + // Mailboxes for pending texture requests, to write to plugin's textures.
|
| + std::vector<gpu::Mailbox> pending_texture_mailboxes_;
|
| + // Queue of pending decoded frames. These have been converted to RGB, and
|
| + // await upload to a GL texture.
|
| + typedef std::queue<PendingFrame*> PendingFrameQueue;
|
| + PendingFrameQueue pending_frames_;
|
| + uint32_t num_pending_decodes_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(VideoDecoderProxy);
|
| +};
|
| +
|
| +} // namespace content
|
| +
|
| +namespace base {
|
| +
|
| +template <class T>
|
| +struct DefaultDeleter;
|
| +
|
| +// Specialize DefaultDeleter so that scoped_ptr<content::VideoDecoderProxy>
|
| +// always uses "Destroy()" instead of trying to use the destructor.
|
| +template <>
|
| +struct DefaultDeleter<content::VideoDecoderProxy> {
|
| + public:
|
| + inline void operator()(void* video_decoder) const {
|
| + static_cast<content::VideoDecoderProxy*>(video_decoder)->Destroy();
|
| + }
|
| +};
|
| +
|
| +} // namespace base
|
| +
|
| +#endif // CONTENT_RENDERER_PEPPER_VIDEO_DECODER_PROXY_H_
|
|
|