| 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 |