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 // fulfills |buffer_properties| that are dictionary values as defined in | |
77 // pp_video_dev.h. Returns true if successful, otherwise false. | |
78 virtual bool ProvideGLESPictureBuffer( | |
79 const std::vector<uint32_t>& buffer_properties, | |
80 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.
| |
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_; | |
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
| |
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 cb_factory_(this), | |
167 instance_(instance), | |
168 client_(client), | |
169 video_source_(video_bitstream_if), | |
170 display_(display_if), | |
171 end_of_stream_(false), | |
172 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.
| |
173 ~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.
| |
174 | |
175 // Functions to control the execution. |completion_callback| is called when | |
176 // state transition is complete. | |
177 bool Initialize(const std::vector<uint32_t>& decoder_config, | |
178 pp::CompletionCallback completion_callback); | |
179 bool Run(pp::CompletionCallback completion_callback); | |
180 bool Stop(pp::CompletionCallback completion_callback); | |
181 bool Flush(pp::CompletionCallback completion_callback); | |
182 bool Teardown(pp::CompletionCallback completion_callback); | |
183 | |
184 // VideoDecoder::Client implementation. | |
185 virtual void ProvidePictureBuffers( | |
186 uint32_t requested_num_of_buffers, | |
187 const std::vector<uint32_t>& buffer_properties); | |
188 virtual void DismissPictureBuffer(int32_t picture_buffer_id); | |
189 virtual void PictureReady(const PP_Picture_Dev& picture); | |
190 virtual void NotifyEndOfStream(); | |
191 virtual void NotifyError(PP_VideoDecodeError_Dev error); | |
192 | |
193 // Generate unique id. | |
194 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.
| |
195 | |
196 private: | |
197 // Callback implementations for decoder events. | |
198 void OnInitializeDone(int32_t result, pp::CompletionCallback callback); | |
199 void OnBitstreamBufferProcessed(int32_t result, int32_t bitstream_buffer_id); | |
200 void OnUserFlushDone(int32_t result, State target_state, | |
201 pp::CompletionCallback callback); | |
202 void OnInternalFlushDone(int32_t result); | |
203 void OnAbortDone(int32_t result); | |
204 // Callback from display subsystem. | |
205 void OnDrawPictureDone(int32_t result, int32_t picture_buffer_id); | |
206 // Input buffer allocation and freeing. | |
207 bool AllocateInputBuffers(); | |
208 void FreeInputBuffers(); | |
209 // Read an bitstream unit to bitstream buffer with |bitstream_buffer_id|. | |
210 // After successful read, dispatch the unit to video decoder. | |
211 bool ReadAndDispatchBitstreamUnit(int32_t bitstream_buffer_id); | |
212 // Change the state of the session. | |
213 void ChangeState(State to_state); | |
214 // Pepper buffer interface. | |
215 const struct PPB_Buffer_Dev* buffer_if_; | |
216 // Callback factory for generating completion callbacks. | |
217 pp::CompletionCallbackFactory<VideoDecoderSession> cb_factory_; | |
218 // Pointer to the Instance interface of this plugin module. | |
219 pp::Instance* instance_; | |
220 // Pointer to the client of this session. | |
221 VideoDecoderSessionClient* client_; | |
222 // Pepper video decoder instance. | |
223 pp::VideoDecoder* video_decoder_; | |
224 // Source for video bitstream. | |
225 VideoBitstreamInterface* video_source_; | |
226 // Pointer to the display. | |
227 DisplayInterface* display_; | |
228 // Map to hold |id| => |bitstream buffer| pairs. | |
229 std::map<int32_t, PP_VideoBitstreamBuffer_Dev> bitstream_buffers_; | |
230 // Indicator whether end of stream has been encountered. | |
231 bool end_of_stream_; | |
232 // Configuration used to initialize the decoder. | |
233 const std::vector<uint32_t> decoder_config_; | |
234 // Variable to hold the state of the client. | |
235 State state_; | |
236 // Variable to hold the next unique id. | |
237 static int32_t next_id_; | |
238 // | |
239 }; | |
240 | |
241 // Class to render decoded video pictures using OpenGL ES 2.0. | |
242 class GLES2Display : public pp::Graphics3DClient_Dev, | |
243 public DisplayInterface { | |
244 public: | |
245 // |instance| and |video_decoder| are NOT owned by this object and they must | |
246 // outlive this class. | |
247 explicit GLES2Display(pp::Instance* instance, PP_Size size) : | |
248 pp::Graphics3DClient_Dev(instance), | |
249 instance_(instance), | |
250 surface_size_(size) {} | |
251 virtual ~GLES2Display() {} | |
252 | |
253 // Initializes the GLES display. | |
254 bool Initialize(); | |
255 | |
256 // Graphics3DClient_Dev implementation. | |
257 virtual void Graphics3DContextLost(); | |
258 | |
259 // DisplayInterface implementation. | |
260 virtual bool ProvideGLESPictureBuffer( | |
261 const std::vector<uint32_t>& buffer_properties, | |
262 PP_GLESBuffer_Dev* picture_buffer); | |
263 virtual bool DismissPictureBuffer(int32_t picture_buffer_id); | |
264 virtual bool DrawPicture(const PP_Picture_Dev& picture, | |
265 pp::CompletionCallback completion_callback); | |
266 | |
267 private: | |
268 void assertNoGLError(); | |
vrk (LEFT CHROMIUM)
2011/06/02 01:47:02
nit: capitalization: Assert
Ville-Mikko Rautio
2011/06/03 13:24:39
Done.
| |
269 bool InitGL(int width, int height); | |
270 void CreateShader(GLuint program, GLenum type, const char* source, int size); | |
271 void LinkProgram(const PPB_OpenGLES2_Dev* gles2_if); | |
272 void ProgramShaders(); | |
273 | |
274 // Pointer to the Instance interface of this plugin module. | |
275 pp::Instance* instance_; | |
276 // Pepper GLES2 interface. | |
277 const struct PPB_OpenGLES2_Dev* gles2_if_; | |
278 // Pepper 3D context in which we are rendering. | |
279 pp::Context3D_Dev* context_; | |
280 // Pepper 3D surface that represents the frame buffer for our plugin. | |
281 pp::Surface3D_Dev* surface_; | |
282 // Size of the output surface we are using. | |
283 PP_Size surface_size_; | |
284 // Map for GLES buffers. | |
285 std::map<int32_t, PP_GLESBuffer_Dev> gles_buffers_; | |
286 // GLES name for vertex buffer. | |
287 GLuint vertex_buffer_; | |
288 // GLES name for fragment buffer used. | |
289 GLuint fragment_buffer_; | |
290 // GLES name for our shader programs. | |
291 GLuint program_; | |
292 }; | |
293 | |
294 #endif // PPAPI_EXAMPLES_VIDEO_DECODER_VIDEO_DECODER_SESSION_H_ | |
OLD | NEW |