Chromium Code Reviews| 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..8546d0bdacb0183c0dccfb90ffb52db1e5782786 |
| --- /dev/null |
| +++ b/ppapi/examples/video_decoder/video_decoder_session.h |
| @@ -0,0 +1,294 @@ |
| +// 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 |
| + // fulfills |buffer_properties| that are dictionary values as defined in |
| + // pp_video_dev.h. Returns true if successful, otherwise false. |
| + virtual bool ProvideGLESPictureBuffer( |
| + const std::vector<uint32_t>& buffer_properties, |
| + PP_GLESBuffer_Dev* picture_buffer) = 0; |
|
vrk (LEFT CHROMIUM)
2011/06/02 01:47:02
Why does this only provide one picture buffer at a
Ville-Mikko Rautio
2011/06/03 13:24:39
Changed the function to output multiple pictures.
|
| + // 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_; |
|
vrk (LEFT CHROMIUM)
2011/06/02 01:47:02
scoped_ptr?
Ville-Mikko Rautio
2011/06/03 13:24:39
Probably not on Pepper-side of things? Trying to a
|
| + 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) : |
| + cb_factory_(this), |
| + instance_(instance), |
| + client_(client), |
| + video_source_(video_bitstream_if), |
| + display_(display_if), |
| + end_of_stream_(false), |
| + state_(kCreated) {} |
|
vrk (LEFT CHROMIUM)
2011/06/02 01:47:02
Put definition in the .cc file.
Ville-Mikko Rautio
2011/06/03 13:24:39
Done.
|
| + ~VideoDecoderSession() {} |
|
vrk (LEFT CHROMIUM)
2011/06/02 01:47:02
Put definition in the .cc file.
Ville-Mikko Rautio
2011/06/03 13:24:39
Done.
|
| + |
| + // Functions to control the execution. |completion_callback| is called when |
| + // state transition is complete. |
| + bool Initialize(const std::vector<uint32_t>& 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); |
| + |
| + // VideoDecoder::Client implementation. |
| + virtual void ProvidePictureBuffers( |
| + uint32_t requested_num_of_buffers, |
| + const std::vector<uint32_t>& buffer_properties); |
| + virtual void DismissPictureBuffer(int32_t picture_buffer_id); |
| + virtual void PictureReady(const PP_Picture_Dev& picture); |
| + virtual void NotifyEndOfStream(); |
| + virtual void NotifyError(PP_VideoDecodeError_Dev error); |
| + |
| + // Generate unique id. |
| + static int32_t GetUniqueId(); |
|
vrk (LEFT CHROMIUM)
2011/06/02 01:47:02
Should be private.
Ville-Mikko Rautio
2011/06/03 13:24:39
Done.
|
| + |
| + 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); |
| + // 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. |
| + static 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. |
| + explicit GLES2Display(pp::Instance* instance, PP_Size size) : |
| + pp::Graphics3DClient_Dev(instance), |
| + instance_(instance), |
| + surface_size_(size) {} |
| + virtual ~GLES2Display() {} |
| + |
| + // Initializes the GLES display. |
| + bool Initialize(); |
| + |
| + // Graphics3DClient_Dev implementation. |
| + virtual void Graphics3DContextLost(); |
| + |
| + // DisplayInterface implementation. |
| + virtual bool ProvideGLESPictureBuffer( |
| + const std::vector<uint32_t>& buffer_properties, |
| + PP_GLESBuffer_Dev* picture_buffer); |
| + virtual bool DismissPictureBuffer(int32_t picture_buffer_id); |
| + virtual bool DrawPicture(const PP_Picture_Dev& picture, |
| + pp::CompletionCallback completion_callback); |
| + |
| + private: |
| + void assertNoGLError(); |
|
vrk (LEFT CHROMIUM)
2011/06/02 01:47:02
nit: capitalization: Assert
Ville-Mikko Rautio
2011/06/03 13:24:39
Done.
|
| + 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(); |
| + |
| + // 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_; |
| +}; |
| + |
| +#endif // PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ |