blob: 4fca8ec6498ecbaca90194cd0ee36b37c67b8856 [file] [log] [blame]
// Copyright (c) 2011 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_GPU_VIDEO_DECODER_HOST_H_
#define CONTENT_RENDERER_GPU_VIDEO_DECODER_HOST_H_
#include <deque>
#include <map>
#include "base/memory/singleton.h"
#include "base/shared_memory.h"
#include "content/renderer/gpu_channel_host.h"
#include "media/base/buffers.h"
#include "media/base/video_frame.h"
#include "media/video/video_decode_engine.h"
using media::VideoFrame;
using media::Buffer;
class MessageRouter;
struct GpuVideoDecoderInitDoneParam;
// This class is used to talk to GpuVideoDecoder in the GPU process through
// IPC messages. It implements the interface of VideoDecodeEngine so users
// view it as a regular video decode engine, the implementation is a portal
// to the GPU process.
//
// THREAD SEMANTICS
//
// All methods of this class can be accessed on any thread. A message loop
// needs to be provided to class through Initialize() for accessing the
// IPC channel. Event handlers are called on that message loop.
//
// Since this class is not refcounted, it is important to delete this
// object only after OnUninitializeCompelte() is called.
class GpuVideoDecoderHost : public media::VideoDecodeEngine,
public IPC::Channel::Listener {
public:
// |router| is used to dispatch IPC messages to this object.
// |ipc_sender| is used to send IPC messages to GPU process.
// It is important that the above two objects are accessed on the
// |message_loop_|.
GpuVideoDecoderHost(MessageRouter* router,
IPC::Message::Sender* ipc_sender,
int context_route_id,
int32 decoder_host_id);
virtual ~GpuVideoDecoderHost();
// IPC::Channel::Listener.
virtual void OnChannelConnected(int32 peer_pid) {}
virtual void OnChannelError();
virtual bool OnMessageReceived(const IPC::Message& message);
// media::VideoDecodeEngine implementation.
virtual void Initialize(MessageLoop* message_loop,
VideoDecodeEngine::EventHandler* event_handler,
media::VideoDecodeContext* context,
const media::VideoCodecConfig& config);
virtual void ConsumeVideoSample(scoped_refptr<Buffer> buffer);
virtual void ProduceVideoFrame(scoped_refptr<VideoFrame> frame);
virtual void Uninitialize();
virtual void Flush();
virtual void Seek();
private:
typedef std::map<int32, scoped_refptr<media::VideoFrame> > VideoFrameMap;
// Internal states.
enum GpuVideoDecoderHostState {
kStateUninitialized,
kStateNormal,
kStateError,
kStateFlushing,
};
// Takes care of sending IPC message to create a video decoder.
void CreateVideoDecoder();
// Handlers for messages received from the GPU process.
void OnCreateVideoDecoderDone(int32 decoder_id);
void OnInitializeDone(const GpuVideoDecoderInitDoneParam& param);
void OnUninitializeDone();
void OnFlushDone();
void OnPrerollDone();
void OnEmptyThisBufferACK();
void OnProduceVideoSample();
void OnConsumeVideoFrame(int32 frame_id, int64 timestamp,
int64 duration, int32 flags);
void OnAllocateVideoFrames(int32 n, uint32 width,
uint32 height, int32 format);
void OnReleaseAllVideoFrames();
// Handler for VideoDecodeContext. This method is called when video frames
// allocation is done.
void OnAllocateVideoFramesDone();
// Send a message to the GPU process to inform that a video frame is
// allocated.
void SendVideoFrameAllocated(int32 frame_id,
scoped_refptr<media::VideoFrame> frame);
// Send a video sample to the GPU process and tell it to use the buffer for
// video decoding.
void SendConsumeVideoSample();
// Look up the frame_id for |frame| and send a message to the GPU process
// to use that video frame to produce an output.
void SendProduceVideoFrame(scoped_refptr<media::VideoFrame> frame);
// A router used to send us IPC messages.
MessageRouter* router_;
// Sends IPC messages to the GPU process.
IPC::Message::Sender* ipc_sender_;
// Route ID of the GLES2 context in the GPU process.
int context_route_id_;
// Message loop that this object runs on.
MessageLoop* message_loop_;
// We expect that the client of us will always available during our life span.
EventHandler* event_handler_;
// A Context for allocating video frame textures.
media::VideoDecodeContext* context_;
// Dimensions of the video.
int width_;
int height_;
// Current state of video decoder.
GpuVideoDecoderHostState state_;
// ID of this GpuVideoDecoderHost.
int32 decoder_host_id_;
// ID of GpuVideoDecoder in the GPU process.
int32 decoder_id_;
// We are not able to push all received buffer to gpu process at once.
std::deque<scoped_refptr<Buffer> > input_buffer_queue_;
// Currently we do not use ring buffer in input buffer, therefore before
// GPU process had finished access it, we should not touch it.
bool input_buffer_busy_;
// Transfer buffers for both input and output.
// TODO(jiesun): remove output buffer when hardware composition is ready.
scoped_ptr<base::SharedMemory> input_transfer_buffer_;
// Frame ID for the newly generated video frame.
int32 current_frame_id_;
// The list of video frames allocated by VideoDecodeContext.
std::vector<scoped_refptr<media::VideoFrame> > video_frames_;
// The mapping between video frame ID and a video frame.
VideoFrameMap video_frame_map_;
DISALLOW_COPY_AND_ASSIGN(GpuVideoDecoderHost);
};
#endif // CONTENT_RENDERER_GPU_VIDEO_DECODER_HOST_H_