Index: ppapi/examples/video_decoder/video_decoder_session.h |
diff --git a/ppapi/examples/video_decoder/video_decoder_session.h b/ppapi/examples/video_decoder/video_decoder_session.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d4aef32ac63c6e0a99c25e9275d7d328fa4635f3 |
--- /dev/null |
+++ b/ppapi/examples/video_decoder/video_decoder_session.h |
@@ -0,0 +1,287 @@ |
+// 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. |
+ |
+// VideoDecoderSession implements decoding session on top of Pepper Video |
+// Decoder API. It relies on VideoBitstreamInterface for getting the decodable |
+// video bitstream units and DisplayInterface for providing picture buffers and |
+// drawing them onto screen. Subsystem hidden by VideoDecoderSession can be |
+// reused by applications as long as they provide valid implementations of |
+// VideoBitstreamInterface and DisplayInterface to the VideoDecoderSession |
+// class. Once session is complete it will inform the client about completion |
+// through VideoDecoderSessionClient interface. |
+// |
+// O VideoDecoderSessionClient |
+// ^ |
+// | |
+// +---------------------+ |
+// +------ | VideoDecoderSession |----------------+ |
+// | +---------------------+ | |
+// | | | | |
+// | | O pp::VideoDecoder::Client |
+// | | ^ | |
+// | V | | |
+// | +--------------------+ | |
+// | | pp::VideoDecoder | | |
+// | +--------------------+ | |
+// V V |
+// O VideoBitstreamInterface DisplayInterface O |
+// | | |
+// +---------------------------+ +--------------+ |
+// | LocalVideoBitstreamSource | | GLES2Display | |
+// +---------------------------+ +--------------+ |
+ |
+#ifndef PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ |
+#define PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ |
+ |
+#include <map> |
+#include <string> |
+#include <vector> |
+ |
+#include "ppapi/c/pp_stdint.h" |
+#include "ppapi/cpp/completion_callback.h" |
+#include "ppapi/cpp/dev/graphics_3d_client_dev.h" |
+#include "ppapi/cpp/dev/video_decoder_dev.h" |
+#include "ppapi/tests/test_case.h" |
+#include "ppapi/tests/testing_instance.h" |
+ |
+class DisplayInterface; |
+class TestVideoSource; |
+class VideoDecoderSession; |
+ |
+namespace pp { |
+ class Context3D_Dev; |
+ class Surface3D_Dev; |
+} // namespace pp. |
+ |
+// Interface for acquiring video bitstream units from a source. |
+class VideoBitstreamInterface { |
+ public: |
+ virtual ~VideoBitstreamInterface(); |
+ |
+ // Writes decodable bitstream unit to |target_mem| which has size of |
+ // |target_mem_size_in_bytes|. The actual size of the unit will be stored in |
+ // |unit_size_in_bytes|. Returns true on success, otherwise false. |
+ virtual bool GetBitstreamUnit(void* target_mem, |
+ uint32_t target_mem_size_in_bytes, |
+ int32_t* unit_size_in_bytes) = 0; |
+}; |
+ |
+// Interface for display drawing and buffer management. |
+class DisplayInterface { |
+ public: |
+ virtual ~DisplayInterface(); |
+ |
+ // Provides one GLES2-backed picture buffer pointer into |picture_buffer| that |
+ // is sized as |dimensions|. Returns true if successful, otherwise false. |
+ virtual bool ProvideGLESPictureBuffers( |
+ uint32_t req_num_of_bufs, |
+ PP_Size dimensions, |
+ std::vector<PP_GLESBuffer_Dev>& gles_buffers) = 0; |
+ // Dismisses the picture buffer whose id is |picture_buffer_id|. |
+ virtual bool DismissPictureBuffer(int32_t picture_buffer_id) = 0; |
+ // Draws the picture described in |picture| and once drawing is complete calls |
+ // the |completion_callback|. Return true, if drawing successfully accepted. |
+ // Otherwise returns false and |completion_callback| will NOT be called and |
+ // needs to be freed by the user. |
+ virtual bool DrawPicture(const PP_Picture_Dev& picture, |
+ pp::CompletionCallback completion_callback) = 0; |
+}; |
+ |
+// Video bitstream source for local files. |
+class LocalVideoBitstreamSource : public VideoBitstreamInterface { |
+ public: |
+ // Constructs the object to read the data with the |filename|. |
+ explicit LocalVideoBitstreamSource(std::string filename); |
+ virtual ~LocalVideoBitstreamSource(); |
+ |
+ // VideoBitstreamInterface implementation. |
+ virtual bool GetBitstreamUnit(void* target_mem, |
+ uint32_t target_mem_size_in_bytes, |
+ int32_t* unit_size_in_bytes); |
+ |
+ private: |
+ std::string file_; |
+ TestVideoSource* video_source_; |
+ bool video_source_open_; |
+}; |
+ |
+// Interface for video session to inform abouot the completion of session. |
+class VideoDecoderSessionClient { |
+ public: |
+ virtual ~VideoDecoderSessionClient(); |
+ // Called by the VideoDecoderSession to tell the session is over. |result| |
+ // tells if something has gone wrong. |
+ virtual void OnSessionCompleted(int32_t result) = 0; |
+}; |
+ |
+ |
+// Video decoder client class that implements less domain-specific abstraction |
+// on top of basic Pepper Video Decoder API. |
+// |
+// State machine: |
+// States |
+// +---------------+-------------+---------------+---------------+ |
+// Trigger | Created | Initialized | Running | Flushing | |
+// -------------|---------------|-------------|---------------|---------------+ |
+// Initialize() |-> Initialized | N/A | N/A | N/A | |
+// -------------|---------------|-------------|---------------|---------------+ |
+// Run() | N/A | -> Running | N/A | N/A | |
+// -------------|---------------|-------------|---------------|---------------+ |
+// Stop() | N/A | N/A |-> Initialized | N/A | |
+// -------------|---------------|-------------|---------------|---------------+ |
+// Flush() | N/A | N/A |-> Flushing | N/A | |
+// -------------|---------------|-------------|---------------|---------------+ |
+// Teardown() | N/A | -> Created | N/A | N/A | |
+// -------------|---------------|-------------|---------------|---------------+ |
+// NotifyEOS() | N/A | N/A |-> Initialized | N/A | |
+// -------------|---------------|-------------|---------------|---------------+ |
+// NotifyError()| N/A | N/A |-> Initialized | N/A | |
+// -------------+---------------+-------------+---------------+---------------+ |
+// OnFlushDone()| N/A | N/A | N/A |-> Running | |
+// -------------+---------------+-------------+---------------+---------------+ |
+// |
+// In Initialized, Running and Flushing states session has resources allocated. |
+// |
+// In Running state session keeps asking VideoBitstreamSource for more data and |
+// will decode the data using the video decoder. |
+// |
+// In Flushing state the session will keep pushing output pictures out. |
+class VideoDecoderSession : public pp::VideoDecoder::Client { |
+ public: |
+ // Enumeration for client states. |
+ enum State { |
+ kCreated, |
+ kInitialized, |
+ kRunning, |
+ kFlushing |
+ }; |
+ |
+ // Constructor expects the user of this class to provide concrete |
+ // implementation of VideoBitstreamInterface and DisplayInterface. |
+ VideoDecoderSession(pp::Instance* instance, |
+ VideoDecoderSessionClient* client, |
+ VideoBitstreamInterface* video_bitstream_if, |
+ DisplayInterface* display_if); |
+ ~VideoDecoderSession(); |
+ |
+ // Functions to control the execution. |completion_callback| is called when |
+ // state transition is complete. |
+ bool Initialize(const PP_VideoConfigElement* decoder_config, |
+ pp::CompletionCallback completion_callback); |
+ bool Run(pp::CompletionCallback completion_callback); |
+ bool Stop(pp::CompletionCallback completion_callback); |
+ bool Flush(pp::CompletionCallback completion_callback); |
+ bool Teardown(pp::CompletionCallback completion_callback); |
+ |
+ virtual void ProvidePictureBuffers( |
+ uint32_t req_num_of_bufs, |
+ PP_Size dimensions, |
+ enum PP_PictureBufferType_Dev type); |
+ virtual void DismissPictureBuffer(int32_t picture_buffer_id); |
+ virtual void PictureReady(const PP_Picture_Dev& picture); |
+ virtual void EndOfStream(); |
+ virtual void NotifyError(PP_VideoDecodeError_Dev error); |
+ |
+ private: |
+ // Callback implementations for decoder events. |
+ void OnInitializeDone(int32_t result, pp::CompletionCallback callback); |
+ void OnBitstreamBufferProcessed(int32_t result, int32_t bitstream_buffer_id); |
+ void OnUserFlushDone(int32_t result, State target_state, |
+ pp::CompletionCallback callback); |
+ void OnInternalFlushDone(int32_t result); |
+ void OnAbortDone(int32_t result); |
+ // Callback from display subsystem. |
+ void OnDrawPictureDone(int32_t result, int32_t picture_buffer_id); |
+ // Input buffer allocation and freeing. |
+ bool AllocateInputBuffers(); |
+ void FreeInputBuffers(); |
+ // Read an bitstream unit to bitstream buffer with |bitstream_buffer_id|. |
+ // After successful read, dispatch the unit to video decoder. |
+ bool ReadAndDispatchBitstreamUnit(int32_t bitstream_buffer_id); |
+ // Change the state of the session. |
+ void ChangeState(State to_state); |
+ // Generate unique id. |
+ int32_t GetUniqueId(); |
+ // Pepper buffer interface. |
+ const struct PPB_Buffer_Dev* buffer_if_; |
+ // Callback factory for generating completion callbacks. |
+ pp::CompletionCallbackFactory<VideoDecoderSession> cb_factory_; |
+ // Pointer to the Instance interface of this plugin module. |
+ pp::Instance* instance_; |
+ // Pointer to the client of this session. |
+ VideoDecoderSessionClient* client_; |
+ // Pepper video decoder instance. |
+ pp::VideoDecoder* video_decoder_; |
+ // Source for video bitstream. |
+ VideoBitstreamInterface* video_source_; |
+ // Pointer to the display. |
+ DisplayInterface* display_; |
+ // Map to hold |id| => |bitstream buffer| pairs. |
+ std::map<int32_t, PP_VideoBitstreamBuffer_Dev> bitstream_buffers_; |
+ // Indicator whether end of stream has been encountered. |
+ bool end_of_stream_; |
+ // Configuration used to initialize the decoder. |
+ const std::vector<uint32_t> decoder_config_; |
+ // Variable to hold the state of the client. |
+ State state_; |
+ // Variable to hold the next unique id. |
+ int32_t next_id_; |
+}; |
+ |
+// Class to render decoded video pictures using OpenGL ES 2.0. |
+class GLES2Display : public pp::Graphics3DClient_Dev, |
+ public DisplayInterface { |
+ public: |
+ // |instance| and |video_decoder| are NOT owned by this object and they must |
+ // outlive this class. |
+ GLES2Display(pp::Instance* instance, PP_Size size); |
+ virtual ~GLES2Display(); |
+ |
+ // Initializes the GLES display. |
+ bool Initialize(); |
+ |
+ // Graphics3DClient_Dev implementation. |
+ virtual void Graphics3DContextLost(); |
+ |
+ // DisplayInterface implementation. |
+ virtual bool ProvideGLESPictureBuffers( |
+ uint32_t req_num_of_bufs, |
+ PP_Size dimensions, |
+ std::vector<PP_GLESBuffer_Dev>& gles_buffers); |
+ virtual bool DismissPictureBuffer(int32_t picture_buffer_id); |
+ virtual bool DrawPicture(const PP_Picture_Dev& picture, |
+ pp::CompletionCallback completion_callback); |
+ |
+ private: |
+ void AssertNoGLError(); |
+ bool InitGL(int width, int height); |
+ void CreateShader(GLuint program, GLenum type, const char* source, int size); |
+ void LinkProgram(const PPB_OpenGLES2_Dev* gles2_if); |
+ void ProgramShaders(); |
+ // Generate unique id. |
+ int32_t GetUniqueId(); |
+ |
+ // Pointer to the Instance interface of this plugin module. |
+ pp::Instance* instance_; |
+ // Pepper GLES2 interface. |
+ const struct PPB_OpenGLES2_Dev* gles2_if_; |
+ // Pepper 3D context in which we are rendering. |
+ pp::Context3D_Dev* context_; |
+ // Pepper 3D surface that represents the frame buffer for our plugin. |
+ pp::Surface3D_Dev* surface_; |
+ // Size of the output surface we are using. |
+ PP_Size surface_size_; |
+ // Map for GLES buffers. |
+ std::map<int32_t, PP_GLESBuffer_Dev> gles_buffers_; |
+ // GLES name for vertex buffer. |
+ GLuint vertex_buffer_; |
+ // GLES name for fragment buffer used. |
+ GLuint fragment_buffer_; |
+ // GLES name for our shader programs. |
+ GLuint program_; |
+ // Next id. |
+ int32_t next_id_; |
+}; |
+ |
+#endif // PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ |