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 // VideoDecoderSession implements decoding session on top of Pepper Video |
| 6 // Decoder API. It relies on VideoBitstreamInterface for getting the decodable |
| 7 // video bitstream units and DisplayInterface for providing picture buffers and |
| 8 // drawing them onto screen. Subsystem hidden by VideoDecoderSession can be |
| 9 // reused by applications as long as they provide valid implementations of |
| 10 // VideoBitstreamInterface and DisplayInterface to the VideoDecoderSession |
| 11 // class. Once session is complete it will inform the client about completion |
| 12 // through VideoDecoderSessionClient interface. |
| 13 // |
| 14 // O VideoDecoderSessionClient |
| 15 // ^ |
| 16 // | |
| 17 // +---------------------+ |
| 18 // +------ | VideoDecoderSession |----------------+ |
| 19 // | +---------------------+ | |
| 20 // | | | | |
| 21 // | | O pp::VideoDecoder::Client |
| 22 // | | ^ | |
| 23 // | V | | |
| 24 // | +--------------------+ | |
| 25 // | | pp::VideoDecoder | | |
| 26 // | +--------------------+ | |
| 27 // V V |
| 28 // O VideoBitstreamInterface DisplayInterface O |
| 29 // | | |
| 30 // +---------------------------+ +--------------+ |
| 31 // | LocalVideoBitstreamSource | | GLES2Display | |
| 32 // +---------------------------+ +--------------+ |
| 33 |
| 34 #ifndef PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ |
| 35 #define PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ |
| 36 |
| 37 #include <map> |
| 38 #include <string> |
| 39 #include <vector> |
| 40 |
| 41 #include "ppapi/c/pp_stdint.h" |
| 42 #include "ppapi/cpp/completion_callback.h" |
| 43 #include "ppapi/cpp/dev/graphics_3d_client_dev.h" |
| 44 #include "ppapi/cpp/dev/video_decoder_dev.h" |
| 45 #include "ppapi/tests/test_case.h" |
| 46 #include "ppapi/tests/testing_instance.h" |
| 47 |
| 48 class DisplayInterface; |
| 49 class TestVideoSource; |
| 50 class VideoDecoderSession; |
| 51 |
| 52 namespace pp { |
| 53 class Context3D_Dev; |
| 54 class Surface3D_Dev; |
| 55 } // namespace pp. |
| 56 |
| 57 // Interface for acquiring video bitstream units from a source. |
| 58 class VideoBitstreamInterface { |
| 59 public: |
| 60 virtual ~VideoBitstreamInterface(); |
| 61 |
| 62 // Writes decodable bitstream unit to |target_mem| which has size of |
| 63 // |target_mem_size_in_bytes|. The actual size of the unit will be stored in |
| 64 // |unit_size_in_bytes|. Returns true on success, otherwise false. |
| 65 virtual bool GetBitstreamUnit(void* target_mem, |
| 66 uint32_t target_mem_size_in_bytes, |
| 67 int32_t* unit_size_in_bytes) = 0; |
| 68 }; |
| 69 |
| 70 // Interface for display drawing and buffer management. |
| 71 class DisplayInterface { |
| 72 public: |
| 73 virtual ~DisplayInterface(); |
| 74 |
| 75 // Provides one GLES2-backed picture buffer pointer into |picture_buffer| that |
| 76 // is sized as |dimensions|. Returns true if successful, otherwise false. |
| 77 virtual bool ProvideGLESPictureBuffers( |
| 78 uint32_t req_num_of_bufs, |
| 79 PP_Size dimensions, |
| 80 std::vector<PP_GLESBuffer_Dev>& gles_buffers) = 0; |
| 81 // Dismisses the picture buffer whose id is |picture_buffer_id|. |
| 82 virtual bool DismissPictureBuffer(int32_t picture_buffer_id) = 0; |
| 83 // Draws the picture described in |picture| and once drawing is complete calls |
| 84 // the |completion_callback|. Return true, if drawing successfully accepted. |
| 85 // Otherwise returns false and |completion_callback| will NOT be called and |
| 86 // needs to be freed by the user. |
| 87 virtual bool DrawPicture(const PP_Picture_Dev& picture, |
| 88 pp::CompletionCallback completion_callback) = 0; |
| 89 }; |
| 90 |
| 91 // Video bitstream source for local files. |
| 92 class LocalVideoBitstreamSource : public VideoBitstreamInterface { |
| 93 public: |
| 94 // Constructs the object to read the data with the |filename|. |
| 95 explicit LocalVideoBitstreamSource(std::string filename); |
| 96 virtual ~LocalVideoBitstreamSource(); |
| 97 |
| 98 // VideoBitstreamInterface implementation. |
| 99 virtual bool GetBitstreamUnit(void* target_mem, |
| 100 uint32_t target_mem_size_in_bytes, |
| 101 int32_t* unit_size_in_bytes); |
| 102 |
| 103 private: |
| 104 std::string file_; |
| 105 TestVideoSource* video_source_; |
| 106 bool video_source_open_; |
| 107 }; |
| 108 |
| 109 // Interface for video session to inform abouot the completion of session. |
| 110 class VideoDecoderSessionClient { |
| 111 public: |
| 112 virtual ~VideoDecoderSessionClient(); |
| 113 // Called by the VideoDecoderSession to tell the session is over. |result| |
| 114 // tells if something has gone wrong. |
| 115 virtual void OnSessionCompleted(int32_t result) = 0; |
| 116 }; |
| 117 |
| 118 |
| 119 // Video decoder client class that implements less domain-specific abstraction |
| 120 // on top of basic Pepper Video Decoder API. |
| 121 // |
| 122 // State machine: |
| 123 // States |
| 124 // +---------------+-------------+---------------+---------------+ |
| 125 // Trigger | Created | Initialized | Running | Flushing | |
| 126 // -------------|---------------|-------------|---------------|---------------+ |
| 127 // Initialize() |-> Initialized | N/A | N/A | N/A | |
| 128 // -------------|---------------|-------------|---------------|---------------+ |
| 129 // Run() | N/A | -> Running | N/A | N/A | |
| 130 // -------------|---------------|-------------|---------------|---------------+ |
| 131 // Stop() | N/A | N/A |-> Initialized | N/A | |
| 132 // -------------|---------------|-------------|---------------|---------------+ |
| 133 // Flush() | N/A | N/A |-> Flushing | N/A | |
| 134 // -------------|---------------|-------------|---------------|---------------+ |
| 135 // Teardown() | N/A | -> Created | N/A | N/A | |
| 136 // -------------|---------------|-------------|---------------|---------------+ |
| 137 // NotifyEOS() | N/A | N/A |-> Initialized | N/A | |
| 138 // -------------|---------------|-------------|---------------|---------------+ |
| 139 // NotifyError()| N/A | N/A |-> Initialized | N/A | |
| 140 // -------------+---------------+-------------+---------------+---------------+ |
| 141 // OnFlushDone()| N/A | N/A | N/A |-> Running | |
| 142 // -------------+---------------+-------------+---------------+---------------+ |
| 143 // |
| 144 // In Initialized, Running and Flushing states session has resources allocated. |
| 145 // |
| 146 // In Running state session keeps asking VideoBitstreamSource for more data and |
| 147 // will decode the data using the video decoder. |
| 148 // |
| 149 // In Flushing state the session will keep pushing output pictures out. |
| 150 class VideoDecoderSession : public pp::VideoDecoder::Client { |
| 151 public: |
| 152 // Enumeration for client states. |
| 153 enum State { |
| 154 kCreated, |
| 155 kInitialized, |
| 156 kRunning, |
| 157 kFlushing |
| 158 }; |
| 159 |
| 160 // Constructor expects the user of this class to provide concrete |
| 161 // implementation of VideoBitstreamInterface and DisplayInterface. |
| 162 VideoDecoderSession(pp::Instance* instance, |
| 163 VideoDecoderSessionClient* client, |
| 164 VideoBitstreamInterface* video_bitstream_if, |
| 165 DisplayInterface* display_if); |
| 166 ~VideoDecoderSession(); |
| 167 |
| 168 // Functions to control the execution. |completion_callback| is called when |
| 169 // state transition is complete. |
| 170 bool Initialize(const PP_VideoConfigElement* decoder_config, |
| 171 pp::CompletionCallback completion_callback); |
| 172 bool Run(pp::CompletionCallback completion_callback); |
| 173 bool Stop(pp::CompletionCallback completion_callback); |
| 174 bool Flush(pp::CompletionCallback completion_callback); |
| 175 bool Teardown(pp::CompletionCallback completion_callback); |
| 176 |
| 177 virtual void ProvidePictureBuffers( |
| 178 uint32_t req_num_of_bufs, |
| 179 PP_Size dimensions, |
| 180 enum PP_PictureBufferType_Dev type); |
| 181 virtual void DismissPictureBuffer(int32_t picture_buffer_id); |
| 182 virtual void PictureReady(const PP_Picture_Dev& picture); |
| 183 virtual void EndOfStream(); |
| 184 virtual void NotifyError(PP_VideoDecodeError_Dev error); |
| 185 |
| 186 private: |
| 187 // Callback implementations for decoder events. |
| 188 void OnInitializeDone(int32_t result, pp::CompletionCallback callback); |
| 189 void OnBitstreamBufferProcessed(int32_t result, int32_t bitstream_buffer_id); |
| 190 void OnUserFlushDone(int32_t result, State target_state, |
| 191 pp::CompletionCallback callback); |
| 192 void OnInternalFlushDone(int32_t result); |
| 193 void OnAbortDone(int32_t result); |
| 194 // Callback from display subsystem. |
| 195 void OnDrawPictureDone(int32_t result, int32_t picture_buffer_id); |
| 196 // Input buffer allocation and freeing. |
| 197 bool AllocateInputBuffers(); |
| 198 void FreeInputBuffers(); |
| 199 // Read an bitstream unit to bitstream buffer with |bitstream_buffer_id|. |
| 200 // After successful read, dispatch the unit to video decoder. |
| 201 bool ReadAndDispatchBitstreamUnit(int32_t bitstream_buffer_id); |
| 202 // Change the state of the session. |
| 203 void ChangeState(State to_state); |
| 204 // Generate unique id. |
| 205 int32_t GetUniqueId(); |
| 206 // Pepper buffer interface. |
| 207 const struct PPB_Buffer_Dev* buffer_if_; |
| 208 // Callback factory for generating completion callbacks. |
| 209 pp::CompletionCallbackFactory<VideoDecoderSession> cb_factory_; |
| 210 // Pointer to the Instance interface of this plugin module. |
| 211 pp::Instance* instance_; |
| 212 // Pointer to the client of this session. |
| 213 VideoDecoderSessionClient* client_; |
| 214 // Pepper video decoder instance. |
| 215 pp::VideoDecoder* video_decoder_; |
| 216 // Source for video bitstream. |
| 217 VideoBitstreamInterface* video_source_; |
| 218 // Pointer to the display. |
| 219 DisplayInterface* display_; |
| 220 // Map to hold |id| => |bitstream buffer| pairs. |
| 221 std::map<int32_t, PP_VideoBitstreamBuffer_Dev> bitstream_buffers_; |
| 222 // Indicator whether end of stream has been encountered. |
| 223 bool end_of_stream_; |
| 224 // Configuration used to initialize the decoder. |
| 225 const std::vector<uint32_t> decoder_config_; |
| 226 // Variable to hold the state of the client. |
| 227 State state_; |
| 228 // Variable to hold the next unique id. |
| 229 int32_t next_id_; |
| 230 }; |
| 231 |
| 232 // Class to render decoded video pictures using OpenGL ES 2.0. |
| 233 class GLES2Display : public pp::Graphics3DClient_Dev, |
| 234 public DisplayInterface { |
| 235 public: |
| 236 // |instance| and |video_decoder| are NOT owned by this object and they must |
| 237 // outlive this class. |
| 238 GLES2Display(pp::Instance* instance, PP_Size size); |
| 239 virtual ~GLES2Display(); |
| 240 |
| 241 // Initializes the GLES display. |
| 242 bool Initialize(); |
| 243 |
| 244 // Graphics3DClient_Dev implementation. |
| 245 virtual void Graphics3DContextLost(); |
| 246 |
| 247 // DisplayInterface implementation. |
| 248 virtual bool ProvideGLESPictureBuffers( |
| 249 uint32_t req_num_of_bufs, |
| 250 PP_Size dimensions, |
| 251 std::vector<PP_GLESBuffer_Dev>& gles_buffers); |
| 252 virtual bool DismissPictureBuffer(int32_t picture_buffer_id); |
| 253 virtual bool DrawPicture(const PP_Picture_Dev& picture, |
| 254 pp::CompletionCallback completion_callback); |
| 255 |
| 256 private: |
| 257 void AssertNoGLError(); |
| 258 bool InitGL(int width, int height); |
| 259 void CreateShader(GLuint program, GLenum type, const char* source, int size); |
| 260 void LinkProgram(const PPB_OpenGLES2_Dev* gles2_if); |
| 261 void ProgramShaders(); |
| 262 // Generate unique id. |
| 263 int32_t GetUniqueId(); |
| 264 |
| 265 // Pointer to the Instance interface of this plugin module. |
| 266 pp::Instance* instance_; |
| 267 // Pepper GLES2 interface. |
| 268 const struct PPB_OpenGLES2_Dev* gles2_if_; |
| 269 // Pepper 3D context in which we are rendering. |
| 270 pp::Context3D_Dev* context_; |
| 271 // Pepper 3D surface that represents the frame buffer for our plugin. |
| 272 pp::Surface3D_Dev* surface_; |
| 273 // Size of the output surface we are using. |
| 274 PP_Size surface_size_; |
| 275 // Map for GLES buffers. |
| 276 std::map<int32_t, PP_GLESBuffer_Dev> gles_buffers_; |
| 277 // GLES name for vertex buffer. |
| 278 GLuint vertex_buffer_; |
| 279 // GLES name for fragment buffer used. |
| 280 GLuint fragment_buffer_; |
| 281 // GLES name for our shader programs. |
| 282 GLuint program_; |
| 283 // Next id. |
| 284 int32_t next_id_; |
| 285 }; |
| 286 |
| 287 #endif // PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ |
OLD | NEW |