| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_GPU_GPU_VIDEO_DECODER_H_ | |
| 6 #define CHROME_GPU_GPU_VIDEO_DECODER_H_ | |
| 7 | |
| 8 #include <map> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/basictypes.h" | |
| 12 #include "base/callback.h" | |
| 13 #include "base/process.h" | |
| 14 #include "base/ref_counted.h" | |
| 15 #include "base/scoped_ptr.h" | |
| 16 #include "base/shared_memory.h" | |
| 17 #include "chrome/gpu/media/gpu_video_device.h" | |
| 18 #include "media/video/video_decode_context.h" | |
| 19 #include "media/video/video_decode_engine.h" | |
| 20 #include "ipc/ipc_channel.h" | |
| 21 | |
| 22 using media::Buffer; | |
| 23 using media::PipelineStatistics; | |
| 24 using media::VideoCodecConfig; | |
| 25 using media::VideoCodecInfo; | |
| 26 using media::VideoStreamInfo; | |
| 27 using media::VideoFrame; | |
| 28 | |
| 29 namespace gpu { | |
| 30 namespace gles2 { | |
| 31 class GLES2Decoder; | |
| 32 } // namespace gles2 | |
| 33 } // namespace gpu | |
| 34 | |
| 35 class GpuChannel; | |
| 36 struct GpuVideoDecoderInitDoneParam; | |
| 37 struct GpuVideoDecoderInitParam; | |
| 38 struct GpuVideoDecoderInputBufferParam; | |
| 39 | |
| 40 // A GpuVideoDecoder is a platform independent video decoder that uses platform | |
| 41 // specific VideoDecodeEngine and GpuVideoDevice for the actual decoding | |
| 42 // operations. | |
| 43 // | |
| 44 // In addition to delegating video related commamnds to VideoDecodeEngine it | |
| 45 // has the following important functions: | |
| 46 // | |
| 47 // BUFFER ALLOCATION | |
| 48 // | |
| 49 // VideoDecodeEngine requires platform specific video frame buffer to operate. | |
| 50 // In order to abstract the platform specific bits GpuVideoDecoderContext is | |
| 51 // used to allocate video frames that a VideoDecodeEngine can use. | |
| 52 // | |
| 53 // Since all the video frames appear to the Renderer process as textures, the | |
| 54 // first thing GpuVideoDecoder needs to do is to ask Renderer process to | |
| 55 // generate and allocate textures. This will establish a texture record in the | |
| 56 // command buffer decoder. After the texture is allocated, this class will | |
| 57 // pass the textures meaningful in the local GLES context to | |
| 58 // GpuVideoDevice for generating VideoFrames that VideoDecodeEngine | |
| 59 // can actually use. | |
| 60 // | |
| 61 // In order to coordinate these operations, GpuVideoDecoder implements | |
| 62 // VideoDecodeContext and is injected into the VideoDecodeEngine. | |
| 63 // | |
| 64 // The sequence of operations is: | |
| 65 // 1. VideoDecodeEngine requests by call AllocateVideoFrames(). | |
| 66 // 2. GpuVideoDecoder receives AllocateVideoFrames() and then call to the | |
| 67 // Renderer process to generate textures. | |
| 68 // 3. Renderer process replied with textures. | |
| 69 // 4. Textures generated are passed into GpuVideoDevice. | |
| 70 // 5. GpuVideoDevice::AllocateVideoFrames() is called to generate | |
| 71 // VideoFrame(s) from the textures. | |
| 72 // 6. GpuVideoDecoder sends the VideoFrame(s) generated to VideoDecodeEngine. | |
| 73 // | |
| 74 // BUFFER UPLOADING | |
| 75 // | |
| 76 // A VideoDecodeEngine always produces some device specific buffer. In order to | |
| 77 // use them in Chrome we always upload them to GL textures. The upload step is | |
| 78 // different on each platform and each subsystem. We perform these special | |
| 79 // upload steps by using GpuVideoDevice which are written for each | |
| 80 // VideoDecodeEngine. | |
| 81 // | |
| 82 // BUFFER MAPPING | |
| 83 // | |
| 84 // GpuVideoDecoder will be working with VideoDecodeEngine, they exchange | |
| 85 // buffers that are only meaningful to VideoDecodeEngine. In order to map that | |
| 86 // to something we can transport in the IPC channel we need a mapping between | |
| 87 // VideoFrame and buffer ID known between GpuVideoDecoder and | |
| 88 // GpuVideoDecoderHost in the Renderer process. | |
| 89 // | |
| 90 // After texture allocation and VideoFrame allocation are done, GpuVideoDecoder | |
| 91 // will maintain such mapping. | |
| 92 // | |
| 93 class GpuVideoDecoder | |
| 94 : public base::RefCountedThreadSafe<GpuVideoDecoder>, | |
| 95 public IPC::Channel::Listener, | |
| 96 public media::VideoDecodeEngine::EventHandler, | |
| 97 public media::VideoDecodeContext { | |
| 98 public: | |
| 99 // Constructor and destructor. | |
| 100 GpuVideoDecoder(MessageLoop* message_loop, | |
| 101 int32 decoder_host_id, | |
| 102 IPC::Message::Sender* sender, | |
| 103 base::ProcessHandle handle, | |
| 104 gpu::gles2::GLES2Decoder* decoder); | |
| 105 virtual ~GpuVideoDecoder(); | |
| 106 | |
| 107 // IPC::Channel::Listener implementation. | |
| 108 virtual void OnChannelConnected(int32 peer_pid); | |
| 109 virtual void OnChannelError(); | |
| 110 virtual bool OnMessageReceived(const IPC::Message& message); | |
| 111 | |
| 112 // VideoDecodeEngine::EventHandler implementation. | |
| 113 virtual void OnInitializeComplete(const VideoCodecInfo& info); | |
| 114 virtual void OnUninitializeComplete(); | |
| 115 virtual void OnFlushComplete(); | |
| 116 virtual void OnSeekComplete(); | |
| 117 virtual void OnError(); | |
| 118 virtual void OnFormatChange(VideoStreamInfo stream_info); | |
| 119 virtual void ProduceVideoSample(scoped_refptr<Buffer> buffer); | |
| 120 virtual void ConsumeVideoFrame(scoped_refptr<VideoFrame> frame, | |
| 121 const PipelineStatistics& statistics); | |
| 122 | |
| 123 // VideoDecodeContext implementation. | |
| 124 virtual void* GetDevice(); | |
| 125 virtual void AllocateVideoFrames( | |
| 126 int n, size_t width, size_t height, media::VideoFrame::Format format, | |
| 127 std::vector<scoped_refptr<media::VideoFrame> >* frames, Task* task); | |
| 128 virtual void ReleaseAllVideoFrames(); | |
| 129 virtual void ConvertToVideoFrame(void* buffer, | |
| 130 scoped_refptr<media::VideoFrame> frame, | |
| 131 Task* task); | |
| 132 virtual void Destroy(Task* task); | |
| 133 | |
| 134 // These methods are used in unit test only. | |
| 135 void SetVideoDecodeEngine(media::VideoDecodeEngine* engine); | |
| 136 void SetGpuVideoDevice(GpuVideoDevice* device); | |
| 137 | |
| 138 private: | |
| 139 struct PendingAllocation; | |
| 140 | |
| 141 int32 decoder_host_id() { return decoder_host_id_; } | |
| 142 | |
| 143 bool CreateInputTransferBuffer(uint32 size, | |
| 144 base::SharedMemoryHandle* handle); | |
| 145 | |
| 146 // These methods are message handlers for the messages sent from the Renderer | |
| 147 // process. | |
| 148 void OnInitialize(const GpuVideoDecoderInitParam& param); | |
| 149 void OnUninitialize(); | |
| 150 void OnFlush(); | |
| 151 void OnPreroll(); | |
| 152 void OnEmptyThisBuffer(const GpuVideoDecoderInputBufferParam& buffer); | |
| 153 void OnProduceVideoFrame(int32 frame_id); | |
| 154 void OnVideoFrameAllocated(int32 frame_id, std::vector<uint32> textures); | |
| 155 | |
| 156 // Helper methods for sending messages to the Renderer process. | |
| 157 void SendInitializeDone(const GpuVideoDecoderInitDoneParam& param); | |
| 158 void SendUninitializeDone(); | |
| 159 void SendFlushDone(); | |
| 160 void SendPrerollDone(); | |
| 161 void SendEmptyBufferDone(); | |
| 162 void SendEmptyBufferACK(); | |
| 163 void SendConsumeVideoFrame(int32 frame_id, int64 timestamp, int64 duration, | |
| 164 int32 flags); | |
| 165 void SendAllocateVideoFrames( | |
| 166 int n, size_t width, size_t height, media::VideoFrame::Format format); | |
| 167 void SendReleaseAllVideoFrames(); | |
| 168 | |
| 169 // The message loop that this object should run on. | |
| 170 MessageLoop* message_loop_; | |
| 171 | |
| 172 // ID of GpuVideoDecoderHost in the Renderer Process. | |
| 173 int32 decoder_host_id_; | |
| 174 | |
| 175 // Used only in system memory path. i.e. Remove this later. | |
| 176 scoped_refptr<VideoFrame> frame_; | |
| 177 | |
| 178 IPC::Message::Sender* sender_; | |
| 179 base::ProcessHandle renderer_handle_; | |
| 180 | |
| 181 // The GLES2 decoder has the context associated with this decoder. This object | |
| 182 // is used to switch context and translate client texture ID to service ID. | |
| 183 gpu::gles2::GLES2Decoder* gles2_decoder_; | |
| 184 | |
| 185 // Memory for transfering the input data for the hardware video decoder. | |
| 186 scoped_ptr<base::SharedMemory> input_transfer_buffer_; | |
| 187 | |
| 188 // VideoDecodeEngine is used to do the actual video decoding. | |
| 189 scoped_ptr<media::VideoDecodeEngine> decode_engine_; | |
| 190 | |
| 191 // GpuVideoDevice is used to generate VideoFrame(s) from GL textures. The | |
| 192 // frames generated are understood by the decode engine. | |
| 193 scoped_ptr<GpuVideoDevice> video_device_; | |
| 194 | |
| 195 // Contain information for allocation VideoFrame(s). | |
| 196 scoped_ptr<PendingAllocation> pending_allocation_; | |
| 197 | |
| 198 // Contains the mapping between a |frame_id| and VideoFrame generated by | |
| 199 // GpuVideoDevice from the associated GL textures. | |
| 200 // TODO(hclam): Using a faster data structure than map. | |
| 201 typedef std::map<int32, scoped_refptr<media::VideoFrame> > VideoFrameMap; | |
| 202 VideoFrameMap video_frame_map_; | |
| 203 | |
| 204 media::VideoCodecInfo info_; | |
| 205 | |
| 206 DISALLOW_COPY_AND_ASSIGN(GpuVideoDecoder); | |
| 207 }; | |
| 208 | |
| 209 #endif // CHROME_GPU_GPU_VIDEO_DECODER_H_ | |
| OLD | NEW |