| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 17 matching lines...) Expand all Loading... |
| 28 #include "ppapi/utility/completion_callback_factory.h" | 28 #include "ppapi/utility/completion_callback_factory.h" |
| 29 | 29 |
| 30 // Use assert as a poor-man's CHECK, even in non-debug mode. | 30 // Use assert as a poor-man's CHECK, even in non-debug mode. |
| 31 // Since <assert.h> redefines assert on every inclusion (it doesn't use | 31 // Since <assert.h> redefines assert on every inclusion (it doesn't use |
| 32 // include-guards), make sure this is the last file #include'd in this file. | 32 // include-guards), make sure this is the last file #include'd in this file. |
| 33 #undef NDEBUG | 33 #undef NDEBUG |
| 34 #include <assert.h> | 34 #include <assert.h> |
| 35 | 35 |
| 36 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a | 36 // Assert |context_| isn't holding any GL Errors. Done as a macro instead of a |
| 37 // function to preserve line number information in the failure message. | 37 // function to preserve line number information in the failure message. |
| 38 #define assertNoGLError() \ | 38 #define assertNoGLError() assert(!gles2_if_->GetError(context_->pp_resource())); |
| 39 assert(!gles2_if_->GetError(context_->pp_resource())); | |
| 40 | 39 |
| 41 namespace { | 40 namespace { |
| 42 | 41 |
| 43 struct PictureBufferInfo { | 42 struct PictureBufferInfo { |
| 44 PP_PictureBuffer_Dev buffer; | 43 PP_PictureBuffer_Dev buffer; |
| 45 GLenum texture_target; | 44 GLenum texture_target; |
| 46 }; | 45 }; |
| 47 | 46 |
| 48 struct Shader { | 47 struct Shader { |
| 49 Shader() : program(0), | 48 Shader() : program(0), texcoord_scale_location(0) {} |
| 50 texcoord_scale_location(0) {} | |
| 51 | 49 |
| 52 GLuint program; | 50 GLuint program; |
| 53 GLint texcoord_scale_location; | 51 GLint texcoord_scale_location; |
| 54 }; | 52 }; |
| 55 | 53 |
| 56 class VideoDecodeDemoInstance : public pp::Instance, | 54 class VideoDecodeDemoInstance : public pp::Instance, |
| 57 public pp::Graphics3DClient, | 55 public pp::Graphics3DClient, |
| 58 public pp::VideoDecoderClient_Dev { | 56 public pp::VideoDecoderClient_Dev { |
| 59 public: | 57 public: |
| 60 VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module); | 58 VideoDecodeDemoInstance(PP_Instance instance, pp::Module* module); |
| 61 virtual ~VideoDecodeDemoInstance(); | 59 virtual ~VideoDecodeDemoInstance(); |
| 62 | 60 |
| 63 // pp::Instance implementation (see PPP_Instance). | 61 // pp::Instance implementation (see PPP_Instance). |
| 64 virtual void DidChangeView(const pp::Rect& position, | 62 virtual void DidChangeView(const pp::Rect& position, |
| 65 const pp::Rect& clip_ignored); | 63 const pp::Rect& clip_ignored); |
| 66 | 64 |
| 67 // pp::Graphics3DClient implementation. | 65 // pp::Graphics3DClient implementation. |
| 68 virtual void Graphics3DContextLost() { | 66 virtual void Graphics3DContextLost() { |
| 69 // TODO(vrk/fischman): Properly reset after a lost graphics context. In | 67 // TODO(vrk/fischman): Properly reset after a lost graphics context. In |
| 70 // particular need to delete context_ and re-create textures. | 68 // particular need to delete context_ and re-create textures. |
| 71 // Probably have to recreate the decoder from scratch, because old textures | 69 // Probably have to recreate the decoder from scratch, because old textures |
| 72 // can still be outstanding in the decoder! | 70 // can still be outstanding in the decoder! |
| 73 assert(false && "Unexpectedly lost graphics context"); | 71 assert(false && "Unexpectedly lost graphics context"); |
| 74 } | 72 } |
| 75 | 73 |
| 76 // pp::VideoDecoderClient_Dev implementation. | 74 // pp::VideoDecoderClient_Dev implementation. |
| 77 virtual void ProvidePictureBuffers( | 75 virtual void ProvidePictureBuffers(PP_Resource decoder, |
| 78 PP_Resource decoder, | 76 uint32_t req_num_of_bufs, |
| 79 uint32_t req_num_of_bufs, | 77 const PP_Size& dimensions, |
| 80 const PP_Size& dimensions, | 78 uint32_t texture_target); |
| 81 uint32_t texture_target); | |
| 82 virtual void DismissPictureBuffer(PP_Resource decoder, | 79 virtual void DismissPictureBuffer(PP_Resource decoder, |
| 83 int32_t picture_buffer_id); | 80 int32_t picture_buffer_id); |
| 84 virtual void PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture); | 81 virtual void PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture); |
| 85 virtual void NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error); | 82 virtual void NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error); |
| 86 | 83 |
| 87 private: | 84 private: |
| 88 enum { kNumConcurrentDecodes = 7, | 85 enum { |
| 89 kNumDecoders = 2 }; // Baked into viewport rendering. | 86 kNumConcurrentDecodes = 7, |
| 87 kNumDecoders = 2 |
| 88 }; // Baked into viewport rendering. |
| 90 | 89 |
| 91 // A single decoder's client interface. | 90 // A single decoder's client interface. |
| 92 class DecoderClient { | 91 class DecoderClient { |
| 93 public: | 92 public: |
| 94 DecoderClient(VideoDecodeDemoInstance* gles2, | 93 DecoderClient(VideoDecodeDemoInstance* gles2, |
| 95 pp::VideoDecoder_Dev* decoder); | 94 pp::VideoDecoder_Dev* decoder); |
| 96 ~DecoderClient(); | 95 ~DecoderClient(); |
| 97 | 96 |
| 98 void DecodeNextNALUs(); | 97 void DecodeNextNALUs(); |
| 99 | 98 |
| 100 // Per-decoder implementation of part of pp::VideoDecoderClient_Dev. | 99 // Per-decoder implementation of part of pp::VideoDecoderClient_Dev. |
| 101 void ProvidePictureBuffers( | 100 void ProvidePictureBuffers(uint32_t req_num_of_bufs, |
| 102 uint32_t req_num_of_bufs, | 101 PP_Size dimensions, |
| 103 PP_Size dimensions, | 102 uint32_t texture_target); |
| 104 uint32_t texture_target); | |
| 105 void DismissPictureBuffer(int32_t picture_buffer_id); | 103 void DismissPictureBuffer(int32_t picture_buffer_id); |
| 106 | 104 |
| 107 const PictureBufferInfo& GetPictureBufferInfoById(int id); | 105 const PictureBufferInfo& GetPictureBufferInfoById(int id); |
| 108 pp::VideoDecoder_Dev* decoder() { return decoder_; } | 106 pp::VideoDecoder_Dev* decoder() { return decoder_; } |
| 109 | 107 |
| 110 private: | 108 private: |
| 111 void DecodeNextNALU(); | 109 void DecodeNextNALU(); |
| 112 static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); | 110 static void GetNextNALUBoundary(size_t start_pos, size_t* end_pos); |
| 113 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); | 111 void DecoderBitstreamDone(int32_t result, int bitstream_buffer_id); |
| 114 void DecoderFlushDone(int32_t result); | 112 void DecoderFlushDone(int32_t result); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 130 | 128 |
| 131 // Initialize Video Decoders. | 129 // Initialize Video Decoders. |
| 132 void InitializeDecoders(); | 130 void InitializeDecoders(); |
| 133 | 131 |
| 134 // GL-related functions. | 132 // GL-related functions. |
| 135 void InitGL(); | 133 void InitGL(); |
| 136 GLuint CreateTexture(int32_t width, int32_t height, GLenum texture_target); | 134 GLuint CreateTexture(int32_t width, int32_t height, GLenum texture_target); |
| 137 void CreateGLObjects(); | 135 void CreateGLObjects(); |
| 138 void Create2DProgramOnce(); | 136 void Create2DProgramOnce(); |
| 139 void CreateRectangleARBProgramOnce(); | 137 void CreateRectangleARBProgramOnce(); |
| 140 Shader CreateProgram(const char* vertex_shader, | 138 Shader CreateProgram(const char* vertex_shader, const char* fragment_shader); |
| 141 const char* fragment_shader); | |
| 142 void CreateShader(GLuint program, GLenum type, const char* source, int size); | 139 void CreateShader(GLuint program, GLenum type, const char* source, int size); |
| 143 void DeleteTexture(GLuint id); | 140 void DeleteTexture(GLuint id); |
| 144 void PaintFinished(int32_t result, PP_Resource decoder, | 141 void PaintFinished(int32_t result, |
| 142 PP_Resource decoder, |
| 145 int picture_buffer_id); | 143 int picture_buffer_id); |
| 146 | 144 |
| 147 // Log an error to the developer console and stderr (though the latter may be | 145 // Log an error to the developer console and stderr (though the latter may be |
| 148 // closed due to sandboxing or blackholed for other reasons) by creating a | 146 // closed due to sandboxing or blackholed for other reasons) by creating a |
| 149 // temporary of this type and streaming to it. Example usage: | 147 // temporary of this type and streaming to it. Example usage: |
| 150 // LogError(this).s() << "Hello world: " << 42; | 148 // LogError(this).s() << "Hello world: " << 42; |
| 151 class LogError { | 149 class LogError { |
| 152 public: | 150 public: |
| 153 LogError(VideoDecodeDemoInstance* demo) : demo_(demo) {} | 151 LogError(VideoDecodeDemoInstance* demo) : demo_(demo) {} |
| 154 ~LogError() { | 152 ~LogError() { |
| 155 const std::string& msg = stream_.str(); | 153 const std::string& msg = stream_.str(); |
| 156 demo_->console_if_->Log(demo_->pp_instance(), PP_LOGLEVEL_ERROR, | 154 demo_->console_if_->Log( |
| 157 pp::Var(msg).pp_var()); | 155 demo_->pp_instance(), PP_LOGLEVEL_ERROR, pp::Var(msg).pp_var()); |
| 158 std::cerr << msg << std::endl; | 156 std::cerr << msg << std::endl; |
| 159 } | 157 } |
| 160 // Impl note: it would have been nicer to have LogError derive from | 158 // Impl note: it would have been nicer to have LogError derive from |
| 161 // std::ostringstream so that it can be streamed to directly, but lookup | 159 // std::ostringstream so that it can be streamed to directly, but lookup |
| 162 // rules turn streamed string literals to hex pointers on output. | 160 // rules turn streamed string literals to hex pointers on output. |
| 163 std::ostringstream& s() { return stream_; } | 161 std::ostringstream& s() { return stream_; } |
| 162 |
| 164 private: | 163 private: |
| 165 VideoDecodeDemoInstance* demo_; // Unowned. | 164 VideoDecodeDemoInstance* demo_; // Unowned. |
| 166 std::ostringstream stream_; | 165 std::ostringstream stream_; |
| 167 }; | 166 }; |
| 168 | 167 |
| 169 pp::Size plugin_size_; | 168 pp::Size plugin_size_; |
| 170 bool is_painting_; | 169 bool is_painting_; |
| 171 // When decode outpaces render, we queue up decoded pictures for later | 170 // When decode outpaces render, we queue up decoded pictures for later |
| 172 // painting. Elements are <decoder,picture>. | 171 // painting. Elements are <decoder,picture>. |
| 173 std::list<std::pair<PP_Resource, PP_Picture_Dev> > pictures_pending_paint_; | 172 std::list<std::pair<PP_Resource, PP_Picture_Dev> > pictures_pending_paint_; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 187 typedef std::map<int, DecoderClient*> Decoders; | 186 typedef std::map<int, DecoderClient*> Decoders; |
| 188 Decoders video_decoders_; | 187 Decoders video_decoders_; |
| 189 | 188 |
| 190 // Shader program to draw GL_TEXTURE_2D target. | 189 // Shader program to draw GL_TEXTURE_2D target. |
| 191 Shader shader_2d_; | 190 Shader shader_2d_; |
| 192 // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target. | 191 // Shader program to draw GL_TEXTURE_RECTANGLE_ARB target. |
| 193 Shader shader_rectangle_arb_; | 192 Shader shader_rectangle_arb_; |
| 194 }; | 193 }; |
| 195 | 194 |
| 196 VideoDecodeDemoInstance::DecoderClient::DecoderClient( | 195 VideoDecodeDemoInstance::DecoderClient::DecoderClient( |
| 197 VideoDecodeDemoInstance* gles2, pp::VideoDecoder_Dev* decoder) | 196 VideoDecodeDemoInstance* gles2, |
| 198 : gles2_(gles2), decoder_(decoder), callback_factory_(this), | 197 pp::VideoDecoder_Dev* decoder) |
| 198 : gles2_(gles2), |
| 199 decoder_(decoder), |
| 200 callback_factory_(this), |
| 199 next_picture_buffer_id_(0), | 201 next_picture_buffer_id_(0), |
| 200 next_bitstream_buffer_id_(0), encoded_data_next_pos_to_decode_(0) { | 202 next_bitstream_buffer_id_(0), |
| 203 encoded_data_next_pos_to_decode_(0) { |
| 201 } | 204 } |
| 202 | 205 |
| 203 VideoDecodeDemoInstance::DecoderClient::~DecoderClient() { | 206 VideoDecodeDemoInstance::DecoderClient::~DecoderClient() { |
| 204 delete decoder_; | 207 delete decoder_; |
| 205 decoder_ = NULL; | 208 decoder_ = NULL; |
| 206 | 209 |
| 207 for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin(); | 210 for (BitstreamBufferMap::iterator it = bitstream_buffers_by_id_.begin(); |
| 208 it != bitstream_buffers_by_id_.end(); ++it) { | 211 it != bitstream_buffers_by_id_.end(); |
| 212 ++it) { |
| 209 delete it->second; | 213 delete it->second; |
| 210 } | 214 } |
| 211 bitstream_buffers_by_id_.clear(); | 215 bitstream_buffers_by_id_.clear(); |
| 212 | 216 |
| 213 for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin(); | 217 for (PictureBufferMap::iterator it = picture_buffers_by_id_.begin(); |
| 214 it != picture_buffers_by_id_.end(); ++it) { | 218 it != picture_buffers_by_id_.end(); |
| 219 ++it) { |
| 215 gles2_->DeleteTexture(it->second.buffer.texture_id); | 220 gles2_->DeleteTexture(it->second.buffer.texture_id); |
| 216 } | 221 } |
| 217 picture_buffers_by_id_.clear(); | 222 picture_buffers_by_id_.clear(); |
| 218 } | 223 } |
| 219 | 224 |
| 220 VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance, | 225 VideoDecodeDemoInstance::VideoDecodeDemoInstance(PP_Instance instance, |
| 221 pp::Module* module) | 226 pp::Module* module) |
| 222 : pp::Instance(instance), pp::Graphics3DClient(this), | 227 : pp::Instance(instance), |
| 228 pp::Graphics3DClient(this), |
| 223 pp::VideoDecoderClient_Dev(this), | 229 pp::VideoDecoderClient_Dev(this), |
| 224 is_painting_(false), | 230 is_painting_(false), |
| 225 num_frames_rendered_(0), | 231 num_frames_rendered_(0), |
| 226 first_frame_delivered_ticks_(-1), | 232 first_frame_delivered_ticks_(-1), |
| 227 swap_ticks_(0), | 233 swap_ticks_(0), |
| 228 callback_factory_(this), | 234 callback_factory_(this), |
| 229 context_(NULL) { | 235 context_(NULL) { |
| 230 assert((console_if_ = static_cast<const PPB_Console*>( | 236 assert((console_if_ = static_cast<const PPB_Console*>( |
| 231 module->GetBrowserInterface(PPB_CONSOLE_INTERFACE)))); | 237 module->GetBrowserInterface(PPB_CONSOLE_INTERFACE)))); |
| 232 assert((core_if_ = static_cast<const PPB_Core*>( | 238 assert((core_if_ = static_cast<const PPB_Core*>( |
| 233 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); | 239 module->GetBrowserInterface(PPB_CORE_INTERFACE)))); |
| 234 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( | 240 assert((gles2_if_ = static_cast<const PPB_OpenGLES2*>( |
| 235 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); | 241 module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE)))); |
| 236 } | 242 } |
| 237 | 243 |
| 238 VideoDecodeDemoInstance::~VideoDecodeDemoInstance() { | 244 VideoDecodeDemoInstance::~VideoDecodeDemoInstance() { |
| 239 if (shader_2d_.program) | 245 if (shader_2d_.program) |
| 240 gles2_if_->DeleteProgram(context_->pp_resource(), shader_2d_.program); | 246 gles2_if_->DeleteProgram(context_->pp_resource(), shader_2d_.program); |
| 241 if (shader_rectangle_arb_.program) { | 247 if (shader_rectangle_arb_.program) { |
| 242 gles2_if_->DeleteProgram( | 248 gles2_if_->DeleteProgram(context_->pp_resource(), |
| 243 context_->pp_resource(), shader_rectangle_arb_.program); | 249 shader_rectangle_arb_.program); |
| 244 } | 250 } |
| 245 | 251 |
| 246 for (Decoders::iterator it = video_decoders_.begin(); | 252 for (Decoders::iterator it = video_decoders_.begin(); |
| 247 it != video_decoders_.end(); ++it) { | 253 it != video_decoders_.end(); |
| 254 ++it) { |
| 248 delete it->second; | 255 delete it->second; |
| 249 } | 256 } |
| 250 video_decoders_.clear(); | 257 video_decoders_.clear(); |
| 251 delete context_; | 258 delete context_; |
| 252 } | 259 } |
| 253 | 260 |
| 254 void VideoDecodeDemoInstance::DidChangeView( | 261 void VideoDecodeDemoInstance::DidChangeView(const pp::Rect& position, |
| 255 const pp::Rect& position, const pp::Rect& clip_ignored) { | 262 const pp::Rect& clip_ignored) { |
| 256 if (position.width() == 0 || position.height() == 0) | 263 if (position.width() == 0 || position.height() == 0) |
| 257 return; | 264 return; |
| 258 if (plugin_size_.width()) { | 265 if (plugin_size_.width()) { |
| 259 assert(position.size() == plugin_size_); | 266 assert(position.size() == plugin_size_); |
| 260 return; | 267 return; |
| 261 } | 268 } |
| 262 plugin_size_ = position.size(); | 269 plugin_size_ = position.size(); |
| 263 | 270 |
| 264 // Initialize graphics. | 271 // Initialize graphics. |
| 265 InitGL(); | 272 InitGL(); |
| 266 InitializeDecoders(); | 273 InitializeDecoders(); |
| 267 } | 274 } |
| 268 | 275 |
| 269 void VideoDecodeDemoInstance::InitializeDecoders() { | 276 void VideoDecodeDemoInstance::InitializeDecoders() { |
| 270 assert(video_decoders_.empty()); | 277 assert(video_decoders_.empty()); |
| 271 for (int i = 0; i < kNumDecoders; ++i) { | 278 for (int i = 0; i < kNumDecoders; ++i) { |
| 272 DecoderClient* client = new DecoderClient( | 279 DecoderClient* client = new DecoderClient( |
| 273 this, new pp::VideoDecoder_Dev( | 280 this, |
| 281 new pp::VideoDecoder_Dev( |
| 274 this, *context_, PP_VIDEODECODER_H264PROFILE_MAIN)); | 282 this, *context_, PP_VIDEODECODER_H264PROFILE_MAIN)); |
| 275 assert(!client->decoder()->is_null()); | 283 assert(!client->decoder()->is_null()); |
| 276 assert(video_decoders_.insert(std::make_pair( | 284 assert( |
| 277 client->decoder()->pp_resource(), client)).second); | 285 video_decoders_.insert(std::make_pair(client->decoder()->pp_resource(), |
| 286 client)).second); |
| 278 client->DecodeNextNALUs(); | 287 client->DecodeNextNALUs(); |
| 279 } | 288 } |
| 280 } | 289 } |
| 281 | 290 |
| 282 void VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone( | 291 void VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone( |
| 283 int32_t result, int bitstream_buffer_id) { | 292 int32_t result, |
| 293 int bitstream_buffer_id) { |
| 284 assert(bitstream_ids_at_decoder_.erase(bitstream_buffer_id) == 1); | 294 assert(bitstream_ids_at_decoder_.erase(bitstream_buffer_id) == 1); |
| 285 BitstreamBufferMap::iterator it = | 295 BitstreamBufferMap::iterator it = |
| 286 bitstream_buffers_by_id_.find(bitstream_buffer_id); | 296 bitstream_buffers_by_id_.find(bitstream_buffer_id); |
| 287 assert(it != bitstream_buffers_by_id_.end()); | 297 assert(it != bitstream_buffers_by_id_.end()); |
| 288 delete it->second; | 298 delete it->second; |
| 289 bitstream_buffers_by_id_.erase(it); | 299 bitstream_buffers_by_id_.erase(it); |
| 290 DecodeNextNALUs(); | 300 DecodeNextNALUs(); |
| 291 } | 301 } |
| 292 | 302 |
| 293 void VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone(int32_t result) { | 303 void VideoDecodeDemoInstance::DecoderClient::DecoderFlushDone(int32_t result) { |
| 294 assert(result == PP_OK); | 304 assert(result == PP_OK); |
| 295 // Check that each bitstream buffer ID we handed to the decoder got handed | 305 // Check that each bitstream buffer ID we handed to the decoder got handed |
| 296 // back to us. | 306 // back to us. |
| 297 assert(bitstream_ids_at_decoder_.empty()); | 307 assert(bitstream_ids_at_decoder_.empty()); |
| 298 delete decoder_; | 308 delete decoder_; |
| 299 decoder_ = NULL; | 309 decoder_ = NULL; |
| 300 } | 310 } |
| 301 | 311 |
| 302 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { | 312 static bool LookingAtNAL(const unsigned char* encoded, size_t pos) { |
| 303 return pos + 3 < kDataLen && | 313 return pos + 3 < kDataLen && encoded[pos] == 0 && encoded[pos + 1] == 0 && |
| 304 encoded[pos] == 0 && encoded[pos + 1] == 0 && | 314 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; |
| 305 encoded[pos + 2] == 0 && encoded[pos + 3] == 1; | |
| 306 } | 315 } |
| 307 | 316 |
| 308 void VideoDecodeDemoInstance::DecoderClient::GetNextNALUBoundary( | 317 void VideoDecodeDemoInstance::DecoderClient::GetNextNALUBoundary( |
| 309 size_t start_pos, size_t* end_pos) { | 318 size_t start_pos, |
| 319 size_t* end_pos) { |
| 310 assert(LookingAtNAL(kData, start_pos)); | 320 assert(LookingAtNAL(kData, start_pos)); |
| 311 *end_pos = start_pos; | 321 *end_pos = start_pos; |
| 312 *end_pos += 4; | 322 *end_pos += 4; |
| 313 while (*end_pos + 3 < kDataLen && | 323 while (*end_pos + 3 < kDataLen && !LookingAtNAL(kData, *end_pos)) { |
| 314 !LookingAtNAL(kData, *end_pos)) { | |
| 315 ++*end_pos; | 324 ++*end_pos; |
| 316 } | 325 } |
| 317 if (*end_pos + 3 >= kDataLen) { | 326 if (*end_pos + 3 >= kDataLen) { |
| 318 *end_pos = kDataLen; | 327 *end_pos = kDataLen; |
| 319 return; | 328 return; |
| 320 } | 329 } |
| 321 } | 330 } |
| 322 | 331 |
| 323 void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALUs() { | 332 void VideoDecodeDemoInstance::DecoderClient::DecodeNextNALUs() { |
| 324 while (encoded_data_next_pos_to_decode_ <= kDataLen && | 333 while (encoded_data_next_pos_to_decode_ <= kDataLen && |
| (...skipping 15 matching lines...) Expand all Loading... |
| 340 GetNextNALUBoundary(start_pos, &end_pos); | 349 GetNextNALUBoundary(start_pos, &end_pos); |
| 341 pp::Buffer_Dev* buffer = new pp::Buffer_Dev(gles2_, end_pos - start_pos); | 350 pp::Buffer_Dev* buffer = new pp::Buffer_Dev(gles2_, end_pos - start_pos); |
| 342 PP_VideoBitstreamBuffer_Dev bitstream_buffer; | 351 PP_VideoBitstreamBuffer_Dev bitstream_buffer; |
| 343 int id = ++next_bitstream_buffer_id_; | 352 int id = ++next_bitstream_buffer_id_; |
| 344 bitstream_buffer.id = id; | 353 bitstream_buffer.id = id; |
| 345 bitstream_buffer.size = end_pos - start_pos; | 354 bitstream_buffer.size = end_pos - start_pos; |
| 346 bitstream_buffer.data = buffer->pp_resource(); | 355 bitstream_buffer.data = buffer->pp_resource(); |
| 347 memcpy(buffer->data(), kData + start_pos, end_pos - start_pos); | 356 memcpy(buffer->data(), kData + start_pos, end_pos - start_pos); |
| 348 assert(bitstream_buffers_by_id_.insert(std::make_pair(id, buffer)).second); | 357 assert(bitstream_buffers_by_id_.insert(std::make_pair(id, buffer)).second); |
| 349 | 358 |
| 350 pp::CompletionCallback cb = | 359 pp::CompletionCallback cb = callback_factory_.NewCallback( |
| 351 callback_factory_.NewCallback( | 360 &VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone, id); |
| 352 &VideoDecodeDemoInstance::DecoderClient::DecoderBitstreamDone, id); | |
| 353 assert(bitstream_ids_at_decoder_.insert(id).second); | 361 assert(bitstream_ids_at_decoder_.insert(id).second); |
| 354 encoded_data_next_pos_to_decode_ = end_pos; | 362 encoded_data_next_pos_to_decode_ = end_pos; |
| 355 decoder_->Decode(bitstream_buffer, cb); | 363 decoder_->Decode(bitstream_buffer, cb); |
| 356 } | 364 } |
| 357 | 365 |
| 358 void VideoDecodeDemoInstance::ProvidePictureBuffers(PP_Resource decoder, | 366 void VideoDecodeDemoInstance::ProvidePictureBuffers(PP_Resource decoder, |
| 359 uint32_t req_num_of_bufs, | 367 uint32_t req_num_of_bufs, |
| 360 const PP_Size& dimensions, | 368 const PP_Size& dimensions, |
| 361 uint32_t texture_target) { | 369 uint32_t texture_target) { |
| 362 DecoderClient* client = video_decoders_[decoder]; | 370 DecoderClient* client = video_decoders_[decoder]; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 377 dimensions.width, dimensions.height, info.texture_target); | 385 dimensions.width, dimensions.height, info.texture_target); |
| 378 int id = ++next_picture_buffer_id_; | 386 int id = ++next_picture_buffer_id_; |
| 379 info.buffer.id = id; | 387 info.buffer.id = id; |
| 380 buffers.push_back(info.buffer); | 388 buffers.push_back(info.buffer); |
| 381 assert(picture_buffers_by_id_.insert(std::make_pair(id, info)).second); | 389 assert(picture_buffers_by_id_.insert(std::make_pair(id, info)).second); |
| 382 } | 390 } |
| 383 decoder_->AssignPictureBuffers(buffers); | 391 decoder_->AssignPictureBuffers(buffers); |
| 384 } | 392 } |
| 385 | 393 |
| 386 const PictureBufferInfo& | 394 const PictureBufferInfo& |
| 387 VideoDecodeDemoInstance::DecoderClient::GetPictureBufferInfoById( | 395 VideoDecodeDemoInstance::DecoderClient::GetPictureBufferInfoById(int id) { |
| 388 int id) { | |
| 389 PictureBufferMap::iterator it = picture_buffers_by_id_.find(id); | 396 PictureBufferMap::iterator it = picture_buffers_by_id_.find(id); |
| 390 assert(it != picture_buffers_by_id_.end()); | 397 assert(it != picture_buffers_by_id_.end()); |
| 391 return it->second; | 398 return it->second; |
| 392 } | 399 } |
| 393 | 400 |
| 394 void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder, | 401 void VideoDecodeDemoInstance::DismissPictureBuffer(PP_Resource decoder, |
| 395 int32_t picture_buffer_id) { | 402 int32_t picture_buffer_id) { |
| 396 DecoderClient* client = video_decoders_[decoder]; | 403 DecoderClient* client = video_decoders_[decoder]; |
| 397 assert(client); | 404 assert(client); |
| 398 client->DismissPictureBuffer(picture_buffer_id); | 405 client->DismissPictureBuffer(picture_buffer_id); |
| 399 } | 406 } |
| 400 | 407 |
| 401 void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer( | 408 void VideoDecodeDemoInstance::DecoderClient::DismissPictureBuffer( |
| 402 int32_t picture_buffer_id) { | 409 int32_t picture_buffer_id) { |
| 403 gles2_->DeleteTexture(GetPictureBufferInfoById( | 410 gles2_->DeleteTexture( |
| 404 picture_buffer_id).buffer.texture_id); | 411 GetPictureBufferInfoById(picture_buffer_id).buffer.texture_id); |
| 405 picture_buffers_by_id_.erase(picture_buffer_id); | 412 picture_buffers_by_id_.erase(picture_buffer_id); |
| 406 } | 413 } |
| 407 | 414 |
| 408 void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder, | 415 void VideoDecodeDemoInstance::PictureReady(PP_Resource decoder, |
| 409 const PP_Picture_Dev& picture) { | 416 const PP_Picture_Dev& picture) { |
| 410 if (first_frame_delivered_ticks_ == -1) | 417 if (first_frame_delivered_ticks_ == -1) |
| 411 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); | 418 assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); |
| 412 if (is_painting_) { | 419 if (is_painting_) { |
| 413 pictures_pending_paint_.push_back(std::make_pair(decoder, picture)); | 420 pictures_pending_paint_.push_back(std::make_pair(decoder, picture)); |
| 414 return; | 421 return; |
| 415 } | 422 } |
| 416 DecoderClient* client = video_decoders_[decoder]; | 423 DecoderClient* client = video_decoders_[decoder]; |
| 417 assert(client); | 424 assert(client); |
| 418 const PictureBufferInfo& info = | 425 const PictureBufferInfo& info = |
| 419 client->GetPictureBufferInfoById(picture.picture_buffer_id); | 426 client->GetPictureBufferInfoById(picture.picture_buffer_id); |
| 420 assert(!is_painting_); | 427 assert(!is_painting_); |
| 421 is_painting_ = true; | 428 is_painting_ = true; |
| 422 int x = 0; | 429 int x = 0; |
| 423 int y = 0; | 430 int y = 0; |
| 424 if (client != video_decoders_.begin()->second) { | 431 if (client != video_decoders_.begin()->second) { |
| 425 x = plugin_size_.width() / kNumDecoders; | 432 x = plugin_size_.width() / kNumDecoders; |
| 426 y = plugin_size_.height() / kNumDecoders; | 433 y = plugin_size_.height() / kNumDecoders; |
| 427 } | 434 } |
| 428 | 435 |
| 429 if (info.texture_target == GL_TEXTURE_2D) { | 436 if (info.texture_target == GL_TEXTURE_2D) { |
| 430 Create2DProgramOnce(); | 437 Create2DProgramOnce(); |
| 431 gles2_if_->UseProgram(context_->pp_resource(), shader_2d_.program); | 438 gles2_if_->UseProgram(context_->pp_resource(), shader_2d_.program); |
| 432 gles2_if_->Uniform2f( | 439 gles2_if_->Uniform2f( |
| 433 context_->pp_resource(), shader_2d_.texcoord_scale_location, 1.0, 1.0); | 440 context_->pp_resource(), shader_2d_.texcoord_scale_location, 1.0, 1.0); |
| 434 } else { | 441 } else { |
| 435 assert(info.texture_target == GL_TEXTURE_RECTANGLE_ARB); | 442 assert(info.texture_target == GL_TEXTURE_RECTANGLE_ARB); |
| 436 CreateRectangleARBProgramOnce(); | 443 CreateRectangleARBProgramOnce(); |
| 437 gles2_if_->UseProgram( | 444 gles2_if_->UseProgram(context_->pp_resource(), |
| 438 context_->pp_resource(), shader_rectangle_arb_.program); | 445 shader_rectangle_arb_.program); |
| 439 gles2_if_->Uniform2f(context_->pp_resource(), | 446 gles2_if_->Uniform2f(context_->pp_resource(), |
| 440 shader_rectangle_arb_.texcoord_scale_location, | 447 shader_rectangle_arb_.texcoord_scale_location, |
| 441 info.buffer.size.width, | 448 info.buffer.size.width, |
| 442 info.buffer.size.height); | 449 info.buffer.size.height); |
| 443 } | 450 } |
| 444 | 451 |
| 445 gles2_if_->Viewport(context_->pp_resource(), x, y, | 452 gles2_if_->Viewport(context_->pp_resource(), |
| 453 x, |
| 454 y, |
| 446 plugin_size_.width() / kNumDecoders, | 455 plugin_size_.width() / kNumDecoders, |
| 447 plugin_size_.height() / kNumDecoders); | 456 plugin_size_.height() / kNumDecoders); |
| 448 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); | 457 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); |
| 449 gles2_if_->BindTexture( | 458 gles2_if_->BindTexture( |
| 450 context_->pp_resource(), info.texture_target, info.buffer.texture_id); | 459 context_->pp_resource(), info.texture_target, info.buffer.texture_id); |
| 451 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); | 460 gles2_if_->DrawArrays(context_->pp_resource(), GL_TRIANGLE_STRIP, 0, 4); |
| 452 | 461 |
| 453 gles2_if_->UseProgram(context_->pp_resource(), 0); | 462 gles2_if_->UseProgram(context_->pp_resource(), 0); |
| 454 | 463 |
| 455 pp::CompletionCallback cb = | 464 pp::CompletionCallback cb = callback_factory_.NewCallback( |
| 456 callback_factory_.NewCallback( | 465 &VideoDecodeDemoInstance::PaintFinished, decoder, info.buffer.id); |
| 457 &VideoDecodeDemoInstance::PaintFinished, decoder, info.buffer.id); | |
| 458 last_swap_request_ticks_ = core_if_->GetTimeTicks(); | 466 last_swap_request_ticks_ = core_if_->GetTimeTicks(); |
| 459 assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING); | 467 assert(context_->SwapBuffers(cb) == PP_OK_COMPLETIONPENDING); |
| 460 } | 468 } |
| 461 | 469 |
| 462 void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder, | 470 void VideoDecodeDemoInstance::NotifyError(PP_Resource decoder, |
| 463 PP_VideoDecodeError_Dev error) { | 471 PP_VideoDecodeError_Dev error) { |
| 464 LogError(this).s() << "Received error: " << error; | 472 LogError(this).s() << "Received error: " << error; |
| 465 assert(false && "Unexpected error; see stderr for details"); | 473 assert(false && "Unexpected error; see stderr for details"); |
| 466 } | 474 } |
| 467 | 475 |
| 468 // This object is the global object representing this plugin library as long | 476 // This object is the global object representing this plugin library as long |
| 469 // as it is loaded. | 477 // as it is loaded. |
| 470 class VideoDecodeDemoModule : public pp::Module { | 478 class VideoDecodeDemoModule : public pp::Module { |
| 471 public: | 479 public: |
| 472 VideoDecodeDemoModule() : pp::Module() {} | 480 VideoDecodeDemoModule() : pp::Module() {} |
| 473 virtual ~VideoDecodeDemoModule() {} | 481 virtual ~VideoDecodeDemoModule() {} |
| 474 | 482 |
| 475 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 483 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
| 476 return new VideoDecodeDemoInstance(instance, this); | 484 return new VideoDecodeDemoInstance(instance, this); |
| 477 } | 485 } |
| 478 }; | 486 }; |
| 479 | 487 |
| 480 void VideoDecodeDemoInstance::InitGL() { | 488 void VideoDecodeDemoInstance::InitGL() { |
| 481 assert(plugin_size_.width() && plugin_size_.height()); | 489 assert(plugin_size_.width() && plugin_size_.height()); |
| 482 is_painting_ = false; | 490 is_painting_ = false; |
| 483 | 491 |
| 484 assert(!context_); | 492 assert(!context_); |
| 485 int32_t context_attributes[] = { | 493 int32_t context_attributes[] = { |
| 486 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, | 494 PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8, |
| 487 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, | 495 PP_GRAPHICS3DATTRIB_BLUE_SIZE, 8, |
| 488 PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, | 496 PP_GRAPHICS3DATTRIB_GREEN_SIZE, 8, |
| 489 PP_GRAPHICS3DATTRIB_RED_SIZE, 8, | 497 PP_GRAPHICS3DATTRIB_RED_SIZE, 8, |
| 490 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, | 498 PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 0, |
| 491 PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, | 499 PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 0, |
| 492 PP_GRAPHICS3DATTRIB_SAMPLES, 0, | 500 PP_GRAPHICS3DATTRIB_SAMPLES, 0, |
| 493 PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, | 501 PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS, 0, |
| 494 PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(), | 502 PP_GRAPHICS3DATTRIB_WIDTH, plugin_size_.width(), |
| 495 PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(), | 503 PP_GRAPHICS3DATTRIB_HEIGHT, plugin_size_.height(), |
| 496 PP_GRAPHICS3DATTRIB_NONE, | 504 PP_GRAPHICS3DATTRIB_NONE, |
| 497 }; | 505 }; |
| 498 context_ = new pp::Graphics3D(this, context_attributes); | 506 context_ = new pp::Graphics3D(this, context_attributes); |
| 499 assert(!context_->is_null()); | 507 assert(!context_->is_null()); |
| 500 assert(BindGraphics(*context_)); | 508 assert(BindGraphics(*context_)); |
| 501 | 509 |
| 502 // Clear color bit. | 510 // Clear color bit. |
| 503 gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1); | 511 gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1); |
| 504 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); | 512 gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT); |
| 505 | 513 |
| 506 assertNoGLError(); | 514 assertNoGLError(); |
| 507 | 515 |
| 508 CreateGLObjects(); | 516 CreateGLObjects(); |
| 509 } | 517 } |
| 510 | 518 |
| 511 void VideoDecodeDemoInstance::PaintFinished(int32_t result, PP_Resource decoder, | 519 void VideoDecodeDemoInstance::PaintFinished(int32_t result, |
| 512 int picture_buffer_id) { | 520 PP_Resource decoder, |
| 521 int picture_buffer_id) { |
| 513 assert(result == PP_OK); | 522 assert(result == PP_OK); |
| 514 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_; | 523 swap_ticks_ += core_if_->GetTimeTicks() - last_swap_request_ticks_; |
| 515 is_painting_ = false; | 524 is_painting_ = false; |
| 516 ++num_frames_rendered_; | 525 ++num_frames_rendered_; |
| 517 if (num_frames_rendered_ % 50 == 0) { | 526 if (num_frames_rendered_ % 50 == 0) { |
| 518 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; | 527 double elapsed = core_if_->GetTimeTicks() - first_frame_delivered_ticks_; |
| 519 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; | 528 double fps = (elapsed > 0) ? num_frames_rendered_ / elapsed : 1000; |
| 520 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; | 529 double ms_per_swap = (swap_ticks_ * 1e3) / num_frames_rendered_; |
| 521 LogError(this).s() << "Rendered frames: " << num_frames_rendered_ | 530 LogError(this).s() << "Rendered frames: " << num_frames_rendered_ |
| 522 << ", fps: " << fps << ", with average ms/swap of: " | 531 << ", fps: " << fps |
| 523 << ms_per_swap; | 532 << ", with average ms/swap of: " << ms_per_swap; |
| 524 } | 533 } |
| 525 DecoderClient* client = video_decoders_[decoder]; | 534 DecoderClient* client = video_decoders_[decoder]; |
| 526 if (client && client->decoder()) | 535 if (client && client->decoder()) |
| 527 client->decoder()->ReusePictureBuffer(picture_buffer_id); | 536 client->decoder()->ReusePictureBuffer(picture_buffer_id); |
| 528 if (!pictures_pending_paint_.empty()) { | 537 if (!pictures_pending_paint_.empty()) { |
| 529 std::pair<PP_Resource, PP_Picture_Dev> decoder_picture = | 538 std::pair<PP_Resource, PP_Picture_Dev> decoder_picture = |
| 530 pictures_pending_paint_.front(); | 539 pictures_pending_paint_.front(); |
| 531 pictures_pending_paint_.pop_front(); | 540 pictures_pending_paint_.pop_front(); |
| 532 PictureReady(decoder_picture.first, decoder_picture.second); | 541 PictureReady(decoder_picture.first, decoder_picture.second); |
| 533 } | 542 } |
| 534 } | 543 } |
| 535 | 544 |
| 536 GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width, | 545 GLuint VideoDecodeDemoInstance::CreateTexture(int32_t width, |
| 537 int32_t height, | 546 int32_t height, |
| 538 GLenum texture_target) { | 547 GLenum texture_target) { |
| 539 GLuint texture_id; | 548 GLuint texture_id; |
| 540 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); | 549 gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id); |
| 541 assertNoGLError(); | 550 assertNoGLError(); |
| 542 // Assign parameters. | 551 // Assign parameters. |
| 543 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); | 552 gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0); |
| 544 gles2_if_->BindTexture(context_->pp_resource(), texture_target, texture_id); | 553 gles2_if_->BindTexture(context_->pp_resource(), texture_target, texture_id); |
| 545 gles2_if_->TexParameteri( | 554 gles2_if_->TexParameteri(context_->pp_resource(), |
| 546 context_->pp_resource(), texture_target, GL_TEXTURE_MIN_FILTER, | 555 texture_target, |
| 547 GL_NEAREST); | 556 GL_TEXTURE_MIN_FILTER, |
| 548 gles2_if_->TexParameteri( | 557 GL_NEAREST); |
| 549 context_->pp_resource(), texture_target, GL_TEXTURE_MAG_FILTER, | 558 gles2_if_->TexParameteri(context_->pp_resource(), |
| 550 GL_NEAREST); | 559 texture_target, |
| 551 gles2_if_->TexParameterf( | 560 GL_TEXTURE_MAG_FILTER, |
| 552 context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_S, | 561 GL_NEAREST); |
| 553 GL_CLAMP_TO_EDGE); | 562 gles2_if_->TexParameterf(context_->pp_resource(), |
| 554 gles2_if_->TexParameterf( | 563 texture_target, |
| 555 context_->pp_resource(), texture_target, GL_TEXTURE_WRAP_T, | 564 GL_TEXTURE_WRAP_S, |
| 556 GL_CLAMP_TO_EDGE); | 565 GL_CLAMP_TO_EDGE); |
| 566 gles2_if_->TexParameterf(context_->pp_resource(), |
| 567 texture_target, |
| 568 GL_TEXTURE_WRAP_T, |
| 569 GL_CLAMP_TO_EDGE); |
| 557 | 570 |
| 558 if (texture_target == GL_TEXTURE_2D) { | 571 if (texture_target == GL_TEXTURE_2D) { |
| 559 gles2_if_->TexImage2D( | 572 gles2_if_->TexImage2D(context_->pp_resource(), |
| 560 context_->pp_resource(), texture_target, 0, GL_RGBA, width, height, 0, | 573 texture_target, |
| 561 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | 574 0, |
| 575 GL_RGBA, |
| 576 width, |
| 577 height, |
| 578 0, |
| 579 GL_RGBA, |
| 580 GL_UNSIGNED_BYTE, |
| 581 NULL); |
| 562 } | 582 } |
| 563 assertNoGLError(); | 583 assertNoGLError(); |
| 564 return texture_id; | 584 return texture_id; |
| 565 } | 585 } |
| 566 | 586 |
| 567 void VideoDecodeDemoInstance::DeleteTexture(GLuint id) { | 587 void VideoDecodeDemoInstance::DeleteTexture(GLuint id) { |
| 568 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id); | 588 gles2_if_->DeleteTextures(context_->pp_resource(), 1, &id); |
| 569 } | 589 } |
| 570 | 590 |
| 571 void VideoDecodeDemoInstance::CreateGLObjects() { | 591 void VideoDecodeDemoInstance::CreateGLObjects() { |
| 572 // Assign vertex positions and texture coordinates to buffers for use in | 592 // Assign vertex positions and texture coordinates to buffers for use in |
| 573 // shader program. | 593 // shader program. |
| 574 static const float kVertices[] = { | 594 static const float kVertices[] = { |
| 575 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. | 595 -1, 1, -1, -1, 1, 1, 1, -1, // Position coordinates. |
| 576 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. | 596 0, 1, 0, 0, 1, 1, 1, 0, // Texture coordinates. |
| 577 }; | 597 }; |
| 578 | 598 |
| 579 GLuint buffer; | 599 GLuint buffer; |
| 580 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); | 600 gles2_if_->GenBuffers(context_->pp_resource(), 1, &buffer); |
| 581 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); | 601 gles2_if_->BindBuffer(context_->pp_resource(), GL_ARRAY_BUFFER, buffer); |
| 582 | 602 |
| 583 gles2_if_->BufferData(context_->pp_resource(), GL_ARRAY_BUFFER, | 603 gles2_if_->BufferData(context_->pp_resource(), |
| 584 sizeof(kVertices), kVertices, GL_STATIC_DRAW); | 604 GL_ARRAY_BUFFER, |
| 605 sizeof(kVertices), |
| 606 kVertices, |
| 607 GL_STATIC_DRAW); |
| 585 assertNoGLError(); | 608 assertNoGLError(); |
| 586 } | 609 } |
| 587 | 610 |
| 588 static const char kVertexShader[] = | 611 static const char kVertexShader[] = |
| 589 "varying vec2 v_texCoord; \n" | 612 "varying vec2 v_texCoord; \n" |
| 590 "attribute vec4 a_position; \n" | 613 "attribute vec4 a_position; \n" |
| 591 "attribute vec2 a_texCoord; \n" | 614 "attribute vec2 a_texCoord; \n" |
| 592 "uniform vec2 v_scale; \n" | 615 "uniform vec2 v_scale; \n" |
| 593 "void main() \n" | 616 "void main() \n" |
| 594 "{ \n" | 617 "{ \n" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 shader_rectangle_arb_ = | 649 shader_rectangle_arb_ = |
| 627 CreateProgram(kVertexShader, kFragmentShaderRectangle); | 650 CreateProgram(kVertexShader, kFragmentShaderRectangle); |
| 628 } | 651 } |
| 629 | 652 |
| 630 Shader VideoDecodeDemoInstance::CreateProgram(const char* vertex_shader, | 653 Shader VideoDecodeDemoInstance::CreateProgram(const char* vertex_shader, |
| 631 const char* fragment_shader) { | 654 const char* fragment_shader) { |
| 632 Shader shader; | 655 Shader shader; |
| 633 | 656 |
| 634 // Create shader program. | 657 // Create shader program. |
| 635 shader.program = gles2_if_->CreateProgram(context_->pp_resource()); | 658 shader.program = gles2_if_->CreateProgram(context_->pp_resource()); |
| 636 CreateShader(shader.program, GL_VERTEX_SHADER, vertex_shader, | 659 CreateShader( |
| 637 strlen(vertex_shader)); | 660 shader.program, GL_VERTEX_SHADER, vertex_shader, strlen(vertex_shader)); |
| 638 CreateShader(shader.program, GL_FRAGMENT_SHADER, fragment_shader, | 661 CreateShader(shader.program, |
| 662 GL_FRAGMENT_SHADER, |
| 663 fragment_shader, |
| 639 strlen(fragment_shader)); | 664 strlen(fragment_shader)); |
| 640 gles2_if_->LinkProgram(context_->pp_resource(), shader.program); | 665 gles2_if_->LinkProgram(context_->pp_resource(), shader.program); |
| 641 gles2_if_->UseProgram(context_->pp_resource(), shader.program); | 666 gles2_if_->UseProgram(context_->pp_resource(), shader.program); |
| 642 gles2_if_->Uniform1i( | 667 gles2_if_->Uniform1i( |
| 643 context_->pp_resource(), | 668 context_->pp_resource(), |
| 644 gles2_if_->GetUniformLocation( | 669 gles2_if_->GetUniformLocation( |
| 645 context_->pp_resource(), shader.program, "s_texture"), 0); | 670 context_->pp_resource(), shader.program, "s_texture"), |
| 671 0); |
| 646 assertNoGLError(); | 672 assertNoGLError(); |
| 647 | 673 |
| 648 shader.texcoord_scale_location = gles2_if_->GetUniformLocation( | 674 shader.texcoord_scale_location = gles2_if_->GetUniformLocation( |
| 649 context_->pp_resource(), shader.program, "v_scale"); | 675 context_->pp_resource(), shader.program, "v_scale"); |
| 650 | 676 |
| 651 GLint pos_location = gles2_if_->GetAttribLocation( | 677 GLint pos_location = gles2_if_->GetAttribLocation( |
| 652 context_->pp_resource(), shader.program, "a_position"); | 678 context_->pp_resource(), shader.program, "a_position"); |
| 653 GLint tc_location = gles2_if_->GetAttribLocation( | 679 GLint tc_location = gles2_if_->GetAttribLocation( |
| 654 context_->pp_resource(), shader.program, "a_texCoord"); | 680 context_->pp_resource(), shader.program, "a_texCoord"); |
| 655 assertNoGLError(); | 681 assertNoGLError(); |
| 656 | 682 |
| 657 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location); | 683 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), pos_location); |
| 658 gles2_if_->VertexAttribPointer(context_->pp_resource(), pos_location, 2, | 684 gles2_if_->VertexAttribPointer( |
| 659 GL_FLOAT, GL_FALSE, 0, 0); | 685 context_->pp_resource(), pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0); |
| 660 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location); | 686 gles2_if_->EnableVertexAttribArray(context_->pp_resource(), tc_location); |
| 661 gles2_if_->VertexAttribPointer( | 687 gles2_if_->VertexAttribPointer( |
| 662 context_->pp_resource(), tc_location, 2, GL_FLOAT, GL_FALSE, 0, | 688 context_->pp_resource(), |
| 689 tc_location, |
| 690 2, |
| 691 GL_FLOAT, |
| 692 GL_FALSE, |
| 693 0, |
| 663 static_cast<float*>(0) + 8); // Skip position coordinates. | 694 static_cast<float*>(0) + 8); // Skip position coordinates. |
| 664 | 695 |
| 665 gles2_if_->UseProgram(context_->pp_resource(), 0); | 696 gles2_if_->UseProgram(context_->pp_resource(), 0); |
| 666 assertNoGLError(); | 697 assertNoGLError(); |
| 667 return shader; | 698 return shader; |
| 668 } | 699 } |
| 669 | 700 |
| 670 void VideoDecodeDemoInstance::CreateShader( | 701 void VideoDecodeDemoInstance::CreateShader(GLuint program, |
| 671 GLuint program, GLenum type, const char* source, int size) { | 702 GLenum type, |
| 703 const char* source, |
| 704 int size) { |
| 672 GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type); | 705 GLuint shader = gles2_if_->CreateShader(context_->pp_resource(), type); |
| 673 gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size); | 706 gles2_if_->ShaderSource(context_->pp_resource(), shader, 1, &source, &size); |
| 674 gles2_if_->CompileShader(context_->pp_resource(), shader); | 707 gles2_if_->CompileShader(context_->pp_resource(), shader); |
| 675 gles2_if_->AttachShader(context_->pp_resource(), program, shader); | 708 gles2_if_->AttachShader(context_->pp_resource(), program, shader); |
| 676 gles2_if_->DeleteShader(context_->pp_resource(), shader); | 709 gles2_if_->DeleteShader(context_->pp_resource(), shader); |
| 677 } | 710 } |
| 678 } // anonymous namespace | 711 } // anonymous namespace |
| 679 | 712 |
| 680 namespace pp { | 713 namespace pp { |
| 681 // Factory function for your specialization of the Module object. | 714 // Factory function for your specialization of the Module object. |
| 682 Module* CreateModule() { | 715 Module* CreateModule() { |
| 683 return new VideoDecodeDemoModule(); | 716 return new VideoDecodeDemoModule(); |
| 684 } | 717 } |
| 685 } // namespace pp | 718 } // namespace pp |
| OLD | NEW |