OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <string.h> | 5 #include <string.h> |
6 | 6 |
7 #include <iostream> | 7 #include <iostream> |
8 #include <list> | 8 #include <list> |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 virtual void Graphics3DContextLost() { | 51 virtual void Graphics3DContextLost() { |
52 // TODO(vrk/fischman): Properly reset after a lost graphics context. In | 52 // TODO(vrk/fischman): Properly reset after a lost graphics context. In |
53 // particular need to delete context_ & surface_ and re-create textures. | 53 // particular need to delete context_ & surface_ and re-create textures. |
54 // Probably have to recreate the decoder from scratch, because old textures | 54 // Probably have to recreate the decoder from scratch, because old textures |
55 // can still be outstanding in the decoder! | 55 // can still be outstanding in the decoder! |
56 assert(!"Unexpectedly lost graphics context"); | 56 assert(!"Unexpectedly lost graphics context"); |
57 } | 57 } |
58 | 58 |
59 // pp::VideoDecoderClient_Dev implementation. | 59 // pp::VideoDecoderClient_Dev implementation. |
60 virtual void ProvidePictureBuffers( | 60 virtual void ProvidePictureBuffers( |
61 pp::VideoDecoder_Dev decoder, uint32_t req_num_of_bufs, | 61 uint32_t req_num_of_bufs, PP_Size dimensions, |
62 PP_Size dimensions, PP_PictureBufferType_Dev type); | 62 PP_PictureBufferType_Dev type); |
63 virtual void DismissPictureBuffer( | 63 virtual void DismissPictureBuffer(int32_t picture_buffer_id); |
64 pp::VideoDecoder_Dev decoder, int32_t picture_buffer_id); | 64 virtual void PictureReady(const PP_Picture_Dev& picture); |
65 virtual void PictureReady( | 65 virtual void EndOfStream(); |
66 pp::VideoDecoder_Dev decoder, const PP_Picture_Dev& picture); | 66 virtual void NotifyError(PP_VideoDecodeError_Dev error); |
67 virtual void EndOfStream(pp::VideoDecoder_Dev decoder); | |
68 virtual void NotifyError( | |
69 pp::VideoDecoder_Dev decoder, PP_VideoDecodeError_Dev error); | |
70 | 67 |
71 private: | 68 private: |
72 enum { kNumConcurrentDecodes = 7 }; | 69 enum { kNumConcurrentDecodes = 7 }; |
73 | 70 |
74 // Initialize Video Decoder. | 71 // Initialize Video Decoder. |
75 void InitializeDecoder(); | 72 void InitializeDecoder(); |
76 | 73 |
77 // Callbacks passed into pp:VideoDecoder_Dev functions. | 74 // Callbacks passed into pp:VideoDecoder_Dev functions. |
78 void DecoderInitDone(int32_t result); | 75 void DecoderInitDone(int32_t result); |
79 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); | 76 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); |
80 void DecoderFlushDone(int32_t result); | 77 void DecoderFlushDone(int32_t result); |
81 void DecoderAbortDone(int32_t result); | |
82 | 78 |
83 // Decode helpers. | 79 // Decode helpers. |
84 void DecodeNextNALUs(); | 80 void DecodeNextNALUs(); |
85 void DecodeNextNALU(); | 81 void DecodeNextNALU(); |
86 void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); | 82 void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); |
87 void Render(const PP_GLESBuffer_Dev& buffer); | 83 void Render(const PP_GLESBuffer_Dev& buffer); |
88 | 84 |
89 // GL-related functions. | 85 // GL-related functions. |
90 void InitGL(); | 86 void InitGL(); |
91 GLuint CreateTexture(int32_t width, int32_t height); | 87 GLuint CreateTexture(int32_t width, int32_t height); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 context_(NULL), | 135 context_(NULL), |
140 surface_(NULL), | 136 surface_(NULL), |
141 video_decoder_(NULL) { | 137 video_decoder_(NULL) { |
142 assert((core_if_ = static_cast<const struct PPB_Core*>( | 138 assert((core_if_ = static_cast<const struct PPB_Core*>( |
143 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); | 139 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); |
144 assert((gles2_if_ = static_cast<const struct PPB_OpenGLES2_Dev*>( | 140 assert((gles2_if_ = static_cast<const struct PPB_OpenGLES2_Dev*>( |
145 module->GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE)))); | 141 module->GetBrowserInterface(PPB_OPENGLES2_DEV_INTERFACE)))); |
146 } | 142 } |
147 | 143 |
148 GLES2DemoInstance::~GLES2DemoInstance() { | 144 GLES2DemoInstance::~GLES2DemoInstance() { |
149 delete video_decoder_; | 145 delete video_decoder_; // May be NULL, which is fine. |
150 delete surface_; | 146 delete surface_; |
151 delete context_; | 147 delete context_; |
152 } | 148 } |
153 | 149 |
154 void GLES2DemoInstance::DidChangeView( | 150 void GLES2DemoInstance::DidChangeView( |
155 const pp::Rect& position, const pp::Rect& clip_ignored) { | 151 const pp::Rect& position, const pp::Rect& clip_ignored) { |
156 if (position.width() == 0 || position.height() == 0) | 152 if (position.width() == 0 || position.height() == 0) |
157 return; | 153 return; |
158 if (position_size_.width()) { | 154 if (position_size_.width()) { |
159 assert(position.size() == position_size_); | 155 assert(position.size() == position_size_); |
(...skipping 27 matching lines...) Expand all Loading... |
187 bitstream_buffers_by_id_.find(bitstream_buffer_id); | 183 bitstream_buffers_by_id_.find(bitstream_buffer_id); |
188 assert(it != bitstream_buffers_by_id_.end()); | 184 assert(it != bitstream_buffers_by_id_.end()); |
189 delete it->second; | 185 delete it->second; |
190 DecodeNextNALUs(); | 186 DecodeNextNALUs(); |
191 } | 187 } |
192 | 188 |
193 void GLES2DemoInstance::DecoderFlushDone(int32_t result) { | 189 void GLES2DemoInstance::DecoderFlushDone(int32_t result) { |
194 // Check that each bitstream buffer ID we handed to the decoder got handed | 190 // Check that each bitstream buffer ID we handed to the decoder got handed |
195 // back to us. | 191 // back to us. |
196 assert(bitstream_ids_at_decoder_.empty()); | 192 assert(bitstream_ids_at_decoder_.empty()); |
197 } | 193 delete video_decoder_; |
198 | 194 video_decoder_ = NULL; |
199 void GLES2DemoInstance::DecoderAbortDone(int32_t result) { | |
200 } | 195 } |
201 | 196 |
202 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { | 197 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { |
203 return pos + 3 < kDataLen && | 198 return pos + 3 < kDataLen && |
204 encoded[pos] == 0 && encoded[pos + 1] == 0 && | 199 encoded[pos] == 0 && encoded[pos + 1] == 0 && |
205 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; | 200 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; |
206 } | 201 } |
207 | 202 |
208 void GLES2DemoInstance::GetNextNALUBoundary( | 203 void GLES2DemoInstance::GetNextNALUBoundary( |
209 size_t start_pos, size_t* end_pos) { | 204 size_t start_pos, size_t* end_pos) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 | 244 |
250 pp::CompletionCallback cb = | 245 pp::CompletionCallback cb = |
251 callback_factory_.NewCallback( | 246 callback_factory_.NewCallback( |
252 &GLES2DemoInstance::DecoderBitstreamDone, id); | 247 &GLES2DemoInstance::DecoderBitstreamDone, id); |
253 assert(bitstream_ids_at_decoder_.insert(id).second); | 248 assert(bitstream_ids_at_decoder_.insert(id).second); |
254 video_decoder_->Decode(bitstream_buffer, cb); | 249 video_decoder_->Decode(bitstream_buffer, cb); |
255 encoded_data_next_pos_to_decode_ = end_pos; | 250 encoded_data_next_pos_to_decode_ = end_pos; |
256 } | 251 } |
257 | 252 |
258 void GLES2DemoInstance::ProvidePictureBuffers( | 253 void GLES2DemoInstance::ProvidePictureBuffers( |
259 pp::VideoDecoder_Dev decoder, uint32_t req_num_of_bufs, PP_Size dimensions, | 254 uint32_t req_num_of_bufs, PP_Size dimensions, |
260 PP_PictureBufferType_Dev type) { | 255 PP_PictureBufferType_Dev type) { |
261 std::vector<PP_GLESBuffer_Dev> buffers; | 256 std::vector<PP_GLESBuffer_Dev> buffers; |
262 for (uint32_t i = 0; i < req_num_of_bufs; i++) { | 257 for (uint32_t i = 0; i < req_num_of_bufs; i++) { |
263 PP_GLESBuffer_Dev buffer; | 258 PP_GLESBuffer_Dev buffer; |
264 buffer.texture_id = CreateTexture(dimensions.width, dimensions.height); | 259 buffer.texture_id = CreateTexture(dimensions.width, dimensions.height); |
265 int id = ++next_picture_buffer_id_; | 260 int id = ++next_picture_buffer_id_; |
266 buffer.info.id= id; | 261 buffer.info.id= id; |
267 buffers.push_back(buffer); | 262 buffers.push_back(buffer); |
268 assert(buffers_by_id_.insert(std::make_pair(id, buffer)).second); | 263 assert(buffers_by_id_.insert(std::make_pair(id, buffer)).second); |
269 } | 264 } |
270 video_decoder_->AssignGLESBuffers(buffers); | 265 video_decoder_->AssignGLESBuffers(buffers); |
271 } | 266 } |
272 | 267 |
273 void GLES2DemoInstance::DismissPictureBuffer( | 268 void GLES2DemoInstance::DismissPictureBuffer(int32_t picture_buffer_id) { |
274 pp::VideoDecoder_Dev decoder, int32_t picture_buffer_id) { | |
275 PictureBufferMap::iterator it = buffers_by_id_.find(picture_buffer_id); | 269 PictureBufferMap::iterator it = buffers_by_id_.find(picture_buffer_id); |
276 assert(it != buffers_by_id_.end()); | 270 assert(it != buffers_by_id_.end()); |
277 DeleteTexture(it->second.texture_id); | 271 DeleteTexture(it->second.texture_id); |
278 buffers_by_id_.erase(it); | 272 buffers_by_id_.erase(it); |
279 } | 273 } |
280 | 274 |
281 void GLES2DemoInstance::PictureReady( | 275 void GLES2DemoInstance::PictureReady(const PP_Picture_Dev& picture) { |
282 pp::VideoDecoder_Dev decoder, const PP_Picture_Dev& picture) { | |
283 if (first_frame_delivered_ticks_ == -1) | 276 if (first_frame_delivered_ticks_ == -1) |
284 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); | 277 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); |
285 if (is_painting_) { | 278 if (is_painting_) { |
286 pictures_pending_paint_.push_back(picture); | 279 pictures_pending_paint_.push_back(picture); |
287 return; | 280 return; |
288 } | 281 } |
289 PictureBufferMap::iterator it = | 282 PictureBufferMap::iterator it = |
290 buffers_by_id_.find(picture.picture_buffer_id); | 283 buffers_by_id_.find(picture.picture_buffer_id); |
291 assert(it != buffers_by_id_.end()); | 284 assert(it != buffers_by_id_.end()); |
292 Render(it->second); | 285 Render(it->second); |
293 } | 286 } |
294 | 287 |
295 void GLES2DemoInstance::EndOfStream(pp::VideoDecoder_Dev decoder) { | 288 void GLES2DemoInstance::EndOfStream() { |
296 } | 289 } |
297 | 290 |
298 void GLES2DemoInstance::NotifyError( | 291 void GLES2DemoInstance::NotifyError(PP_VideoDecodeError_Dev error) { |
299 pp::VideoDecoder_Dev decoder, PP_VideoDecodeError_Dev error) { | |
300 } | 292 } |
301 | 293 |
302 // This object is the global object representing this plugin library as long | 294 // This object is the global object representing this plugin library as long |
303 // as it is loaded. | 295 // as it is loaded. |
304 class GLES2DemoModule : public pp::Module { | 296 class GLES2DemoModule : public pp::Module { |
305 public: | 297 public: |
306 GLES2DemoModule() : pp::Module() {} | 298 GLES2DemoModule() : pp::Module() {} |
307 virtual ~GLES2DemoModule() {} | 299 virtual ~GLES2DemoModule() {} |
308 | 300 |
309 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 301 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 is_painting_ = false; | 351 is_painting_ = false; |
360 ++num_frames_rendered_; | 352 ++num_frames_rendered_; |
361 if (num_frames_rendered_ % 50 == 0) { | 353 if (num_frames_rendered_ % 50 == 0) { |
362 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; | 354 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; |
363 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; | 355 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; |
364 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; | 356 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; |
365 std::cerr << "Rendered frames: " << num_frames_rendered_ << ", fps: " | 357 std::cerr << "Rendered frames: " << num_frames_rendered_ << ", fps: " |
366 << fps << ", with average ms/swap of: " << ms_per_swap | 358 << fps << ", with average ms/swap of: " << ms_per_swap |
367 << std::endl; | 359 << std::endl; |
368 } | 360 } |
369 video_decoder_->ReusePictureBuffer(picture_buffer_id); | 361 if (video_decoder_) |
| 362 video_decoder_->ReusePictureBuffer(picture_buffer_id); |
370 while (!pictures_pending_paint_.empty() && !is_painting_) { | 363 while (!pictures_pending_paint_.empty() && !is_painting_) { |
371 PP_Picture_Dev picture = pictures_pending_paint_.front(); | 364 PP_Picture_Dev picture = pictures_pending_paint_.front(); |
372 pictures_pending_paint_.pop_front(); | 365 pictures_pending_paint_.pop_front(); |
373 PictureReady(*video_decoder_, picture); | 366 PictureReady(picture); |
374 } | 367 } |
375 } | 368 } |
376 | 369 |
377 GLuint GLES2DemoInstance::CreateTexture(int32_t width, int32_t height) { | 370 GLuint GLES2DemoInstance::CreateTexture(int32_t width, int32_t height) { |
378 GLuint texture_id; | 371 GLuint texture_id; |
379 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); | 372 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); |
380 assertNoGLError(); | 373 assertNoGLError(); |
381 // Assign parameters. | 374 // Assign parameters. |
382 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); | 375 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); |
383 gles2_if_->BindTexture( | 376 gles2_if_->BindTexture( |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 gles2_if_->DeleteShader(context_->pp_resource(), shader); | 472 gles2_if_->DeleteShader(context_->pp_resource(), shader); |
480 } | 473 } |
481 } // anonymous namespace | 474 } // anonymous namespace |
482 | 475 |
483 namespace pp { | 476 namespace pp { |
484 // Factory function for your specialization of the Module object. | 477 // Factory function for your specialization of the Module object. |
485 Module* CreateModule() { | 478 Module* CreateModule() { |
486 return new GLES2DemoModule(); | 479 return new GLES2DemoModule(); |
487 } | 480 } |
488 } // namespace pp | 481 } // namespace pp |
OLD | NEW |